Private/Collectors/TargetWorker.ps1
|
$script:DCInvTargetWorker = { param($Controller, $Credential, $Settings, [string]$RemoteCollectorText) $ErrorActionPreference='Stop' $target=[string]$Controller.HostName $ad=@{Server=$target;ErrorAction='Stop'} if($null -ne $Credential){$ad.Credential=$Credential} function Read-Value($Object,[string]$Property){if($null -ne $Object -and $null -ne $Object.PSObject.Properties[$Property]){$Object.$Property}} function Emit-Section([string]$Key,[string]$Method,[scriptblock]$Action){ $clock=[diagnostics.stopwatch]::StartNew();$start=[datetimeoffset]::Now.ToString('o') $status='Succeeded';$rows=@();$errorId=$null;$message=$null try{$rows=@(& $Action)}catch{$status='Failed';$errorId=$_.FullyQualifiedErrorId;$message=$_.Exception.Message} $clock.Stop() [pscustomobject]@{Kind='Section';Target=$target;Key=$Key;Status=$status;Method=$Method;StartedAt=$start;CollectedAt=[datetimeoffset]::Now.ToString('o');DurationMs=$clock.ElapsedMilliseconds;Records=$rows;ErrorId=$errorId;ErrorMessage=$message} } Emit-Section 'roles' 'Discovery / Get-ADDomainController.OperationMasterRoles' { foreach($role in @($Controller.OperationMasterRoles)){ if(-not [string]::IsNullOrWhiteSpace([string]$role)){ [pscustomobject][ordered]@{Name=$target;Role=[string]$role;Scope=if([string]$role -in @('SchemaMaster','DomainNamingMaster')){'Forest'}else{$Controller.Domain}} } } } Emit-Section 'subnets' 'ADWS / Get-ADReplicationSubnet (subnets assigned to this DC site)' { Import-Module ActiveDirectory -ErrorAction Stop $site=Get-ADReplicationSite -Identity $Controller.Site @ad Get-ADReplicationSubnet -Filter * -Properties Description,Location @ad | Where-Object { [string]$_.Site -eq [string]$site.DistinguishedName } | ForEach-Object { [pscustomobject][ordered]@{Name=$target;Subnet=$_.Name;'Mapped site'=$Controller.Site;Description=Read-Value $_ 'Description';Location=Read-Value $_ 'Location';'Site DN'=[string]$_.Site} } } Emit-Section 'partners' 'ADWS / Get-ADReplicationPartnerMetadata (inbound, all hosted partitions)' { Import-Module ActiveDirectory -ErrorAction Stop $partnerParameters=@{Target=$target;EnumerationServer=$target;Partition='*';PartnerType='Inbound';ErrorAction='Stop'} if($null -ne $Credential){$partnerParameters.Credential=$Credential} Get-ADReplicationPartnerMetadata @partnerParameters | ForEach-Object { [pscustomobject][ordered]@{ Name=$target;'Source partner'=[string]$_.Partner;'Naming context'=[string]$_.Partition;Transport=[string]$_.IntersiteTransport;Direction='Inbound' 'Last success'=if($null -ne $_.LastReplicationSuccess){([datetimeoffset]$_.LastReplicationSuccess).ToString('o')}else{$null} 'Last attempt'=if($null -ne $_.LastReplicationAttempt){([datetimeoffset]$_.LastReplicationAttempt).ToString('o')}else{$null} 'Last result'=Read-Value $_ 'LastReplicationResult';'Consecutive failures'=Read-Value $_ 'ConsecutiveReplicationFailures' } } } Emit-Section 'connections' 'ADWS / nTDSConnection objects under this DC NTDS Settings' { Import-Module ActiveDirectory -ErrorAction Stop if([string]::IsNullOrWhiteSpace([string]$Controller.NTDSSettingsObjectDN)){throw 'NTDS Settings DN is missing from discovery.'} Get-ADObject -SearchBase $Controller.NTDSSettingsObjectDN -SearchScope OneLevel -LDAPFilter '(objectClass=nTDSConnection)' -Properties fromServer,enabledConnection,options,transportType @ad | ForEach-Object { $options=Read-Value $_ 'options' [pscustomobject][ordered]@{ Name=$target;Connection=$_.Name;'Source server'=Read-Value $_ 'fromServer';'Destination site'=$Controller.Site 'Generated by'=if($null -eq $options){'Unknown'}elseif(([int]$options -band 1) -eq 1){'KCC'}else{'Manual / not KCC-generated'} Enabled=Read-Value $_ 'enabledConnection';Transport=Read-Value $_ 'transportType';'Connection DN'=$_.DistinguishedName } } } $remoteKeys=@('system','disks','paths','network','forwarders','zones','conditional','time','certificates','shares') if($Settings.SkipRemote){ foreach($key in $remoteKeys){ [pscustomobject]@{Kind='Section';Target=$target;Key=$key;Status='NotAttempted';Method='Remote collection disabled by -SkipRemote';StartedAt=[datetimeoffset]::Now.ToString('o');CollectedAt=[datetimeoffset]::Now.ToString('o');DurationMs=0;Records=@();ErrorId=$null;ErrorMessage='Not attempted by explicit scope selection.'} } return } $parameters=@{ ComputerName=$target;ScriptBlock=[scriptblock]::Create($RemoteCollectorText);ArgumentList=@($target) Authentication='Kerberos';ErrorAction='Stop' SessionOption=New-PSSessionOption -OpenTimeout ($Settings.OpenTimeoutSeconds*1000) -OperationTimeout 60000 -CancelTimeout 5000 } if($null -ne $Credential){$parameters.Credential=$Credential} if($Settings.UseSSL){$parameters.UseSSL=$true} if($Settings.Port -gt 0){$parameters.Port=$Settings.Port} # Envelopes stream as sections complete; completed sections survive a later timeout. Invoke-Command @parameters } |