Advertisement
joedigital

ps-refactor-get groups

Jun 12th, 2025 (edited)
836
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #assign params from command line
  2. param(
  3.   [Alias("UNCPath")]
  4.   [Parameter(Mandatory)]
  5.     [string]$SourcePath,
  6.   [Alias("OFilePath")]
  7.   [Parameter(Mandatory)]
  8.     [string]$OutputFilePath,
  9.   [Parameter()]
  10.     [switch] $processAllACLs
  11. )
  12.  
  13. begin {
  14.   if ($processAllACLs.IsPresent) {
  15.     write-host "initializing FoldersArray (all ACLs)..." -ForegroundColor green -backgroundColor DarkGray  
  16.   } else {
  17.     write-host "initializing FoldersArray (excluding common ACLs)..." -ForegroundColor green -backgroundColor DarkGray  
  18.     }
  19.  
  20.   Import-Module Microsoft.PowerShell.Security #PowerShell 7 moved ACLs...
  21.   $startTime = Get-Date
  22.  
  23.   #create arrayLists to hold output from 3 tasks: 1) count, 2) get ACLs, 3) expand group membership
  24.   #$arrayListFolderCountResults = [System.Collections.ArrayList]@()
  25.   #$arrayListACLs = [System.Collections.ArrayList]@()
  26.   #$arrayListGroupsToExpand = [System.Collections.ArrayList]@()
  27.  
  28.   #.net List (for performance and mutability) of identity/group names to exclude (case-insensitive matching will be used)
  29.   #These are the "name parts" after any domain or "BUILTIN\" prefix.
  30.   $listExcludedGroups = [System.Collections.Generic.List[string]]@()
  31.     $listExcludedGroups.Add("Administrators")      # Matches BUILTIN\Administrators
  32.     $listExcludedGroups.Add("Authenticated Users") # Matches well-known group
  33.     $listExcludedGroups.Add("Backup_OPs")
  34.     $listExcludedGroups.Add("Domain Admins")       # Matches well-known group
  35.     $listExcludedGroups.Add("Domain Users")        # Matches well-known group
  36.     $listExcludedGroups.Add("NETWORK SERVICE")     # Matches well-known group
  37.     $listExcludedGroups.Add("SYSTEM")              # Matches NT AUTHORITY\SYSTEM
  38.     $listExcludedGroups.Add("CREATOR OWNER")       # Matches special identity
  39.     $listExcludedGroups.Add("Users")               # Matches BUILTIN\Users
  40.     $listExcludedGroups.Add("Everyone")            # Matches BUILTIN\Users
  41.  
  42.   #get [only] folders (-Directory) under the source path for file counts and sizes
  43.   #**  ACLs uses -Recurse: need to account for this
  44.   #**   trying to avoid the perf hit of scanning the folders twice
  45.  
  46.   #long paths
  47.   #$longpath = '\\?\'
  48.   #$SourcePath = "B:\Customer Support Return Mail HM LEAD Daily Count\Health Monitor Daily Count\Customer Support Team Ebill\Customer Support Team Direct Debit\Customer Support Team CC&B Health Monitors FO\CSODISSUES\CSODISSUEOCT\6754pa_files\Options_split_files"
  49.   #$longpath + $SourcePath
  50.   #"b:\Customer Support Return Mail HM LEAD Daily Count\Health Monitor Daily Count\Customer Support Team Ebill\Customer Support Team Direct Debit\Daily Direct Debit Log"
  51.   #$SourcePath #**debug
  52.  
  53.   $FoldersArray = @(Get-ChildItem $SourcePath -Directory -Recurse)# -Recurse) #**debug recurse is later
  54.  
  55.   #new [pcustomobject] array for ACL results which will be the input to expand group members
  56.   $ACLOutInfo = @()
  57.  
  58.   #Write-Verbose "Script initialized. Excluded identities (case-insensitive): $($Global:ExcludedIdentities -join ', ')" -Verbose
  59. } #end "begin block"
  60.  
  61. process {
  62.   $loopstart = Get-Date -DisplayHint Time
  63.   $elapsedtimeFoldersArray = New-TimeSpan -Start $startTime -End $loopstart | Select-Object -Property TotalSeconds, TotalMinutes
  64.  
  65.   #loop through the folders for ACLs + file counts; write separate CSVs for each
  66.   $Foldercount = 0
  67.   ForEach ($currentFolder in $FoldersArray) {
  68.     $Foldercount++
  69.     #display the current path being evaluated (top level only for file counts)
  70.     "$Foldercount of $($FoldersArray.count) $($currentFolder.FullName)"
  71.       #write-host "$Foldercount of $($FoldersArray.count) $($currentFolder.FullName)" -ForegroundColor Yellow -backgroundColor DarkGray
  72.  
  73.     #extract the ACLs for each folder in this loop
  74.  
  75.     #create a FolderInfo object (.net for speed)
  76.       #$objCurrentFolderInfo = New-Object System.IO.DirectoryInfo($currentFolder.FullName) #must use "FullName" for the complete UNC path
  77.       #$ACLs = $objCurrentFolderInfo.GetAccessControl()
  78.       $directoryInfo = [System.IO.DirectoryInfo]$currentFolder
  79.       #$directoryInfo = New-Object System.IO.DirectoryInfo($FolderPath)
  80.  
  81.     #get the Access Control (DirectorySecurity) .NET Object
  82.     # GetAccessControl() returns the security descriptor for the directory.
  83.     # This can fail if the user running the script lacks permissions.
  84.     $directorySecurity = $directoryInfo.GetAccessControl()
  85.     $ACLs = $directorySecurity.GetAccessRules($true, $false, [System.Security.Principal.NTAccount])
  86.     <# The parameters specify:
  87.     #   $true  - Include rules explicitly set on the object.
  88.     # ** $false - DO NOT include rules inherited from parent objects. **
  89.     #   [type] - The type to use for translating the Security Identifier (SID),
  90.     #            e.g., BUILTIN\Administrators instead of S-1-5-32-544.
  91.     #>
  92.     #$ACLs = (get-acl $currentFolder.fullname).Access
  93.  
  94.     #exclude ACLs in the ExcludedGroups array (see "begin {}" section above)
  95.     #ForEach ($accessRule in $ACLs.Access) {
  96.     ForEach ($accessRule in $ACLs) {
  97.       #$ACLs.Access | Format-Table
  98.       $thisGroupName = $accessRule.IdentityReference.Value
  99.         #Write-host "thisGroupName = $thisGroupName" -ForegroundColor Green -backgroundColor DarkGray #**debug
  100.  
  101.       #only ACLs that are not inherited
  102.       #if (-not $accessRule.IsInherited) { #-eq $false
  103.         #$accessRule.IsInherited #**debug
  104.         #Extract the GroupName, e.g., "Administrators" from "BUILTIN\Administrators" or "SalesUsers" from "CONTOSO\SalesUsers"
  105.         $thisShortGroupName = $thisGroupName.Split('\')[-1]
  106.        
  107.         #save this group for group member expansion
  108.         #Write-host "$thisGroupName not inherited" -ForegroundColor Yellow -backgroundColor DarkBlue #**debug
  109.        
  110.         if ($processAllACLs) {
  111.           $ACLOutInfo += [pscustomobject]@{
  112.             FolderPath = $currentFolder.FullName
  113.             IdentityReference = $thisGroupName
  114.             FileSystemRights = $accessRule.FileSystemRights
  115.             AccessControlType = $accessRule.AccessControlType
  116.             IsInherited = $accessRule.IsInherited
  117.             InheritanceFlags = $accessRule.InheritanceFlags
  118.             PropagationFlags = $accessRule.PropagationFlags# Check if the ShortGroupName is in the exclusion list (PowerShell -eq is case-insensitive for strings)
  119.           }
  120.         } else {
  121.             $IsExcluded = $false
  122.             ForEach ($ExcludedItem in $listExcludedGroups) {
  123.               #test for exclusion
  124.               if ($thisShortGroupName -eq $ExcludedItem) {
  125.                 $IsExcluded = $true
  126.                 #Write-host "Excluding '$thisGroupName' because '$ExcludedItem' is in the exclusion list." -ForegroundColor Yellow -backgroundColor DarkBlue
  127.                 break #match
  128.               } #end excluded groups loop
  129.             }
  130.             if (-not $IsExcluded) {
  131.               #abbreviated output (fewer columns)
  132.                 $ACLOutInfo += [pscustomobject]@{
  133.                 FolderPath = $currentFolder.FullName
  134.                 IdentityReference = $thisGroupName
  135.                 FileSystemRights = $accessRule.FileSystemRights
  136.               }
  137.             } #endif Excluded
  138.           } #endif processAllACLs
  139.       <#} else {
  140.           #$accessRule.IsInherited #**debug
  141.           #Write-Host "     inherited: skipping rule for $thisGroupName" -ForegroundColor Yellow -BackgroundColor DarkRed
  142.       #  } #endif IsInherited
  143.       #>
  144.       #Write-host "looping for next access rule in $($currentFolder.FullName)" -ForegroundColor Green -backgroundColor DarkGray
  145.     } #end access rules loop
  146.   } #end currentFolder loop
  147.   Write-host "`nelapsed time to retrieve the folders: $elapsedtimeFoldersArray" -ForegroundColor Green -backgroundColor DarkGray
  148. } #end "process block"
  149.  
  150. end {
  151.  
  152.   #create OutFile (ACLs)
  153.   $OutFile = $OutputFilePath + "-acls-" + $((Get-Date).ToString('yyyy-MM-dd_HH-mm-ss')) + ".csv"
  154.   #Save results to csv file
  155. #  $ACLOutInfo | Export-Csv -Path "G:\My Drive\tmp\myarrayList.csv" -NoTypeInformation
  156.   $ACLOutInfo | Export-Csv $OutFile -NoTypeInformation
  157.   Write-host "saving $OutFile..." -ForegroundColor Green -backgroundColor DarkBlue
  158.  
  159.   $endTime = Get-Date
  160.   New-TimeSpan -Start $startTime -End $endTime | Select-Object -Property TotalSeconds, TotalMinutes
  161.  
  162.   Write-Host "end of script" -ForegroundColor Green -backgroundColor DarkGray
  163.  
  164. }
Advertisement
Comments
Add Comment
Please, Sign In to add comment
Advertisement