Predict the Future with PowerShell
Summary: Microsoft Scripting Guy, Ed Wilson, discusses using Windows PowerShell to see what a command will do before it does it.
Hey, Scripting Guy! My football coach always said, “If you’re scared, admit you’re scared.” Well, Scripting Guy, in honor of my old coach, I am admitting I am scared. I do not know Windows PowerShell, but it seems that so many of the new products from Microsoft use it. It seems that there are some things that I have to use Windows PowerShell for—like I have no option. Maybe there is an option, but I can’t find it. So what do it do? I am afraid I will mess something up by typing stuff when I have no idea what it is going to do. Can you help me?
Microsoft Scripting Guy, Ed Wilson, is here. The other day I was talking to my mom on the phone, and she said, “I don’t like tea that has a string on it.”
"Hmmm." At least I get my love for tea honestly. We grew up in an international community, and our neighbors had lived all over the world, so it is no wonder that we like tea. But the string? I know what she means, she prefers loose leaf tea. I do too, but I have also had some excellent tea that came in nice tea bags, and the string makes it rather convenient. When you get right down to it, tea is tea—whether it is good tea or bad tea, the string doesn’t really matter.
TD, it’s not Windows PowerShell that is the problem. In fact, many of admin tools use Windows PowerShell under the covers, for example Server Manager and the Exchange Admin tools. The GUI in these cases is simply another way of interacting with Windows PowerShell.
But when I click, click, click through one of the GUI tools, do I really know what it is doing behind the scenes? Some “wizards” tell me that they will do this, that, and the other thing—but I am not clear about all of the steps or all of the things that will be set or unset or installed or configured.
So although it may seem like the GUI tools are safer, in reality they are not always safer. I have seen many websites that say something like the following: To fix this problem or install this software, click here, click here and here, and clear this box and that one.
But what all that means or does is not often fully described. So in the end, I am still doing something I do not understand, and I am making changes when I know not what they might do.
What if I run this command?
One really beneficial parameter with Windows PowerShell is -Whatif. It is a common parameter, but it is only available when a command will make a change of some sort. For example, -WhatIf is not available for Get-Service because all that command does is produce information about services that are configured on a system. But Stop-Service does have the –WhatIf parameter because it will make changes to the system.
In a similar fashion, Get-Item does not have a –WhatIf parameter because it only returns items, but New-Item does have a –WhatIf parameter because it makes something new, and as a result, it makes changes to a system.
If I am using the Command Add-on tool in the Windows PowerShell ISE, and if a cmdlet has the –WhatIf parameter, it will be available as a check box. The following example illustrates this.
I open the Windows PowerShell ISE, and in the Command Add-on I begin typing the word Process. I do not need to type it completely. In fact, as shown in the following image, after I have typed proc, I have filtered enough of the cmdlets to permit me to find what I want:
I select Get-Process, use a wildcard character for the Name parameter, and press the Copy button. I then paste the command in the Script pane. I type a single space and then the pipeline character ( | ), which on my keyboard appears above the backslash key. This will take all of the process objects and send them to my next command. After I have typed the pipeline character, I press ENTER.
In the following image, notice that at the end of my first line, there is a red squiggle. This red squiggle is how Windows PowerShell tells me that I have an incomplete command. When I added the pipeline character at the end of the line, Windows PowerShell expects it to be followed with something else. This is not a problem right now because in the next step I will add an additional command. My Windows PowerShell ISE now appears as shown here:
I go back to my Command Add-on pane, press the Down arrow a couple times until I select Stop-Process from the list of cmdlets. The first tab is for the Id set of commands, the second tab is for the InputObject set of commands, and the last tab is for the Name set.
It is the Name set that I want, so I click the that tab. The text box is where I can type the name of the process I want to stop. The bottom check box is for the WhatIf parameter. I select that box.
Warning It is crucial that you select the WhatIf check box before proceeding. Otherwise, your system could become unstable or even shut down when you run the script.
After I select the WhatIf check box, I press the Copy button and paste my command under the Get-Process * | command. This is shown here:
Because the Stop-Process command is using –WhatIf, Windows PowerShell will prototype the results of the command for me, and let me know what would happen if I run the command. This single feature of Windows PowerShell will save hours of potential down time related to misconfiguration and inadvertent commands.
Now I run the command to see what will happen. To run the command, I press the green triangle in the menu (I can also press F-5). The output is shown here:
It appears that the preceding command would stop every process on my system. That is not what I want to do.
Note This is another reason for running as a non-admin—a non-admin would not have rights to stop system processes. The computer may become unstable, but it would not immediately crash because Windows PowerShell only has rights to do whatever the currently logged-in user has rights to do. As a best practice, one should always log in to the system with a least privileged user account, and then elevate when a specific action requires elevated privileges.
I can also use –WhatIf to see if other commands would work. For example, I noted earlier that the default paramater for Stop-Process is –Id. So can I use a wildcard character for the –Id parameter? Obviously, I want to test this—otherwise, I would essentially be re-creating my previous command to stop all processes.
I click the Id tab, and I note that the WhatIf check box is cleared.
Note When changing tabs in the Command Add-on pane, –WhatIf and other check boxes are sometimes cleared. Do not get click happy and accidently run a command without –WhatIf if that is not your intention.
When I run my new command, I see that it is not allowed. So I learned that I cannot use a wildcard character for a process ID (it expects an integer). This is shown here:
I go back to the Name tab and change it to a wildcard character. I ensure that the WhatIf box is selected, and I run it. Yep, I can use a wildcard character for Name. It provides the same output as my prior Get-Process * | Stop-Process –WhatIf command. This is shown here:
TD, that is all there is to using Windows PowerShell to see the results of a command before it runs. Don’t Learn PowerShell Week will continue tomorrow when I will talk about more way cool stuff.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at firstname.lastname@example.org, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy