Summary: Learn how to configure Windows PowerShell remoting, store credentials, and use remote commands.
Hey, Scripting Guy! I keep hearing about Windows PowerShell remoting. But I do not really know what Windows PowerShell remoting is. For example, I can use the Get-WMIObject to work with remote computers. Is that remoting? If so, what is the big deal? I could do that in Windows PowerShell 1.0. Is this just a bunch of typical marketing hype, or is there something that actually works here and I am missing it?
—GB
Hello GB,
Microsoft Scripting Guy Ed Wilson here. GB, I hate to tell you, but you are missing the boat. There is a common misconception about what Windows PowerShell remoting really is. There are several ways to run a command on a remote computer:
- Windows Management Instrumentation (WMI) can target a remote computer via the computername parameter. The Get-WMiObject cmdlet also allows for alternate credentials.
- The computername cmdlets (not including the Get-WmiObject cmdlet). There are a lot of cmdlets that have a computername parameter. These cmdlets permit making a connection to a remote computer and retrieving information from them. However, not all of these cmdlets have a credential parameter and therefore they must run with administrator rights on the remote computer. In addition, in many cases these cmdlets require specific holes open in the firewall, and even certain services running on the remote machine before they will work properly. To find the cmdlets that have a computername parameter, use the following Windows PowerShell command:
get-command -CommandType cmdlet | where { $_.definition -match 'computername'} - Some computername cmdlets do permit the use of alternative credentials. These cmdlets allow you to run a command against a remote machine, and to specify the context in which to run the command. This solves the problem of supplying alternative credentials. To find these cmdlets, use the following Windows PowerShell command (gcm is an alias for the Get-Command cmdlet, and ? is an alias for the Where-Object cmdlet; the command is a single command, and I did not include any line continuation;it has wrapped in the output here, but would appear on a single line in the Windows PowerShell console):
gcm -CommandType cmdlet | ? { $_.definition -match 'computername' -AND $_.definition -match 'credential'} - True, Windows PowerShell remoting is the other way to run a Windows PowerShell command on a remote computer. Windows PowerShell remoting uses Windows Remote Management (WinRM) as the underlying technology, and is therefore firewall friendly. WinRM is Microsoft’s implementation of the WS-Management Protocol that allows hardware and operating systems from different vendors to interoperate. It is industry standard, and extremely powerful.
The first thing to do is to enable and configure Windows PowerShell remoting. To do this, use the Enable-PSRemoting cmdlet. Enable Windows PowerShell remoting on all machines that will communicate. If this only involves a couple computers, using the Enable-PSRemoting cmdlet works fine. But if you need to turn on Windows PowerShell remoting on an entire organizational unit, domain, or forest, it is better to use Group Policy. Unfortunately, there are myriad Group Policy settings from which to choose, and I like the convenience of the Enable-PSRemoting cmdlet. Therefore, I use a script that calls the Enable-PSRemoting cmdlet with Group Policy and assign it as a logon script. I discuss this technique in the Enable PowerShell Remoting to Enable Running Commands blog post.
After it is configured, I like to use the Invoke-Command cmdlet to ensure that Windows PowerShell remoting works properly. By running a simple command such as hostname.exe, I ensure that Windows PowerShell remoting works, and confirm the actual location that ran the command. Here is the syntax:
invoke-command -cn syddc01 -credential contoso\administrator -scriptblock {hostname}
After I have run that command, I know everything works. Now, I like to store my credentials in a variable to make it easier to run remote commands. To do this, I use the Get-Credential cmdlet. Here is the command I use:
$cred = Get-credential contoso\administrator
When the command runs, the following dialog box is displayed.
After I have a credential object stored in the $cred variable, I use it to invoke a remote command. These commands are shown here:
$cred = Get-Credential contoso\administrator
invoke-command -cn syddc01 -cred $cred -script {hostname}
Now, I want to use the Invoke-Command cmdlet to run the Get-Process cmdlet on a remote computer and use alternate credentials. The syntax for this command is shown here (this command uses the cn computername alias for Invoke-Command, the credentials stored in the $cred variable, and the gps alias for the Get-Process cmdlet):
Invoke-Command -cn syddc01 -Credential $cred -ScriptBlock {gps}
The command and associated output are shown in the following figure.
GB, that is all there is to getting Windows PowerShell remoting up and running, and storing credentials in a credential object to simplify running remote commands. Join me tomorrow when I will talk about creating remote Windows PowerShell sessions.
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