page hit counter
Welcome to MSDN Blogs Sign in | Join | Help

Taylor Brown's Blog

Test Lead for Windows Core OS Division on the Hyper-V Team.

Syndication

News

Welcome to the professional blog of Taylor Brown.  I am a test lead on the core virtualization team (Hyper-V) at Microsoft.

This blog will contain information about virtualization, Microsoft, Hyper-V, operating systems, testing, and whatever else I end up talking about...

 

Standard Microsoft Disclaimer:
"This posting is provided "AS IS" with no warranties, and confers no rights. You assume all risk for your use."

-Taylor Brown


PDC Teaser – Attaching a VHD to A Virtual Machine

PDC is just around the corner now – I am giving the dry run of my talk tomorrow morning, so of course I am working on my demo’s today…  Just to give you a bit of a teaser here’s one of the scripts that I am using in one of my demo’s…

This script will take a VHD and attach it to the second port of the first IDE controller, just change the address numbers and you can change where it get’s attached.


Note that I am using the ProcessWMIJob function from Hyper-V WMI: Rich Error Messages for Non-Zero ReturnValue (no more 32773, 32768, 32700…)

$vhdToMount = "c:\test.vhd"
$HyperVGuest = "ScriptTest"

$VMManagementService = Get-WmiObject -class "Msvm_VirtualSystemManagementService" -namespace "root\virtualization"
$Vm = Get-WmiObject -Namespace "root\virtualization" -Query "Select * From Msvm_ComputerSystem Where ElementName='$HyperVGuest'"
$VMSettingData = Get-WmiObject -Namespace "root\virtualization" -Query "Associators of {$Vm} Where ResultClass=Msvm_VirtualSystemSettingData AssocClass=Msvm_SettingsDefineState"
$VmScsiController = (Get-WmiObject -Namespace "root\virtualization" -Query "Associators of {$VMSettingData} Where ResultClass=Msvm_ResourceAllocationSettingData AssocClass=Msvm_VirtualSystemSettingDataComponent" | `
                       
where-object {$_.ResourceSubType -eq "Microsoft Emulated IDE Controller" -and $_.Address -eq 0})
                        
$DiskAllocationSetting = Get-WmiObject -Namespace "root\virtualization" -Query "SELECT * FROM Msvm_AllocationCapabilities WHERE ResourceSubType = 'Microsoft Synthetic Disk Drive'"
$DefaultDiskDrive = (Get-WmiObject -Namespace "root\virtualization" -Query "Associators of {$DiskAllocationSetting} Where ResultClass=Msvm_ResourceAllocationSettingData AssocClass=Msvm_SettingsDefineCapabilities" | `
                       
where-object {$_.InstanceID -like "*Default"})
$DefaultDiskDrive.Parent = $VmScsiController.__Path
$DefaultDiskDrive.Address = 1
$NewDiskDrive = ($VMManagementService.AddVirtualSystemResources($Vm.__Path, $DefaultDiskDrive.PSBase.GetText(1)) | ProcessWMIJob $VMManagementService "AddVirtualSystemResources").NewResources

