How to get the -Depth switch to work in a script?

383 Views Asked by At

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.

1

There are 1 best solutions below

1
On BEST ANSWER

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