2
votes

I am using PowerShell to create local users. I need to get input from keyboard: Username & Password. To get the password I can use one of the following:

$user_details = Get-Credential

or

$pass = Read-Host -assecureString "Please enter your password"

In both cases, I will get encrypted password variable System.Security.SecureString. In both cases, when I try to create the user, with

New-LocalUser -Name $username -Password $pass

I get an error that the password is not complex.

New-LocalUser : Unable to update the password. The value provided for the new password does not meet the length, complexity, or history requirements of the domain."

Since the password is encrypted, (System.Security.SecureString) I have no way to know the complexity of the password. How can I force the user to type a password that complies the complexity rules?

(using unencrypted passwords is not a good solution for me)

Update: After few answers that were relevant with good solutions, but did not meet my security requirement, I'd like to rephrase:

How can I check password complexity which is already stored in object: System.Security.SecureString (without decryption)

4
$pass.GetNetworkCredential().Password voila: plaintext password. - Maximilian Burszley

4 Answers

3
votes

In addition to what TheIncorrigible1 and KoryGill already answered and as you included the error message The value provided for the new password does not meet the length, complexity, or history requirements of the domain, you may include a test for the Default password complexity.

If you do a

Get-ADDefaultDomainPasswordPolicy

You will get an object like this:

ComplexityEnabled           : True
DistinguishedName           : DC=yourdomain,DC=com
LockoutDuration             : 00:30:00
LockoutObservationWindow    : 00:30:00
LockoutThreshold            : 3
MaxPasswordAge              : 42.00:00:00
MinPasswordAge              : 1.00:00:00
MinPasswordLength           : 7
objectClass                 : {domainDNS}
objectGuid                  : 44e3c936-5c8f-40cd-af67-f846c184cc8c
PasswordHistoryCount        : 24
ReversibleEncryptionEnabled : False

From this you can check interesting properties like the minimal length for a password in MinPasswordLength, after how many times a password can be re-used in PasswordHistoryCount. If ComplexityEnabled is True, then a password also requires a mix of Uppercase, Lowercase, Digits and Nonalphanumeric characters.

I found an excellent blog about that here you might want to read.

1
votes

By using if statement in the Powershell script, you can validate the user inputs before moving to the next command. You can get the required password by this:

$Input = Read-Host "Please enter your password. `nPassword must meet complexity requirements: 
`nAt least one upper case English letter [A-Z]`nAt least one lower case English letter [a-z]`nAt least one digit [0-9]`nAt least one special character (!,@,#,%,^,&,$)`nMinimum 7 in length."

if(($input -cmatch '[a-z]') -and ($input -cmatch '[A-Z]') -and ($input -match '\d') -and ($input.length -ge 7) -and ($input -match '!|@|#|%|^|&|$'))
{
    Write-Output "$input is valid password"
}
else
{
    Write-Output "$input is Invalid password"
}
1
votes

Using a Try-Catch is the best way for me to handle this Issue.
I read the password, trying to execute the command
Catch the exception error, and request password again in case of password error

0
votes

Decode the password/securestring...

Use the answer from here: PowerShell - Decode System.Security.SecureString to readable password

Then check it against your password complexity as you wish and give the user chances to re-enter it.