$DiskAllocationSetting = Get-WmiObject -Namespace "root\virtualization" -Query "SELECT * FROM Msvm_AllocationCapabilities WHERE ResourceSubType = 'Microsoft Virtual Hard Disk'"
$DefaultHardDisk = (Get-WmiObject -Namespace "root\virtualization" -Query "Associators of {$DiskAllocationSetting} Where ResultClass=Msvm_ResourceAllocationSettingData AssocClass=Msvm_SettingsDefineCapabilities" | `
                       
where-object {$_.InstanceID -like "*Default"})
                        
$DefaultHardDisk.Parent = $NewDiskDrive
$DefaultHardDisk.Connection = $vhdToMount

$VMManagementService.AddVirtualSystemResources($Vm.__Path, $DefaultHardDisk.PSBase.GetText(1)) | ProcessWMIJob $VMManagementService "AddVirtualSystemResources"

 

Taylor Brown
Hyper-V Integration Test Lead
http://blogs.msdn.com/taylorb

clip_image001

Published Monday, October 13, 2008 3:55 PM by taylorb

Filed under: , ,

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# re: PDC Teaser – Attaching a VHD to A Virtual Machine @ Monday, December 08, 2008 8:47 PM

Cool, now how about a C# sample?

===========================================================

Take a look at http://msdn.microsoft.com/en-us/library/cc160705(VS.85).aspx

-taylor

Mark Turner

# re: PDC Teaser – Attaching a VHD to A Virtual Machine @ Tuesday, December 09, 2008 2:00 PM

Yeh, I've tried that sample, but having troubles translating that to virtual hard drives.  They seem a bit more complicated???  On a side note the referenced sample works great, just not sure how to specify the "network" to attach the nic.

 ==========================================================
I start my "vacation" next week - I am planning on trying to get cought up on blog posts and I'll add this to the list.

-Taylor
p.s. yes that is my idea of a vacation.

Mark Turner

# re: PDC Teaser – Attaching a VHD to A Virtual Machine @ Monday, December 15, 2008 8:38 AM

Could you please provide the C# version of above code? We are having problems in executing the MSDN code. Thanks.

Siva

# re: PDC Teaser – Attaching a VHD to A Virtual Machine @ Tuesday, December 16, 2008 1:57 PM

Interesting way to vacation, guess you're a computer geek like the rest of us :-(

OK, I figured out the same in C#...guess the secret was to understand how the WMI objects are all related.

I did this by creating a VirtualMachineList utility that attempts to dump WMI objects that are

related to an existing virtual machine, that helped tons.  

Anyway, following is a sample of how to attach a virtual hard drive (.VHD) to a virtual machine's SCSI controller in C# ...

This sample uses utilities found at http://msdn.microsoft.com/en-us/library/cc723869(VS.85).aspx

using System;

using System.Management;

using System.Collections;

using System.Text;

...

Interesting way to vacation, guess you're a computer geek like the rest of us :-(

OK, I figured out the same in C#...guess the secret was to understand how the WMI objects are all related.

I did this by creating a VirtualMachineList utility that attempts to dump WMI objects that are

related to an existing virtual machine, that helped tons.  

Anyway, following is a sample of how to attach a virtual hard drive (.VHD) to a virtual machine's SCSI controller in C#...

This sample uses utilities found at http://msdn.microsoft.com/en-us/library/cc723869(VS.85).aspx

using System;

using System.Management;

using System.Collections;

using System.Text;

...

//********************************************************************************************************************

static UInt32 AddVirtualSystemResource(ManagementScope scope, ManagementObject virtualMachine, ManagementObject resourceToAdd, ref ManagementObject resourceAdded)

{

  UInt32 result = 0;

  ManagementObject[] resourcesToAddList = new ManagementObject[1];

  resourcesToAddList[0] = resourceToAdd;

  string[] resourcesAddedList = null;

  result = AddVirtualSystemResources(scope, virtualMachine, resourcesToAddList, ref resourcesAddedList);

  if ((result == 0) && (resourcesAddedList != null))

  {

      resourceAdded = new ManagementObject(scope, new ManagementPath(resourcesAddedList[0]), null);

  }

  return result;

}

//********************************************************************************************************************

static UInt32 AddVirtualSystemResources(ManagementScope scope, ManagementObject virtualMachine, ManagementObject[] resourcesToAdd, ref string[] resourcesAdded)

{

  UInt32 result = 0;

  ManagementObject virtualSystemService = Utility.GetServiceObject(scope, "Msvm_VirtualSystemManagementService");

  ManagementBaseObject inParams = virtualSystemService.GetMethodParameters("AddVirtualSystemResources");

  int idx = resourcesToAdd.GetLength(0);

  string[] resourcesToAddString = new string[idx];

  g_dumpData.DumpString("------------------------------------------------------------------------------");

  g_dumpData.DumpString("AddedVirtualSystemResources():");

  idx = 0;

  foreach (ManagementObject resource in resourcesToAdd)

  {

      resourcesToAddString[idx++] = resource.GetText(TextFormat.CimDtd20);

      g_dumpData.DumpString("Type=" + resource["ResourceType"] + ", Subtype=" + resource["ResourceSubtype"]);

      if (resource["Connection"] != null)

      {

          foreach (string connection in (string[])resource["Connection"])

          {

              g_dumpData.DumpString("Connection=" + connection);

          }

      }

  }

  inParams["ResourcesettingData"] = resourcesToAddString;

  inParams["TargetSystem"] = virtualMachine.Path.Path;

  resourcesAdded = null;

  ManagementBaseObject outParams = virtualSystemService.InvokeMethod("AddVirtualSystemResources", inParams, null);

  resourcesAdded = null;

  if ((UInt32)outParams["ReturnValue"] == ReturnCode.Started)

  {

      if (Utility.JobCompleted(outParams, scope))

      {

          result = 0;

          resourcesAdded = (string[])outParams["NewResources"];

          //syntheticNic = new ManagementObject(addedResources[0]);

          g_dumpData.DumpString("Resource(s) were added successfully.");

      }

      else

      {

          result = (UInt32)outParams["ReturnValue"];

          g_dumpData.DumpString("Failed to add resource(s)");

      }

  }

  else if ((UInt32)outParams["ReturnValue"] == ReturnCode.Completed)

  {

      result = 0;

      resourcesAdded = (string[])outParams["NewResources"];

      //syntheticNic = new ManagementObject(addedResources[0]);

      g_dumpData.DumpString("Resource(s) were added successfully.");

  }

  else

  {

      result = (UInt32)outParams["ReturnValue"];

      g_dumpData.DumpString("Add virtual system resource(s) failed with error:" + outParams["ReturnValue"]);

  }

  inParams.Dispose();

  outParams.Dispose();

  return result;

}

//********************************************************************************************************************

static UInt32 AddVirtualHarddrive(ManagementScope scope, ManagementObject virtualMachine, string newVHDParams)

{

  UInt32 result = 0;

  string vhdToMount = @"E:\test.vhd";

  ManagementObject virtualSystemService = Utility.GetServiceObject(scope, "Msvm_VirtualSystemManagementService");

  ManagementObject vmSettingsData = Utility.GetVirtualSystemSettingData(virtualMachine);

  // Locate the SCSI controller on the vm

  ManagementObject vmDiskController = Utility.GetResourceAllocationsettingData(virtualMachine, ResourceType.ParallelSCSIHBA, ResourceSubType.ParallelSCSIHBA, null);

  if (vmDiskController == null)

  {

      // SCSI controller does not exits on the vm, create it

      ManagementObject vmDiskControllerDefault = Utility.GetResourceAllocationsettingDataDefault(scope, ResourceType.ParallelSCSIHBA, ResourceSubType.ParallelSCSIHBA, null);

      result = AddVirtualSystemResource(scope, virtualMachine, vmDiskControllerDefault, ref vmDiskController);

  }

  // Create the Synthetic disk drive on the SCSI controller

  int SCSIfreeLocation = -1;

  LocateFreeSCSILocation(scope, vmDiskController.Path.ToString(), ref SCSIfreeLocation);

  ManagementObject syntheticDiskDriveDefault = Utility.GetResourceAllocationsettingDataDefault(scope, ResourceType.Disk, ResourceSubType.DiskSynthetic, null);

  syntheticDiskDriveDefault["Parent"] = vmDiskController.Path;

  syntheticDiskDriveDefault["Address"] = SCSIfreeLocation;

  syntheticDiskDriveDefault["Limit"] = 1; // Not sure what this does???

  ManagementObject newDiskDrive = null;

  result = AddVirtualSystemResource(scope, virtualMachine, syntheticDiskDriveDefault, ref newDiskDrive);

  // Now create a new virtual hard disk, associate it with the new synthetic disk drive and attach the virtual hard drive to the virtual machine

  ManagementObject vhdDefault = Utility.GetResourceAllocationsettingDataDefault(scope, ResourceType.StorageExtent, ResourceSubType.VHD, null);

  vhdDefault["Parent"] = newDiskDrive;

  string[] connection = new string[1];

  connection[0] = vhdToMount;

  vhdDefault["Connection"] = connection;

  ManagementObject newVHD = null;

  result = AddVirtualSystemResource(scope, virtualMachine, vhdDefault, ref newVHD);

  return result; // maybe return newVHD

}

//********************************************************************************************************************

Mark Turner

# re: PDC Teaser – Attaching a VHD to A Virtual Machine @ Thursday, December 18, 2008 11:32 AM

Mark,

     in your C# example you have LocateFreeSCSILocation(scope, vmDiskController.Path.ToString(), ref SCSIfreeLocation);

but "LocateFreeSCSILocation" doesn’t exist anywhere else in the context?

-Don

Don V.

Leave a Comment

(required) 
required 
(required) 

  
Enter Code Here: Required
Page view tracker