windowspowershellactive-directorynetwork-share

Get Information from Shares with Information to create the folders in a new Domain


so I am helping with the migration of the data to another company which bought the first one, for which I have to export Foldernames, User-Names and Permissions in an .csv File. I have a working Skript but it seems to be taking an awful long amount of time. It worked with a few shares which don´t have too much folders, but now I have run into scripts running for multiple hours(100.000+ Folders). From the smaller shares I know it gives me the correct information but it is taking to long for the amount of shares left.

$FolderPath = dir -Directory -LiteralPath "\\?\UNC\Server\Share" -Recurse -Force
$Report = @()
Foreach ($Folder in $FolderPath) {
    $Acl = Get-Acl -Path $Folder.FullName
    foreach ($Access in $acl.Access){
            $Properties = [ordered]@{
                'FolderName'=$Folder.FullName
                'AD Group or User'=$Access.IdentityReference
                'Permissions'=$Access.FileSystemRights
                'Inherited'=$Access.IsInherited
            }
            $Report += New-Object -TypeName PSObject -Property $Properties
   }
}
$Report | Export-Csv -path "C:\Filepath\export.csv" -Delimiter ";" -Encoding UTF8

Am I missing a simple thing why its taking so long or did I just mess up completely? I just don´t seem to find it.

Any help would be very much appreciated Thanks in Advance

Michael


Solution

  • As commented, building the $Report array by adding new items to it with += is a very time and memory consuming way.

    It is way quicker to let PowerShell do the collecting like below.

    Also, Get-ChildItem (alias dir) can be slow, especially when dealing with many subfolders, so using RoboCopy could be a faster alternative for this.

    # get the list of directory full path names
    # Get-ChildItem can be slow, so maybe try Robocopy as alternative
    # $Folders = (Get-ChildItem -Directory -LiteralPath "\\?\UNC\Server\Share" -Recurse -Force).FullName
    
    $Folders = (robocopy "\\Server\Share" NULL /L /E /NP /NFL /XJ /NC /NJH /NJS /R:0 /W:0) -replace '^\s*\d*\s*'
    $Report  = foreach ($Folder in $Folders) {
        $Acl = Get-Acl -Path $Folder
        foreach ($Access in $Acl.Access){
            [PsCustomObject]@{
                'FolderName'       = $Folder
                'AD Group or User' = $Access.IdentityReference
                'Permissions'      = $Access.FileSystemRights.ToString()
                'Inherited'        = $Access.IsInherited
            }
       }
    }
    $Report | Export-Csv -Path "C:\Filepath\export.csv" -Delimiter ";" -Encoding UTF8