I am iniating a project where I am going to have to setup potentially 2-300 new VMs to upgrade existing infrastructure.
They’re all based on Hyper V so it makes sense to script this so it can be quickly deployed either one at a time or in bulk with the ISOs attached and ready to go!
So this would be better supported by a VHDX with a SYSPrep already created and a working OS in there so that the machine could be quickly stood up, patched and ready to roll!
That’ll be in a later itteration.
Onward… with the code!
[powershell]# Script to Create and Deploy a HyperV Guest from onscreen prompts or from CSV.
# CSV format:
# name,vcpu,mem,memtype,newvhd,vhdtype,switchname,vlanid,vmisopath,newvhdpath,path,generation
Push-Location (Split-Path -path $MyInvocation.MyCommand.Definition -Parent)
$manual = New-Object System.Management.Automation.Host.ChoiceDescription '&Manual', 'Create Manually'
$csv = New-Object System.Management.Automation.Host.ChoiceDescription '&CSV', 'Create from CSV'
$options = [System.Management.Automation.Host.ChoiceDescription[]]($manual, $CSV)
$title = 'HyperV Guest Creation'
$message = 'Hello, would you like a VM manually or from a CSV?'
$result = $host.ui.PromptForChoice($title, $message, $options, 0)
switch ($result)
{
0 { 'Create Manually'
$name = Read-Host -Prompt "New VM Name"
$vcpu = Read-Host "How Many CPUs (Numeral Only)"
$mem = Read-Host -Prompt "Memory Required (GB) (Numeral Only)"
$memType = Read-Host "Dynamic Memory?(Y/N)"
$NewVHD = Read-Host -Prompt "Disk Size (GB) (Numeral Only)"
$vhdType = Read-Host "Dynamic VHD?(Y/N)"
$SwitchName = Read-Host -Prompt "Switch Name"
$vLANid = Read-Host -Prompt "VLAN (Numeral Only)"
$vmISOPath = "C:\ClusterStorage\Volume1\ISO\SW_DVD9_Win_Server_STD_CORE_2019_1909.4_64Bit_English_DC_STD_MLF_X22-29333.iso"
$NewVHDPath = "C:\ClusterStorage\Volume1\Virtual Hard Disks\"+$name+"\"+$name+"-OSDisk.vhdx"
$Path = "C:\ClusterStorage\Volume1\Virtual Machines\"
$Generation = 2
Write-Host "Confirm Below is correct:" -foregroundcolor black -BackgroundColor Yellow
Write-Host "Name : $Name"
Write-Host "CPU : $vcpu"
Write-Host "Memory : $mem GB. Dynamic = $memtype"
Write-Host "Switch Name : $Switchname"
Write-Host "VLAN : $vlanID"
Write-Host "Disk Size : $newVHD GB. Dynamic = $vhdType"
Write-Host "ISO : `n $vmisopath"
Write-Host "Generation : $generation"
Write-Host "VM Path : `n $path"
Write-Host "VHD Path : `n $newvhdpath"
Pause
# Create VM with options Above.
New-VM -Name $Name -Path $Path -Generation $Generation
# Set Amount of CPU
Set-VMProcessor -VMname $name -Count $vcpu
# Set Memory and Specify Fixed or Dynamic
If($memType -eq 'N'){
#Convert RAM to Bytes
[int64]$mem = 1GB*$mem
Set-VMMemory -VMName $name -StartupBytes $mem -DynamicMemoryEnabled $false}
Else{
#Convert RAM to Bytes
[int64]$mem = 1GB*$mem
Set-VMMemory -VMName $name -StartupBytes $mem -DynamicMemoryEnabled $True}
# Set VM Network Details
Connect-VMNetworkAdapter -VMName $name -SwitchName $SwitchName
Set-VMNetworkAdapterVlan -VMName $name -Access -VlanId $vLANid
# Set Virtual Disk Drives
If($vhdType -eq 'N'){
#Convert Size to Bytes
[int64]$newVHD = 1GB*$NewVHD
New-VHD -path $NewVHDPath -SizeBytes $newVHD -fixed}
Else{
#Convert Size to Bytes
[int64]$newVHD = 1GB*$NewVHD
New-VHD -path $NewVHDPath -SizeBytes $newVHD -dynamic}
#Attach to VM
Add-VMHardDiskDrive -VMName $name -path $NewVHDPath
# Set Boot Media
Add-VMDvdDrive -VMName $Name -Path $vmISOPath
Set-VMDvdDrive -VMName $name -Path $vmISOPath
# Set 1st Boot Device to DVD
$vm = Get-VM -Name $name
$firmware = Get-VMFirmware -VM $vm
$bootorder = $firmware.BootOrder
foreach ($bootdev in $bootorder) {
if ($bootdev.FirmwarePath.Contains("Scsi(0,1)")) {
Set-VMFirmware -FirstBootDevice $bootdev -VM $vm
}
}
# Start VM
Start-VM -VMName $name}
1 { 'Create from CSV'
$CSV = Import-CSV C:\Users\adminno\Documents\NewServers.csv
ForEach($guest in $csv){
$name = $guest.name
$vcpu = $guest.vcpu
$mem = $guest.mem
$memType = $guest.memtype
$NewVHD = $guest.newVHD
$vhdType = $guest.vhdType
$SwitchName = $guest.switchname
$vLANid = $guest.vlanid
$vmISOPath = $guest.vmISOpath
$NewVHDPath = $guest.NewVHDPath+$name+"\"+$name+"-OSDisk.vhdx"
$Path = $guest.path
$Generation = $guest.generation
Write-Host "Confirm Below is correct:" -foregroundcolor black -BackgroundColor Yellow
Write-Host "Name : $Name"
Write-Host "CPU : $vcpu"
Write-Host "Memory : $mem GB. Dynamic = $memtype"
Write-Host "Switch Name : $Switchname"
Write-Host "VLAN : $vlanID"
Write-Host "Disk Size : $newVHD GB. Dynamic = $vhdType"
Write-Host "ISO : `n $vmisopath"
Write-Host "Generation : $generation"
Write-Host "VM Path : `n $path"
Write-Host "VHD Path : `n $newvhdpath"
Pause
# Create VM with options Above.
New-VM -Name $Name -Path $Path -Generation $Generation
# Set Amount of CPU
Set-VMProcessor -VMname $name -Count $vcpu
# Set Memory and Specify Fixed or Dynamic
If($memType -eq 'N'){
#Convert RAM to Bytes
[int64]$mem = 1GB*$mem
Set-VMMemory -VMName $name -StartupBytes $mem -DynamicMemoryEnabled $false}
Else{
#Convert RAM to Bytes
[int64]$mem = 1GB*$mem
Set-VMMemory -VMName $name -StartupBytes $mem -DynamicMemoryEnabled $True}
# Set VM Network Details
Connect-VMNetworkAdapter -VMName $name -SwitchName $SwitchName
Set-VMNetworkAdapterVlan -VMName $name -Access -VlanId $vLANid
# Set Virtual Disk Drives
If($vhdType -eq 'N'){
#Convert Size to Bytes
[int64]$newVHD = 1GB*$NewVHD
New-VHD -path $NewVHDPath -SizeBytes $newVHD -fixed}
Else{
#Convert Size to Bytes
[int64]$newVHD = 1GB*$NewVHD
New-VHD -path $NewVHDPath -SizeBytes $newVHD -dynamic}
#Attach to VM
Add-VMHardDiskDrive -VMName $name -path $NewVHDPath
# Set Boot Media
Add-VMDvdDrive -VMName $Name -Path $vmISOPath
Set-VMDvdDrive -VMName $name -Path $vmISOPath
# Set 1st Boot Device to DVD
$vm = Get-VM -Name $name
$firmware = Get-VMFirmware -VM $vm
$bootorder = $firmware.BootOrder
foreach ($bootdev in $bootorder) {
if ($bootdev.FirmwarePath.Contains("Scsi(0,1)")) {
Set-VMFirmware -FirstBootDevice $bootdev -VM $vm
}
}
# Start VM
Start-VM -VMName $name}
}
}
[/powershell]

