I’m deploying a small VDI infrastructure for my employer. Being used to Citrix XenDesktop, the Windows 2012 implementation is, how to put it, “lightweight”.
The team has done a tremendous job of exposing the various config tasks in Server Manager. Tasks such as changing SSL certs across multiple hosts or deploying new VDI collections use remoting and PowerShell workflows to an impressive degree. It all seems almost too easy. Which is just what it is when you get stuck. Microsoft has completely forgotten to write good documentation for its VDI implementation. All you’ll find on Technet is some “test lab guides” (that are more often than not wrong of simply missing important steps) and a “troubleshooting” guide. I mean, come on. The best I’ve found so far is the built-in help for the RemoteDesktop PowerShell module. Simply nowhere near good enough for serious use.
Anyways. Apart from a few glaring bugs, the solution works fairly well. User Profile Disks are nice, and it’s even possible to specify what parts of the profile to keep at logoff, and what to discard.
The bugs I’ve found:
1. When creating a new Collection (of VDI VMs), I’m not able to choose the Template VM (or “Gold VM”) from the list. It simply isn’t there. Using PowerShell to create the Collection, it all works as advertised
2. If you’re customizing the VMs with an unattend.xml file, I’ve read that you need to remove the first line in the unattend file, or else the deployment will fail.
3. The “Auto save delay” setting on the collection, which specifies how long the VM should be kept running after user logoff before reverting, doesn’t always work. I have no idea why.
As for the PowerShell support, it’s in line with the rest of Windows Server 2012 – just great. It lets you script every single thing you’re able to do in the UI. Some of the CmdLets take an insane number of parameters, but that’s just how it is. Lots to do. In case you need it, I’ve included my own script for deploying a new Collection of 3 VMs. The “Template VM” needs to be a sysprepped VM, in powered off mode. I’ve tried to explain the various parameters as best I could, since official documentation is so lacking at the moment.
$CollectionName = "Timpex VDI" #Name of the VDI Collection
$TemplateName = "Timpex_VDI_Template" #The VM to be used as a template. Needs to be sysprepped and shut down
$TemplateHostServer = "TP-HV01.timpex.net" #The Hyper-V Server where the template exists
$Allocation = @{"TP-HV01.timpex.net"=3} #The hosts and number of VMs to create. Here I'm creating only one, on host TP-HV01
$usergroups = "TIMPEXNET\domain users" #The AD Group with access to the Collection
$ConnectionBroker = "tp-app13.timpex.net" #The Connection Broker computer
$UnattendFilePath = "\\tp-app13\c$\RDVirtualDesktopTemplate\Timpex-vdi-template-unattend.xml" #Path of the unattend file (Be sure to remove the first line (<!--?xml version="1.0" encoding="utf-8"?-->) in this file.
$LocalStoragePath = "D:\Hyper-V Data\VDI" #Where (on the hyper-v host) the VMs should be placed
$NamePrefix = "TPVDI" #The computername prefix of VMs. A number will be added to this prefix when VMs are generated
$UserProfileDiskPath = "\\tp-fil01.timpex.net\uvhd" #Path of User Profile disks
$machineOU = "OU=VDI VMs,OU=Workstations,DC=timpex,DC=net" #OU where machine accounts for VMs are to be placed. The connection broker computer needs write access to this OU.
#Do it
New-RDVirtualDesktopCollection -CollectionName $CollectionName -PooledManaged -VirtualDesktopTemplateName $TemplateName -VirtualDesktopTemplateHostServer $TemplateHostServer -VirtualDesktopAllocation $Allocation -StorageType LocalStorage -Description "PowerShell created Virtual Desktop Pool" -UserGroups $usergroups -ConnectionBroker $ConnectionBroker -VirtualDesktopNamePrefix $NamePrefix -VirtualDesktopPasswordAge 31 -UserProfileDiskPath $UserProfileDiskPath -MaxUserProfileDiskSizeGB 10 -OU $MachineOU -LocalStoragePath $LocalStoragePath -Verbose -CustomSysprepUnattendFilePath $UnattendFilePath
#Configure stuff
$RDColl = Get-RDVirtualDesktopCollection $CollectionName
$RDCOll | Set-RDVirtualDesktopCollectionConfiguration -ClientDeviceRedirectionOptions Clipboard,Drive,AudioVideoPlayBack -RedirectAllMonitors $false -SaveDelayMinutes 5
Also, here’s the unattend file I’m referencing. Notice that you don’t need to specify domain join details or computername, as these will be dynamically injected into the unattend file as the vms are deployed (mind you, I’m deploying x86-based VMs at the moment, so if you want to use x64-based VMs you need to use the corresponding x64 components in the unattend file).
<unattend xmlns="urn:schemas-microsoft-com:unattend"> <settings pass="specialize"> <component name="Microsoft-Windows-International-Core" processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="<a href="http://schemas.microsoft.com/WMIConfig/2002/State">http://schemas.microsoft.com/WMIConfig/2002/State</a>" xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>"> <InputLocale>0414:00000414</InputLocale> <SystemLocale>nb-NO</SystemLocale> <UILanguage>nb-NO</UILanguage> <UserLocale>nb-NO</UserLocale> </component> </settings> <settings pass="oobeSystem"> <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="<a href="http://schemas.microsoft.com/WMIConfig/2002/State">http://schemas.microsoft.com/WMIConfig/2002/State</a>" xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>"> <OOBE> <HideEULAPage>true</HideEULAPage> <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE> <NetworkLocation>Work</NetworkLocation> <ProtectYourPC>3</ProtectYourPC> <SkipMachineOOBE>true</SkipMachineOOBE> <SkipUserOOBE>true</SkipUserOOBE> </OOBE> <UserAccounts> <AdministratorPassword> <Value>WouldntYouLike2Know</Value> <PlainText>false</PlainText> </AdministratorPassword> </UserAccounts> <WindowsFeatures> <ShowMediaCenter>false</ShowMediaCenter> <ShowWindowsMail>false</ShowWindowsMail> <ShowWindowsMediaPlayer>false</ShowWindowsMediaPlayer> </WindowsFeatures> </component> <component name="Microsoft-Windows-International-Core" processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="<a href="http://schemas.microsoft.com/WMIConfig/2002/State">http://schemas.microsoft.com/WMIConfig/2002/State</a>" xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>"> <SystemLocale>nb-NO</SystemLocale> <UILanguage>nb-NO</UILanguage> <UserLocale>nb-NO</UserLocale> <InputLocale>0414:00000414</InputLocale> </component> </settings> <cpi:offlineImage cpi:source="catalog://tp-fil01/pc-deployment/operating systems/win7sp1x64no_office2013_patched20130417/win7sp1x64no_office2013_patched20130417_dep07ddrive.clg" xmlns:cpi="urn:schemas-microsoft-com:cpi" /> </unattend>







