PowerShell: The basics – Part 6 – Remoting

This blog series will teach you the basics of PowerShell. You’ll learn common concepts such as variables, loops, functions and scripts in this series, along with PowerShell unique concepts such as cmdlets, modules and the pipeline.

In this post we will take a look at how to work with remote servers with PowerShell.

PowerShell makes it easy to execute code on remote computers, wether as a an interactive session, or by executing one scriptblock at a time. You can easily run the same code against tens, or hundreds of computers (sequencial, pretty slow). Although not straightforward, it’s also possible to run code against many computers at once (parallell, very fast). Parallell execution is not considered basic, so I will not cover it in this series, but rather in a later dedicated blog post.

Enable PowerShell Remoting

PowerShell remoting is enabled by default on Windows Server operating systems, but not on clients. The capability may also have been disabled on your servers, so I will show how to make sure PowerShell remoting is enabled.

# To enable PSRemoting, you only have to run this command
Enable-PSRemoting -Force

PowerShell uses Windows Remote Management (WinRM) for remoting. This means that it is dependant on both the WinRM service, and the corresponding firewall openings. WinRM uses TCP/5985 for unencrypted traffic, and TCP/5986 for encrypted traffic.

# Check if WinRM service is running
Get-Service -Name WinRM

# To connect to a workgroup computer, it must first be added to Trusted Hosts
Set-Item -Path WSMan:\localhost\Client\TrustedHosts -Value 192.168.1.10

Interactive Remoting

When connected to an interactive session, every command ou issue wil be run on the remote system.

# Create a persistent session, and save it to a variable
$session = New-PSSession -Computername Server1

# Connect to the session, then you can run any command on the remote system as if you were locally
Enter-PSSession -Session $Session

# To exit a remote session, use this command
Exit

# To remove a persistent session
Remove-PSSession -Session $session

# Even easier, directly connect to the server. No need for persistent sessions.
Enter-PSSession -ComputerName Server1

# Connect using different credentials
Enter-PSSession -ComputerName Server1 -Credential (Get-Credential)

ComputerName Parameter

Many cmdlets have a parameter called ComputerName. By supplying a computername to that parameter, the cmdlet will run on the specified computer, and not locally. This parameter accepts an array of names, to make it easy to run the same cmdlet against multiple remote systems.

Get-CimInstance -ClassName Win32_Operatingsystem -ComputerName Server1
Get-Service -Name Spooler -ComputerName Server1, Server2

Note: This method works best in an Active Directory environment where you can authenticate with the same credentials, as the cmdlet doesn’t necessarily let you specify different credentials. An alternative is to wrap the command in Invoke-Command instead.

Invoke-Command

The Invoke-Command cmdlets makes it easy to run multiple lines, against multiple computers, and return the output to the local computer. When the Invoke-Command cmdlet is finishd executing whatever is in the scriptblock, it will automatically close the remote session, and then continue to the next computer if you have specified multiple computers.

$Result = Invoke-Command -ComputerName Server1, Server2 -ScriptBlock {
    Write-Output "This code was executed on $($env:COMPUTERNAME)"
}
Write-Output $Result

Further reading

If you want more detailed reading on the topics of this post I suggest the following resources:

Leave a Reply