Summary: Microsoft Scripting Guy, Ed Wilson, talks about running commands on remote servers.
Hey, Scripting Guy! One of the things I really don’t understand is why Windows PowerShell is broken. I look at commands like you suggest, but they don’t work. Specifically, I wanted to see the status of services on my servers, but the commands just don’t work. What’s up with that?
—BB
Hello BB,
Microsoft Scripting Guy, Ed Wilson, is here. This morning it is cold and raining, which would not be unusual winter weather for Charlotte, North Carolina—except the weather app on Bing said it was going to be sunny all day. It seems that Punxsutawney Phil is more accurate—and he is just a gopher. I wonder, at times, why the weather forecast remains a mystery and isn't updated. I can look outside and see that it is raining, and yet the app says sunshine. Hmmm...
BB, one thing that is not a mystery is why Windows PowerShell won’t work. There is always a reason, and in your case, there are a few likely suspects:
- Rights.
The account you are using to make your remote command may not have rights on the destination server. - Firewall.
The port used by the command you are attempting to run may be blocked at the firewall. - Services.
Some commands rely on services, such as the Remote Registry Service or others that may not be running by default.
Because of these issues, I have pretty much quit using commands such as Get-Service –ComputerName MyRemoteServer. The command will fail by default unless you have made configuration changes on your servers—and I would not recommend making such changes due to the fact that you would be widening the attack surface on your servers.
A simple change
The solution is simple: change your command...just a little bit.
I add the command Invoke-Command. When I use Invoke-Command, the command uses WinRM (which is enabled by default on Windows Server 2012 R2. Windows PowerShell uses WinRM for remoting commands. The great thing about this is that it is already enabled on servers, and I do not need to do anything.
Note If WinRm is not enabled, I use the Enable-PSRemoting command. I can test if WinRM is enabled and configured properly by using the Test-WsMan command.
The command to check the status of the BITS service on a remote server named S1, so the command would therefore be:
Invoke-Command -ComputerName S1 { Get-Service bits }
If I need to check the status of the BITS service on several remote servers, I can separate the computer names with a comma. The following command checks the status of the BITS service on the servers named S1, S2, and SGW.
Invoke-Command -ComputerName S1, S2, SGW { Get-Service bits }
The cool thing is that Windows PowerShell automatically adds a column named PSComputerName to the output. This is shown in the following image:
If I need to add different credentials, I use the –Credential parameter. This causes a dialog box to appear that prompts me to type my password. Here is the command:
Invoke-Command -ComputerName S1, S2, SGW -Credential nwtraders\administrator { Get-Service bits }
The dialog box is shown here:
BB, that is all there is to using Windows PowerShell against remote servers. Don’t Learn Windows PowerShell Week will continue tomorrow when I will talk about more cool stuff.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy