2

#PSTip Setting Hyper-V client settings

Note: This tip requires PowerShell 3.0 or above.

When working with Hyper-V in Windows Server 2012 or Windows 8 and higher, you can set various Hyper-V host settings via the “Hyper-V Settings” dialog. Every option under the “Server” section is settable via the Set-VMHost cmdlet.

HVServerSettings

The dialog also includes a “User” section. With this section you can control where keyboard key combination will run, which key combination will be used to release the mouse key (getting out of the VM window bounds), and more.

HVClientSettings

However, User settings cannot be set using any of the Hyper-V cmdlets. They are a part of the Hyper-V Manager MMC snap-in. The Hyper-V Manager keeps tracking of its settings via a series of config files:

PS> $path = "$env:APPDATA\Microsoft\Windows\Hyper-V\Client\1.0"
PS> Get-ChildItem $path

    Directory: C:\Users\shay\AppData\Roaming\Microsoft\Windows\Hyper-V\Client\1.0

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---         2/15/2014  12:22 PM        902 clientsettings.config
-a---         2/11/2014  10:06 PM        759 user.config
-a---         2/11/2014  10:06 PM       1511 virtmgmt.VMBrowser.config
-a---          2/5/2014  10:41 AM        622 vmconnect.config
-a---         12/2/2013  10:02 AM       1404 vmwizards.config

The settings in the “User” section in Hyper-V Manager are stored in the clientsettings.config file. You can take a peek of the content with the Get-HVClientSettings function. Note that the file might not exist if you haven’t made a change to the “User” section in Hyper-V Manager. The values you get back are also version dependant. Prior to Server 2012 R2/Windows 8.1, you will only see the first two values. Additionally, there seems to be one setting that is missing from the UI, ‘UseAllMonitors’, which I guess is probably related to the Remote Desktop Multimon feature available in Remote Desktop Client 7.0.

function Get-HVClientSettings
{
    $path = "$env:APPDATA\Microsoft\Windows\Hyper-V\Client\1.0\clientsettings.config"

    if(Test-Path $path)
    {
        $ClientSettings = Get-Content $path
        $settings = $ClientSettings.configuration.'Microsoft.Virtualization.Client.ClientVirtualizationSettings'
        $settings.setting
    }
    else
    {
        Write-Error "'$path' was not found"
    }
}

PS> Get-HVClientSettings | Select-Object Name,Value

name                     value
----                     -----
VMConnectKeyboardOption  Remote
VMConnectReleaseKey      Shift
VMConnectUseEnhancedMode True
DesktopSize              1366, 768
UseAllMonitors           True

As already stated, none of the above can be changed using the Hyper-V module. But now that you know where the settings reside…

Here’s a function that will help you automate the update of User settings.

function Set-HVClientSettings
{
    [CmdletBinding()]

    param(
        [ValidateSet('Remote','Local','FullScreen')]
        [string]$ConnectKeyboardOption,

        [ValidateSet('LeftArrow','RightArrow','Space','Shift')]
        [string]$ReleaseKey,

        [bool]$UseEnhancedMode,

        [bool]$UseAllMonitors,

        [switch]$RestartClient
    )

    $requiredVersion = $PSVersionTable.BuildVersion -lt '6.3.9600'
    $path = "$env:APPDATA\Microsoft\Windows\Hyper-V\Client\1.0\clientsettings.config"

    if(Test-Path $path)
    {
        $ClientSettings = Get-Content $path
        $settings = $ClientSettings.configuration.'Microsoft.Virtualization.Client.ClientVirtualizationSettings'

        if($ConnectKeyboardOption)
        {
            $settings.SelectSingleNode("//setting[@name='VMConnectKeyboardOption']").value = $ConnectKeyboardOption
        }

        if($PSCmdlet.MyInvocation.BoundParameters.ContainsKey('UseEnhancedMode'))
        {
            if($requiredVersion)
            {
                Write-Warning "'UseEnhancedMode' is available only in Windows 8.1/Windows server 2012 R2 and higher."
            }
            else
            {
                $settings.SelectSingleNode("//setting[@name='VMConnectUseEnhancedMode']").value = "$UseEnhancedMode"
            }
        }

        if($PSCmdlet.MyInvocation.BoundParameters.ContainsKey('UseAllMonitors'))
        {
            if($requiredVersion)
            {
                Write-Warning "'UseAllMonitors' is available only in Windows 8.1/Windows server 2012 R2 and higher."
            }
            else
            {
                $settings.SelectSingleNode("//setting[@name='UseAllMonitors']").value = "$UseAllMonitors"
            }
        }

        if($ReleaseKey)
        {
            $settings.SelectSingleNode("//setting[@name='VMConnectReleaseKey']").value = $ReleaseKey -replace 'arrow'
        }

        $ClientSettings.Save($path)

        if($RestartClient)
        {
            Get-Process | Where-Object MainWindowTitle -eq 'Hyper-V Manager' | Stop-Process -Force

            if(Test-Path "$env:ProgramFiles\Hyper-V\virtmgmt.msc")
            {
                # 2008 R2 location
                & "$env:ProgramFiles\Hyper-V\virtmgmt.msc"
            }
            else
            {
                virtmgmt.msc
            }
        }
    }
    else
    {
        Write-Error "'$path' was not found"
    }
}

The function also supports the option to restart Hyper-V Manager as changes will only apply to new instances of virtual machine connections.

Filed in: Columns, Tips and Tricks Tags: , ,

2 Responses to "#PSTip Setting Hyper-V client settings"

Leave a Reply

Submit Comment

© 2016 PowerShell Magazine. All rights reserved. XHTML / CSS Valid.
Proudly designed by Theme Junkie.
%d bloggers like this: