Nano Server Hyper-V cluster on VirtualBox

In a previous post I discussed setting up Nano server from Windows Server 2016 Technical Preview 2.  At the time, the process of creating a Nano server VHD was pretty unclear, and fairly arduous.  The good news is that with the release of Technical Preview 3, the process is much simpler, even if not exactly obvious.  If you are looking for the basics, check out the Microsoft article here to get started with Nano server.  The post assumes that you are running Hyper-V or physical hardware, cause why would you do anything else?  For those of you looking to run in VirtualBox, here is a guide to getting a two-node Nano server Hyper-V cluster up and running in VirtualBox.

First let's lay down some specifics.  Everything I am doing is from a laptop running Windows 10 Build 10565.  VirtualBox is version 5.0.4r102546.  And the source media for Nano server is the most recent Windows Server 2016 Technical Preview 3 ISO.  If you are playing along at home, your mileage may vary depending on your setup.  It shouldn't... but hey all this stuff is ridiculously new.  I tried running the Nano build scripts on a Server 2012 box and it died saying that the cmdlet Get-FileHash doesn't exist.  Wrong WMF apparently.  So make sure you are running everything from either Windows 10 or 2016 TP3.

In my VirtualBox configuration I have setup an Internal Network called ExchangeNet and a domain controller running Windows Server 2016 TP3 with the DHCP role installed.  I have installed the Hyper-V and Failover Cluster management tools as well.

First step is to get a Nano Server image built.  The new process uses two PowerShell scripts located on the Server 2016 ISO in the NanoServer folder.  Copy the entire NanoServer folder to a local drive, since we are going to be making an edit to one of the scripts.  You could run the scripts directly from the ISO if you want, but you'll see why we're editing the script in a moment.  The two scripts are new-nanoserverimage.ps1 and convert-windowsimage.ps1.  New-nanoserverimage.ps1 is the main script, and it uses the convert-windowsimage.ps1 script as a helper.  Convert-windowsimage.ps1 takes a WIM image and uses dism to service it and generate the base VHD for NanoServer.  By default, the VHD it creates is dynamically expanding with a size of 40GB.  As you know, the footprint for Nano server is about 500MB, so it seems a bit ludicrous to give it a 40GB VHD.  The convert-windowsimage.ps1 script does take a parameter of SizeBytes with a range of 512MB to 64TB.  The new-nanoserverimage.ps1 script does not take a SizeBytes parameter to pass along, so if you use the script unmodified, you will end up with a 40GB VHD.  No thanks.  Open the new-nanoserverimage.ps1 file and drop down to line 925.  The modified line should look like this:
Convert-WindowsImage -SourcePath $Script:BaseImageFilePath -VHD $Script:BaseVHDImageFilePath –VHDformat VHD -EnableDebugger None -Edition "CORESYSTEMSERVER_INSTALL" -VHDPartitionStyle MBR -SizeBytes 2GB
As you can see I set the size to 2GB, but you can set it to whatever makes the most sense for your application.  If you were feeling particularly savvy, you could add a parameter to the script to pass through a value.  This is much easier for a quick tutorial.

Once you have saved the modified script, open an Administrative PowerShell window.  Navigate to the NanoServer folder.  Dot source the new-nanoserverimage.ps1 script by entering:

. .\new-nanoserverimage.ps1
That command loads the script and imports each function without submitting any parameters.  Now you can call any of the functions within the script.  I've done this before when I create a function library in a separate script file, but I have no idea why Microsoft chose to do that here.  Oh well.  The command I used to create the VHD was the following:
New-NanoServerImage -MediaPath F:\ -BasePath G:\NanoServerBase -TargetPath G:\NanoServer2GB -Compute -Clustering -OEMDrivers -ComputerName "Nano01" -EnableIPDisplayOnBoot -EnableRemoteManagementPort
In my case the ISO was mounted on the F: drive, and my G: drive is a local SSD drive I keep my VMs on.  When you execute the command it will prompt you for the administrator password.  I've had some issues with trying complex passwords, so instead I am just using "password" and changing it after the fact.  You can run this command with the same BasePath parameter, and it will skip calling convert-windowsimage and use the existing VHD.  That will speed up the creation process, but it also means that whatever size VHD you picked is locked in to that base image and any subsequent NanoServer VHDs that are generated from it.

When the script completes, there will be a VHD file in the TargetPath folder you specified.  Now we are going to make a few copies of the VHD to run in VirtualBox.  In the same PowerShell windows navigate to installation directory for VirtualBox, typically %ProgramFiles%\Oracle\VirtualBox.  From there run the following command:
.\VBoxManage.exe clonemedium disk G:\NanoServerVMware\NanoServer.vhd G:\NanoServerVMware\NanoServer2.vhd --format VHD
Substitue your TargetPath location and VHD names as appropriate.  This will create a copy of the existing VHD and give it a new UUID.  VirtualBox won't let you have multiple VHDs with the same UUID, so you can't simply copy and paste the VHD file in the folder.

Now we have our VHD files for VirtualBox to use.  Open VirtualBox and create a new VM.  Leave the Type as Windows and set the Version to Other Windows (64-bit).  Select use an existing virtual hard disk file, and pick one of the VHDs.  Once the VM is created, open the VM's settings and set the network to whatever internal network you would like.  The VM is now ready to be powered up.  Rinse and repeat for the additional VM.

On first boot, Nano server will run the Windows unattend.xml file that was generated when the new-nanoserverimage.ps1 script ran.  You will see a black screen with the text Ok. for a bit.  In the background Nano server is parsing and applying the unattend.xml, so don't worry.  When it completes you'll see the login screen.  You should be able to login with administrator and the password you set when you ran the script.  From there you should be able to get the IP address Nano server picked up through DHCP.  And... that's about all you can do from the console.  The rest of the Nano server configuration is all done remotely through PowerShell, as Jeffrey Snover intended.

Now we are going to rename the computer, join it to the domain, and add it to the Hyper-V console.  All of these commands will be run from the domain controller in my lab, creatively named DC.  The remote PowerShell commands will be using wsman, and since the Nano server is not yet a member of the domain, it must be added to the trusted host list using the following commands:
$ip = "ipAddressofNanoServer"
Set-Item wsman:\localhost\Client\TrustedHosts -Value $ip
Now rename the Nano server by running:
Rename-Computer -ComputerName "$ip" -NewName "Name" -LocalCredential "$ip\administrator"
Restart-Computer -ComputerName "$ip" -Credential "$ip\administrator"

After the Nano server is renamed, we are going to join it to the domain.  From the DC run the following:
Djoin.exe /provision /domain /machine ComputerName /savefile .\ComputerName
Net use Z: \\ipAddress\C$Copy .\ComputerName Z:\
Enter-PSSession -ComputerName $ip -Credential "$ip\administrator"
Djoin /requestodj /loadfile C:\ComputerName /windowspath C:\windows /localos
Shutdown /r /t 5
Substitute the ComputerName with whatever you named your Nano servers.  Rinse and repeat for the second one.

Now that they are members of the domain, you can easily add them to you Hyper-V console.  I found that I had to restart my Nano servers a second time before they registered in DNS, but that might have just been my lab environment and not anything to do with the Nano servers.  If you are having trouble adding them to Hyper-V, make sure you can ping the servers by name.  Last step is to create a cluster in the Failover cluster management tool.  This demo doesn't have any shared storage, and you won't be able to power on VMs since Hyper-V nested in VirtualBox is not supported.  That's why for my next post I'll be converting these VHDs to VMDKs and dropping them in a vSphere environment.  See you then!

Labels: , , , ,