Public/DomainReport/Security/Get-ADSecurityConfiguration.ps1
|
function Get-ADSecurityConfiguration { try { Write-Log "Retrieving AD security configuration..." -Level Info # Retrieve Organizational Units (OUs) $OUs = Invoke-ADRetrievalWithProgress -ObjectType "OrganizationalUnits" ` -Filter "*" ` -Properties @('Name', 'DistinguishedName') ` -ProcessingScript { param($ou) [PSCustomObject]@{ Name = $ou.Name DistinguishedName = $ou.DistinguishedName Description = $ou.Description Created = $ou.Created Modified = $ou.Modified } } ` -ActivityName "Retrieving Organizational Units" if (-not $OUs) { Write-Log "Failed to retrieve Organizational Units." -Level Warning $OUs = @() } # Retrieve Domain Controllers (DCs) $DCs = Invoke-ADRetrievalWithProgress -ObjectType "DomainControllers" ` -Filter "*" ` -ProcessingScript { param($dc) [PSCustomObject]@{ HostName = $dc.HostName } } ` -ActivityName "Retrieving Domain Controllers" if (-not $DCs) { Write-Log "Failed to retrieve Domain Controllers." -Level Warning $DCs = @() } # Compile the security configuration into a PSCustomObject $securityConfig = [PSCustomObject]@{ ObjectACLs = Get-CriticalObjectACLs -OUs $OUs FileShareACLs = Get-CriticalShareACLs -DCs $DCs } # Add ToString method to securityConfig Add-Member -InputObject $securityConfig -MemberType ScriptMethod -Name "ToString" -Value { "ObjectACLs=$($this.ObjectACLs.Count); FileShareACLs=$($this.FileShareACLs.Count); SPNConfiguration=$($this.SPNConfiguration.Count)" } -Force Write-Log "Successfully retrieved AD security configuration." -Level Info return $securityConfig } catch { Write-Log "Error retrieving AD security configuration: $($_.Exception.Message)" -Level Error return $null } } function Get-CriticalObjectACLs { [CmdletBinding()] param( [Parameter(Mandatory)] [array]$OUs ) try { Write-Log "Collecting ACLs for critical AD objects..." -Level Info # Define a processing scriptblock for each OU $processingScript = { param($ou) try { # Retrieve ACL for the OU $acl = Get-Acl -Path ("AD:" + $ou.DistinguishedName) # Process Access Rules $accessRules = $acl.Access | ForEach-Object { [PSCustomObject]@{ Principal = $_.IdentityReference.Value AccessType = $_.AccessControlType.ToString() Rights = $_.ActiveDirectoryRights.ToString() Inherited = $_.IsInherited } } # Construct the ACL object [PSCustomObject]@{ OU = $ou.Name Path = $ou.DistinguishedName Owner = $acl.Owner AccessRules = $accessRules } } catch { Write-Log "Error getting ACL for $($ou.DistinguishedName): $($_.Exception.Message)" -Level Warning return $null } } # Use the helper to process each OU with progress reporting $objectACLs = Invoke-ADRetrievalWithProgress -ObjectType "OrganizationalUnits" ` -Filter "*" ` -Properties @('Name', 'DistinguishedName') ` -InputData $OUs ` -ProcessingScript $processingScript ` -ActivityName "Retrieving OU ACLs" # Remove any null entries resulting from errors $objectACLs = $objectACLs | Where-Object { $_ -ne $null } # Add ToString method to each ACL object foreach ($aclObj in $objectACLs) { Add-Member -InputObject $aclObj -MemberType ScriptMethod -Name "ToString" -Value { "OU=$($this.OU); Owner=$($this.Owner); Rules=$($this.AccessRules.Count)" } -Force } Write-Log "Successfully collected ACLs for critical AD objects." -Level Info return $objectACLs } catch { Write-Log "Error collecting critical object ACLs: $($_.Exception.Message)" -Level Error return @() } } function Get-CriticalShareACLs { [CmdletBinding()] param( [Parameter(Mandatory)] [array]$DCs ) try { Write-Log "Collecting ACLs for SYSVOL and NETLOGON shares..." -Level Info # Define the shares to retrieve $shares = @("SYSVOL", "NETLOGON") # Prepare share information from all DCs $shareInfos = foreach ($dc in $DCs) { foreach ($share in $shares) { [PSCustomObject]@{ HostName = $dc.HostName ShareName = $share } } } # Define a processing scriptblock for each share $processingScript = { param($shareInfo) try { # Construct the share path $path = "\\$($shareInfo.HostName)\$($shareInfo.ShareName)" # Retrieve ACL for the share $acl = Get-Acl -Path $path # Process Access Rules $accessRules = $acl.Access | ForEach-Object { [PSCustomObject]@{ Principal = $_.IdentityReference.Value AccessType = $_.AccessControlType.ToString() Rights = $_.FileSystemRights.ToString() Inherited = $_.IsInherited } } # Construct the Share ACL object [PSCustomObject]@{ ShareName = $shareInfo.ShareName Path = $path Owner = $acl.Owner AccessRules = $accessRules } } catch { Write-Log "Error getting ACL for $($shareInfo.ShareName): $($_.Exception.Message)" -Level Warning return $null } } # Use the helper to process each share with progress reporting $shareACLs = Invoke-ADRetrievalWithProgress -ObjectType "CustomShares" ` -ProcessingScript $processingScript ` -ActivityName "Retrieving Share ACLs" ` -InputData $shareInfos # Remove any null entries resulting from errors $shareACLs = $shareACLs | Where-Object { $_ -ne $null } # Add ToString method to each Share ACL object foreach ($shareAclObj in $shareACLs) { Add-Member -InputObject $shareAclObj -MemberType ScriptMethod -Name "ToString" -Value { "Share=$($this.ShareName); Owner=$($this.Owner); Rules=$($this.AccessRules.Count)" } -Force } Write-Log "Successfully collected ACLs for SYSVOL and NETLOGON shares." -Level Info return $shareACLs } catch { Write-Log "Error collecting share ACLs: $($_.Exception.Message)" -Level Error return @() } } |