Creating Hyper-V VM with PowerShell

I was trying to learn how to create a VM in Windows 2019 Hypervisor with PowerShell. Microsoft Resource was a big help.
Some of things that I started to learn was how to setup VM Switches, enable VLAN, create and configure a VM that would show up in Hyper-V and the settings needed to run.
Reading what others did, I worked through trying to build a PowerShell install Process using resources found on internet, where others had the same questions, I had.
- Identify the VM Switch – I only had one to work with, but I could see where changing the variable to exact name would make sense.
- Server Names – New Server name for the new VM, and the old Server name that I would be replacing gathering information from it.
- Storage path – Place where I would host the VM’s
- Source Location – The location for the VHDX’s that would be used as part of the build process that would be linked together.
- Identify VLAN ID – Identify VLAN ID on system that was being replaced, this was very hard to figure out for what I wanted to do.
- Building the VM
- Create the new VM folder on the destination location.
- Copy the source location to new VM Folder
- Set VM Configurations
- Memory, TPM, CPU, VLAN ID
- Set Automatic checkpoint.
- Remove VMDVD – I wanted to have this removed before adding the new Volumes, it could be added back afterwards if that is what I wanted to
- Copy the additional volumes (VHDX) files to the new VM Folder
- Add New Volumes after Primary Volume is attached to the Hyper-V VM.
- Create Snapshot – Should I need to restore after I started working and had issues.
- Start VM – I still need to work on automating joining to the domain, setting static IP and making sure all volumes are connected to the VM inside the Operating System.
$NICSwitch = (Get-VMSwitch).Name # Hyper-V VM Switch name $VMNames = 'BAT-TECH-VM' # New Server that is replacing or being added to Hyper-V $ReplacingServer = "BAT-TECH-3" # Replacing old Server with a new server $MachinePath = "D:\" # Drive where VM's are created and Stored $DiskPath = "D:\" # Drive where VM's are stored $SmartPagingFilePath = "D:\" $SysprepVHD = "D:\Source\BAT-TECH-DEV.vhdx" # C Drive Sysprepped VHD location $DataVHD = "D:\Source\Data.VHDX" # D Drive added Data Volume $RepositoryVHD = "D:\Source\Repository.VHDX" # E Drive added Repository Volume ############################################################################################################ #Capture VLANID $virtualmachines = $ReplaceServer $vmvlans = Get-VMNetworkAdapterVlan -VMName $virtualmachines $vmnetworkinfo = @() foreach ($virtualmachine in $virtualmachines) { $virtualnetworkadapters = Get-VMNetworkAdapter -VMName $virtualmachine $vmvlans = Get-VMNetworkAdapterVlan -VMName $virtualmachine $vmproperties = New-Object -TypeName PSObject $vmproperties | Add-Member -MemberType NoteProperty -Name VMName -Value $virtualnetworkadapters.vmname $vmproperties | Add-Member -MemberType NoteProperty -Name Name -value $virtualnetworkadapters.Name $vmproperties | Add-Member -MemberType NoteProperty -Name SwitchName -Value $virtualnetworkadapters.switchname $vmproperties | Add-Member -MemberType NoteProperty -Name isLegacy -Value $virtualnetworkadapters.islegacy $vmproperties | Add-Member -MemberType NoteProperty -name VlanList -value $vmvlans.accessvlanid $vmnetworkinfo += $vmproperties } $VLANID = ($vmnetworkinfo | Select-Object VlanList | Format-Table -HideTableHeaders | Out-String | ForEach-Object { $_.Trim() }) $VLANID # Showing that I got the VLAN ID number ############################################################################################################ #Build VM foreach ($VMName IN $VMNames) { Write-Host "Preparing " $VMName MkDir "$Diskpath\$VMName" -ErrorAction SilentlyContinue Copy-Item $SysprepVHD -destination "$DiskPath\$VMName\$VMName.vhdx" New-VM -Name $VMName -path $MachinePath -switchname $NICSwitch -generation 2 -VHDPath "$DiskPath\$VMName\$VMName.vhdx" -MemorystartupBytes 8GB | Out-Null Set-VMKeyProtector -VMName $VMName -NewLocalKeyProtector | Out-Null Enable-VMTPM -VMName $VMName | Out-Null Set-VMProcessor $VMname -Count 4 | Out-Null set-VMNetworkAdapterVlan -VMName "$VMName" -Access -VlanId $VLANID Set-VM -Name $VMName -automaticCheckpointsenabled $false -SmartPagingFilePath "$SmartPagingFilePath\$VMName" -staticmemory | Out-Null Get-VMDvdDrive -VMName $VMName -ControllerNumber 1 | Remove-VMDvdDrive Copy-Item $DataVHD -destination "$DiskPath\$VMName\Data.vhdx" Add-VMHardDiskDrive -VMName $VMName -Path "$DiskPath\$VMName\Data.vhdx" #-ControllerType SCSI -ControllerNumber 1 Copy-Item $RepositoryVHD -destination "$DiskPath\$VMName\Repository.vhdx" Add-VMHardDiskDrive -VMName $VMName -Path "$DiskPath\$VMName\Repository.vhdx" #-ControllerType SCSI -ControllerNumber 2 Checkpoint-vm -name $VMName -SnapShotName '' | Out-Null Start-VM -Name $VMName | Out-Null Write-Host "Starting " $VMName }
Now that I have this, I want to make some changes to streamline it more, put some checks in place to make sure files and resources are available and create a log file for reporting back on creation of VM.
Thanks for reading.