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.
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