Private/Helpers/Invoke-ADRetrievalWithProgress.ps1
|
#region Invoke-ADRetrievalWithProgress.ps1 function Invoke-ADRetrievalWithProgress { [CmdletBinding()] param( [Parameter(Mandatory)] [ValidateSet("Users", "Computers", "Groups", "ForestInfo", "Sites", "Trusts", "Policies", "OrganizationalUnits", "DomainInfo", "DomainControllers")] [string]$ObjectType, [Parameter()] [string]$Filter = "*", # Default filter [Parameter()] [string[]]$Properties, # Properties to retrieve [Parameter()] [System.Management.Automation.PSCredential]$Credential, [Parameter(Mandatory)] [scriptblock]$ProcessingScript, # Transformation logic for each object [string]$ActivityName = "Retrieving $ObjectType" ) try { Write-Log "Starting retrieval of $ObjectType..." -Level Info # Map ObjectType to corresponding AD cmdlet $cmdletName = switch ($ObjectType) { "Users" { "Get-ADUser" } "Computers" { "Get-ADComputer" } "Groups" { "Get-ADGroup" } "ForestInfo" { "Get-ADForest" } "Sites" { "Get-ADReplicationSite" } "Trusts" { "Get-ADTrust" } "Policies" { "Get-GPO" } "OrganizationalUnits" { "Get-ADOrganizationalUnit" } "DomainInfo" { "Get-ADDomain" } "DomainControllers" { "Get-ADDomainController" } default { throw "Unsupported ObjectType: $ObjectType" } } # Count total objects for progress calculation Write-Log "Counting total $ObjectType for progress calculation..." -Level Info $countParams = @{ Filter = $Filter } if ($Credential) { $countParams.Credential = $Credential } # Handle single-object cmdlets like Get-ADForest, Get-GPO, Get-ADDomain if ($ObjectType -in @("ForestInfo", "Policies", "DomainInfo")) { $total = 1 } else { $total = (& $cmdletName @countParams | Measure-Object).Count } if ($total -eq 0) { Write-Log "No $ObjectType found based on the specified criteria." -Level Warning return $null } Write-Log "Retrieving and processing $total $ObjectType..." -Level Info # Build retrieval parameters $getParams = @{ Filter = $Filter } if ($Properties) { $getParams.Properties = $Properties } if ($Credential) { $getParams.Credential = $Credential } $count = 0 $results = (& $cmdletName @getParams) | ForEach-Object -Begin { Show-Progress -Activity $ActivityName -Status "Starting..." -PercentComplete 0 } -Process { $count++ try { # Apply the transformation logic provided by the caller $obj = & $ProcessingScript $_ # Update progress $percent = [int]( ($count / $total) * 100 ) Show-Progress -Activity $ActivityName -Status "Processing $ObjectType $count of $total" -PercentComplete $percent # Output the transformed object $obj } catch { Write-Log "Error processing $ObjectType $($ObjectType -eq 'Users' ? $_.SamAccountName : $_.Name): $($_.Exception.Message)" -Level Warning # Create a fallback object in case of processing error switch ($ObjectType) { "Users" { $errorObject = [PSCustomObject]@{ SamAccountName = $_.SamAccountName DisplayName = $null EmailAddress = $null Enabled = $null LastLogonDate = $null PasswordLastSet = $null PasswordNeverExpires = $null PasswordExpired = $null DistinguishedName = $_.DistinguishedName MemberOf = @() AccountStatus = "Error" AccessStatus = "Access Error: $($_.Exception.Message)" } Add-Member -InputObject $errorObject -MemberType ScriptMethod -Name "ToString" -Value { "SamAccountName=$($this.SamAccountName); Status=Error; Groups=0" } -Force $errorObject } "Computers" { $errorObject = [PSCustomObject]@{ Name = $_.Name IPv4Address = $null DNSHostName = $null OperatingSystem = $null OperatingSystemVersion = $null Enabled = $null LastLogonDate = $null Created = $null Modified = $null DistinguishedName = $_.DistinguishedName ServicePrincipalNames = $null MemberOf = @() AccessStatus = "Access Error: $($_.Exception.Message)" NetworkStatus = "Error" IsAlive = $false } Add-Member -InputObject $errorObject -MemberType ScriptMethod -Name "ToString" -Value { "Name=$($this.Name); NetworkStatus=Error; IsAlive=$($this.IsAlive); Groups=0" } -Force $errorObject } "Groups" { $errorObject = [PSCustomObject]@{ Name = $_.Name Description = $_.Description GroupCategory = $_.GroupCategory GroupScope = $_.GroupScope TotalNestedMemberCount = 0 Members = @() Created = $_.Created Modified = $_.Modified DistinguishedName = $_.DistinguishedName AccessStatus = "Access Error: $($_.Exception.Message)" } Add-Member -InputObject $errorObject -MemberType ScriptMethod -Name "ToString" -Value { "Name=$($this.Name); Status=Error" } -Force $errorObject } "ForestInfo" { Write-Log "Error retrieving Forest Info: $($_.Exception.Message)" -Level Warning return $null } "Sites" { Write-Log "Error retrieving Site Info: $($_.Exception.Message)" -Level Warning return $null } "Trusts" { Write-Log "Error retrieving Trust Info: $($_.Exception.Message)" -Level Warning return $null } "Policies" { Write-Log "Error retrieving GPOs: $($_.Exception.Message)" -Level Warning return $null } "OrganizationalUnits" { Write-Log "Error retrieving Organizational Units: $($_.Exception.Message)" -Level Warning return $null } "DomainInfo" { Write-Log "Error retrieving Domain Info: $($_.Exception.Message)" -Level Warning return $null } "DomainControllers" { Write-Log "Error retrieving Domain Controllers: $($_.Exception.Message)" -Level Warning return $null } default { Write-Log "Unhandled ObjectType: $ObjectType" -Level Warning return $null } } } } -End { Show-Progress -Activity $ActivityName -Completed } Write-Log "Successfully retrieved $($results.Count) $ObjectType." -Level Info return $results } catch { Write-Log "Failed to retrieve ${ObjectType}: $($_.Exception.Message)" -Level Error } } #endregion |