# Compulsory variables
$hyperVHost='HYPERV007'
$vmName='WindowsGoldenImage'
$parentDirectory='C:\ClusterStorage\Volume5'
$disk1Size='100GB'
$memoryAllocation='8GB'
$networkSwitch='PublicZone'
$vlan='1005'
$clusterName='DEV-CLUSTER05'
# Optional variables
$disk2Size=$false # false value here means no disk2 creation
$cpuCount=4
$isoDirectory='C:\ClusterStorage\Volume1\_ISOs'
$isoFile="$isoDirectory\SW_DVD9_Win_Server_STD_CORE_2019_64Bit_English_DC_STD_MLF_X21-96581.ISO"
function createNewVm{
param(
$hyperVHost,
$vmName,
$parentDirectory,
$disk1Size='80GB',
$disk2Size=$false,
$memoryAllocation='4GB',
$cpuCount=2,
$isoFile,
$networkSwitch,
$vlan=$false
)
$ErrorActionPreference='Stop'
$vmFolder="$parentDirectory\$vmName"
$vmDisk1="$vmFolder\$vmName`_disk0.vhdx"
$vmDisk2="$vmFolder\$vmName`_disk1.vhdx"
$disk1Size/=1
$memoryAllocation/=1
if($disk2size){$disk2Size/=1}
#Pre-empt this error
#New-VHD : Cannot bind parameter 'SizeBytes'. Cannot convert value GB to type "System.UInt64". Error: "Input string
#was not in a correct format."
#At line:1 char:35
#+ New-VHD -Path $vmDisk1 -SizeBytes $disk1Size -Dynamic
#+ ~~~~~~~~~~
# + CategoryInfo : InvalidArgument: (:) [New-VHD], ParameterBindingException
# + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.Vhd.PowerShell.Cmdlets.NewVhd
#
function confirmation($content,$testValue="I confirm",$maxAttempts=3){
$confirmed=$false;
$attempts=0;
$content|write-host
write-host "Please review this content for accuracy.`r`n"
while ($attempts -le $maxAttempts){
if($attempts++ -ge $maxAttempts){
write-host "A maximum number of attempts have reached. No confirmations received!`r`n"
break;
}
$userInput = Read-Host -Prompt "Please type in this value => $testValue <= to confirm";
if ($userInput.ToLower() -ne $testValue.ToLower()){
cls;
$content|write-host
write-host "Attempt number $attempts of $maxAttempts`: $userInput does not match $testValue. Try again..`r`n"
}else{
$confirmed=$true;
write-host "Confirmed!`r`n";
break;
}
}
return $confirmed;
}
$confirm=confirmation "Please verify these variables for accuracy:`nVM Name`t: $vmName`nVM Folder`t: $vmFolder`nVM Disk1`t: $disk1Size bytes`nVM Disk2`t: $disk2Size bytes`nVM RAM`t: $memoryAllocation bytes`nVM Network`t: $networkSwitch`nVM VLAN`t: $vlan"
if($confirm){
try{
write-host 'Creating VM Folder...'
if (!(test-path $vmFolder)){mkdir $vmFolder -force}
write-host 'Creating virtual hard disk(s)...'
if(!(test-path $vmDisk1)){New-VHD -Path $vmDisk1 -SizeBytes $disk1Size -Dynamic}
if($disk2Size -and !(test-path $vmDisk2)){New-VHD -Path $vmDisk2 -SizeBytes $disk2Size -Dynamic}
write-host 'Creating VM...'
New-VM -Name $vmName `
-MemoryStartupBytes $memoryAllocation `
-BootDevice VHD `
-VHDPath $vmDisk1 `
-Path $vmFolder `
-Generation 2 `
-Switch $networkSwitch
write-host "Adding CPU count as $cpuCount"
SET-VMProcessor –VMName $vmName –count $cpuCount
write-host 'Attaching 2nd disk if necessary'
if($disk2Size){Add-VMHardDiskDrive -VMName $vmName -path $vmDisk2}
write-host "Mapping ISO image to $isoFile..."
Add-VMDvdDrive -VMName $vmName -Path $isoFile
write-host "Checking VLAN assignment $vlan"
if($vlan){Set-VMNetworkAdapterVlan -VMName $vmName -Access -VlanId $vlan}
write-host "Starting VM $vmName..."
Start-VM -Name $vmName
write-host 'Connecting to new VM...'
if ($env:computername -eq $(.{[void]($hyperVHost -match '([\w\-]+)\.{0,1}');$matches[1]})){
invoke-expression "VMConnect.exe $env:computername $vmName"
}
else{
write-host "Please RDP into the $env:computername Hyper-V host to run this command 'VMConnect.exe `$env:computername $vmName'"
}
return $true
}
catch{
write-warning "$($error[0])"
return $false
}
}
else{
write-host 'Cancelled.'
}
}
createNewVm -hyperVHost $hyperVHost -vmName $vmName -parentDirectory $parentDirectory -disk1Size $disk1Size -disk2Size $disk2Size `
-cpuCount $cpuCount -memoryAllocation $memoryAllocation -isoFile $isoFile -networkSwitch $networkSwitch -vlan $vlan
Categories: