Thursday, February 20, 2014

PowerShell Session - Execute PowerShell Commands on Remote Computer

You have used Windows PowerShell command to perform tasks on local server. Some times, you need to execute commands against other servers. There are some PowerShell commands with -Computer parameter to let you execute against remote server, but not all PowerShell command has this parameter. You may choose to remote to the server and execute it there, but there is another way. It may be easier and more powerful to utilize the really cool PowerShell session to perform remoting commands or for automation.

Starting from PowerShell 2.0, Microsoft start shipping this enhanced remoting functionality, Persistence Sessions (PSSession). It uses WinRM, Microsoft implementation of WS-Management protocol (SOAP) to manage hardware and operating systems. WinRM communicates via HTTP oor HTTPS. Starting in WinRM 2.0 (PowerShell 2.0), it is listening to default port 5985 and 5986 for secured connection.

On the server that will receive remote command, it needs to be configured to enable PowerShell remoting. On Windows Server 2012, Windows PowerShell remoting is enabled by default. To enable remoting, use Enable-PSRemoting or Winrm quickconfig (or abbreviated version winrm qc). The command in general perform these tasks,

- start the WinRM service and set the service to auto startup,
- configure listener port to send and listen using http or https on any IP address,
- enable firewall exception for WinRM and open the http and https port
- register Microsoft.PowerShell, Microsoft.PowerShell.Workflow and other session configurations

If any server is not on domain which Kerberos authentication cannot be used, the receiving server (remote server) can be added to the trusted hosts list of the sending server (local server).

winrm set winrm/config/client '@{TrustedHosts="RemoteServerName"}'

In our example,
Local Computer : SQLTest0
Remote Computer : SQLTest1

winrm set winrm/config/client '@{TrustedHosts="SQLTest1"}'

In addition, if the sending server is not in the same subnet as receiving server, you may need to modify the firewall. By default, the firewall exception for public profiles limits access within same local subnet. Modify the remote server firewall public profile for Windows Remote Management (HTTP-In) or (HTTPS-In) to include the subnet or IP of the sending server.

If all settings above have been configured correctly, it is time to use PowerShell remote session. Lets's start with Enter-PSSession cmdlet. This cmdlet starts an interactive remoting session. In our example,

Enter-PSSession -ComputerName SQLTest1 -Credential TestUser

Enter password when when prompted. If the remote session is successfully connected, you will see the prompt preceded with remote server name.

This example will check the status of the mssqlserver service and restart it.

When the remote session is no longer needed, ends the remote interactive session with Exit-PSSession cmdlet.

Enter-PSSession cmdlet serves more an ad-hoc remoting session that we remote, perform task, and end the session. If we are going to create persistent connection to remote server(s) that we could maintain for later use, use New-PSSession. New-PSSession is used to create a new remoting session and could be stored in a variable.

$session = New-PSSession -ComputerName SQLTest1 -Credential TestUser
Enter-PSSession -Session $session

After enter the session, if we execute the Exit-PSSession, it only end the interactive session, but the connection is still open as you can see from Get-PSSession cmdlet. Get-PSSession get all the PowerShell sessions on local and remote computers.

We can reuse to the remote connection again.

To remove the persistent connection, use Remove-PSSession cmdlet. Use Get-PSSession to obtain the name or Id, then remove the connection with the respective name or Id.

Remove-PSSession -Name Session9

Another use case for the persistent connection is that you could execute command in script block to server(s).

Invoke-Command -Session $session -SciptBlock {Get-Service mssqlserver}

Note: In this example, the session only connected to one server. To set the session with multiple computers, you can list all computers in a text file and use Get-Content to retrieve the data and save it in a variable.

$sessions = Get-Content Servers.txt | New-PSSession

These are some of the usage of different PSSession cmdlets. Hope this post give you a general idea of how to use PowerShell session to perform tasks on remote computer.