Scenario: Carl is a helpdesk agent and today he is feeling a bit stressed out. There has been an outage on one of the business critical systems and the phones are constantly ringing. One of the calls is a user who forgot his password and Carl quickly asks the usual control questions to make sure that the user is who he claims to be, locates the user account and clicks on reset password. Carl is an experienced agent and is usually very good at quickly making random passwords up but today he just can’t find the inspiration so he quickly enters the password he has heard his colleagues use so many times, Summer15. There is a long queue on the phone line and he simply just don’t have the time to do it right. He also forgot so check that little checkbox that forces the user to change his password on next logon. These do things happen repeatedly once in a while and suddenly there are a whole lot of users using the same password.
Resetting a users password in Active Directory using the Active Directory Users and Computers is quite time consuming. Using Active Directory Administrative Center is a bit faster since it has the Reset Password tile. But both these alternative depends on the technician to make up a password.
Doing the same thing using cmdlets in the Active Directory PowerShell module is a lot of typing and not really a good alternative. Unless you combine all the cmdlets in an advanced function. Let’s start by looking at the process of resetting a password in Active Directory using PowerShell:
First I need to make up a new password and convert it to a secure string.
$SecPaswd= ConvertTo-SecureString –String ‘Summer2014’ –AsPlainText –Force
Then I reset the password using Set-ADAccountPassword.
Set-ADAccountPassword -Reset -NewPassword $SecPaswd –Identity john.smith
Now I could check if the account is locked out, but I usually just unlock the account, locked or not.
Unlock-ADAccount –Identity john.smith
Last I make sure that the user has to change the password on next logon
Set-ADUser –Identity john.smith –ChangePasswordAtLogon $true
This is a lot to type while having a user waiting in the phone and making up passwords manually is never a good practice. To solve this scenario I wrote the function Reset-SWADPassword that takes four parameters:
- Identity <String> Takes either account name or distinguished name and is used to identify the account to have its password reset.
- Length <Int> Defines the number chars in the new password, defaults to 8
- InputStrings <String> An optional list of strings that defines character groups. The generated password will contain at least one char from each string.
- NoChange Specifies that the user should NOT have to change password on next logon.
The function will make use of two of my previously published functions, New-SWRandomPassword and Get-Phonetic, to generate a new random password and output the password using NATO phonetic spelling to make it easier to read the new password to a user over phone.
Load these three functions on a computer with the Active Directory PowerShell module installed and you can simply reset a users password by running:
Reset-SWADPassword –Identity phil.brath
This shows us that Phil now has the password ixi9EG!e
By default, the parameter –InputStrings has the following value:
$InputStrings = @('abcdefghijkmnopqrstuvwxyz', 'ABCEFGHJKLMNPQRSTUVWXYZ', '23456789', '!"#%&')
Meaning that every password will consist of one character from each of the strings. If I find that way too complex I can specify my own inputstrings. However specifying inputstrings every time I want to reset a password is just not going to happen. The solution to this is to set default parameter values in the automatic variable $PSDefaultParameterValues. $PSDefaultParameterValues is a special variable of the type DefaultParameterDictionary which has a hashtable-like structure. To set a default parameter value, I index into the variable like this:
$PSDefaultParameterValues["Reset-SWADPassword:InputStrings"]=@('abcd', 'ABCD', '1234567890')
Now I can run Reset-SWADPassword again without having to specify my custom inputstrings.
This time the generated password only contains lowercase a-d, uppercase A-D and numbers 0-9.
To read more about $PSDefaultParameterValues, see the help document about_Parameters_Default_Values
$PSDefaultParameterValues is reset every time I close my PowerShell window. If I want to have this value set every time I open PowerShell I have to put it in my profile. The profile is a script that gets run every time I start PowerShell and I’ve written a post on using PowerShell profiles. Just add the modification of $PSDefaultParameterValues to the appropriate profile script and you’re set!
Here is the function in full: