PowerShell Set-ADAccountPassword -WhatIf bug

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.