In my PowerShell training class this week, I was demonstrating how to take advantage of the -Whatif and -Confirm parameters. These parameters exist (or should) for any cmdlet that changes the environment such as stopping a service, killing a process or copying a file.
ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
PS C:\> get-process | kill -whatif What if: Performing operation "Stop-Process" on Target "cAudioFilterAgent64 (4004)" What if: Performing operation "Stop-Process" on Target "cfp (3720)". What if: Performing operation "Stop-Process" on Target "CFSwMgr (5548)". What if: Performing operation "Stop-Process" on Target "chrome (1512)".' ...
The students liked that and clearly recognized the value. In fact, one student asked if there was a way to make that behavior the default. that is always use -whatif. Intriguing idea thought. I thought for a moment and realized there might be an automatic variable to controls that behavior. For example, to turn on the verbose pipeline I can change $VerbosePrefence to Continue.
I took a quick look at variables and tucked away, because I never had reason to notice it before, is $WhatIfPreference. If you look that value, it is False. So try this: set the value to True.
$WhatIfPreference=$True
Now see what happens when you try to do something that would change the environment.
PS C:\> stop-service spooler What if: Performing operation "Stop-Service" on Target "Print Spooler (spooler)". PS C:\> ps -id $pid | kill What if: Performing operation "Stop-Process" on Target "powershell (3896)". PS C:\> dir $pshome\*.exe | del What if: Performing operation "Remove File" on Target "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe". What if: Performing operation "Remove File" on Target "C:\Windows\System32\WindowsPowerShell\v1.0\powershell_ise.exe".
You can't complete any of these expressions. Any command that supports Whatif will automatically use it. In essence I have turned my PowerShell session into a "read-only" experience. Of course this isn't foolproof as this only applies to PowerShell cmdlets. I could still run the NET or SC command line tools. Setting the $WhatIfPreference back to false puts things back to normal. But for a novice user, you could setup a profile for them to modify the preference variable and trust that they wouldn't get into any problems. I have to admit I'm intrigued by this and time permitting want to look into ways that this could be enforced for an end user but not for an admin, among other scenarios.
The long term solution for this sort of thing is a constrained runspace, but that requires a bit more PowerShell expertise and complexity. I love the simplicity of changing a single variable. The other take-away from this experience is to look at the PowerShell variables and make sure you understand their purpose and what changes you might make to improve your PowerShell experience.
I have this set for my ‘not-that-knowledgeable’ colleagues. There is a way how to bypass it. Just use this:
Remove-Item * -WhatIf:$False
It will skip WhatIf for current run of Remove-Item (same situation is with Confirm parameter). But they will never find it (unless they read your blog/comments 🙂
David
Sure. There are any number of ways to get around the restriction. As you suggest this is for casual novice users.
Good to know !