Tuesday, November 24, 2015

Create a new VM from an image

I have two standalone Hyper-V hosts and I needed to create multiple VMs on each host. I don't have SCVMM or any other management suite, so I decided to script the build. Being the good lazy sysadmin that I am, a quick search landed me on Jeffery Hicks page at http://www.altaro.com/hyper-v/create-virtual-machine-from-template-powershell/.

Mr Hicks script did almost exactly what I wanted, except he is building from an ISO image. I wanted a fully updated image that was ready to go. This means creating a template and syspreping the system. Now that I have a fully updated Server 2012 R2 vhdx image we can modify the script to use a copy of this as the base for our new systems.

Possible Feature enhancements


  • Currently this script needs to be run from the Hyper-V host, but I plan on improving it to run remotely
  • Add a loop to create multiple machines at once
  • Expand the menu to include Win7, Win8.1, Win10, Server 2008 R2, Server 2016 images

The Script



#requires -version 3.0
<#
.Synopsis
Provision a new Hyper-V virtual machine based on a template
.Description
This script will create a new Hyper-V virtual machine based on a template or
hardware profile. You can create a small, medium or large virtual machine. All
virtual machines will use the same virtual switch and the same paths for the
virtual machine and VHDX file.  

This script requires the Hyper-V 3.0 PowerShell module.
Credit goes to Jeffery Hicks
http://www.altaro.com/hyper-v/create-virtual-machine-from-template-powershell/

.Example
PS C:\Scripts\> .\New-VMFromTemplate lab101 -VMType small -passthru
Name       State CPUUsage(%) MemoryAssigned(M) Uptime   Status
----       ----- ----------- ----------------- ------   ------
lab101     Off   0           0                 00:00:00 Operating normally
.Link
New-VM
Set-VM
#>

[cmdletbinding(SupportsShouldProcess)]
Param(
    [Parameter(Position=0,Mandatory,HelpMessage="Enter the name of your new virtual machine")]
    [ValidateNotNullOrEmpty()]
    [string]$VMName,
    [ValidateSet("small","medium","large")]
    [string]$VMType="small",
    [switch]$Passthru
)

#define parameter values based on VM Type
Switch ($VMType) {
    "small" {
        $MemoryStartup=2048MB
        $VHDSize=150GB
        $ProcCount=1
        $MemoryMinimum=512MB
        $MemoryMaximum=4096MB
    }
    "medium" {
        $MemoryStartup=4096MB
        $VHDSize=200GB
        $ProcCount=2
        $MemoryMinimum=1024MB
        $MemoryMaximum=8192MB
    }
    "large" {
        $MemoryStartup=8192MB
        $VHDSize=200GB
        $ProcCount=4
        $MemoryMinimum=4096MB
        $MemoryMaximum=16GB
    }
} #end switch

Write-Verbose "Creating new $VMType virtual machine"

$SwitchName = "v207"
$VMRoot = "D:\Hyper-V"
$VMPath = "${VMRoot}\${VMName}"
$VHDimage = "D:\sysadmin\images\Server2012R2.vhdx"
$VHDPath = "${VMPath}\Virtual Hard Disks\"
$VHDName = "${VMPath}\Virtual Hard Disks\${VMName}.vhdx"

mkdir $VHDPath

Convert-VHD -Path $VHDimage -DestinationPath $VHDName


#define a hash table of parameters for New-VM
$newParam = @{
 Name=$VMName
 SwitchName=$SwitchName
 MemoryStartupBytes=$MemoryStartup
 Generation=2
 Path=$VMRoot
 VHDPath=$VHDName
 ErrorAction="Stop"
}
#define a hash table of parameters for Set-VM
$setParam = @{
 ProcessorCount=$ProcCount
 DynamicMemory=$True
 MemoryMinimumBytes=$MemoryMinimum
 MemoryMaximumBytes=$MemoryMaximum
 ErrorAction="Stop"
}
if ($Passthru) {
    $setParam.Add("Passthru",$True)
}
Try {
    Write-Verbose "Creating new virtual machine"
    Write-Verbose ($newParam | out-string)
    $VM = New-VM @newparam
}
Catch {
    Write-Warning "Failed to create virtual machine $Name"
    Write-Warning $_.Exception.Message
    #bail out
    Return
}


if ($VM) {
    Try {
        Write-Verbose "Configuring new virtual machine"
        Write-Verbose ($setParam | out-string)
        $VM | Set-VM @setparam
    }
    Catch {
    Write-Warning "Failed to configure virtual machine $Name"
    Write-Warning $_.Exception.Message
    #bail out
    Return
    }
}

No comments:

Post a Comment