Alan's Blog

"Yeah. I wrote a script that will do that."

Menu
  • About My Blog
Menu

Get AD Replication Metadata

Posted on December 25, 2021 by Alan

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
    }
}

 

 

 

Leave a Reply

You must be logged in to post a comment.

Search

Please Note

All the scripts are saved as .txt files. Newer files have a “View Script” button which will let you save or open a script in notepad. For earlier posts, the easiest way to download with IE is to right click on the link and use “Save Target As”. Rename file from Name_ext.txt to Name.ext.

To see a full post after searching, please click on the title.

PowerShell Scripts were written with version 3 or later.

https connections are supported.

All new users accounts must be approved, as are comments. Please be patient.  If you find a post error or a script which doesn’t work as expected, I appreciate being notified.  My email is my first name at the domain name, and you are welcome to contact me that way.

Tags

1E ACLS Active Directory ActiveDirectory ADSI Advanced Functions Audit Change Administrator Password COMObject Computer Groups DateTime Desktop DNS Excel FileScriptingObject Forms General GPO GPS Group Policy Hacks ISE Lockout logons NAV740 Nessus OU OU permissions Outlook Pick Folder Power PowerShell Powershell Scriptlets RDP SCCM schedule reboot Scripting Security Shell.Application user information VBA Windows Update WMI WordPress WPF

Categories

akaplan.com

  • Back to Home Page

Archives

Scripting Sites

  • A Big Pile of Small Things
  • Adam, the Automator
  • Art of the DBA
  • Ashley McGlone
  • Boe Prox
  • Carlo Mancini
  • DexterPOSH
  • Doug Finke
  • Jaap Brasser's Blog
  • JeffOps The Scripting Dutchman
  • Jonathan Medd's Blog
  • Keith Hill's Blog
  • LazyWinAdmin
  • Nana Lakshmanan
  • PowerShell Magazine
  • PowerShell Team Blog
  • PowerShell.org
  • PwrShell.net
  • Richard Siddaway's Blog
  • Ryan Yates' Blog
  • Skatterbrainz
  • The Lonely Administrator

SQL Site

  • Art of the DBA

Meta

  • Register
  • Log in
  • Entries feed
  • Comments feed
  • WordPress.org
©2025 Alan's Blog | Theme by SuperbThemes

Terms and Conditions - Privacy Policy