Share via


Exercise 2: Remoting in PowerShell V2 (Background)

Figure 1

Picture a scenario where you have several servers running Windows Server 2008, Exchange, System Center Operations Manager, IIS, Terminal Services gateways, domain controllers, and many other exciting Microsoft products that are complying with a standard rule set for all of them, building on top of PowerShell. That’s the scenario that Microsoft has been effectively working towards since PowerShell V1, and it means you can interact with these products, collect data, and interact with the Windows operating systems as well, making it possible for the IT Pro to automate tasks quicker and easier than ever.

A natural next step to exploiting all this power would be to have centralized scripts that could query several servers; for example, check the logs in the domain controllers and if any of them is showing identified critical errors, go ahead and send an e-mail to the administrators group with a compilation of the results (so far so good for V1), and query your System Center Operations Manager remote machine for performance data during the time of the logs and send a separate e-mail (not so good for V1). How do you access that Exchange snap-in that’s running on a separate computer? Well, you could write up an agent script or service that runs in the Exchange machine and query its data from PowerShell using Web Services, or you can upgrade to PowerShell V2 in both machines.

One of the main new features of Windows PowerShell V2 is a major overhaul of the remoting capabilities. How big of an overhaul is a “major overhaul?” Bigger than you might expect: PowerShell remoting now works only on computers running Windows Vista Service Pack 1 or Windows Server 2008, and there’s now a new cmdlet (Invoke-Command) used to run commands against remote machines.

Before we talk about Invoke-Command, let’s reiterate that, in PowerShell V2, remoting works only on computers running Windows Vista Service Pack 1 or Windows Server 2008, or Windows 7. (And even then, you need to install a corresponding version of WinRM to get anything to work). That also means that you can connect only to another Windows Vista/Windows Server 2008 machine that has PowerShell V2 and WinRM installed. Creating a remote connection between your Windows Vista machine and a computer running Windows XP is not supported by PowerShell V2.

If it’s not a problem (for example, because you only have PowerShell running on Windows Vista machines) then you just need to know about the changes involved in actually running commands on remote computers. In the initial CTP release for Windows PowerShell 2.0, the Invoke-Expression cmdlet was used to run a command against a remote machine:

PowerShell

Invoke-Expression –computerName atl-fs-001 –command Get-Process

This is not the case in CTP2 or ahead; in fact, parameters like –computerName have actually been removed from InvokeExpression. Instead, if you want to run the Get-Process cmdlet against the remote computer atl-fs-001 then you need to use this command:

PowerShell

Invoke-Command –computerName atl-fs-001 –scriptblock {Get-Process}

As you can see, the basic syntax is the same; the PowerShell team simply substituted Invoke-Command for Invoke-Expression, and replaced the parameter –command with –scriptblock. That’s all there is to it as far as the user can tell, but under the covers there are many more changes than that that improve the stability, security and performance through the network.

Of course, you can still run a command against multiple computers; for example, this command returns information about the processes running on the computers atl-fs-001, atl-fs-002, and atl-fs-003:

PowerShell

Invoke-Command –computerName atl-fs-001, atl-fs-002, atl-fs-003 –scriptblock {Get-Process}

As was the case with Invoke-Expression, Invoke-Command makes a connection to a remote machine, runs the command, and then immediately drops that connection. If you need to make a persistent connection to a remote computer (or set of computers) you can still create a PowerShell Session:

PowerShell

$objRunspace = New-Runspace atl-fs-001, atl-fs-002, atl-fs-003
Note:
You can then reference that runspace in your call to Invoke-Command:

PowerShell

Invoke-Command –runspace $objRunspace –scriptblock {Get-Process}

Several cmdlets have a -ComputerName parameter that lets you get objects from remote computers. Because these cmdlet do not use Windows PowerShell remoting to communicate, you can use the -ComputerName parameter of these cmdlets on any computer that is running Windows PowerShell. There is no restriction as to what versions of PowerShell or WinRM are installed on the computer that you are querying objects from, or the computer that you are pulling them from.

The computers do not have to be configured for Windows PowerShell remoting or fulfill the system requirements for remoting.

The ComputerName cmdlets include:

PowerShell

Get-Process Get-Service Get-Event Get-EventLog Get-WmiObject Add-Computer Remove-Computer Restart-Computer

For more information and many examples, take a peek at the Invoke-Command documentation by typing this command:

PowerShell

Get-Help Invoke-Command –full | more

And for more information on remoting in general, take a look at the various “About” topics on the subject. You can retrieve a list of those topics by running the following command:

PowerShell

Get-Help About_Remote*