Managing Hyper-V VMs using PowerShell Direct

Virtual machines are easier to manage via PowerShell than with the the Hyper-V Manager console. PowerShell Direct takes this further by allowing you to interact easily with the virtual machines on the Hyper-V host without needing network access. With Windows Nano Server, PowerShell Direct is an essential because this OS requires you to use remote management via PowerShell scripts.

Overview

When your network environment reaches the point where it can become complicated to manage your virtual machines, you can use PowerShell Direct to eliminate all the network constraints. PowerShell Direct lets you to manage your VMs whether or not you have network connectivity, just as long as your virtual machines are located on your Hyper-V host!

Introduction

Many of you have probably already experienced the awful moment when you modify a network setting on a virtual machine (VM) and suddenly all connectivity is lost to the VM. Up to now, you would then need to use the Hyper-V console to retrieve the VM. Now, with PowerShell Direct, this is no longer necessary. PowerShell allows you to access the virtual machine directly without using the network. This happened because Microsoft introduced a new feature called “PowerShell Direct“. As the name implies, PowerShell is now able to directly access the virtual machine. How? It does it by using the Virtual Machine Bus (VMBus).

Here is the official definition of Microsoft:

VMBus – Channel-based communication mechanism used for inter-partition communication and device enumeration on systems with multiple active virtualized partitions. The VMBus is installed with Hyper-V Integration Services.

More information about the Hyper-V architecture here: Hyper-V Architecture

PowerShell Direct

Since Windows PowerShell version 5, Microsoft has implemented a new way to directly manage your virtual machines without network connectivity. However, this new feature requires some prerequisites before it can be used:

Before using PowerShell Direct,

  • The virtual machine must be running locally on the Hyper-V host and must be started.
  • You must be logged into the host computer as a Hyper-V administrator.
  • You must supply valid user credentials for the virtual machine.
  • The host operating system and the virtual machine must be running Windows 10 or Windows Server 2016.
  • Local installation of the guest systems is necessary.

For those who do not perceive the big advantage of this feature, compare this to a management interface directly connected to your VMs. Think of the physical management interfaces you use on physical servers such as:

  • HPE iLO
  • Dell iDRAC

Microsoft has developed PowerShell Direct to make life easier for the Hyper-V administrators in managing and configuring VMs.

PowerShell Direct in action

Before PowerShell Direct, what were the different methods of accessing a virtual machine?

  • Remote PowerShell : This method requires to modify some settings in your firewall configuration.
  • Remote Desktop : You must allow some users as “Remote Users” and open the TCP port 3389 on Windows Firewall.
  • VMConnect : The default management tool is used by default for accessing a VM. This is very useful but it does not automate your tasks.

The first two methods, Remote PowerShell and Remote desktop, require network connectivity because you use the IP address of the VM or its DNS name to connect to the VM.

PowerShell Direct combines these three methods to provide continuous, automated access to your virtual machines.

PowerShell Direct therefore relies on the VMBus concept, a Hyper-V internal mechanism that provides a communication channel between the host and the VM. VMBus accesses the VMs using two parameters:

  • The virtual machine name
  • The VM Id

The big advantage of PowerShell Direct is that it uses PowerShell interactive sessions allowing more flexibility and more tasks automation.

What is the syntax of PowerShell Direct?

Basically, this is the same syntax as a PowerShell session, with the only difference that the -VMName parameter is used instead of –ComputerName parameter:

Or

 Enter-PSSession –VMId 31d787fe-02cd-4363-b50b-16bc8243fc77

This method allows you to log on to the VM and thus run several commands. Results are displayed in your PowerShell console. If you want to run a single command without opening an interactive session on the VM, you must use the Invoke-Command cmdlet:

PS > Invoke-Command -VMName VM01 -ScriptBlock { commands }

And finally, if you have a script that is located on your Hyper-V host and you want to run it in the VM, use the following command:

PS > Invoke-Command -VMName VM01 -FilePath 'C:\scripts\MyScript.ps1'

The Get-VM cmdlet will show you all the information you need to connect to your VM:

It is possible to enter your credentials in order to reuse them easily:

PS > $cred = Get-Credential
PS > Enter-PSSession -VMGuid 31d787fe-02cd-4363-b50b-16bc8243fc77 -Credential $cred

Here is a full example of how to use PowerShell Direct.

First step

Identify the virtual machine and its name using the “Get-VM” cmdlet. Here, the name of the VM is “SQL011“, this one is started and version 8.0 indicates to me that it is compatible with PowerShell Direct:

PS C:\Users\Administrator> get-vm

