Enable PowerShell Remoting to Enable Running Commands

 

Summary: Learn how to enable Windows PowerShell remoting to allow execution of commands on remote computers.

 

Hey, Scripting Guy! QuestionHey, Scripting Guy! I need to be able to run commands on remote computers. I have Windows PowerShell 2.0, is there something in that I can use?

— ML

 

Hey, Scripting Guy! AnswerHello ML, Microsoft Scripting Guy Ed Wilson here. I got back late last night from Columbia, South Carolina because I was speaking to the SQL Users group down there. It is a nice drive at night, and generally not too much traffic. The Scripting Wife went with me, and to be honest I believe they were more excited about talking to her than to me but that is fine, I like to talk to her as well. The group asked lots of questions, and I only made it to my second slide in my Microsoft PowerPoint deck, but hey I only carry that deck around with me so I have something to turn in for conference abstracts. I rarely follow it. For me, one of the great things about Windows PowerShell is that I can solve a problem with a few lines of code, and to show SQL DBA’s (Database Administrators) that I can do that in an interactive manner, without having to run a script is a powerful message. Therefore, most of my presentation is impromptu, and it has a tendency to morph in the direction of the audience’s interest (Note: I do not advocate this as a recommended presentation approach. I am merely relating how I approach informal user group meetings). The meeting room filled. There was standing room only. I had met several of the attendees at SQL Saturday and therefore it was great to renew acquaintances. This morning I actually had some questions that continued last night’s discussion. It really is great to get out of the house, and to talk with people who are learning Windows PowerShell.

ML, to be able to use Windows PowerShell remoting, you have to first enable it. This is because Windows PowerShell ships in a locked down configuration. You cannot run scripts, and you cannot use remoting.

The easiest way to enable Windows PowerShell remoting is to use the Enable-PSRemoting cmdlet. To do this, you have to launch Windows PowerShell with Admin rights. If you do not have Admin rights when you run Windows PowerShell, the following error occurs.

PS C:\> Enable-PSRemoting -Force

Enable-PSRemoting : Access is denied. You have to run this cmdlet from an elevated p

rocess.

At line:1 char:18

+ Enable-PSRemoting <<<<  -Force

    + CategoryInfo          : NotSpecified: (:) [Enable-PSRemoting], InvalidOperati

   onException

    + FullyQualifiedErrorId : System.InvalidOperationException,Microsoft.PowerShell

   .Commands.EnablePSRemotingCommand

 

PS C:\>

 

To make sure Windows PowerShell is running with Admin rights, right-click the Windows PowerShell icon, and select Run as Administrator, seen in the following figure, if you are running Windows 7.

 

 

On Windows XP, you can use the Run as… feature that you can access by holding down the Shift Key while right-clicking on the Windows PowerShell icon. The Run As… menu is seen in following figure.

 

 

After you have Windows PowerShell running with Admin rights, use the Enable-PSRemoting Windows PowerShell cmdlet to automatically configure WinRM, the firewall, and the WinRM service to enable Windows PowerShell remoting to work. If you want to be prompted before each change, do not use any switches when you run the Windows PowerShell cmdlet. If you do not want to be prompted use the force parameter as seen here.

Enable-PsRemoting -Force

 

When you run the cmdlet without the switch, you are prompted several times during the configuration of Windows PowerShell (an activity that usually takes less than a minute to complete). This is seen in the following figure.

 

 

After the configuration is complete, I like to perform a quick test to make sure that everything has worked correctly. First, I use Ping to make sure that my computer can resolve the remote host, and then I use the invoke-command Windows PowerShell cmdlet. When you use the invoke-command Windows PowerShell cmdlet, I have to give it the name of the remote computer, and the command to execute. The command to execute is put in the scriptblock parameter. The syntax of this command is seen here.

Invoke-Command -computername [COMPUTER} -ScriptBlock { COMMAND }

 

The scriptblock parameter accepts your code to run, and is enclosed inside a pair of braces. As seen here, I first ping the remote computer, and then execute the hostname command on the remote computer. This guarantees that I am working with the computer that I think I am working upon.

PS C:\> ping teresa-kitchen

 

Pinging teresa-kitchen.NWTraders.Com [192.168.1.89] with 32 bytes of data:

Reply from 192.168.1.89: bytes=32 time<1ms TTL=128

Reply from 192.168.1.89: bytes=32 time<1ms TTL=128

Reply from 192.168.1.89: bytes=32 time<1ms TTL=128

Reply from 192.168.1.89: bytes=32 time<1ms TTL=128

 

Ping statistics for 192.168.1.89:

    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),

Approximate round trip times in milli-seconds:

    Minimum = 0ms, Maximum = 0ms, Average = 0ms

PS C:\> Invoke-Command -ComputerName teresa-kitchen -ScriptBlock { hostname }

teresa-kitchen

PS C:\>

 

If I have to specify alternative credentials for the remote command, I use the credential parameter as seen here.

PS C:\> Invoke-Command -ComputerName teresa-kitchen -ScriptBlock { hostname } -Creden

tial nwtraders\administrator

teresa-kitchen

PS C:\>

 

When the command runs, the Windows PowerShell Credential Request dialog box seen in the following figure appears.

 

 

In reality, I only have to type my alternative credentials once because I can store them in a variable. In this example, I use the Get-Credential Windows PowerShell cmdlet to retrieve my alternative credentials. I store the credential object in the $credential variable. I then use those credentials to run commands on two different computers. This is seen here. The following commands are single line commands. I used line continuation to break the command onto two lines due to display limitations on the blog. If you are using a similar command, you will not have to use the backtick  (`) character for line continuation.

PS C:\> $credential = Get-Credential -Credential nwtraders\administrator

PS C:\> Invoke-Command -ComputerName teresa-kitchen -ScriptBlock { hostname } `

-Credential $credential

teresa-kitchen

PS C:\> Invoke-Command -ComputerName hyperv -ScriptBlock { hostname } `

-Credential $credential

HyperV

PS C:\>

 

If you are working in a networked setting and you want to enable Windows PowerShell remoting on all computers in a forest, domain, or organizational unit, you can use Group Policy to make the configuration changes. Unfortunately, there is no Enable-PSRemoting Group Policy object. The WinRM service is configurable through Group Policy and is well documented on MSDN. The Group Policy settings are seen in the following figure, Windows PowerShell remoting relies on more than just WinRM.

 

 

One way to get the advantage of Group Policy and the advantage of using the Enable-PSRemoting cmdlet is to use Group Policy to specify a startup script. This is seen in the following figure.

 

 

The script is a single line, saved in a .ps1 file.

Enable-PSRemoting -Force

 

ML, that is all there is to using configuring and to using Windows PowerShell Remoting. Remoting week will continue tomorrow when I will talk about how to establish remote sessions.

I invite you to follow me on Twitter or Facebook. If you have any questions, send email to me at scripter@microsoft.com or post them on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

 

Ed Wilson, Microsoft Scripting Guy