- Use PowerShell splatting and PSBoundParameters to pass parameters - Wed, Nov 9 2022
- Using PowerShell with $PSStyle - Mon, Jan 24 2022
- Clean up user profiles with PowerShell - Mon, Jun 9 2014
On one hand this seems a bit unnecessary as you probably aren’t changing your domain password policy all of the time. But if you are firing up new domains often, say as part of a private cloud provisioning task, you might want to automate setting the domain policy. Or at the very least you might want to roll back to a previous policy configuration.
The first thing I would recommend is getting your current domain password policy.
PS C:\> Get-ADDefaultDomainPasswordPolicy ComplexityEnabled : True DistinguishedName : DC=GLOBOMANTICS,DC=local 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
As you can see, my policy is essentially the default policy we’ve had for years. If you haven’t done so, save this information to a file.
PS C:\> Get-ADDefaultDomainPasswordPolicy | Export-Clixml C:\scripts\Globomantics_PWD_Policy.xml
Oh, and if you are following along you are in a non-production test environment, right? Now I have a copy of my current policy. We’ll come back to this later.
To modify the policy, I bet you guessed that the cmdlet to use is Set-ADDefaultDomainPasswordPolicy. If you look at cmdlet help, you’ll notice that the parameters correspond to the property names we see from Get-ADDefaultDomainPasswordPolicy.
Unfortunately, none of the parameters other than Identity use pipeline binding. This means you can’t pipe an object with your new values to this cmdlet. Instead you simply specify the value you want to set. Be careful though as some properties are expecting certain object types such as a TimeSpan.
PS C:\> Set-ADDefaultDomainPasswordPolicy -Identity "globomantics.local" -MaxPasswordAge "60.00:00:00" -PassThru ComplexityEnabled : True DistinguishedName : DC=GLOBOMANTICS,DC=local LockoutDuration : 00:30:00 LockoutObservationWindow : 00:30:00 LockoutThreshold : 3 MaxPasswordAge : 60.00:00:00 MinPasswordAge : 1.00:00:00 MinPasswordLength : 7 objectClass : {domainDNS} objectGuid : 44e3c936-5c8f-40cd-af67-f846c184cc8c PasswordHistoryCount : 24 ReversibleEncryptionEnabled : False
Here I set the MaxPasswordAge property to 60 days. The cmdlet converted the string “60.00:00:00” into a TimeSpan object. But you may find it easier to do yourself.
PS C:\> Set-ADDefaultDomainPasswordPolicy -Identity "globomantics.local" -MaxPasswordAge (New-Timespan -Days 51 ) -MinPasswordLength 8 -PassThru ComplexityEnabled : True DistinguishedName : DC=GLOBOMANTICS,DC=local LockoutDuration : 00:30:00 LockoutObservationWindow : 00:30:00 LockoutThreshold : 3 MaxPasswordAge : 51.00:00:00 MinPasswordAge : 1.00:00:00 MinPasswordLength : 8 objectClass : {domainDNS} objectGuid : 44e3c936-5c8f-40cd-af67-f846c184cc8c PasswordHistoryCount : 24 ReversibleEncryptionEnabled : False
Here I used a nested command, New-Timespan, to define the max age parameter value. I also went ahead and modified another parameter to require 8 character passwords. Notice too that I’m using –Passthru. By default the cmdlet doesn’t write anything to the pipeline unless you specify –Passthru. However, the cmdlet does support –WhatIf and –Confirm which is good.
Suppose at some point you realize you need to roll back to a previous policy. This is where the saved XML file comes in handy. I’ll step through the process but you could easily build a simple script around it. First, import the XML file.
$saved = Import-Clixml C:\scripts\Globomantics_PWD_Policy.xml
Next, I’ll define an array of property names.
$properties = 'ComplexityEnabled', 'LockoutDuration', 'LockoutObservationWindow', 'LockoutThreshold', 'MaxPasswordAge', 'MinPasswordAge', 'MinPasswordLength', 'PasswordHistoryCount', 'ReversibleEncryptionEnabled'
With this, I can build a hash table of parameters and values that I can splat against Set-ADDefaultDomainPasswordPolicy.
$paramHash=@{Identity="globomantics.local"} foreach ($property in $properties) { $paramHash.Add($property,$saved.$property) }
Because the parameter and property names match this is a pretty simple command. Here’s what the hash table looks like.
Name Value ---- ----- LockoutObservationWindow 00:30:00 MinPasswordAge 1.00:00:00 MinPasswordLength 7 ComplexityEnabled True LockoutDuration 00:30:00 Identity globomantics.local PasswordHistoryCount 24 LockoutThreshold 3 MaxPasswordAge 42.00:00:00 ReversibleEncryptionEnabled False
All that remains is to invoke the cmdlet with this parameters.
PS C:\> Set-ADDefaultDomainPasswordPolicy @paramhash -PassThru ComplexityEnabled : True DistinguishedName : DC=GLOBOMANTICS,DC=local 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
Just like that I’m back to a previous policy. I am unlikely to frequently change my password policy, and I trust you are the same, but should someone get in and change something they shouldn’t, assuming I’ve planned ahead, I can fix things pretty easily.