0

The concern I have is that I can't store the user's password anywhere. As soon as the user enters the password, I want to validate if it's compliant with the password policy settings on that machine.

  • I came across net commands to retrieve related information but net doesn't work for standard users.

  • A standard user can't create another user account on that machine- so from that account, I can't try to create another user with same password to check the password compliance.

  • Also tried changing the standard user's password with the same password itself with the intention that if it's not compliant, I will get a password non-compliant error. But it can mess up the password history.

Is there any way I can just simply check if password is compliant for a standard user via powershell without performing any write actions?

Neetu Soni
  • 51
  • 3

1 Answers1

0

Perhaps this utility function can help you out there:

function Test-PasswordForDomain {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory = $true, Position = 0)]
        [string]$Password,
        
        [Parameter(Mandatory = $false)]
        [string]$AccountSamAccountName = $null,
        
        [Parameter(Mandatory = $false)]
        [string]$AccountDisplayName = $null
    )
    # [Microsoft.ActiveDirectory.Management.ADEntity]
    $PasswordPolicy = Get-ADDefaultDomainPasswordPolicy -ErrorAction SilentlyContinue

    If ($Password.Length -lt $PasswordPolicy.MinPasswordLength) {
        Write-Verbose "Password '$Password' is too short. Minimal length is $($PasswordPolicy.MinPasswordLength)"
        return $false
    }
    if (($AccountSamAccountName) -and ($Password -match "$AccountSamAccountName")) {
        Write-Verbose "The password '$Password' includes the users SamAccountName"
        return $false
    }
    if ($AccountDisplayName) {
        # if ANY PART of the display name that is split by the characters below, the password should fail the complexity rules.
        $tokens = $AccountDisplayName.Split(",.-,_ #`t")
        foreach ($token in $tokens) {
            if (($token) -and ($Password -match "$token")) {
                Write-Verbose "The password '$Password' includes (part of) the users DisplayName"
                return $false
            }
        }
    }
    if ($PasswordPolicy.ComplexityEnabled -eq $true) {
        # check for presence of 
        # - Uppercase: A through Z, with diacritic marks, Greek and Cyrillic characters
        if ($Password -cnotmatch "[A-Z\p{Lu}\s]") {
            Write-Verbose "The password '$Password' is missing Uppercase characters"
            return $false
        }
        # - Lowercase: a through z, sharp-s, with diacritic marks, Greek and Cyrillic characters
        if ($Password -cnotmatch "[a-z\p{Ll}\s]") {
            Write-Verbose "The password '$Password' is missing Lowercase characters"
            return $false
        }
        # - Base 10 digits (0 through 9)
        if ($Password -notmatch "[\d]") {
            Write-Verbose "The password '$Password' is missing digits (0-9)"
            return $false
        }
        # - Nonalphanumeric characters: ~!@#$%^&*_-+=`|\(){}[]:;”‘<>,.?/
        if ($Password -notmatch "[^\w]") {
            Write-Verbose "The password '$Password' is missing Nonalphanumeric characters: ~!@#$%^&*_-+=`|\(){}[]:;`"'<>,.?/"
            return $false
        }
    }

    return $true
}
Theo
  • 57,719
  • 8
  • 24
  • 41
  • Thanks Theo! How do I handle rules where history is involved e.g. user can't repeat last 3 passwords? I tried searching online. Doesn't look like there is an api exposed for the same. – Neetu Soni Feb 11 '21 at 16:00
  • @NeetuSoni I have not found anything either to check if a password has already been used and if it can be used again. This function is for checking the password complexity itself. If reuse is allowed or not is 'trial and error' – Theo Feb 11 '21 at 16:19
  • 1
    As for `How do I handle rules where history is involved e.g. user can't repeat last 3 passwords`. Are you saying while you ar using Theo's helpful answer, or from ADDS itself? If it is the latter, then, ditto to what Theo stated. Why, because in ADDS, passwords are stored as hashes, not plain text, so one would have to get to and dump all the hashes and work the. However, if it is the former, just capture the entries in an array then that you check on each attempt. – postanote Feb 11 '21 at 19:00
  • @postanote I am not using Azure Active directory, but local user accounts. But what Theo suggested gave me a hint regarding possible solution. The password history is the only unknown. – Neetu Soni Feb 12 '21 at 06:16