Some Active Directory attributes are local to the domain controller where the event occurred, such as lastlogon, but most others are replicated to all domain controllers within that domain. This should be distinguished from the attributes which are part of the Global Catalog – those attributes are a subset of domain attributes which exist and may be read from Global Catalog servers which are DCs in other domains. The script is interactive, and does not require administrative rights. You can select a single attribute, and see its value across DCs, or all attributes on a single DC. The script returns the attribute name, value, when changed, and the DC where the change occurred if recent.
<# Gets replication metadata for any AD object given the distinguishedname. Alternatively, get replication of any attribute across all domain controllers. Does not require admin permissions or ActiveDirectory module Alan Kaplan, www.akaplan.com 12/24/21 Public version 11/16/21 v 1.3 #> Param ( [Parameter(Mandatory = $True, Position = 0)] [string]$objDN ) $adObject = [adsi]"LDAP://$objDN" $adObjectName = ($adObject).SamAccountName #Delimiter for clipboard. Pick comma or tab $delim = "," #$delim = "`t" Add-Type -assemblyname Microsoft.visualBasic Function Get-DomainFromDNString($strADsPath) { if ($strADsPath.startsWith('DC=')) { ($strADsPath.Replace("DC=", ".").Replace(',', '')).Substring(1) } Else { $strADsPath.Substring($strADsPath.IndexOf(",DC")).Replace(",DC=", ".").Substring(1) } } $Domain = Get-DomainFromDNString $objDN $msg = @" Choose the type of information to view: 1) All replicated attributes from a single DC 2) A selected replicated attribute from all DCs 0) Exit "@ $retval = [Microsoft.VisualBasic.Interaction]::InputBox($msg, "Report Type", 1) switch ($retval) { 1 { $AllData = $true; break } 2 { $AllData = $false; break } default { Exit-Script } } Write-Progress "Getting replication data, please wait" # Connect to the specified domain and retrieve the list of all dcs within this domain $DomainContext = new-object System.directoryServices.ActiveDirectory.DirectoryContext("Domain", $Domain) $ADSIDomain = [System.DirectoryServices.ActiveDirectory.Domain]::GetDomain($DomainContext) $oDC = $ADSIDomain.DomainControllers[0] $dcName = $oDC.Name $metaData = $oDC.GetReplicationMetaData($objDN) if ($AllData -eq $true) { $metadata.Values | Sort-Object Name | select-object Name, @{ Name = 'Value' Expression = { $propVal = $adObject.properties.item($_.name)[0] if ($_.name -match 'set|time|expires') { $timeVal = $adObject.ConvertLargeIntegerToInt64($propVal) [datetime]::FromFileTime($timeVal) } Else { $propVal } } }, @{N = 'LastChanged'; E = { $_.'LastOriginatingChangeTime' } }, OriginatingServer | Sort-Object LastChanged -Descending | Set-Variable Retval $adObjectName = $adObjectName.Replace('$', '') $retval | Out-GridView -Title "AD Replication Metadata for $adObjectname from $dcName. Selected lines are copied to your clipboard as CSV." -PassThru | ConvertTo-CSV -delim $delim -NoTypeInformation | Set-Clipboard } Else { $allDCs = $ADSIDomain.DomainControllers $ReplAttribute = $metaData.AttributeNames | Sort-object | Out-GridView -Title "Select Attribute to test, then [Ok]" -OutputMode Single if ($null -eq $ReplAttribute) { Write-Warning "No attribute selected, exiting" Pause Exit-Script } $Data = @(Foreach ($DC in $allDCs) { $dcName = ($dc).name Write-progress -activity "Checking" -status $dcName -id 1 ($dc.GetReplicationMetadata($objDN)).values | Where-Object { $_.name -eq $ReplAttribute } | Add-member -notepropertyname 'DC' -notepropertyValue $dcname -passthru -force }) | Select-Object * -ExcludeProperty name, LastOriginatingInvocationID | Sort-Object version -Descending Write-Progress "Done" -completed Write-Progress "Done" -completed -id 1 if ($data) { $data | Sort-Object version, DC | Out-GridView -title "Replication of `"$ReplAttribute`" AD attribute for $adObjectName. Selected items will be copied to your clipboard as CSV." -passthru | ConvertTo-CSV -delim $delim -NoTypeInformation | Set-Clipboard } Else { Write-Warning "No metadata for $ReplAttribute found on any DC." Pause } }