## Global Variables ## $DomainControllerName = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().FindDomainController().Name ## Functions ## function Get-ADSite { [CmdletBinding( ConfirmImpact="Low", DefaultParameterSetName="Name" )] Param ( [Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,ParameterSetName="Name")] [ValidateNotNullOrEmpty()] [string] $Name, [Parameter(Mandatory=$true,ParameterSetName="All")] [switch] $All, [Parameter(Mandatory=$true,ParameterSetName="Current")] [switch] $Current, [Parameter(Mandatory=$true,ParameterSetName="ByIPAddress")] [System.Net.IPAddress] $IPAddress, [Parameter(Mandatory=$false)] [ValidateScript({ if (-not $_.Contains(".")) { throw "The Name must be a FQDN" } return $true })] [string] $Server ) begin { $script:ctx = $null try { if (-not $Server) { $script:Server = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().FindDomainController().Name $script:ctx = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext("DirectoryServer", $script:Server) } else { $script:Server = $Server $script:ctx = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext("DirectoryServer", $script:Server) } } catch [Exception] { Write-Error $_ return } } process { $site = $null try { switch ($pscmdlet.ParameterSetName) { "name" { [System.DirectoryServices.ActiveDirectory.ActiveDirectorySite]::FindByName($script:ctx, $name) } } } catch [Exception] { Write-Error -Exception $_.Exception -Message "Could not get the site / sites" } } end { } } function GetSingleDomainController { param( [Parameter(Mandatory=$true)] [ValidateScript({ if (-not $_.Contains(".")) { throw "The Name must be a FQDN" } return $true })] [string] $DomainControllerName ) $rootDSE = [adsi]"LDAP://$script:server/rootDSE" $ds = New-Object System.DirectoryServices.DirectorySearcher $ds.SearchRoot = "LDAP://$script:server/CN=Sites,$($rootDSE.configurationNamingContext)" $ds.Filter = "(&(objectclass=server)(dNSHostName=$DomainControllerName))" try { $serverDn = $ds.FindOne().GetDirectoryEntry().DistinguishedName.Value $siteDn = $serverDn.Substring($serverDn.IndexOf("CN=Servers") + 11, $serverDn.IndexOf("CN=Sites") - ($serverDn.IndexOf("CN=Servers") + 12)) $siteName = $siteDn.Substring(3) } catch [Exception] { throw "Could not find domain controller in $($ds.SearchRoot.DistinguishedName): $($_.Exception.Message)" } try { $dc = (Get-ADSite -Name $siteName -Server $script:Server).Servers | Where-Object { $_.Name -eq $DomainControllerName } if (-not $dc) { throw "The server $DomainControllerName cannot be found" } $dc } catch [Exception] { throw "Cannot read servers from site $siteName : ($_.Exception.Message)" } } function Get-Type { param( [Parameter(Position=0,Mandatory=$true)] [string] $GenericType, [Parameter(Position=1,Mandatory=$true)] [string[]] $T ) $Types = $T -as [type[]] try { $generic = [type]($GenericType + '`' + $Types.Count) $generic.MakeGenericType($Types) } catch [Exception] { throw New-Object System.Exception("Cannot create generic type", $_.Exception) } } function Get-ADReplicationLink { [CmdletBinding()] param( [Parameter(Mandatory=$true,ParameterSetName="AllDCsInSite",ValueFromPipelineByPropertyName=$true)] [string] $SiteName, [Parameter(Mandatory=$true,ParameterSetName="AllDCsInForest")] [switch] $AllDCsInForest, [Parameter(Mandatory=$true,ParameterSetName="AllDCsInDomain")] [switch] $AllDCsInDomain, [Parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] [ValidateScript({ if (-not $_.Contains(".")) { throw "The Name must be a FQDN" } return $true })] [string] $DomainName, [Parameter(Position=0,Mandatory=$false,ValueFromPipelineByPropertyName=$true,ParameterSetName="DcByName")] [ValidateScript({ if (-not $_.Contains(".")) { throw "The Name must be a FQDN" } return $true })] [Alias("DCName")] [string[]] $DomainControllerName, [Parameter(Position=0,Mandatory=$false,ValueFromPipelineByPropertyName=$true)] [Alias("NC")] [string] $NamingContext, [Parameter(Mandatory=$false)] [switch] $ErrorsOnly, [Parameter(Mandatory=$false)] [string] $Server ) begin { $global:tempDestinationServer = $null $script:ctx = $null try { if (-not $Server) { $script:Server = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().FindDomainController().Name $script:ctx = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext("DirectoryServer", $script:Server) $script:serverObject = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().FindDomainController() } else { $script:Server = $Server $script:ctx = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext("DirectoryServer", $script:Server) $script:serverObject = GetSingleDomainController -DomainControllerName $Server } } catch [Exception] { Write-Error $_ return } } process { $dcList = New-Object System.Collections.ArrayList foreach ($DomainController in $DomainControllerName) { [Void]$dcList.Add((GetSingleDomainController -DomainControllerName $DomainController)) } foreach ($dc in $dcList) { foreach ($partition in $dc.Partitions) { $repNeighbors = $dc.GetReplicationNeighbors($partition) if ($ErrorsOnly) { $repNeighbors = $repNeighbors | Where-Object { $_.LastSyncResult -ne 0 } } foreach ($repNeighbor in $repNeighbors) { $repInfo = New-Object (Get-Type -GenericType System.Collections.Generic.List -T System.Management.Automation.PSObject) $repNeighbor = $repNeighbor | Add-Member -MemberType NoteProperty -Name DestinationServer -Value $dc.Name -PassThru $repInfo.Add([psobject]$repNeighbor) $repInfo | ForEach-Object { $repl = new-object System.Collections.ArrayList $currtime = Get-Date -format 'yyyy-MM-ddTHH:mm:sszzz' $repltime = get-date -format "yyyy-MM-dd HH:mm:ss zzz" -date $($_.LastAttemptedSync) [void]$repl.add($currtime); [void]$repl.add("LastAttemptedSync=`"$repltime`"") [void]$repl.add("type=`"ReplicationEvent`"") [void]$repl.add("usn=$($_.UsnLastObjectChangeSynced)") [void]$repl.add("src_host=`"$($_.SourceServer)`"") [void]$repl.add("Result=`"$($_.LastSyncResult)`"") [void]$repl.add("transport=`"$($_.TransportType)`"") [void]$repl.add("naming_context=`"$($repNeighbor.PartitionName)`"") Write-Host ($repl -join " ") } } } } } end { } } ## Call The functions ## Get-ADReplicationlink $DomainControllerName