Today (2017 March) I unfortunately learned of the -WhatIf bug for the PowerShell Active Directory cmdlet Set-ADAccountPassword.
About -WhatIf
“-WhatIf” is a common PowerShell System State parameter that is supposed to “Explain what will happen if the command is executed, without actually executing the command.(Boolean ) -whatif:$false or -whatif:$true.”
I use it all of the time while writing and developing PowerShell scripts to see what would happen if I actually executed the command. It’s a quick and easy way to ensure that your scope and syntax are correct.
Here’s a good -WhatIf example. My objective is to simply stop the process for Notepad++. Being a lazy admin, I couldn’t be bothered to write out the full process name so I used wildcards (e.g. note). Thankfully, I used -WhatIf first, which showed me that my scope was not narrow enough; for Stop-Process would have also killed OneNote. Whew — good catch -WhatIf!.
A -WhatIf Example
1 2 3 4 | # Stop only the NotePad++ process Get-Process *note* | Stop-Process -WhatIf What if: Performing the operation "Stop-Process" on target "notepad++ (9276)". What if: Performing the operation "Stop-Process" on target "ONENOTEM (460)". |
Set-ADAccountPassword ignores -WhatIf
Unfortunately, the Set-ADAccountPassword cmdlet ignores the -WhatIf parameter and will execute your changes anyway. While I thought I was just testing my scope and syntax, Set-ADAccountPassword -WhatIf decided to go ahead and execute the password changes.
I knew something was wrong because What if: Performing the operation “Set-ADAccountPassword” on target was not being outputted to my screen. To confirm, I used the Get-ADUser cmdlet with a PasswordLastSet filter. Yep, it looks like a bunch of accounts just had their password changed.
Query which AD accounts changed their password today
1 2 3 4 5 6 7 8 9 10 11 12 | # Retrieve accounts that had their passwords changed today $Days = (Get-Date).AddDays(-1) Get-ADUser -Filter {PasswordLastSet -ge $Days} -Properties PasswordLastSet | Sort PasswordLastSet -Descending | Format-Table PasswordLastSet, GivenName PasswordLastSet GivenName --------------- --------- 03/04/2017 10:36:54 William 03/04/2017 10:36:54 Brian 03/04/2017 10:36:54 Steven 03/04/2017 10:36:54 Edward 03/04/2017 10:36:54 Timothy etc. |
At this point I was repeatedly typing the expletive parameter -WTF! Thankfully, my scope was correct and I had targeted the correct users for the password change. But had I made an error and targeted more users than desired, I would have had a problem.
Microsoft says the bug is fixed
In late 2015, Microsoft’s Ned Pyle wrote “This is fixed in Windows Server 2016 and the accompanying RSAT.”
That’s great, but I was still using Windows 7 and PowerShell Version 5 when I was affected by this bug.
Windows 7 PowerShell Version 5
1 2 3 4 5 | $PSVersionTable.PSVersion Major Minor Build Revision ----- ----- ----- -------- 5 1 14409 1005 |
I have also run Update-Help, yet neither Get-Help Set-ADAccountPassword -Online nor Get-Help Set-ADAccountPassword -Full make mention of the bug and still indicate that -WhatIf is a working parameter.
Here are the Syntax and Notes from Get-Help Set-ADAccountPassword -Full:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | NAME Set-ADAccountPassword SYNOPSIS Modifies the password of an Active Directory account. PARAMETERS -WhatIf [<SwitchParameter>] Describes what would happen if you executed the command without actually executing the command. Required? false Position? named Default value Accept pipeline input? false Accept wildcard characters? false NOTES This cmdlet does not work with an Active Directory Snapshot. This cmdlet does not work with a read-only domain controller. This cmdlet does not work when connected to Global Catalog port. |
It would be ideal if the bug was fixed for all platforms that run PowerShell 5. Until then, at least update the content retrieved by Update-Help to remove -WhatIf as a valid parameter and make a mention of the bug in the Notes section.