Administrating virtual machines with PowerShell Direct
Direct Access
The Hyper-V virtualization system is one of the most important services in Microsoft's server family, and the PowerShell administration interface is a logical choice for managing Hyper-V virtual machines (VMs). After loading the command extension, by using Import-Module Hyper-V, you have more than 200 new commands at your disposal (depending on the version) for managing your hypervisor and VMs. You can manage the whole deployment and hardware configuration with PowerShell commands. For instance, you can create a new machine with the command:
> new-vm -Name win8 -MemoryStartupBytes 512MB -BootDevice CD
However, if you want to implement PowerShell instructions on the VM you just created, the process can be cumbersome. PowerShell relies on web service management for remote requests. This service protocol, attached to HTTP(S), accepts requests on defined ports via a listener. The guest and host are thus confined to communicating through some form of virtual networking.
Another option for VM management is the WinRM remote management service, which is also a tool that depends upon a network.
Until recently, managing a VM through PowerShell was never an easy option. However, with the arrival of PowerShell version 5, and since Windows 10 or the preview of Server 2016, Microsoft has provided a means for direct management of virtual systems without networking. A new featured called PowerShell Direct lets you run arbitrary commands on a Windows 10 or Windows Server 2016 VM regardless of network or remote access settings.
PowerShell Direct offers a powerful alternative to conventional management tools like VMconnect that makes use of PowerShell's flexibility and superior automation features. Using Windows 10 and Server 2016 on both sides of the communication channel (on the hypervisor and the VM) is a precondition for using PowerShell Direct. In addition, local installation of the guest systems is necessary.
Access via VMBus
PowerShell Direct relies on VMBus, a mechanism within Hyper-V that provides a communication channel between guest and host. VMBus lets you address VMs directly via their GUID or name. VMBus functions as a communication channel that implements the principle of provider and consumer.
The virtualization service provider (VSP) acts on the host side, and the destination device is represented on the VM by virtualization service consumers (VSCs). If you want to transfer a file from the host to the VM, you can create a share with New-SmbShare
, then map the share with:
> New-PsDrive -Root \\server\Release -name Y -PsProvider FileSystem -persist
and subsequently start a simple copying process. Or use a more direct route via VMBus:
> Copy-VMFile -VM dc1 -SourcePath C:\udat\09-11-2015_11964.txt -DestinationPath C:\share
This process also requires that you make the guest services available as part of the integration services, which you can check afterward with a simple PowerShell command:
> Enable-VMIntegrationService -Name 'Guest Service Interface' -VMName dc1 -Verbose
The Hyper-V VM session service is also necessary within the VM. If this service is deactivated, the direct execution of PowerShell commands is prevented.
New but Powerful Parameters
In remote management, Windows makes a distinction between one-to-one (1:1) and one-to-many (1:n) connections. 1:1 remote maintenance scenarios are implemented by the PsSession concept, which is useful for console-based management via PowerShell commands:
> $cred = Get-Credential username@Mydomain.TopLevel; > Enter-Pssession -ComputerName Server.MyDomain.TopLevel -Credential $cred;
The new variant that works without a network connection and established WinRM connection is as follows:
> Enter-Pssession -VmName DC1 -Credential $cred;
You can also address the VM using its GUID with the -VMGUID
option. The often-outstanding PowerShell documentation unfortunately has not yet been updated to explain this approach. Attempting to consult the Help section on this question resulted in an error.
The -VmName
and -VMGUID
parameters are also available in a 1:n management context, allowing you to transfer an instruction list to any number of VMs:
> Invoke-Command -Credential $cred -filePath Path_to_location_file.ps1 -VMName dc1,srv1,srv2
This principle is also called fan-out. Delivering information to the credential parameter is strictly necessary in this case. This need to send credentials distinguishes a VMBus connection from classic remoting via web service management, where a pass-through process can deliver the identity information.
PowerShell script files are executed on the destination system; the commands are not ported. You must therefore use
> Set-ExecutionPolicy -ExecutionPolicy [ByPass]
to direct the execute permissions in the administrative PowerShell console before using remote scripting. Afterward, when specifying the desired user account, you get a login mask with -Credential
. You must also consider the fact that you cannot use domain accounts any longer but must log in with local usernames instead. There is a workaround in the ability to integrate an intermediate step and store the passwords in a text file in encrypted form. First, save the password with:
> Read-Host "Enter_Password" -AsSecureString | ConvertFrom-SecureString | Out-File "C:\udat\Password.txt";
You'll need login details to use PowerShell Direct. Set the user and password in the script file with:
> $ben = "UserAccount; > "$file = "Cudat\Password.txt"; > $MyCred=New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $ben, (Get-Content $file | ConvertTo-SecureString);
Now execute PowerShell Direct with the authentication entered:
> Invoke-Command -Credential MyCred -VmName Win10 -FilePath Path_to_PS1;
Varied Areas of Application
In principle, all PowerShell instructions that are applied locally or in a network environment are also possible for VMs. (One small limitation is that transferring files from VMs in physical systems is currently not yet possible.) Modifying an IP address works as follows:
> Invoke-Command -Credential $cred -VMName dc1 -scriptBlock {New-Net-IPAddress -InterfaceAlias "LAN-Connection" -IPAddress 192.168.1.3 -DefaultGateway 192.168.1.1 -PrefixLength 24}
A further possibility is to provide modular VMs in an Azure environment. A service provider could offer the clients an interface similar to a website, over which they select the services they desire. The necessary permissions could then be provided on the basis of this information. Such a process would be much simpler than just providing an operating system. If you want a dedicated web server, all the necessary features could be injected via Install-WindowsFeature
. The same applies to all structures in the filesystem you might want as a basis for the virtual directories, even before the new server is fitted into the new infrastructure.
Voluntary Waiver
If you want to disable PowerShell Direct, closing the gateway of access is not exactly a trivial matter. To look at the service's settings more closely, first use a simple WMI request:
> get-WmiObject -Class win32_service -Filter "name = 'vmicvmsession'"
Your first idea might be to stop the Hyper-V VM session service, since PowerShell Direct depends on that service. Unfortunately, stopping the VM session alone does not do the job. The service is equipped with a manual start mode, so every new request initializes the service afresh. You therefore have to also modify the start type:
> Set-Service -name "vmicvmsession" -startupType Disabled
Now the session service cannot be started anymore by any means, so PowerShell Direct is no longer available.
Conclusion
VMs are not always accessible through a remote connection. With PowerShell Direct, however, Microsoft provides a means for managing VMs that might not be reachable through conventional networking or remote-administration techniques.