functions/Test-KrbPasswordReset.ps1
function Test-KrbPasswordReset { <# .SYNOPSIS Tests the account reset and synchronization functionality. .DESCRIPTION Tests the account reset and synchronization functionality. This is a dry run of what Reset-KrbPassword would do, executed using a temporary user account. .PARAMETER PDCEmulator The PDC Emulator to operate against. .PARAMETER DomainController The domain controller to synchronize with. .PARAMETER MaxDurationSeconds The maximum number of seconds a switch may take before being considered a failure. Defaults to 180 seconds .PARAMETER DCSuccessPercent The percent of DCs that need to successfully finish execution in order for this test to be considered a success. Defaults to 80 percent .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:\> Test-KrbPasswordReset -PDCEmulator 'dc1.domain.com' -DomainController 'dc2', 'dc3' Tests the account password reset using a dummy account and returns, whether the execution would have been successful. #> [CmdletBinding()] param ( [string] $PDCEmulator = (Get-ADDomain).PDCEmulator, [PSFComputer[]] $DomainController, [int] $MaxDurationSeconds = (Get-PSFConfigValue -FullName 'Krbtgt.Reset.MaxDurationSeconds' -Fallback 100), [int] $DCSuccessPercent = (Get-PSFConfigValue -FullName 'Krbtgt.Reset.DCSuccessPercent' -Fallback 100), [switch] $EnableException ) begin { #region Ensure Domain Controller parameter is filled if (-not $DomainController) { try { $DomainController = (Get-ADDomainController -Server $PDCEmulator -Filter * -ErrorAction Stop).HostName | Where-Object { $_ -ne $PDCEmulator } } catch { Stop-PSFFunction -String 'Test-KrbPasswordReset.FailedDCResolution' -StringValues $PDCEmulator -ErrorRecord $_ return } } #endregion Ensure Domain Controller parameter is filled #region Create a test account to test SO replication with try { $randomName = "krbtgt_test_$(Get-Random -Minimum 100 -Maximum 999)" Write-PSFMessage -String 'Test-KrbPasswordReset.CreatingCanary' -StringValues $randomName $canaryAccount = New-ADUser -Name $randomName -PassThru -Server $PDCEmulator -ErrorAction Stop } catch { Stop-PSFFunction -String 'Test-KrbPasswordReset.FailedCanaryCreation' -StringValues $randomName -ErrorRecord $_ return } #endregion Create a test account to test SO replication with } process { if (Test-PSFFunctionInterrupt) { return } $result = [PSCustomObject]@{ PSTypeName = 'Krbtgt.TestResult' PDCEmulator = $PDCEmulator Start = $null End = $null Duration = $null Reset = $false Sync = @() DCTotal = ($DomainController | Measure-Object).Count DCSuccess = 0 DCSuccessPercent = 0 DCFailed = @() Errors = @() Success = $true Status = '' RWDCs = $DomainController } $result.Start = Get-Date #region Test 1: Password Reset Write-PSFMessage -String 'Test-KrbPasswordReset.ResettingPassword' -StringValues $canaryAccount.DistinguishedName -Target $canaryAccount.DistinguishedName try { Reset-UserPassword -Server $PDCEmulator -Identity $canaryAccount.DistinguishedName -EnableException $result.Reset = $true } catch { Write-PSFMessage -Level Warning -String 'Test-KrbPasswordReset.ResettingPasswordFailed' -StringValues $canaryAccount.DistinguishedName -Target $canaryAccount.DistinguishedName -ErrorRecord $_ $result.Reset = $false $result.Errors += $_ $result.Success = $false $result.Status = $result.Status, 'ResetError' -join ", " } #endregion Test 1: Password Reset #region Test 2: Resync Domain Controllers Write-PSFMessage -String 'Test-KrbPasswordReset.SynchronizingCanary' -StringValues $canaryAccount.DistinguishedName -Target $canaryAccount.DistinguishedName $result.Sync = Sync-KrbAccount -SourceDC $DomainController -TargetDC $PDCEmulator -Identity $canaryAccount.DistinguishedName -EnableException:$false $result.End = Get-Date $result.Duration = $result.End - $result.Start $result.DCSuccess = $result.Sync | Where-Object Success $result.DCSuccessPercent = ($result.DCSuccess | Measure-Object).Count / $result.DCTotal * 100 $result.Sync.Error | ForEach-Object { if ($_) { $result.Errors += $_ } } if ($result.Duration.TotalSeconds -gt $MaxDurationSeconds) { $result.Success = $false $result.Status = $result.Status, 'TooSlowError' -join ", " } if ($result.DCSuccessPercent -lt $DCSuccessPercent) { $result.Success = $false $result.Status = $result.Status, 'SyncErrorRateError' -join ", " } Write-PSFMessage -String 'Test-KrbPasswordReset.Concluded' -StringValues $result.Success, $result.Status, $canaryAccount.DistinguishedName -Target $canaryAccount.DistinguishedName #endregion Test 2: Resync Domain Controllers $result } end { if (Test-PSFFunctionInterrupt) { return } # Remove the test account after finishing its work try { $canaryAccount | Remove-ADUser -Server $PDCEmulator -Confirm:$false -ErrorAction Stop } catch { Stop-PSFFunction -String 'Test-KrbPasswordReset.FailedCanaryCleanup' -StringValues $canaryAccount.DistinguishedName } } } |