Name      State   CPUUsage(%) MemoryAssigned(M) Uptime               Status              Version
----      -----   ----------- ----------------- ------               ------              -------
IIS19     Running 0           4096		  15.08:20:51.4370000  Operating normally  5.0
SQL011    Running 0           8192		  5.02:00:22.2520000   Operating normally  8.0
SQL061    Running 0           8192		  5.02:00:22.2520000   Operating normally  8.0

Then check the host on which the VM is running. Check also the “Guest Services” option:

PS C:\Users\Administrator > Get-VM SQL011 | select computername, VMIntegrationService

ComputerName VMIntegrationService
------------ --------------------
HypVServer01 {Guest Service Interface, Heartbeat,...}

Guest services’ is mandatory in order to copy files between hypervisor and VM. (We will see an example later in this article). If the ‘Guest Services’ option is not active, it can be enabled via PowerShell:

PS > Enable-VMIntegrationService -VMName "SQL011" -Name "Guest Service Interface"

Now, open a PowerShell console as an administrator on your host. In my case, the Hyper-V host is “HypVServer01”.

Second step

Open a PowerShell session with your credentials via the Enter-PSSession cmdlet

PS C:\Users\Administrator> $cred = Get-Credential

cmdlet Get-Credential at command pipeline position 1
Supply values for the following parameters:
Credential
PS C:\Users\Administrator> Enter-PSSession -VMName SQL011 -Credential $cred
[SQL011]: PS C:\Users\admin\Documents> 

In this example, the session was successfully established via PowerShell Direct on the VM named “SQL011”. PowerShell therefore used the VMBus to join the VM.

Third step

To verify this, I display the virtual machine network adapter state using the Get-NetAdapter cmdlet:

[SQL011]: PS C:\Users\admin\Documents> Get-NetAdapter

Name       InterfaceDescription              ifIndex Status       MacAddress             LinkSpeed
----       --------------------              ------- ------       ----------             ---------
Ethernet   Microsoft Hyper-V Network Adapter 3       Disabled     00-1D-D8-B6-4C-04      20 Gbps

This one is disconnected so I have no network connectivity on the VM.

Fourth step

Now I can type the PowerShell commands I want (Get-Service, Restart-Computer, …):

[SQL011]: PS C:\Users\admin\Documents> Get-Service

Status   Name               DisplayName
------   ----               -----------
Stopped  AJRouter           AllJoyn Router Service
Stopped  ALG                Application Layer Gateway Service
Running  AppIDSvc           Application Identity
Stopped  Appinfo            Application Information
Stopped  AppMgmt            Application Management
Stopped  AppReadiness       App Readiness
Stopped  AppVClient         Microsoft App-V Client

In parallel, I can try to access the VM via PowerShell Remoting, but I get an error. PowerShell can’t connect to the VM because the network adapter is disabled.

PS C:\Users\admin> Enter-PSSession -ComputerName SQL011 
Enter-PSSession : Connecting to remote server SQL011 failed with 
the following error message : WinRM cannot 
complete the operation. Verify that the specified computer name is 
valid, that the computer is accessible over the 
network, and that a firewall exception for the WinRM service is 
enabled and allows access from this computer. By 
default, the WinRM firewall exception for public profiles limits 
access to remote computers within the same local 
subnet. For more information, see the about_Remote_Troubleshooting Help topic. 
At line:1 char:1 
+ Enter-PSSession -ComputerName SQL011 
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    + CategoryInfo          : InvalidArgument: (SQL011:String) 
[Enter-PSSession], PSRemotingTransportException 
    + FullyQualifiedErrorId : CreateRemoteRunspaceFailed

Imagine what you could do with PowerShell Direct

You could also copy files from your Host to your VM without any network access. So there is no need to create a shared folder on the VM, then assign the permissions on this folder. From now on, a simple PowerShell command and your file will be copied!

Imagine that we have a script located on the Hyper-V host in the “C:\Scripts\” directory:

PS > $Session = New-PSSession -VMName SQL011 -Credential $cred 
PS > Copy-Item -ToSession $Session -path C:\Scripts\MyScript.ps1 -Destination C:\ 
PS > Enter-PSSession –VMName SQL011 -Credential $cred 
[SQL011]: PS C:\Users\Admin\Documents> cd c:\ 
[SQL011]: PS C:\> gci 

    Directory: C:\ 

