New Hyper-V VM via PowerShell or GUI
If you prefer video over written format the corresponding video for this write-up can be viewed below:
Here is all the PowerShell code required for the creation of a new Hyper-V VM. The code below can be used to prompt for all needed settings to fully setup and configure a new Hyper-V VM. This is a fully functional script that could be easily modified to spin up multiple VMs at once, or even import settings from a .csv or .txt file. A full write-up with examples for the GUI can also be found below.
Create a New Hyper-V VM – PowerShell Method
#----------------USER CREATION QUESTIONS------------------- [string]$vmName= Read-Host ”Name of VM” #__________________________________________________________ [int32]$generation = Read-Host "Generation Type" #__________________________________________________________ [string]$dynamic = $null while("yes","no" -notcontains $dynamic){ $dynamic = Read-Host "Will this VM use dyanmic memory? (yes/no)" } if($dynamic -eq "yes"){ [bool]$dynMemory = $true [int64]$minMemory = Read-Host "Memory Minimum (MB)" [int64]$maxMemory = Read-Host "Memory Maximum (MB)" [int64]$startMemory = Read-Host "Starting Memory (MB)" #convert to bytes $minMemory = 1MB*$minMemory $maxMemory = 1MB*$maxMemory $startMemory = 1MB*$startMemory [int64]$memory = $minMemory } else{ [int64]$memory = Read-Host "Memory (MB)" #convert to bytes $memory = 1MB*$memory } #__________________________________________________________ Write-Host "--------AVAILABLE SWITCHES--------" -BackgroundColor Black Get-VMSwitch | Select-Object -ExpandProperty Name Write-Host "--------AVAILABLE SWITCHES--------" -BackgroundColor Black [string]$vmSwitch = Read-Host "Please enter a virtual switch name" #__________________________________________________________ [int32]$cpu = Read-Host "Number of CPUs" #__________________________________________________________ [string]$vmPath = Read-Host "Enter path for VM config files (Ex E:\VM\)" [string]$newVMPath = $vmPath #__________________________________________________________ [string]$vhdPath = Read-Host "Enter path where .vhdx will reside (Ex E:\VHD\)" [string]$newVHD = $vhdPath+$VMName+".vhdx" [int64]$vhdSize = Read-Host "Enter VHDSize (GB)" $vhdSize = [math]::round($vhdSize *1Gb, 3) #converts GB to bytes #__________________________________________________________ #----------------END USER CREATION QUESTIONS--------------- try{ #-----------------CONFIRM CREATE NEW VM---------------- Write-Host "Creating new VM:" $vmName "Generation type:" $generation ` "Starting memory:" $memory "stored at:" $newVMPath ", ` with its .vhdx stored at:" $newVHD "(size" $vhdSize ")" -ForegroundColor Cyan [string]$confirm = $null while("yes","no" -notcontains $confirm){ $confirm = Read-Host "Proceed? (yes/no)" } #---------------END CONFIRM CREATE NEW VM-------------- if($confirm -eq "yes"){ #------------------CREATE NEW VM----------------------- NEW-VM –Name $vmName -Generation $generation –MemoryStartupBytes $memory ` -Path $newVMPath –NewVHDPath $newVHD –NewVHDSizeBytes $vhdSize | Out-Null Start-Sleep 5 #pause script for a few seconds to allow VM creation to complete #----------------END CREATE NEW VM--------------------- #---------------CONFIGURE NEW VM----------------------- ADD-VMNetworkAdapter –VMName $vmName –Switchname $vmSwitch #______________________________________________________ Set-VMProcessor –VMName $vmName –count $cpu #______________________________________________________ if($dynMemory -eq $true){ Set-VMMemory $vmName -DynamicMemoryEnabled $true -MinimumBytes $minMemory ` -StartupBytes $startMemory -MaximumBytes $maxMemory } Start-Sleep 8 #pause script for a few seconds - allow VM config to complete #---------------END CONFIGURE NEW VM------------------- #display new VM information Get-VM -Name $vmName | Select Name,State,Generation,ProcessorCount,` @{Label=”MemoryStartup”;Expression={($_.MemoryStartup/1MB)}},` @{Label="MemoryMinimum";Expression={($_.MemoryMinimum/1MB)}},` @{Label="MemoryMaximum";Expression={($_.MemoryMaximum/1MB)}} ` ,Path,Status | ft -AutoSize } else{ Exit } } catch{ Write-Host "An error was encountered creating the new VM" ` -ForegroundColor Red -BackgroundColor Black Write-Error $_ }
Create a New Hyper-V VM – GUI Method
1. Initiate the New Virtual Machine Wizard
Open Hyper-V Manager – virtmgmt.msc – right click your Hyper-V server – New – Virtual Machine…
2. Give your new VM Name and choose where to save the VM configuration files
Note: This is just the name of the VM as it will be displayed on the Hyp. This is not the hostname of the VM.
The New Virtual Machine Wizard will have a default location of where the VM configuration files will be stored. There are several files associated with this location as you can see in the below example so make sure you are storing them in an appropriate location.
#get VM config file locations and VHD locations $vm = Get-VM -Name VM01 $vm | Select-Object VMName,Path,ConfigurationLocation,SnapshotFileLocation,` SmartPagingFilePath Get-VHD -VMId $vm.ID | select Path
VMName : VM01 Path : V:\VMs ConfigurationLocation : V:\VMs SnapshotFileLocation : V:\VMs SmartPagingFilePath : V:\VMs Path : V:\VHDs\VM01.vhdx
Notice that the location of the config files and VHD/VHDX files differ.
Note: The SnapshotFileLocation is defaulted to store at this location as well. Something to keep in mind!
If you wish you can change the default location that is populated in the wizard. This can be accomplished through the Hyper-V Manager – Hyper-V Settings – Virtual Hard Disks and Virtual Machines.
Alternatively, you can run the following PowerShell code to change the default locations for Hyper-V VMs and VHDs:
#Set Default HYPER-V locations SET-VMHOST -virtualharddiskpath $Script:vmVHDLocation\LocalVMs\VHDs SET-VMHOST -virtualmachinepath $Script:vmVHDLocation\LocalVMs\VMs
3. Specify a VM Generation type
This is an important decision and one that is not easily changed later (in some cases it is impossible to change). You may want to familiarize yourself with the differences between the two by referencing the following Technet articles on the subject:
Generation 2 Virtual Machine Overview
Deciding When To Use Generation 1 or Generation 2 Virtual Machines with Hyper-V
The general idea is that if you’re running Windows 8/8.1/2012/2012R2 or newer, you will be choosing Generation 2.
Anything older and you will be running Generation 1.
4. Specify the startup memory
This is one setting where you don’t get nearly as much control via the GUI. Here are a couple of case scenarios to help explain this screen:
Scenario #1: Startup Memory – 1024MB – Dynamic Memory Unchecked
Startup Memory: 1GB Minimum Memory: 1GB, Max Memory: 1GB
Scenario #2: Startup Memory – 1024MB – Dynamic Memory Checked
Startup Memory: 1GB Minimum Memory: 1GB, Max Memory: 1024GB (the GUI default sets it to this)
To adjust these further you will have to wait until the VM is created, right click on the new VM – Settings – Memory
5. Create the virtual hard disk
Again, the Wizard will place this in the default location (which you can change) with a default 127GB .vhd/.vhdx file. I find that typically this is too large and 60GB for a system drive is generally sufficient.
6. Determine how you will install the OS
Here you get an opportunity to either defer the OS installation to a later time, or to immediately configure it for ISO boot or PXE boot.
Brilliant! Thank you. I will certainly be using this going forward.
Just came across this while re-creating my own script. You’ve implemented a lot of the changes I was going to make and some extras so thanks for doing the legwork and sharing, you just saved my a morning of scripting… One simple thing I added at the end promotes the VM to a
cluster role. Just added it the the very end.
Get-VM -Name $vmName | Add-ClusterVirtualMachineRole
thanks, for the wonderful script, just 1 question as to why there are 2 network adapters are being created
Thank you! This is what I wanted. However, I’ve been running into something like this after running your code:
“`
Cannot bind parameter ‘Generation’. Cannot convert value “â€NewVHDPath C:\Users\YChan14\Documents\hyper-v\vhd\testVM.vhdx â€NewVHDSizeBytes” to type “System.Int16”. Error: “Input string was not in a correct format.”
“`
Do you have any idea why this is happening?