Using PowerShell to run commands on another server

If you find yourself constantly having to log onto various servers to perform maintenance tasks, you may eventually run into something that can't be done by the Windows Admin Center, Server Manager, or any of the RSAT tools. You might need to delete a file or adjust a firewall rule. In the past, we would have fired up Remote Desktop, typed in our username and password, waited for the desktop to load in, then started Command Prompt, Windows Explorer, or any number of other mundane maintenance tasks.

With PowerShell, however, there is often no need to jump through the RDP hoops to access a server. In the same way that you can ssh into another server to run commands with Linux, PowerShell has Enter-PSSession, Invoke-Command, and other commands that can be used to configure servers remotely. In this recipe, we'll go through some of these commands to show you how they can save you time in the future.

Getting ready

We will be using a Windows 10 computer to connect remotely to our Windows Server 2019 domain controller DC01.

How to do it…

Let's run through three common scenarios: when you need to browse around on the remote server, when you just need to run a single command, and when you have a cmdlet that has built-in support for remoting. We'll do the same thing three times – check what time our server was last booted:

  1. On your Windows 10 computer, launch a PowerShell prompt as Administrator.
  2. Run the Enter-PSSession DC01 command. This may take a moment to connect, but after, your Command Prompt should be prefixed with [DC01] (or whatever server name you chose to connect to). Every command you type now is going to be executed on your remote server, not yours.
  3. To make sure this is the case, run hostname. You should see the remote computer's name show up – not yours.
  4. Let's check what time the server was last booted. Run the following command:

    (Get-CimInstance Win32_OperatingSystem).LastBootUpTime

    This results in the following output:

    Figure 2.31 – Demonstrating the Enter-PSSession PowerShell command

  5. That was pretty cool – but if you just have a small script or a one-liner to run, you do not need to use Enter-PSSession at all! Run exit to get out of your remote session and back to your local computer's PowerShell prompt.
  6. Now, run this:

    Invoke-Command -ComputerName DC01 -ScriptBlock { (Get-CimInstance Win32_OperatingSystem).LastBootUpTime }

  7. What we've done now is run the exact same command that we typed out on DC01, but we did it without ever having to get an interactive session on the server. The -ComputerName argument here can take more than one name, so we could run this command against multiple servers if we wanted to.

    Note

    If you get different LastBootUpTimes when running these commands, this will be due to timezone differences between your server and your local computer. The first command was presented in the servers timezone, while the second command was presented in your timezone.

  8. That's still a bit cumbersome, though, but we're in luck. The Get-CimInstance cmdlet also supports the -ComputerName argument directly, so we don't need to wrap the command in the Invoke-Command cmdlet. Try this:

    (Get-CimInstance -ComputerName DC01 Win32_OperatingSystem).LastBootUpTime

  9. The result should be exactly the same as what we got with the previous code we ran. And like the previous code, -ComputerName takes more than one computer name, so we could also run the following:

    (Get-CimInstance -ComputerName DC01,DC02 Win32_OperatingSystem).LastBootUpTime

    The following is the output:

Figure 2.32 – Running a PowerShell command against multiple computers remotely

How it works…

In this recipe, we looked at three different ways of running commands on a remote server. Enter-PSSession gives us full control over PowerShell on the remote computer, allowing us to do virtually anything we need to. Invoke-Command is a great way to execute small scripts that you may need to run on multiple servers. And finally, we saw that some cmdlets have built-in remote capabilities with -ComputerName. Most of the Windows RSAT cmdlets support this -ComputerName functionality. You can see a full list of which ones by running Get-Command -ParameterName ComputerName.

This remoting ability can make your tasks so much simpler, especially once you start to integrate them into some of your scripts. You may never need to remote desktop into a server ever again – and, in fact, if you are running Server Core (which we will cover in Chapter 12, Server Core, you will need to use this functionality as there is basically no remote desktop!