functions/Sync-KrbAccount.ps1
function Sync-KrbAccount { <# .SYNOPSIS Forces a single item AD Replication. .DESCRIPTION Will command the replication of an AD User object between two DCs. Uses PowerShell remoting against the source DC(s). .PARAMETER SourceDC The DC to start the synchronization command from. .PARAMETER TargetDC The DC to replicate with. .PARAMETER Identity The user identity to replicate. Defaults to krbtgt. .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions. This is less user friendly, but allows catching exceptions in calling scripts. .EXAMPLE PS C:\> Sync-KrbAccount -SourceDC 'dc1' -TargetDC 'dc2' Replicates the krbtgt account between dc1 and dc2. #> [CmdletBinding()] param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] [PSFComputer[]] $SourceDC, [Parameter(Mandatory = $true)] [string] $TargetDC, [string] $Identity = 'krbtgt', [switch] $EnableException ) begin { try { $krbtgtDN = (Get-ADUser -Identity $Identity -Server $TargetDC -ErrorAction Stop).DistinguishedName } catch { Stop-PSFFunction -String 'Sync-KrbAccount.UserNotFound' -StringValues $Identity, $TargetDC -ErrorRecord $_ return } } process { if (Test-PSFFunctionInterrupt) { return } $errorVar = @() $pwdLastSet = [System.DateTime]::FromFileTimeUtc((Get-ADObject -Identity $krbtgtDN -Server $TargetDC -Properties PwdLastSet).PwdLastSet) Write-PSFMessage -String 'Sync-KrbAccount.Connecting' -StringValues ($SourceDC -join ', '), $krbtgtDN -Target $SourceDC Invoke-PSFCommand -ComputerName $SourceDC -ScriptBlock { param ( $TargetDC, $KrbtgtDN, $PwdLastSet ) $message = repadmin.exe /replsingleobj $env:COMPUTERNAME $TargetDC $KrbtgtDN *>&1 $result = 0 -eq $LASTEXITCODE # Verify the password change was properly synced $pwdLastSetLocal = [System.DateTime]::FromFileTimeUtc((Get-ADObject -Identity $KrbtgtDN -Server $env:COMPUTERNAME -Properties PwdLastSet).PwdLastSet) if ($pwdLastSetLocal -ne $PwdLastSet) { $result = $false } [PSCustomObject]@{ ComputerName = $env:COMPUTERNAME Success = $result Message = ($message | Where-Object { $_ }) ExitCode = $LASTEXITCODE Error = $null } } -ArgumentList $TargetDC, $krbtgtDN, $pwdLastSet -ErrorVariable errorVar -ErrorAction SilentlyContinue | Select-PSFObject -KeepInputObject -TypeName 'Krbtgt.SyncResult' foreach ($errorObject in $errorVar) { Write-PSFMessage -Level Warning -Message 'Sync-KrbAccount.ConnectError' -StringValues $errorObject.TargetObject -ErrorRecord $errorObject [PSCustomObject]@{ PSTypeName = 'Krbtgt.SyncResult' ComputerName = $errorObject.TargetObject Success = $false Message = $errorObject.Exception.Message ExitCode = 1 Error = $errorObject } } } } |