I had a conversation with a VMware customer the other day and they were asking if there was a way to automate the addition and removal of a vGPU to a VM dynamically on a requested or scheduled basis, VMGuru has a great post here on what exactly a vGPU is, I highly recommend reading it.
They asked for a PowerCLI command or function to configure the VM graphics card, specifically to assign a vGPU resources to the VM, a desktop user’s VM is configured by default with vSGA (to not tie up vGPU resources) then the user schedules the vGPU resource for a specific time frame using their end user portal, before the scheduled vGPU reservation time frame the user is logged out and the script would kick in. The script would reconfigure the VM settings and assigns a vGPU profile to it, the equivalent of what is being done in the UI as follows:
The desktop user then logs in and now the VM is configured with the vGPU resource, after a little scripting and testing on an environment with a NVIDIA GRID I was able to provide the below script.
As per the normal I though I would blog it as it may be useful in the future to someone.
Sample output of the script running
The Code
Function Get-GPUProfile { Param ($vmhost) $VMhost = Get-VMhost $VMhost $vmhost.ExtensionData.Config.SharedPassthruGpuTypes } Function Get-vGPUDevice { Param ($vm) $VM = Get-VM $VM $vGPUDevice = $VM.ExtensionData.Config.hardware.Device | Where { $_.backing.vgpu} $vGPUDevice | Select Key, ControllerKey, Unitnumber, @{Name="Device";Expression={$_.DeviceInfo.Label}}, @{Name="Summary";Expression={$_.DeviceInfo.Summary}} } Function Remove-vGPU { Param ( [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true,Position=0)] $VM, [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true,Position=1)] $vGPUDevice ) $ControllerKey = $vGPUDevice.controllerKey $key = $vGPUDevice.Key $UnitNumber = $vGPUDevice.UnitNumber $device = $vGPUDevice.device $Summary = $vGPUDevice.Summary $VM = Get-VM $VM $spec = New-Object VMware.Vim.VirtualMachineConfigSpec $spec.deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec[] (1) $spec.deviceChange[0] = New-Object VMware.Vim.VirtualDeviceConfigSpec $spec.deviceChange[0].operation = 'remove' $spec.deviceChange[0].device = New-Object VMware.Vim.VirtualPCIPassthrough $spec.deviceChange[0].device.controllerKey = $controllerkey $spec.deviceChange[0].device.unitNumber = $unitnumber $spec.deviceChange[0].device.deviceInfo = New-Object VMware.Vim.Description $spec.deviceChange[0].device.deviceInfo.summary = $summary $spec.deviceChange[0].device.deviceInfo.label = $device $spec.deviceChange[0].device.key = $key $_this = $VM | Get-View $nulloutput = $_this.ReconfigVM_Task($spec) } Function New-vGPU { Param ($VM, $vGPUProfile) $VM = Get-VM $VM $spec = New-Object VMware.Vim.VirtualMachineConfigSpec $spec.deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec[] (1) $spec.deviceChange[0] = New-Object VMware.Vim.VirtualDeviceConfigSpec $spec.deviceChange[0].operation = 'add' $spec.deviceChange[0].device = New-Object VMware.Vim.VirtualPCIPassthrough $spec.deviceChange[0].device.deviceInfo = New-Object VMware.Vim.Description $spec.deviceChange[0].device.deviceInfo.summary = '' $spec.deviceChange[0].device.deviceInfo.label = 'New PCI device' $spec.deviceChange[0].device.backing = New-Object VMware.Vim.VirtualPCIPassthroughVmiopBackingInfo $spec.deviceChange[0].device.backing.vgpu = "$vGPUProfile" $vmobj = $VM | Get-View $reconfig = $vmobj.ReconfigVM_Task($spec) if ($reconfig) { $ChangedVM = Get-VM $VM $vGPUDevice = $ChangedVM.ExtensionData.Config.hardware.Device | Where { $_.backing.vgpu} $vGPUDevice | Select Key, ControllerKey, Unitnumber, @{Name="Device";Expression={$_.DeviceInfo.Label}}, @{Name="Summary";Expression={$_.DeviceInfo.Summary}} } } $VMHost = Get-VMHost 10.114.64.86 $vGPUProfile = Get-GPUProfile -vmhost $VMHost Write-Host "The following vGPU Profiles are available to choose for this host" $vGPUProfile # Choose a profile to use from the list $ChosenvGPUProfile = $vGPUProfile | Where {$_ -eq "grid_m60-4q" } # Get a VM to add it to $VM = Get-VM 3DVM_Win7_20GB_86 Write-Host "Adding the vGPU to $vm" New-vGPU -VM $vm -vGPUProfile $ChosenvGPUProfile # At a later date Read-Host "The device has been added, press enter to remove again" Write-Host "Removing the GPU Devices in $VM" Remove-vGPU -VM $vm -vGPUDevice (Get-vGPUDevice -vm $VM)
I realize this article is five years old, but it was still helpful to me. Thanks for writing it!
I want to add specific vGPU device on a VM, need help on the same.
Just add:
$spec.memoryReservationLockedToMax = $true
Thank for you writing this! Much appreciated! Any chance the “reserve all memory” command could be written into the New-vGPU function?
Alan – thanks! this was super helpful and easy to use! I imported the functions into my profile, so it would follow me anywhere I used Powershell_ISE! Thanks.
Sorry I don’t have a configuration with that, perhaps try onyx for the web client to see if that brings back any help? We also have a cmdlet for pass through devices so try that too
Alan,
This is GREAT!!!! Got any extra spice to get passthrough K1 or K2 assigned via POSH?
Cheers, Matt
Autodesk CloudPC team