Private/Add-VM.ps1
function Add-VM { Param ( [Parameter(Mandatory)] [VM]$VM, [Parameter(Mandatory)] [HyperVServer]$HyperVServer, [DeploymentOptions]$DeploymentOptions ) $NewVMParams = @{ Name = $VM.Name MemoryStartupBytes = [int64][scriptblock]::Create($VM.MemoryStartupBytes).Invoke()[0] ComputerName = $HyperVServer.Name } if ($HyperVServer.SwitchName) { $NewVMParams.Add("SwitchName", $HyperVServer.SwitchName) } $SetVMParams = @{ Name = $VM.Name ProcessorCount = $VM.ProcessorCount MemoryMaximumBytes = [int64][scriptblock]::Create($VM.MemoryMaximumBytes).Invoke()[0] ComputerName = $HyperVServer.Name DynamicMemory = $true } if ($VM.CheckpointType) { $SetVMParams.Add("CheckpointType", $VM.CheckpointType) } New-VM @NewVMParams | out-null Set-VM @SetVMParams if ($HyperVServer.VMHardDiskPath) { $diskPath = $HyperVServer.VMHardDiskPath + "\" + $VM.Name Invoke-Command -ComputerName $HyperVServer.Name { if (!(Test-Path -Path $using:diskPath)) { New-Item -ItemType directory -Path $using:diskPath -Force } } if ($HyperVServer.GoldenImagePath) { Write-Verbose "Copying golden image" $path = $HyperVServer.GoldenImagePath if ($HyperVServer.GoldenImagePath.StartsWith("\\")) { $uncCreds = invoke-expression -Command $VM.UNCCredentialScript if ($uncCreds -and $uncCreds.GetType().Name -eq 'PSCredential') { Write-Verbose "Golden Image UNC Path detected - setting up credentials" Invoke-Command -ComputerName $HyperVServer.Name -ScriptBlock { Register-PSSessionConfiguration -Name HyperDeploy -RunAsCredential $using:uncCreds -Force } Write-Verbose "Waiting for WinRM service to be ready" Start-Sleep -Seconds 30 Write-Verbose "Copying Golden Image" Invoke-Command -ConfigurationName HyperDeploy -ComputerName $HyperVServer.Name { $localPath = $using:path $temp = $env:TEMP $extension = $localPath.Split('.')[-1] $tempGI = "$temp\HyperDeployGoldenImage.$extension" if (!(Test-Path "filesystem::$localPath")) { throw "$localPath does not exist" } if (!(Test-Path $tempGI)) { Write-Verbose "Golden Image Path is UNC, caching locally." Copy-Item "filesystem::$localPath" -Destination $tempGI } Copy-Item $tempGI -Destination "$using:diskPath\Disk.$extension" } } else { throw "UNCCredentialScript did not return a valid PSCredential object" } } elseif ($HyperVServer.GoldenImagePath.StartsWith("http")) { $temp = $env:TEMP $extension = $HyperVServer.GoldenImageExtension $tempGI = "$temp\HyperDeployGoldenImage.$extension" if ($HyperVServer.GoldenImagePath.Contains("drive.google")) { $p = & { python -V } 2>&1 if ($p -is [System.Management.Automation.ErrorRecord]) { throw "Google Drive file download requires Python and Pip to be installed" } else { pip install gdown Set-Location $temp gdrive $HyperVServer.GoldenImagePath -O "HyperDeployGoldenImage.$extension" } } else { Invoke-WebRequest -Uri $HyperVServer.GoldenImagePath -OutFile $tempGI } } else { Invoke-Command -ComputerName $HyperVServer.Name { $localPath = $using:path if (!(Test-Path $localPath)) { throw "$localPath does not exist" } $extension = $localPath.Split('.')[-1] Copy-Item $localPath -Destination "$using:diskPath\Disk.$extension" } } } elseif ($VM.NewVMDiskSizeBytes) { $NewVHDParams = @{ Path = "$diskPath\Disk.vhdx" SizeBytes = [int64][scriptblock]::Create($VM.NewVMDiskSizeBytes).Invoke()[0] ComputerName = $HyperVServer.Name } New-VHD @NewVHDParams } Invoke-Command -ComputerName $HyperVServer.Name { $disk = Get-ChildItem -Path $using:diskPath -Filter "Disk.*" -Recurse -Force $name = $using:VM.Name $AddVMHardDiskDriveParams = @{ Path = $disk[0].FullName VMName = $name } Add-VMHardDiskDrive @AddVMHardDiskDriveParams } } if ($DeploymentOptions -and $DeploymentOptions.StartAfterCreation) { Write-Verbose "Starting VM" $StartVMParams = @{ Name = $VM.Name ComputerName = $HyperVServer.Name } Start-VM @StartVMParams if ($VM.Provisioning) { $InitializeVMParams = @{ VM = $VM HyperVServer = $HyperVServer } Initialize-VM @InitializeVMParams } } } |