0

I'm trying to limit the recursion depth for this script that generates a list of folders, associated security groups, and the members of each group. I'm using PowerShell 5.1.

I've tried adding -Depth 3 on line 18 (as seen below), but I still get all levels. I've tried adding -Depth 3 on the command line when I run the script, but that errors.

This is the command I used to run the script:

./Get_folder_acls_depth_test.ps1 -Path I:\dir_name -Recurse | Export-Csv c:\temp\dir_name.csv

I tried this also, but got an error:

./Get_folder_acls_depth_test.ps1 -Path I:\dir_name -Recurse -Depth 3 | Export-Csv c:\temp\dir_name.csv

[CmdletBinding()]
Param(
    [ValidateScript({Test-Path $_ -PathType Container})]
    [Parameter(Mandatory=$true)]
    [string]$Path,
    [switch]$Recurse
)

Write-Verbose "$(Get-Date): Script begins!"
Write-Verbose "Getting domain name..."
$Domain = (Get-ADDomain).NetBIOSName

Write-Verbose "Getting ACLs for folder $Path"

if ($Recurse) {
    Write-Verbose "...and all sub-folders"
    Write-Verbose "Gathering all folder names, this could take a long time on bigger folder trees..."
    $Folders = Get-ChildItem -Path $Path -Directory -Recurse -Depth 3
} else {
    $Folders = Get-Item -Path $Path
}

