In the previous parts, we created the Test-Password function that can test user account passwords for both local and remote user accounts.
In our last part, we’ll add error handling to the Test-Password function so it responds gracefully when the user enters domain that does not exist or is unavailable:
function Test-Password { param ( [Parameter(Mandatory)] [string] $Domain, [Parameter(Mandatory)] [string] $Username, [Parameter(Mandatory)] [SecureString] $Password ) # load assembly for required system commands Add-Type -AssemblyName System.DirectoryServices.AccountManagement # is this a local user account? $local = $Domain -eq $env:COMPUTERNAME if ($local) { $context = [System.DirectoryServices.AccountManagement.ContextType]::Machine } else { $context = [System.DirectoryServices.AccountManagement.ContextType]::Domain } # convert SecureString to a plain text # (the system method requires clear-text) $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Password) $plain = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) # test password try { $PrincipalContext = [System.DirectoryServices.AccountManagement.PrincipalContext]::new($context, $Domain) $PrincipalContext.ValidateCredentials($UserName,$plain) } catch [System.DirectoryServices.AccountManagement.PrincipalServerDownException] { throw "Test-Password: Domain '$Domain' not found." } }
Once you run this code, there is a new command “Test-Password”. When you run it, you are prompted for domain (or local computer name to test local accounts), username, and masked password.
Below is an example running in PowerShell 7: the first call (testing a local account) is successful and yields $true. The second call (specifying a domain that is unavailable) fails with a custom error message:
PS C:\> Test-Password cmdlet Test-Password at command pipeline position 1 Supply values for the following parameters: Domain: dell7390 Username: remotinguser2 Password: *********** True PS C:\> Test-Password cmdlet Test-Password at command pipeline position 1 Supply values for the following parameters: Domain: doesnotexist Username: testuser Password: ******** Exception: Line | 47 | throw "Test-Password: Domain '$Domain' not found." | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | Test-Password: Domain 'doesnotexist' not found.