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]