Recently, I started experimenting with Windows Server 2016 and I thought to give my new laptop a test for its money by using Hyper-V.

At this point, I automate everything and every research effort normally produces a couple of PowerShell scripts.

My goal is to have what I consider operating system templates, from which I can quickly spin up instances. I also want the instances to be prepared in manner that is good for my development efforts.

For example from the VM I need

  • PowerShell remoting enabled.
  • File sharing enabled.
  • Set the local time zone
  • Enable the num lock

Initially I thought Microsoft would be kind enough to provide some sort of automation, where one specifies the host operating system and a magically a new VM spins up. Possible I was dreaming or thinking too much in Azure mode. Instead I figured out that although the Hyper-V PowerShell module is very powerful, it’s also relatively low level. Therefore you need to do many things by yourself.

So I did and the scripts I created I uploaded into a [gist https://gist.github.com/Sarafian/507a035636b36694fe2a0bf665236cd1] that I would like to share.

Examples

Create a template

To create a Windows Server 2016 template

New-HVTemplate.ps1 -OSVersion 2016 -MediaPath "14393.0.160715-1616.RS1_RELEASE_SERVER_EVAL_X64FRE_EN-US.ISO"

In the above script, I reference the evaluation version of Windows Server 2016 and -OSVersion 2016 identifies the template. The value is used later on from New-HV.ps1 script.

When creating the template, the user (me) is responsible for all actions on the operating system’s installation process including the Windows Update. The script will

  1. Setup the necessary artifacts for a temporary VM.
  2. Let you finish the installation.
  3. Export the VM to use as a template.
  4. Remove all artifacts related to this temporary VM.

Create an instance

To create an instance with name VM201601 based on the above template

New-HV.ps1 -OSVersion 2016 -VMName "VM201601"

The script will

  1. Import the template into a new VM.
  2. Start it.
  3. Capture the VM’s IP and add an entry to my host operating system hosts file.
  4. Generate a PowerShell script to bootstrap the VM. This script does many of the above described requirements and rename the computer

One of my requirements is to add a certificate into the VM. Since I do not want to pay but I also want proper certificates, I use the free certificate issuer provided by the company’s domain. To automate the process use my CertificatePS PowerShell module:

  1. On my host operating system, I request a certificate.
  2. I move the certificate and the chain to the new virtual machine.
$vmName="vmname"
$credential=Get-Credential -Message "Local administrator on $vmName"
$certificateAuthority="certificateAuthority"
$certificate=New-DomainSignedCertificate -Hostname $vmName -CertificateAuthority $certificateAuthority 
$certificate | Move-CertificateToRemote -ComputerName $vmName -Credential $credential -PfxPassword $credential.Password -MoveChain

That’s it. We can validate the outcome on the VM with this fragment

Get-ChildItem Cert:\LocalMachine\My\ |Test-Certificate

Clean up

To remove an instance with name VM201601

Remove-HV.ps1 -VMName "VM201601"

The script will

  1. Stop the VM
  2. Remove the virtual disk files
  3. Remove the VM

Leave a Comment