Functions/Start-ADReplication.ps1
function Start-ADReplication { <# .SYNOPSIS Forces replication to occur between domain controllers in domain. .DESCRIPTION Forces replication to occur between domain controllers in domain. Invoke-Command to a DC. Requires to be running in elevated Powershell prompt. .PARAMETER Name A string array containing the name, fqdn or ipaddress of a domain controller. If not specified will query AD for a domain controller. Aliased to 'DomainController', 'DC', 'CN', 'ComputerName' .PARAMETER Quiet Switch will create no output .EXAMPLE Start-ADReplication Will issue a call to Get-ADDomainController and run the replication against that one DC .EXAMPLE Get-ADDomainController -Filter * | Start-ADReplication Will return a list of all DCs and run the replication against that list .EXAMPLE Get-ADDomainController -Filter "Name -like '*CORP*'" | Start-ADReplication Will return a list of all DCs that have 'CORP' in their name and run the replication against that list .EXAMPLE Start-ADReplication -Name DC1 -Verbose Assuming there are two DCs (DC1, DC2) in the contosco.com domain here is a sample return VERBOSE: Starting [Start-ADReplication] VERBOSE: $Name is [DC1] VERBOSE: Processing [DC1] DC1 DC2 "DC=contosco,DC=com" - Sync from DC2 to DC1 completed successfully. DC1 DC2 "CN=Configuration,DC=contosco,DC=com" - Sync from DC2 to DC1 completed successfully. DC1 DC2 "CN=Schema,CN=Configuration,DC=contosco,DC=com" - Sync from DC2 to DC1 completed successfully. DC1 DC2 "DC=DomainDnsZones,DC=contosco,DC=com" - Sync from DC2 to DC1 completed successfully. DC1 DC2 "DC=ForestDnsZones,DC=contosco,DC=com" - Sync from DC2 to DC1 completed successfully. VERBOSE: Ending [Start-ADReplication] .NOTES * Reworked logic so it just replicates the links that are defined. Previously it ran repadmin.exe with /ApeD switch and it was horribly slow. * Changed parameter $DC to $Name so that it would take input from Get-ADDomainController and to accept an array and added aliases to it * Changed output so that it would remove blank or commented lines from the output and to display what is being replicated in the output * Changed output so that it creates CSV output * Added '-ThrottleLimit' to the Invoke-Command so as to not saturate the local computer. Changed value to [environment]::ProcessorCount which is the number of processors on the computer. #> # todo - add -Credential #region parameter [CmdletBinding(ConfirmImpact = 'Medium')] [OutputType('string')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseOutputTypeCorrectly', '')] Param ( [parameter(Mandatory, HelpMessage = 'Please enter the name of a domain controller', ValueFromPipelineByPropertyName)] [Alias('DomainController', 'DC', 'CN', 'ComputerName')] [string[]] $Name, [switch] $Quiet ) #endregion parameter begin { Write-Verbose -Message "Starting [$($MyInvocation.Mycommand)]" if ($Name) { Write-Verbose -Message "`$Name is [$($Name -join ', ')]" } [int] $ThrottleLimit = [environment]::ProcessorCount $ScriptBlock = { $repl = repadmin.exe /showrepl /all /csv | ConvertFrom-Csv | Select-Object -Property 'Destination DSA', 'Source DSA', 'Naming Context' $repl | ForEach-Object { $msg = "`"$($_.'Destination DSA')`",`"$($_.'Source DSA')`",`"$($_.'Naming Context')`"" repadmin.exe /replicate $_.'Destination DSA' $_.'Source DSA' "$($_.'Naming Context')" | Where-Object { $_ -notmatch '^[\s]*$' } | ForEach-Object { "$msg,`"$_`"" } } } if (-not $Quiet) { "`"DestinationDSA`",`"SourceDSA`",`"NamingContext`",`"Message`"" } } process { foreach ($CurName in $Name) { Write-Verbose -Message "Processing [$CurName]" if ($Quiet) { $null = Invoke-Command -ComputerName $CurName -ThrottleLimit $ThrottleLimit -ScriptBlock $ScriptBlock } else { Invoke-Command -ComputerName $CurName -ThrottleLimit $ThrottleLimit -ScriptBlock $ScriptBlock } } } end { Write-Verbose -Message "Ending [$($MyInvocation.Mycommand)]" } } |