Windows Server How-To

How To Run PowerShell Commands Against a Remote VM

Here's a look at the Invoke-Command cmdlet and how it will be extended in Windows Server 2016.

PowerShell is one of Microsoft's preferred tools for managing Windows Servers. Although it's easy to think of PowerShell as a local management tool, PowerShell can just as easily be used to manage other servers in your datacenter. This capability is especially helpful if you have a lot of Hyper-V virtual machines and want to be able to perform bulk management operations.

There are a few different ways of running a PowerShell command against a remote server. For the purposes of this article however, I want to show you how to use the Invoke-Command cmdlet. The reason why I want to talk about this particular method is because the Invoke-Command cmdlet is being extended in Windows Server 2016 to provide better support for Hyper-V virtual machines. I will get to that in a few minutes.

The first thing that you will need to do is to configure the remote system to allow for remote management. Microsoft disables remote PowerShell management by default as a way of enhancing security.

To enable remote PowerShell management, logon to the remote server, open PowerShell (as an Administrator) and run the following command:

Enable-PSRemoting –Force

This command does a few different things. First, it starts the WinRM service, which is used for Windows remote management. It also configures the service to start automatically each time that the server is booted and it also adds a firewall rule that allows inbound connections. In case you are wondering, the Force parameter is used for the sake of convenience. Without it, PowerShell will nag you for approval as it performs the various steps. You can see what the command looks like in action in Figure 1.

[Click on image for larger view.]  Figure 1. You must use the Enable-PSRemoting cmdlet to prepare the remote server for management.

There are about a zillion different ways that you can use the Invoke-Command cmdlet. Microsoft provides full documentation for using this cmdlet here. This site covers the full command syntax in ponderous detail. For the purposes of this article however, I want to try to keep things simple and show you an easy method of running a command against a remote system.

The first thing that you need to know is that any time you are going to be running a PowerShell command against a remote system, you will have to enter an authentication credential. Although this step is necessary, it is a bit of a pain to enter a set of credentials every time you run a command. Therefore, my advice is to map your credentials to a variable. To do so, enter the following command:

$Cred = Get-Credential

As you can see in Figure 2, entering this command causes PowerShell to prompt you for a username and password. The credentials that you enter are mapped to the variable $Cred.

[Click on image for larger view.]  Figure 2. Your credentials can be mapped to a variable.

Now that your credentials have been captured, the easiest way to run a command against a remote server is by using the following syntax:

Invoke-Command –ComputerName <server name> -Credential  $Cred –ScriptBlock{The command that you want to run}

OK, so let's take a look at how this command works. Right now I am using PowerShell on a system that is running Windows 8.1. I have a Hyper-V server named Hyper-V-4. Let's suppose that I want to run the Get-VM cmdlet on that server so that I can find out what virtual machines currently exist on it. To do so, I would use this command:

Invoke-Command –ComputerName Hyper-V-4 –Credential $Cred  –ScriptBlock{Get-VM}

As you can see, the script block contains the command that needs to be executed on the remote system. It is worth noting that this technique only works if both computers are domain joined and are using Kerberos authentication. Otherwise, you will have to use the HTTPS transport or add the remote computer to a list of trusted hosts. The previously mentioned TechNet article contains instructions for doing so.

At the beginning of this article, I mentioned that Invoke-Command was being extended in Windows Server 2016 to better support Hyper-V virtual machines. Microsoft is adding a parameter named VMName (which is used in place of ComputerName). This extension makes use of a new feature called PowerShell direct, which allows you to run PowerShell commands on a Hyper-V virtual machine even if the virtual machine is not connected to the network. This is accomplished by communicating with the VM through the VMBus.

So as you can see, the Invoke-Command cmdlet makes it easy to manage remote servers through PowerShell. I would encourage you to check out the previously mentioned TechNet article because there is a lot more that you can do with the Invoke-Command cmdlet than what I have covered here.

About the Author

Brien Posey is a 22-time Microsoft MVP with decades of IT experience. As a freelance writer, Posey has written thousands of articles and contributed to several dozen books on a wide variety of IT topics. Prior to going freelance, Posey was a CIO for a national chain of hospitals and health care facilities. He has also served as a network administrator for some of the country's largest insurance companies and for the Department of Defense at Fort Knox. In addition to his continued work in IT, Posey has spent the last several years actively training as a commercial scientist-astronaut candidate in preparation to fly on a mission to study polar mesospheric clouds from space. You can follow his spaceflight training on his Web site.

Featured

comments powered by Disqus

Subscribe on YouTube