Mode                LastWriteTime         Length Name 
----                -------------         ------ ---- 
d-----        9/12/2016   1:34 PM                Logs 
d-----        7/16/2016   3:23 PM                PerfLogs 
d-r---       11/28/2016   4:45 PM                Program Files 
d-----       11/28/2016  10:00 PM                Program Files (x86) 
d-r---       11/28/2016   4:55 PM                Users 
d-----       11/29/2016   6:03 PM                Windows 
-a----        12/3/2016   7:40 PM              1 MyScript.ps1

You must first create a PowerShell session and then copy the file using the Copy-Item cmdlet followed by the –ToSession parameter. Then I can list the contents of the directory and notice that the script is copied well.

PowerShell Direct and DSC

I can also use PowerShell Direct to push DSC configurations very easily and without network connectivity. In this example, I set the DSC Local Configuration Manager of the VM to allow reboot, auto correct the config, and then verify that settings are applied using the Get-DSCLocalConfigurationManager cmdlet:

PS > Invoke-Command -VMName SQL011 -ScriptBlock {
    configuration LCMConfiguration {
        Node localhost {
            LocalConfigurationManager
	     {
	         ConfigurationMode = 'ApplyAndAutoCorrect'
	         RebootNodeIfNeeded = $true
                RefreshFrequencyMins = 20
	     }
        }
    }

    LCMConfiguration -OutputPath C:\Scripts\DSC
    Set-DscLocalConfigurationManager -Path C:\Scripts\DSC
    Get-DSCLocalConfigurationManager
} -Credential $cred

More information about Desired State Configuration: https://www.simple-talk.com/sysadmin/powershell/powershell-desired-state-configuration-the-basics/

You will understand that this new feature has been introduced to simplify your daily tasks.

How PowerShell Direct works in Hyper-V cluster?

The idea is simple; you need to be logged on to the node that hosts the virtual machine that you want to manage. In the following example, if I want to reach the VM01 virtual machine that is located on “node 2”, then I need to connect locally to “node 2” to use the PowerShell Direct feature. Use the “Get-VM” cmdlet to verify this.

PowerShell Direct vs VMConnect

Some of you will surely wonder about the utility of PowerShell Direct despite this article. You will probably wonder what the difference there is between

  • Connecting to the Hyper-V host and then using PowerShell Direct to access the VM.
  • Opening the “Hyper-V Manager” console and then using “VMConnect” to run your PowerShell command lines in the VM.

I grant you, the gain of time is not obvious. But imagine if you could create a shortcut on your desktop giving you instant access to the VM? By reading an article on the TechNet website, I found this script which is very simple and that will be very useful to you.

The idea is to create a first PowerShell session on your Hyper-V host, and when it is established, a second session will be created to your VM using this time PowerShell Direct:

$VM = "VM01" 
$HypVServer = "HyperV.domain.local" 
$cred = Get-Credential 
$Session = New-PSSession -ComputerName $HypVServer -Credential $cred 
Invoke-command -Session $Session {Enter-PSSession -VMName $using:VM -credential $using:cred} 
Enter-PSSession $Session

Then, you simply create a shortcut on your desktop that will execute this:

PS > Powershell.exe -NoExit -File C:\Users\%Username%\Desktop\PSDirectToVM01.ps1

By double clicking on this shortcut, you will have to enter your credentials in order to connect to the VM. You access your host via the network, and then you use VMBus to connect to your VM.

To go Further With Nano Server

To go even further in this line of reasoning, PowerShell Direct takes centre stage if you want to manage a Nano server.

With Windows Nano Server, Microsoft imposes a new way to manage the OS which must be done remotely. With this OS, remote management is driven by PowerShell scripts rather than by more conventional management tools such as the Remote Desktop Connection tool.

To date, the difficulty that sysadmins face when managing Nano Server is that it has no graphical user interface. PowerShell Direct fixes this problem by allowing a simplified Nano Server operation from end-to-end. As soon as you deploy it, you can configure it without any network connectivity, so you will never, in theory, ever need to use the “VMConnect” to manage a Nano Server:

Conclusion

We’ve seen in this article the new PowerShell Direct feature that allows you to interact with the virtual machines on the Hyper-V host. Access to these VMs no longer requires network access, which is a great help to Hyper-V administrators.

I think this is an excellent tool. It goes without saying that one must remain cautious about the security and the management of the accesses. Why? Because it is now possible to access the virtual machines without authorization in the firewall of the virtual machine. Imagine a machine in DMZ area for which it is no longer necessary to open network ports in the firewall because you can connect to it directly via the Hyper-V host? That poses a question, doesn’t it?

That is why, to finish, I advise you study another cool feature released by Microsoft: Just Enough Administration which will be very useful in order to secure access to your VMs.

The article is available at: PowerShell Just Enough Administration’