Validating User Account Passwords (Part 3)

by Aug 14, 2020

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. 
 


Twitter This Tip! ReTweet this Tip!