Advertisement
joedigital

ps-refactor-get groups

Jun 12th, 2025
665
0
Never
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. )
  10.  
  11. begin {
  12.  
  13.   $startTime = Get-Date
  14.  
  15.   #create arrayLists to hold output from 3 tasks: 1) count, 2) get ACLs, 3) expand group membership
  16.   #$arrayListFolderCountResults = [System.Collections.ArrayList]@()
  17.   $arrayListACLs = [System.Collections.ArrayList]@()
  18.   #$arrayListGroupsToExpand = [System.Collections.ArrayList]@()
  19.  
  20.   #.net List (for performance and mutability) of identity/group names to exclude (case-insensitive matching will be used)
  21.   #These are the "name parts" after any domain or "BUILTIN\" prefix.
  22.   $listExcludedGroups = [System.Collections.Generic.List[string]]@()
  23.     $listExcludedGroups.Add("Administrators")      # Matches BUILTIN\Administrators
  24.     $listExcludedGroups.Add("Authenticated Users") # Matches well-known group
  25.     $listExcludedGroups.Add("Backup_OPs")
  26.     $listExcludedGroups.Add("Domain Admins")       # Matches well-known group
  27.     $listExcludedGroups.Add("Domain Users")        # Matches well-known group
  28.     $listExcludedGroups.Add("NETWORK SERVICE")     # Matches well-known group
  29.     $listExcludedGroups.Add("SYSTEM")              # Matches NT AUTHORITY\SYSTEM
  30.     $listExcludedGroups.Add("CREATOR OWNER")       # Matches special identity
  31.     $listExcludedGroups.Add("Users")               # Matches BUILTIN\Users
  32.  
  33.   #get [only] folders (-Directory) under the source path for file counts and sizes
  34. #**  ACLs uses -Recurse: need to account for this
  35. #**   trying to avoid the perf hit of scanning the folders twice
  36.   #long paths
  37.   $longpath = '\\?\UNC'
  38.   $SourcePath = $longpath + $SourcePath
  39.   #$SourcePath
  40.   $FoldersArray = @(Get-ChildItem $SourcePath -Directory -Recurse) #**debug recurse is later
  41.  
  42.   #init empty result set if there are no folders
  43.   $Results = @()
  44.   if ($FoldersArray.Count -eq 0) {
  45.     $Results += [pscustomobject] @{
  46.       Path = $SourcePath
  47.       Count = 0
  48.       GBSize = 0.00
  49.       FolderDepth = 0
  50.     }
  51.   }
  52.  
  53.   #init the folder depth counter used in the foreach loop
  54.   #$FoldersDeep = ($SourcePath -split '\\').Count - 2 #subtract for current (.) and parent (..)
  55.  
  56.   #new [pcustomobject] array for ACL results which will be the input to expand group members
  57.   $ACLOutInfo = @()
  58.  
  59.   #new [pcustomobject] array for group member results
  60.   #$uniqueGroups = @()
  61.  
  62.   #Write-Verbose "Script initialized. Excluded identities (case-insensitive): $($Global:ExcludedIdentities -join ', ')" -Verbose
  63.  
  64. }
  65.  
  66. process {
  67.  
  68.   #loop through the folders for ACLs + file counts; write separate CSVs for each
  69.   ForEach ($currentFolder in $FoldersArray) {
  70.     #display the current path being evaluated (top level only for file counts)
  71.     write-host "FoldersArray loop: $($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.     <#alternatives
  79.       # $ACLs = [System.IO.Directory]::GetAccessControl($currentFolder.FullName)
  80.       # $ACLs = Get-Acl -Path $currentFolder.FullName -ErrorAction Stop
  81.       # $ACLs.Access | Format-Table
  82.    
  83.     #$ACLs.Access | Format-Table
  84.     #>
  85.     #exclude ACLs in the ExcludedGroups array (see "begin {}" section above)
  86.     ForEach ($accessRule in $ACLs.Access) {
  87.       <#
  88.       GetAccessRules($true, $true, [System.Security.Principal.NTAccount]))
  89.       GetAccessRules()
  90.       The first boolean indicates that you want to include rules explicitly set on the object.
  91.       The second boolean indicates that you want to exclude inherited rules but it doesn't seem to work. [Bug?]
  92.       [System.Security.Principal.NTAccount] specifies that you want the IdentityReference
  93.        (like a username or group name) to be translated into an NTAccount object, making it easily readable.
  94.       #>
  95.       #$ACLs.Access | Format-Table
  96.      
  97.       #only ACLs that are not inherited
  98.       if ($accessRule.IsInherited -eq $false) {
  99.  
  100.         $thisGroupName = $accessRule.IdentityReference.Value
  101.     #Write-host "thisGroupName = $thisGroupName" -ForegroundColor Green -backgroundColor DarkGray
  102.         # Extract the GroupName, e.g., "Administrators" from "BUILTIN\Administrators" or "SalesUsers" from "CONTOSO\SalesUsers"
  103.         $thisShortGroupName = $thisGroupName.Split('\')[-1]
  104.         #$thisShortGroupName
  105.  
  106.         # Check if the ShortGroupName is in the exclusion list (PowerShell -eq is case-insensitive for strings)
  107.         $IsExcluded = $false
  108.         ForEach ($ExcludedItem in $listExcludedGroups) {
  109.           #test for exclusion
  110.           if ($thisShortGroupName -eq $ExcludedItem) {
  111.             $IsExcluded = $true
  112.     #Write-host "Excluding '$thisGroupName' because '$ExcludedItem' is in the exclusion list." -ForegroundColor Yellow -backgroundColor DarkBlue
  113.             break
  114.           }
  115.         } #end excluded groups loop
  116.  
  117.         if (-not $IsExcluded) {          
  118.           #save this group for group member expansion
  119.           $ACLOutInfo += [pscustomobject]@{
  120.             FolderPath = $currentFolder.FullName
  121.             IdentityReference = $thisGroupName
  122.             #AccessControlType = $ACL.AccessControlType
  123.             #IsInherited = $ACL.IsInherited
  124.             #InheritanceFlags = $ACL.InheritanceFlags
  125.             #PropagationFlags = $ACL.PropagationFlags
  126.             FileSystemRights = $accessRule.FileSystemRights
  127.           }
  128.           <#
  129.           $arrayListGroupsToExpand.Add($thisShortGroupName) #ArrayList because it won't be exported to CSV
  130.           **Use the IdentityReference from the $ACLOutInfo array for the groups to be expanded?
  131.           #>
  132.  
  133.           #add non-inherited, non-excluded ACL to array list
  134.           $arrayListACLs.Add($ACLOutInfo)
  135.           # write-host$arrayListACLs
  136.     #      Write-Host "  File System Rights: $($accessRule.FileSystemRights)"
  137.     #      Write-Host "  Is Inherited: $($accessRule.IsInherited)"
  138.     #      Write-Host "  Identity Reference: $thisGroupName"
  139.           #Write-Host "  File System Rights: $($accessRule.FileSystemRights)"
  140.     #      Write-Host "  Inheritance Flags: $($accessRule.InheritanceFlags)"
  141.           #Write-Host "  Access Control Type: $($accessRule.AccessControlType)"  
  142.           #Write-Host "  Propagation Flags: $($accessRule.PropagationFlags)"
  143.     #      Write-Host "-----------------------------------"
  144.           #**
  145.         } #endif IsExcluded
  146.      
  147.       } else {
  148.    #Write-Host "     skipping this rule (inherited) for $thisGroupName" -ForegroundColor Yellow -BackgroundColor DarkRed
  149.         }
  150.       #endif IsInherited
  151.    #Write-host "looping for next access rule in $($currentFolder.FullName)" -ForegroundColor Green -backgroundColor DarkGray
  152.     } #end access rules loop
  153.   } #end currentFolder loop
  154. } #end process
  155.  
  156. end {
  157.  
  158.   #create output filename (ACLs)
  159.   $OutFile = $OutputFilePath + "acls-" + $((Get-Date).ToString('yyyy-MM-dd_HH-mm-ss')) + ".csv"
  160.   #Save results to csv file
  161.   $ACLOutInfo | Export-Csv $OutFile -NoTypeInformation
  162.   Write-host "saving $OutFile..." -ForegroundColor Green -backgroundColor DarkBlue
  163. #  $ACLOutInfo | Export-Csv -Path "G:\My Drive\tmp\myarrayList.csv" -NoTypeInformation
  164. #>
  165.   $endTime = Get-Date
  166.   New-TimeSpan -Start $startTime -End $endTime | Select-Object -Property TotalSeconds, TotalMinutes
  167.  
  168.   Write-Host "end of script" -ForegroundColor Green -backgroundColor DarkGray
  169.  
  170. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement