Question:
I am trying to write a recursive function that will return information in an array, however when I put a return statement into the function it misses certain entries.
I am trying to recursively look through a specified depth of folders getting the acl’s associated with the folder. I know getChildItem has a recurse option, but I only want to step through 3 levels of folders.
The excerpt of code below is what I have been using for testing. When getACLS is called without a return statement (commented out below) the results are:
Folder 1
Folder 12
Folder 13
Folder 2
When the return statement is used I get the following output:
Folder 1
Folder 12
So it looks like the return statement is exiting out from the recursive loop?
The idea is that I want to return a multidimensional array like [folder name, [acls], [[subfolder, [permissions],[[…]]]]] etc.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
cls function getACLS ([string]$path, [int]$max, [int]$current) { $dirs = Get-ChildItem -Path $path | Where { $_.psIsContainer } $acls = Get-Acl -Path $path $security = @() foreach ($acl in $acls.Access) { $security += ($acl.IdentityReference, $acl.FileSystemRights) } if ($current -le $max) { if ($dirs) { foreach ($dir in $dirs) { $newPath = $path + '\' + $dir.Name Write-Host $dir.Name # return ($newPath, $security, getACLS $newPath $max ($current+1)) # getACLS $newPath $max ($current+1) return getACLS $newPath $max ($current+1) } } } elseif ($current -eq $max ) { Write-Host max return ($path, $security) } } $results = getACLS "PATH\Testing" 2 0 |
Answer:
The problem was the location of the return. I had it inside the foreach loop, meaning it was trying to return multiple times in the one function. I moved it outside the foreach, into the if statement instead.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
function getACLS ([string]$path, [int]$max, [int]$current) { $dirs = Get-ChildItem -Path $path | Where { $_.psIsContainer } $acls = Get-Acl -Path $path $security = @() $results = @() foreach ($acl in $acls.Access) { $security += ($acl.IdentityReference, $acl.FileSystemRights) } if ($current -lt $max) { if ($dirs) { foreach ($dir in $dirs) { $newPath = $path + '\' + $dir.Name $next = $current + 1 $results += (getACLS $newPath $max $next) } } else { $results = ($path, $security) } return ($path, $security, $results) } elseif ($current -eq $max ) { return ($path, $security) } } |