Hyper-V Remote Management With PowerShell

You may have already read my previous two posts on Hyper-V remote management using the UI and configuring Constrained Delegation, for some people that will not be an option or is just undesirable...  Well with Windows 8 and the joy of PowerShell we have another option.  Many of the new Hyper-V PowerShell cmdlets (https://technet.microsoft.com/en-us/library/hh848559.aspx) take a computername parameter to allow for remote usage however if you are creating a virtual machine using SMB storage or if your are live migrating a VM you run into the same double hop constrained delegation problem as with the UI.  Luckily we have PowerShell remoting or WinRM remoting more specifically.

Overview_webGoing back to the example I’ve been using we have a two node Windows Server 8 Scale-Out file server cluster, two standalone Hyper-V Servers and a remote management workstation.  In this case we will be using PowerShell from the management workstation as opposed to the Hyper-V UI.  The other nice part about PowerShell remoting is that your management workstation could be of a different domain or no domain at all depending on how you choice to send the credentials.


Creating a New VM Remotely with SMB Storage – Failure

I’ll start with the error you will get if you try to create a VM remotely using SMB storage in Beta – the error message is wrong (it’s a bug and already fixed) but non the less you can see that using ComputerName parameter with the VM on an SMB share it fails.
PS C:\Windows\system32> New-VM -Name "VMOverSMB" -Path \\hv-w8-beta-smb\VirtualMachines -ComputerName 37-4611K2615L
New-VM : The Virtual Machine Management Service on host '37-4611K2615L' is not running.
At line:1 char:1
+ New-VM -Name "VMOverSMB" -Path \\hv-w8-beta-smb\VirtualMachines -ComputerName 37 ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [New-VM], VirtualizationOperationFailedException
+ FullyQualifiedErrorId : Microsoft.HyperV.PowerShell.Commands.NewVMCommand

Credential Delegation – CredSSP/Kerberos

In order to avoid the double hop and credential delegation issues we need to issue the command in the context of the Hyper-V server.  The easiest way to accomplish this is by using CredSSP and WsMan/WinRM.  By default CredSSP is disabled or more specifically the “AllowFreshCredentials” and “Allow CredSSP authentication” polcies are disabled you can either enable these via group policy or you can enabled them via the Enable-WSManCredSSP cmdlet.  I utilize group policy to enable CredSSP for my environment and have it pretty well locked down such that only systems on my domain and specific trusted domains can provide credentials and further more WinRM only listens on specific IP ranges.

Enable-WSManCredSSP -Role Client -DelegateComputer "*.hyper-v.selfhost.corp.microsoft.com"
Enable-WSManCredSSP -Role Server

It is worth stating the Kerberos delegation is also an option – it does carry with it some caveats as well.  When using Kerberos delegation you have to enable unconstrained delegation on the computer account and unconstrained delegation and constrained don’t seem to get along so it prevents Hyper-V remote UI management.

Using Credential Delegation

There are a few ways in PowerShell to use credential delegation – you can use Invoke-Command with a script block, computer name, credentials or you can create a PSSession and either pass that to InvokeCommand or enter the PSSession and execute the commands locally.  I’ll start with the PSSession example as it breaks down the concepts well.

The first step is getting the credentials that will be used on the remote machine – this is done via the Get-Credential cmdlet which will popup a standard Windows credential dialog, in my case I provide my username so I don’t have to type it in again.  The next step is to create a session via the New-PSSession cmdlet using CredSSP as my authentication and the credentials I got in step 1.  Next I enter the session with Enter-PSSession, after this command I am effectively typing on the remote computer and that’s evidenced by the computer name before my command prompt.  At this point I can create the New VM and away we go.
PS C:\> $remotingCreds = Get-Credential -Credential "hyper-v\taylorb"
PS C:\> $Session = New-PSSession -Authentication Credssp -Credential $remotingCreds -ComputerName "37-4611K2617L"
PS C:\> Enter-PSSession $Session
[37-4611K2617L]: PS C:\Users\taylorb\Documents> New-VM -Name "VMOverSMB" -Path \\hv-w8-beta-smb\VirtualMachines

Name State CPUUsage(%) MemoryAssigned(M) MemoryDemand(M) MemoryStatus Uptime Status ReplicationState
---- ----- ----------- ----------------- --------------- ------------ ------ ------ ----------------
VMOverSMB Off 0 0 0 00:00:00 Operating normally Disabled

In this example the first two steps are the same but as opposed to entering the PS Sessions I use Invoke-Command to execute a script block on the remote server.
PS C:\> $remotingCreds = Get-Credential -Credential "hyper-v\taylorb"
PS C:\> $Session = New-PSSession -Authentication Credssp -Credential $remotingCreds -ComputerName "37-4611K2615L"
PS C:\> Invoke-Command -Session $Session -ScriptBlock {New-VM -Name "VMOverSMB" -Path \\hv-w8-beta-smb\VirtualMachines}

We can also use Invoke-Command without a PSSession (though it will just create one for you and close it when it’s done).
PS C:\> Invoke-Command -Authentication Credssp -Credential (Get-Credential) -ComputerName "37-4611K2617L" -ScriptBlock {New-VM -Name "VMOverSMB" -Path \\hv-w8-beta-smb\VirtualMachines}

Or if you have unconstrained delegation enabled you can use Kerberos – also note that with Kerberos there is no need to provide credentials as the current users credentials will be delegated for you.
PS C:\> Invoke-Command -Authentication Kerberos -ComputerName "37-4611K2617L" -ScriptBlock {New-VM -Name "VMOverSMB" -Path \\hv-w8-beta-smb\VirtualMachines}

Live Storage Migration and Live Migration

These seem to be the biggest challenges for remote management – since they implicitly require a third hop I wanted to make sure there where some samples…

PS C:\> $remotingCreds = Get-Credential -Credential "hyper-v\taylorb"
PS C:\> $Session = New-PSSession -Authentication Credssp -Credential $remotingCreds -ComputerName "37-4611K2617L"

PS C:\> Invoke-Command -Session $Session -ScriptBlock {Move-VM -Name "VMOverSMB" -DestinationHost "37-4611K2615L"}

PS C:\> $remotingCreds = Get-Credential -Credential "hyper-v\taylorb"
PS C:\> $Session = New-PSSession -Authentication Credssp -Credential $remotingCreds -ComputerName "37-4611K2617L"
PS C:\> Invoke-Command -Session $Session -ScriptBlock {Move-VMStorage -VMName LocalVM -DestinationStoragePath \\hv-w8-beta-smb\VirtualMachines\LocalVM

Taylor Brown
Hyper-V Enterprise Deployment Team
taylorb@microsoft.com
https://blogs.msdn.com/taylorb

WS08R2-HyperV_v_rgb

Comments

  • Anonymous
    April 23, 2012
    Thank you so much for this detailed article.  I have been thinking about setting up my computer gear to be able to be controlled by <a href="http://mokimobility.com">remote management</a> .  After reading your articles, I think that I am now ready to do so.  Thanks again for helping me out!

  • Anonymous
    November 06, 2012
    Thank you so much for these examples! Very helpful!

  • Anonymous
    July 03, 2013
    If you do not want to leave powershell then checkout pshvm.codeplex.com for a free hyper-v manger written in powershell, that allows you to configure the vhost virtual paths, create vswitches, create.manage and connect to vm's and then run reports on what you just created.