Powershell – Single or Bulk add new HyperV VMs

Powershell – Single or Bulk add new HyperV VMs

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]

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *