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
}