Alex - stock.adobe.com

How PowerShell can automate Hyper-V deployments

This tutorial explains the basics of how to build a proper template to stand up a Hyper-V VM with a script, then go further with advanced configurations for smoother deployments.

The ability to deploy new VMs quickly and efficiently is critical for IT operations. PowerShell automation adds flexibility and speed to the VM deployment process.

Like most hypervisors, Hyper-V allows the administrator to create templates that can be used to deploy new VMs as needed. Templates provide consistency and ensure every VM meets expectations, a useful trait in the IT world.  Scripting the deployment with PowerShell makes the process even easier. With a script and a disk template, the administrator can deploy a VM with custom-sized memory, CPU or even disk space.

How to prepare a template for automated Hyper-V deployments

To start, install the Hyper-V cmdlets with the following PowerShell command run as an administrator:

Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All

Next, prepare the VM that will serve as the image by keeping the following criteria in mind:

  • Only include required software in the base image deployment. Extra packages introduce complexity, additional size and potential licensing issues.
  • Don't use a templated VM already joined to the domain to avoid potential problems.
  • Do cleanup maintenance on the image, such as emptying the recycle bin and removing files from the downloads folder.
  • Set the IP configuration to DHCP to prevent other VMs from claiming the same static IP address.
  • Turn off automatic snapshots. The process will fail if any snapshots are taken during the build because it will prevent access to all required disks.

Next, export the VM to a template file on the Hyper-V system. Right-click on the powered-off VM, select Export and choose a destination for the folder. Locate the VHDX file and copy it into a new folder. It's helpful to keep the exported template disk in a separate folder for easier management.

Build the PowerShell script with Hyper-V VM settings

The following PowerShell script creates and starts a new Hyper-V VM based on the template with set values for memory allocation, number of virtual CPUs and the destination for the VM. Look through the script to understand how it functions and adjust as needed. The system might prompt to allow access for PowerShell, but this is normal behavior.

## Start variables

$destFolder = "c:\myVirtualMachines"

$vmName ="TestingVM"

$memoryInMB = 4096MB

$vCPU = 2

## End variables

New-Item -ItemType "directory" -Path $destFolder\$vmName
Write-Host "c:\templates\my2019template.vhdx" -Destination $destFolder\$vmName.vhdx

Copy-Item -Path "c:\templates\my2019template.vhdx" -Destination $destFolder\$vmName\$vmName.vhdx

New-VM -Name $vmName -MemoryStartupBytes ($memoryInMB) -VHDPath "$destFolder\$vmName\$vmName.vhdx" -Path

$destFolder\$vmName -Generation 2

Set-VMProcessor -VMName $vmName -Count $vCPU

Start-VM -Name $vmName

Write-Host "Virtual Machine '$vmName' has been created and started."

Make network connections after the VM deployment

At this point, the new VM is stood up as a single non-domain joined server. The administrator can then configure the VM as needed with code put into the template VM as a PowerShell script.

After deploying the VM, the administrator can log in and use a script to set up the IP configuration, including the IP address and DNS servers, then rename the VM and restart it. Run the following script from the PowerShell console, which will show any errors, rather than double-clicking the script.

# Define network settings

$vmName = “MyTestVM”

$IPAddress = "192.168.1.100"   # Replace with the desired IP address

$SubnetMask = "255.255.255.0"  # Replace with the subnet mask

$Gateway = "192.168.1.1"       # Replace with the gateway IP address

$DNS1 = "192.168.1.2"          # Replace with primary DNS server

$DNS2 = "192.168.1.3"          # Replace with secondary DNS server

# Configure network settings

$Nic = Get-NetAdapter | Where-Object { $_.Status -eq "Up" }

$Nic | New-NetIPAddress -IPAddress $IPAddress -PrefixLength 24 -DefaultGateway $Gateway

$Nic | Set-DnsClientServerAddress -ServerAddresses $DNS1, $DNS2

# Display completion message

Write-Host "Network configuration and domain join complete."

Rename-Computer -NewName $vmName -Restart

At this point, the new VM is ready for use, but there is room for more customization. Adding the VM to the domain is as simple as creating a second script to do the domain join:

    $domain = "MyDomain"

$domainCredential = Get-Credential -Message "Enter your domain credentials"

Add-Computer -DomainName $domain -Credential $domainCredential -Restart

Go further with customized Hyper-V deployments

This example is a jumping off point for more advanced deployment customizations. For example, the administrator can produce additional scripts for application setups and registry entries stored in a code repository to run when needed. This method ensures that the base script in the template is the most current one. Every pull from the code repository is the latest code version available.

Using templates and PowerShell automation together saves time and maintains consistency. This avoids the configuration differences and errors that tend to creep in when someone manually enters the setup information.

Stuart Burns is an enterprise Linux administrator at a leading company that specializes in catastrophe and disaster modeling.

Dig Deeper on Windows Server OS and management