1

I am recursively getting a list of folders with their respective permissions in a powershell script, however when the recursive part happens my output string keeps printing the folder structure each time an example of this is:

I have a folder called C:\temp, within that folder are 2 empty folders C:\temp\folder1 and C:\temp\folder2. With my script the output would be:

I have left out the permissions for readability

C:\temp
C:\temp\folder1
C:\temp
C:\temp\folder2

I don't want this to happen I want a list of folders with their permissions and then if the permissions on a child folder are different then look at the get the child folders of that folder. This works apart from the string building which I think I need a fresh pair of eyes to look at it because I'm getting nowhere.

Appreciate the help in advance,

Sam

CODE:

Add-Type -AssemblyName System.Windows.Forms
Import-Module ActiveDirectory
$info = ""
$OutputString
$step = 0
function DisplayForm{

#Some GUI code
#$textBox takes in the base folder from the user

    if ($result -eq [System.Windows.Forms.DialogResult]::OK)
    {
        $baseFolder = $textBox.Text

        $ParentProperties = (Get-Acl $baseFolder).Access| Select-Object -ExpandProperty IdentityReference
        $OutputString = $OutputString + $baseFolder + "`r`n" + $ParentProperties + "`r`n`r`n"
        $ChildFolders = Get-ChildItem $baseFolder | where {$_.Attributes -eq 'Directory'}

        FindPriorities($baseFolder)


        $info = "SAVED TO FOLDER"
        outputList

    }
}

function FindPriorities{
    param($fileName)
    $ChildFolders = Get-ChildItem $fileName | where {$_.Attributes -eq 'Directory'}
    $step = $step + 1
    $TempString = ""
    foreach ($folder in $ChildFolders){
        $child = $fileName + "\\" + $folder.name

    $ParentProperties = (Get-Acl $fileName).Access| Select-Object -ExpandProperty IdentityReference
    $ChildProperties = (Get-Acl $child).Access| Select-Object -ExpandProperty IdentityReference
    $parentString=""

    foreach ($p in $ParentProperties){
        $parentString= $parentString + $p
    }
    $childString=""
    foreach ($c in $childProperties){
        $childString = $childString + $c
    }

    if($childString -ne $parentString){
        $OutputString = $OutputString + $child + "`r`n" + $ChildProperties + "`r`n`r`n"
        FindPriorities ($child)
    }else{
        $OutputString = $OutputString + $child + "`r`n" + $ChildProperties + "`r`n`r`n"
    }

}
}

function outputList{
    $OutputString

}


DisplayForm
Sam Lucas
  • 233
  • 1
  • 4
  • 16
  • You have the same foreach code in `DisplayForm` that's in `FindPriorities` so its all being run twice. (`foreach ($folder in $ChildFolders){ ... }`). Your also calling `DisplayForm` again at the end of the function `DisplayForm` – Richard Jun 30 '16 at 09:48
  • Yes that's just for the sub folders in the base folder, then if it has one that has different permissions it goes into that and finds the sub folders – Sam Lucas Jun 30 '16 at 09:51
  • ---folder1 -----------folder 2(Same permissions) -----------folder 3(Different Permissions) --------------------------------------folder 4...... and so on. I always want it to come back and check through the rest of the folders in the base folder that's why I have it like this – Sam Lucas Jun 30 '16 at 09:53
  • Could you not just give the root search folder (`$baseFolder`) to `FindPriorities` and let it deal with all the child folders. Then you wouldn't need the duplicate code in `DisplayForm`? – Richard Jun 30 '16 at 09:56
  • I could, I'll give that a go now, but wouldn't that then skip over any remaining folders in the base if one is found to have different permissions? – Sam Lucas Jun 30 '16 at 09:58
  • It actually does all the folders like that, I thought it would lose some when it went down a level. The problem is still there with the string building though, it seems like it overwrites the string each time and I have no idea why because all I'm doing is adding to the existing string each time. – Sam Lucas Jun 30 '16 at 10:06
  • The line `$OutputString + $TempString` what's is it meant to be doing? As this will just produce output to the shell and not add the `$TempString` to the output string? – Richard Jun 30 '16 at 10:12
  • That was an experiment, I thought I had taken it out, what it is now: `$OutputString = $OutputString + $child + "`r`n" + $ChildProperties + "`r`n`r`n"` I'll change it in the code – Sam Lucas Jun 30 '16 at 10:16

1 Answers1

2

I think I understood what you want to do.

Please give this snippet a try:

function Get-IdentityReference($path) {    
    Get-Acl $path |
        Select-Object -ExpandProperty Access |
        Select-Object -ExpandProperty IdentityReference    
}

function Extract-Permissions($baseFolder) {
    $folders = Get-ChildItem $baseFolder | Where-Object { $_.PSisContainer }
    $baseACL = Get-IdentityReference $baseFolder

    "$baseFolder : $baseACL"

    foreach($folder in $folders) {
        $folderACL = Get-IdentityReference $folder.FullName
        $childFolders = Get-ChildItem $folder.FullName | Where-Object { $_.PSisContainer }

        "$($folder.FullName) : $folderACL"

        foreach($childFolder in $childFolders) {
            $childACL = Get-IdentityReference $childFolder.FullName

            if(Compare-Object $childACL $folderACL) {
                Extract-Permissions $childFolder.FullName
            } else {
                "$($childFolder.FullName) : $childACL"
            }
        }
    }
}

$baseFolder = "$env:USERPROFILE\Desktop"

Extract-Permissions $baseFolder
sodawillow
  • 12,497
  • 4
  • 34
  • 44
  • This seems to do what I want, I have changed the `Where-Object { $_.PSisContainer }` to `where {$_.Attributes -eq 'Directory'}` as it seemed to not like the first way for some reason. There is one error which I think may be because some folders have no subfolders but once that is sorted then I think this will work! Thanks. – Sam Lucas Jun 30 '16 at 10:37
  • You are welcome. Please read this : http://stackoverflow.com/questions/3085295/how-do-i-get-only-directories-using-get-childitem. `$_.Attributes -eq 'Directory'` will fail in numerous cases, for example with read-only directories. – sodawillow Jun 30 '16 at 10:48
  • Yeah sorry, I thought that was giving an error at first but now I've changed it back its fine. The part that was giving an error was the function Get-IdentityReference, so in this case I changed each line where that was called to `(Get-Acl $folder.FullName).Access | Select-Object -ExpandProperty IdentityReference` I will edit my question with the working code when its finished but this is the answer I will pick. – Sam Lucas Jun 30 '16 at 10:57
  • As this bit was used 3 times I thought it would be best to make it a function. – sodawillow Jun 30 '16 at 11:20