Attaching a VHD To A VM Using The Hyper-V WMI V2 Namespace
Relating to all my recent posts on the WMI V2 namespace here’s another one for attaching a VHD to a VM. It looks like a lot of code but a lot of it is duplicated (so if you where writing an application you can factor it pretty easily). There are effectively two steps to this process, the first is to add a synthetic disk drive and the second is to connect that disk drive to the actual VHD.
Attaching A VHD To A VM
$vmName = "Test"
$vhdPath = "d:\vms\Test.vhdx"
#Retrieve the Hyper-V Management Service, ComputerSystem class for the VM and the VM’s SettingData class.
$Msvm_VirtualSystemManagementService = Get-WmiObject -Namespace root\virtualization\v2 `
-Class Msvm_VirtualSystemManagementService
$Msvm_ComputerSystem = Get-WmiObject -Namespace root\virtualization\v2 `
-Class Msvm_ComputerSystem -Filter "ElementName='$vmName'"
$Msvm_VirtualSystemSettingData = ($Msvm_ComputerSystem.GetRelated("Msvm_VirtualSystemSettingData", `
"Msvm_SettingsDefineState", `
$null, `
$null, `
"SettingData", `
"ManagedElement", `
$false, $null) | % {$_})
#Retrieve the default (primordial) resource pool for Synthetic Disk Drive’s
$Msvm_ResourcePool = Get-WmiObject -Namespace root\virtualization\v2 -Class Msvm_ResourcePool `
-Filter "ResourceSubType = 'Microsoft:Hyper-V:Synthetic Disk Drive' and Primordial = True"
#Retrieve the AllocationCapabilities class for the Resource Pool
$Msvm_AllocationCapabilities = ($Msvm_ResourcePool.GetRelated("Msvm_AllocationCapabilities", `
"Msvm_ElementCapabilities", `
$null, `
$null, `
$null, `
$null, `
$false, `
$null) | % {$_})
#Query the relationships on the AllocationCapabilities class and find the default class (ValueRole = 0)
$Msvm_SettingsDefineCapabilities = ($Msvm_AllocationCapabilities.GetRelationships(`
"Msvm_SettingsDefineCapabilities") | Where-Object {$_.ValueRole -eq "0"})
#The PartComponent is the Default Msvm_StorageAllocationSettingData class values
$Msvm_StorageAllocationSettingDataTemplate = [WMI]$Msvm_SettingsDefineCapabilities.PartComponent
#Clone the default settings
$Msvm_StorageAllocationSettingData = $Msvm_StorageAllocationSettingDataTemplate.Clone()
#Find the IDE Controller To Connect The Disk To
$IdeController = $Msvm_VirtualSystemSettingData.GetRelated("Msvm_ResourceAllocationSettingData") | Where-Object {
($_.ResourceType -eq 5) -and ($_.ResourceSubType -eq "Microsoft:Hyper-V:Emulated IDE Controller") -and ($_.Address -eq 0)}
#Specify the disk drives connection point and address (location on the controller)
$Msvm_StorageAllocationSettingData.Parent = $IdeController
$Msvm_StorageAllocationSettingData.AddressOnParent = 0
#Add the drive to the VM and save the resulting disk drive path
$diskDriveResource = ($Msvm_VirtualSystemManagementService.AddResourceSettings($Msvm_VirtualSystemSettingData, `
$Msvm_StorageAllocationSettingData.GetText(2)).ResultingResourceSettings)
#Retrieve the default (primordial) resource pool for Virtual Hard Disk’s
$Msvm_ResourcePool = Get-WmiObject -Namespace root\virtualization\v2 -Class Msvm_ResourcePool `
-Filter "ResourceSubType = 'Microsoft:Hyper-V:Virtual Hard Disk' and Primordial = True"
#Retrieve the AllocationCapabilities class for the Resource Pool
$Msvm_AllocationCapabilities = ($Msvm_ResourcePool.GetRelated("Msvm_AllocationCapabilities", `
"Msvm_ElementCapabilities", `
$null, `
$null, `
$null, `
$null, `
$false, `
$null) | % {$_})
#Query the relationships on the AllocationCapabilities class and find the default class (ValueRole = 0)
$Msvm_SettingsDefineCapabilities = ($Msvm_AllocationCapabilities.GetRelationships(`
"Msvm_SettingsDefineCapabilities") | Where-Object {$_.ValueRole -eq "0"})
#The PartComponent is the Default Msvm_StorageAllocationSettingData class values
$Msvm_StorageAllocationSettingDataTemplate = [WMI]$Msvm_SettingsDefineCapabilities.PartComponent
#Clone the default settings
$Msvm_StorageAllocationSettingData = $Msvm_StorageAllocationSettingDataTemplate.Clone()
#Specify the VHD's Disk Drive and Path (location on the controller)
$Msvm_StorageAllocationSettingData.Parent = $diskDriveResource
$Msvm_StorageAllocationSettingData.HostResource = @($vhdPath)
#Add the VHD to the disk drive
$Msvm_VirtualSystemManagementService.AddResourceSettings($Msvm_VirtualSystemSettingData, `
$Msvm_StorageAllocationSettingData.GetText(2))
-Taylor Brown
-Program Manager, Hyper-V
Comments
Anonymous
August 26, 2013
The comment has been removedAnonymous
August 26, 2013
The comment has been removedAnonymous
September 03, 2013
The comment has been removedAnonymous
October 28, 2013
Hey guys, I am trying to convert the same script to c# code However I got stucked at [WMI]$Msvm_SettingsDefineCapabilities.PartComponent . How to acheive this . I mean $Msvm_SettingsDefineCapabilities.PartComponent is a string object and how to convert it to WMI.Anonymous
April 20, 2014
Any one please give Suggestion to add SCSI Hard diskAnonymous
August 04, 2014
Hello everyone - I'm trying to convert this script to java using j-interop. Any pointers would be appreciated.Anonymous
August 11, 2015
Do you have this in C#, I've been having a very difficult time attempting to convert it to C#.