Validating User Account Passwords (Part 2)

by Aug 12, 2020

In the previous tip we showed how PowerShell can validate and test user account passwords, however the password was requested in plain text. Let’s change this so that PowerShell masks the password when it is entered.

You can re-use the strategy used below for any other PowerShell function where you’d like to prompt the user for masked input.

Here is the function Test-Password:

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
   $PrincipalContext = [System.DirectoryServices.AccountManagement.PrincipalContext]::new($context, $Domain)
   $PrincipalContext.ValidateCredentials($UserName,$plain)
}

When you run it, you get prompted for a domain (enter your computer name to test local accounts) and a user name. The password is prompted in a masked way. The function returns $true when the password is correct, else $false.

Note how the prompted SecureString is converted to plain text internally. Whenever you need a masked input box, you can use a mandatory parameter of type SecureString and inside your function, convert the SecureString value to a plain text.


Twitter This Tip! ReTweet this Tip!