Write-Verbose "Gathering ACL's for $($Folders.Count) folders..."
foreach ($Folder in $Folders) {
    Write-Verbose "Working on $($Folder.FullName)..."
    $ACLs = Get-Acl $Folder.FullName | ForEach-Object { $_.Access }
    foreach ($ACL in $ACLs) {
        if ($ACL.IdentityReference -match "\\") {
            if ($ACL.IdentityReference.Value.Split("\")[0].ToUpper() -eq $Domain.ToUpper()) {
                $Name = $ACL.IdentityReference.Value.Split("\")[1]
                if ((Get-ADObject -Filter 'SamAccountName -eq $Name').ObjectClass -eq "group") {
                    foreach ($User in (Get-ADGroupMember $Name -Recursive | Select -ExpandProperty Name)) {
                        $Result = New-Object PSObject -Property @{
                            Path = $Folder.Fullname
                            Group = $Name
                            User = $User
                            FileSystemRights = $ACL.FileSystemRights
                            AccessControlType = $ACL.AccessControlType
                            Inherited = $ACL.IsInherited
                        }
                        $Result | Select Path,Group,User,FileSystemRights
                    }
                } else {
                    $Result = New-Object PSObject -Property @{
                        Path = $Folder.Fullname
                        Group = ""
                        User = Get-ADUser $Name | Select -ExpandProperty Name
                        FileSystemRights = $ACL.FileSystemRights
                        AccessControlType = $ACL.AccessControlType
                        Inherited = $ACL.IsInherited
                    }
                    $Result | Select Path,Group,User,FileSystemRights
                }
            } else {
                $Result = New-Object PSObject -Property @{
                    Path = $Folder.Fullname
                    Group = ""
                    User = $ACL.IdentityReference.Value
                    FileSystemRights = $ACL.FileSystemRights
                    AccessControlType = $ACL.AccessControlType
                    Inherited = $ACL.IsInherited
                }
                $Result | Select Path,Group,User,FileSystemRights
            }
        }
    }
}
Write-Verbose "$(Get-Date): Script completed!"

The script works fine for getting all levels, I just would like to limit it to say levels 2-4.

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
  • 1
    Passing `-Depth` to your script errors out because your script doesn't define a parameter `$Depth`. The statement `Get-ChildItem -Path $Path -Directory -Recurse -Depth 3` in your script should work, though. – Ansgar Wiechers Jan 10 '19 at 20:25
  • 1
    Try to isolate the problem. Does using only `$Folders = Get-ChildItem -Path $Path -Directory -Recurse -Depth 3` (with the path defined) still returns more than 3 folder depths ? – Sage Pourpre Jan 10 '19 at 20:35
  • This [Q&A](https://stackoverflow.com/questions/13249085/limit-get-childitem-recursion-depth) provides some answers to limit to a specific depth (not a range like 2-4). –  Jan 10 '19 at 20:36
  • Ansgar Wiechers, I tried adding:[string]$Path, [switch]$Recurse, [switch]$Depth then using the -Depth option on the command line, but that resulted in error "At C:\Temp\Get_folder_acls_depth_test.ps1:6 char:21 + [switch]$Recurse + ~ Missing ')' in function parameter list. At C:\Temp\Get_folder_acls_depth_test.ps1:8 char:1 + ) + ~ Unexpected token ')' in expression or statement. + CategoryInfo : ParserError: (:) [], ParseException + FullyQualifiedErrorId : MissingEndParenthesisInFunctionParameterList" – Daniel Gower Jan 10 '19 at 20:54
  • Sage Pourpre, thanks for the advice, I ran Get-ChildItem -Path I:\dir_name -Directory -Recurse -Depth 3 | export-csv c:\temp... and it still resulted in all levels. I've searched for get-childitem -recurse -depth, but have not found much online. At least now I know it's not the script! Thanks! – Daniel Gower Jan 10 '19 at 21:09
  • @DanielGower `[switch]` parameters don't take numeric arguments. Besides, how do you expect us to guess that you tried that? Put your code and error into your question. Do not leave out relevant information. Do not bury it in comments. – Ansgar Wiechers Jan 10 '19 at 22:42

1 Answers1

0

I tested this hacking your script to check that your if/else statement was working correctly and I get correct results:

function Test-Recurse {
    Param(
        [ValidateScript( {Test-Path $_ -PathType Container})]
        [Parameter(Mandatory = $true)]
        [string]$Path,
        [switch]$Recurse
    )

    begin {
        Write-Verbose "$(Get-Date): Script begins!"
        $folders = $null
    }

    process {
        if ($Recurse) {
            Write-Output -InputObject "Recurse has been selected"
            $folders = Get-ChildItem -Path $Path -Directory -Recurse -Depth 3
        }
        else {
            Write-Output -InputObject "Recurse has NOT been selected"
            $folders = Get-ChildItem -Path $Path -Directory
        }
    }

    end {
        return $folders.fullName
    }
}

PS C:\GitHub\Guyver1wales\PowerShell> Test-Recurse -Path c:\programdata\razer

Recurse has NOT been selected
C:\programdata\razer\Installer
C:\programdata\razer\Razer Central
C:\programdata\razer\RzEndpointPicker
C:\programdata\razer\Services
C:\programdata\razer\ServiceSetup
C:\programdata\razer\Synapse

PS C:\GitHub\Guyver1wales\PowerShell> Test-Recurse -Path c:\programdata\razer -Recurse
Recurse has been selected
C:\programdata\razer\Installer
C:\programdata\razer\Razer Central
C:\programdata\razer\RzEndpointPicker
C:\programdata\razer\Services
C:\programdata\razer\ServiceSetup
C:\programdata\razer\Synapse
C:\programdata\razer\Installer\Logs
C:\programdata\razer\Razer Central\Icons
C:\programdata\razer\Razer Central\Logs
C:\programdata\razer\Razer Central\Icons\Dark
C:\programdata\razer\Razer Central\Icons\Lifestyle
C:\programdata\razer\Razer Central\Icons\Light
C:\programdata\razer\RzEndpointPicker\Accounts
C:\programdata\razer\Services\Logs
C:\programdata\razer\Synapse\Accounts
C:\programdata\razer\Synapse\CrashReporter
C:\programdata\razer\Synapse\Devices
C:\programdata\razer\Synapse\Logs
C:\programdata\razer\Synapse\Mats
C:\programdata\razer\Synapse\Modules
...
C:\programdata\razer\Synapse\ProductUpdates\Uninstallers
C:\programdata\razer\Synapse\ProductUpdates\Uninstallers\RazerCommonConfig
C:\programdata\razer\Synapse\ProductUpdates\Uninstallers\RazerDeathAdder3500Config
C:\programdata\razer\Synapse\ProductUpdates\Uninstallers\RazerFonts
C:\programdata\razer\Synapse\ProductUpdates\Uninstallers\Razer_Common_Driver
PS C:\GitHub\Guyver1wales\PowerShell>

-Depth starts from 0 so -Depth 3 will display 4 sub-folders: C:\programdata\razer\Synapse\ProductUpdates\Uninstallers\RazerDeathAdder3500Config

0 = \Synapse

1 = \ProductsUpdates

2 = \Uninstallers

3 = \RazerDeathAdder3500Config

Leon Evans
  • 146
  • 1
  • 6
  • Thank you! I think that's all it was. I didn't understand where the -depth was starting and stopping and I was getting more levels than expected. – Daniel Gower Jan 11 '19 at 17:15