PowerShell remoting enables an administrator to remotely manage many Windows Servers from a central location. With open-source releases of PowerShell, your target servers could be running Linux or macOS as well. PowerShell remoting simplifies cross-platform system management. As a result, you will be able to send PowerShell commands to control all your servers regardless of the operating system. This article will help you understand how remoting works. In addition, I will show you various methods for remotely connecting to machines in order to manage your environment.
Explaining PowerShell Remoting to Others
Other members of your organization may take a heightened interest in PowerShell remoting because of its powerful capabilities. They may also be fearful of PowerShell remoting because its power can be perceived as dangerous. Once you learn how remoting works and how to secure an implementation, the implementation will be easier to discuss and defend. Your co-workers will see that when configured correctly, it is not any less secure than other remoting protocols. In addition, you can mitigate perceived risks by putting security protection in place, such as SSL. If you make an effective argument to allow PowerShell remoting in a secure and effective manner, it will make your job easier.
Remoting Basics in a Nutshell
The current implementation of PowerShell remoting on Windows runs as the Windows Remote Management Service or WinRM for short. The WinRM service contains at least two endpoints or listeners. By default, enabling PowerShell remoting enables both an http and an https listener. The listeners run on default ports 5985 for http and 5986 for https. You can customize the endpoints to use alternate ports. You can also define your own custom endpoints. PowerShell remoting uses Web Services for Management (WS-MAN) protocol when communicating between machines, which is an http-based protocol. Future versions of PowerShell will also support remoting over SSH.
Remoting to a Single Machine
In the most basic remoting scenario, an administrator remotes to another machine by creating a session using the Enter-PSSession cmdlet. Once the user is authenticated, the user can see that he is in a remote session because of the prompt changes to the name of the remote computer.
Once the session is established, execution of subsequent cmdlets occurs on the remote machine. This is the case until the session ends using Exit-PSSession.
Remoting to Many Machines
Who wants to remotely control just one machine? As an administrator, you manage hundreds of machines. All of which, you want to run a cmdlet or script. Enter-PSSession will not cut it in this case since Enter-PSSession is only good for one session. You will use a different command for this, Invoke-Command. Pass a list of computer names to Invoke-Command with the -ComputerName parameter. You could also pass a scriptblock using the -ScriptBlock parameter or pass a saved script using the -FilePath parameter.
Differences Between Invoke-Command and Enter-PSSession
Using Invoke-Command in this manner establishes a remote connection to each computer and executes the command on the remote computer. It is not just executing on one computer at a time. Invoke-Command allows for parallel execution by default on up to 32 computers at once, which is configurable. The results from each computer are serialized on the remote computer into XML, returned to the local computer, and deserialized for display. Then, the remote connection is ended. You can see this in the type of the returned object. It starts with the name Deserialized. You will also notice that none of the methods for the object are available because it is not possible to perform any action against the object. The object no longer exists because the remote connection has been ended.
Remoting to Many Machines By Reusing Connections
Invoke-Command is an extremely powerful command but using it in the method described above has pitfalls. First, all the computer names need to be specified for every Invoke-Command call. If you are typing these in manually every time you want to run a command, it becomes tedious. Second, you may also need to specify other parameters for Invoke-Command, like credentials or ports. Different computers may require alternate ports or credentials. To handle these differences, you would execute multiple Invoke-Command calls to accomplish your task. In the worst case, you may have to execute one instance of Invoke-Command per machine, making it no better than using Enter-PSSession. To remove this limitation, you can execute New-PSSession to establish persistent remote sessions to all the computers. Using New-PSSession, you specify the credentials and ports when you establish the sessions.
Lastly, you use Invoke-Command just like in the example above. Only use the -Session parameter and get all the sessions using get-PSSession.