02
Apr 10

Poweshell Nested Folder ACL/Permissions Comparison Script

I have been learning and experimenting with Powershell for some daily admin tasks. I plan to post any helpful scripts I come up with. Here is my first one!

With credit to antize for the starting point, I created this powershell script to loop through a nested directory structure and compare permissions.  This was to support a migration of files from one server to another.

The directory structure was:

-Project
----Area
--------Task

The script recurses through a folder on the Source and Target paths and compares ACLs on the Task folders. Any folders that have non-matching permissions are printed to an output file. Feel free to take and modify this for yourself!

#CompareNetworkACL.ps1
[System.IO.FileInfo] $outputFile = "C:\temp\AclCompareDump.txt"
[System.IO.DirectoryInfo] $searchDirSource = Read-Host -Prompt "Enter source project folder path to search"
[System.IO.DirectoryInfo] $searchDirTarget = Read-Host -Prompt "Enter target project folder path to search"

if ($outputFile.Exists)
{
    $outputFile.Delete()
}

if ($searchDirSource.Exists -and $searchDirTarget.Exists)
{
   foreach ( $sourceProject in $( Get-ChildItem $searchDirSource | where { $_.psIsContainer -eq $true } ) ) {
        $targetProject = Get-Item $($searchDirTarget.FullName + "\" + $sourceProject.Name)

        foreach ( $sourceArea in $( Get-ChildItem $sourceProject.FullName | where { $_.psIsContainer -eq $true } ) ) {
            $targetArea = Get-Item $($targetProject.FullName + "\" + $sourceArea.Name)

            foreach ($sourceTaskFolder in $($sourceArea | Get-ChildItem | where { $_.psIsContainer -eq $true }) ){
                $targetTaskFolder = Get-Item $($targetArea.FullName + "\" + $sourceTaskFolder.Name)

                $currentAcl = Get-Acl $sourceTaskFolder.FullName
                $refacl = Get-Acl $targetTaskFolder.Fullname

                Write-Progress -Activity "Searching source for folder ACLs..." -Status ("Comparing " + $sourceTaskFolder.FullName + " to " + $targetTaskFolder.FullName)

                $comparison = compare-object $refacl $currentAcl -Property Access
                if ($comparison -ne $null)
                {
                    $sourceTaskFolder.Fullname | Out-File $outputFile.FullName -Append
                    [int] $hits += 1
                }
                $comparison = $null
            }
        }
    }

    if ($hits)
    {
        & notepad.exe $outputFile.Fullname
    }
    else
    {
        Write-Warning "All target ACLs matched the source ACLs."
    }
}