public static MountedDiskInfo GetMountedDiskInfo(string serverName, int driveNumber) { MountedDiskInfo diskInfo = new MountedDiskInfo { DiskNumber = driveNumber }; // find mounted disk using VDS AdvancedDisk advancedDisk = null; Pack diskPack = null; // first attempt Thread.Sleep(3000); HostedSolutionLog.LogInfo("Trying to find mounted disk - first attempt"); FindVdsDisk(serverName, diskInfo.DiskNumber, out advancedDisk, out diskPack); // second attempt if (advancedDisk == null) { Thread.Sleep(20000); HostedSolutionLog.LogInfo("Trying to find mounted disk - second attempt"); FindVdsDisk(serverName, diskInfo.DiskNumber, out advancedDisk, out diskPack); } if (advancedDisk == null) throw new Exception("Could not find mounted disk"); // Set disk address diskInfo.DiskAddress = advancedDisk.DiskAddress; var addressParts = diskInfo.DiskAddress.ParseExact("Port{0}Path{1}Target{2}Lun{3}"); var portNumber = addressParts[0]; var targetId = addressParts[2]; var lun = addressParts[3]; // check if DiskPart must be used to bring disk online and clear read-only flag bool useDiskPartToClearReadOnly = false; if (ConfigurationManager.AppSettings[Constants.CONFIG_USE_DISKPART_TO_CLEAR_READONLY_FLAG] != null) useDiskPartToClearReadOnly = Boolean.Parse(ConfigurationManager.AppSettings[Constants.CONFIG_USE_DISKPART_TO_CLEAR_READONLY_FLAG]); // determine disk index for DiskPart Wmi cimv2 = new Wmi(serverName, Constants.WMI_CIMV2_NAMESPACE); ManagementObject objDisk = cimv2.GetWmiObject("win32_diskdrive", "Model='Msft Virtual Disk SCSI Disk Device' and ScsiTargetID={0} and ScsiLogicalUnit={1} and scsiPort={2}", targetId, lun, portNumber); if (useDiskPartToClearReadOnly) { // *** Clear Read-Only and bring disk online with DiskPart *** HostedSolutionLog.LogInfo("Clearing disk Read-only flag and bringing disk online"); if (objDisk != null) { // disk found // run DiskPart string diskPartResult = RunDiskPart(serverName, String.Format(@"select disk {0} attributes disk clear readonly online disk exit", Convert.ToInt32(objDisk["Index"]))); HostedSolutionLog.LogInfo("DiskPart Result: " + diskPartResult); } } else { // *** Clear Read-Only and bring disk online with VDS *** // clear Read-Only if ((advancedDisk.Flags & DiskFlags.ReadOnly) == DiskFlags.ReadOnly) { HostedSolutionLog.LogInfo("Clearing disk Read-only flag"); advancedDisk.ClearFlags(DiskFlags.ReadOnly); while ((advancedDisk.Flags & DiskFlags.ReadOnly) == DiskFlags.ReadOnly) { Thread.Sleep(100); advancedDisk.Refresh(); } } // bring disk ONLINE if (advancedDisk.Status == DiskStatus.Offline) { HostedSolutionLog.LogInfo("Bringing disk online"); advancedDisk.Online(); while (advancedDisk.Status == DiskStatus.Offline) { Thread.Sleep(100); advancedDisk.Refresh(); } } } // small pause after getting disk online Thread.Sleep(3000); // get disk again FindVdsDisk(serverName, diskInfo.DiskNumber, out advancedDisk, out diskPack); // find volumes using VDS List<string> volumes = new List<string>(); HostedSolutionLog.LogInfo("Querying disk volumes with VDS"); foreach (Volume volume in diskPack.Volumes) { string letter = volume.DriveLetter.ToString(); if (letter != "") volumes.Add(letter); } // find volumes using WMI if (volumes.Count == 0 && objDisk != null) { HostedSolutionLog.LogInfo("Querying disk volumes with WMI"); foreach (ManagementObject objPartition in objDisk.GetRelated("Win32_DiskPartition")) { foreach (ManagementObject objVolume in objPartition.GetRelated("Win32_LogicalDisk")) { volumes.Add(objVolume["Name"].ToString().TrimEnd(':')); } } } HostedSolutionLog.LogInfo("Volumes found: " + volumes.Count); // Set volumes diskInfo.DiskVolumes = volumes.ToArray(); return diskInfo; }
public MountedDiskInfo MountVirtualHardDisk(string vhdPath) { ManagementObject objImgSvc = GetImageManagementService(); // get method params ManagementBaseObject inParams = objImgSvc.GetMethodParameters("Mount"); inParams["Path"] = FileUtils.EvaluateSystemVariables(vhdPath); ManagementBaseObject outParams = (ManagementBaseObject)objImgSvc.InvokeMethod("Mount", inParams, null); JobResult result = CreateJobResultFromWmiMethodResults(outParams); // load storage job if (result.ReturnValue != ReturnCode.JobStarted) throw new Exception("Failed to start Mount job with the following error: " + result.ReturnValue); ; ManagementObject objJob = wmi.GetWmiObject("msvm_StorageJob", "InstanceID = '{0}'", result.Job.Id); if (!JobCompleted(result.Job)) throw new Exception("Failed to complete Mount job with the following error: " + result.Job.ErrorDescription); try { List<string> volumes = new List<string>(); // load output data ManagementObject objImage = wmi.GetRelatedWmiObject(objJob, "Msvm_MountedStorageImage"); int pathId = Convert.ToInt32(objImage["PathId"]); int portNumber = Convert.ToInt32(objImage["PortNumber"]); int targetId = Convert.ToInt32(objImage["TargetId"]); int lun = Convert.ToInt32(objImage["Lun"]); string diskAddress = String.Format("Port{0}Path{1}Target{2}Lun{3}", portNumber, pathId, targetId, lun); Log.WriteInfo("Disk address: " + diskAddress); // find mounted disk using VDS Vds.Advanced.AdvancedDisk advancedDisk = null; Vds.Pack diskPack = null; // first attempt System.Threading.Thread.Sleep(3000); Log.WriteInfo("Trying to find mounted disk - first attempt"); FindVdsDisk(diskAddress, out advancedDisk, out diskPack); // second attempt if (advancedDisk == null) { System.Threading.Thread.Sleep(20000); Log.WriteInfo("Trying to find mounted disk - second attempt"); FindVdsDisk(diskAddress, out advancedDisk, out diskPack); } if (advancedDisk == null) throw new Exception("Could not find mounted disk"); // check if DiskPart must be used to bring disk online and clear read-only flag bool useDiskPartToClearReadOnly = false; if (ConfigurationManager.AppSettings[CONFIG_USE_DISKPART_TO_CLEAR_READONLY_FLAG] != null) useDiskPartToClearReadOnly = Boolean.Parse(ConfigurationManager.AppSettings[CONFIG_USE_DISKPART_TO_CLEAR_READONLY_FLAG]); // determine disk index for DiskPart Wmi cimv2 = new Wmi(ServerNameSettings, WMI_CIMV2_NAMESPACE); ManagementObject objDisk = cimv2.GetWmiObject("win32_diskdrive", "Model='Msft Virtual Disk SCSI Disk Device' and ScsiTargetID={0} and ScsiLogicalUnit={1} and scsiPort={2}", targetId, lun, portNumber); if (useDiskPartToClearReadOnly) { // *** Clear Read-Only and bring disk online with DiskPart *** Log.WriteInfo("Clearing disk Read-only flag and bringing disk online"); if (objDisk != null) { // disk found // run DiskPart string diskPartResult = RunDiskPart(String.Format(@"select disk {0} attributes disk clear readonly online disk exit", Convert.ToInt32(objDisk["Index"]))); Log.WriteInfo("DiskPart Result: " + diskPartResult); } } else { // *** Clear Read-Only and bring disk online with VDS *** // clear Read-Only if ((advancedDisk.Flags & Vds.DiskFlags.ReadOnly) == Vds.DiskFlags.ReadOnly) { Log.WriteInfo("Clearing disk Read-only flag"); advancedDisk.ClearFlags(Vds.DiskFlags.ReadOnly); while ((advancedDisk.Flags & Vds.DiskFlags.ReadOnly) == Vds.DiskFlags.ReadOnly) { System.Threading.Thread.Sleep(100); advancedDisk.Refresh(); } } // bring disk ONLINE if (advancedDisk.Status == Vds.DiskStatus.Offline) { Log.WriteInfo("Bringing disk online"); advancedDisk.Online(); while (advancedDisk.Status == Vds.DiskStatus.Offline) { System.Threading.Thread.Sleep(100); advancedDisk.Refresh(); } } } // small pause after getting disk online System.Threading.Thread.Sleep(3000); // get disk again FindVdsDisk(diskAddress, out advancedDisk, out diskPack); // find volumes using VDS Log.WriteInfo("Querying disk volumes with VDS"); foreach (Vds.Volume volume in diskPack.Volumes) { string letter = volume.DriveLetter.ToString(); if(letter != "") volumes.Add(letter); } // find volumes using WMI if (volumes.Count == 0 && objDisk != null) { Log.WriteInfo("Querying disk volumes with WMI"); foreach (ManagementObject objPartition in objDisk.GetRelated("Win32_DiskPartition")) { foreach (ManagementObject objVolume in objPartition.GetRelated("Win32_LogicalDisk")) { volumes.Add(objVolume["Name"].ToString().TrimEnd(':')); } } } Log.WriteInfo("Volumes found: " + volumes.Count); // info object MountedDiskInfo info = new MountedDiskInfo(); info.DiskAddress = diskAddress; info.DiskVolumes = volumes.ToArray(); return info; } catch(Exception ex) { // unmount disk UnmountVirtualHardDisk(vhdPath); // throw error throw ex; } }
public static MountedDiskInfo GetMountedDiskInfo(string serverName, int driveNumber) { MountedDiskInfo diskInfo = new MountedDiskInfo { DiskNumber = driveNumber }; // find mounted disk using VDS AdvancedDisk advancedDisk = null; Pack diskPack = null; // first attempt Thread.Sleep(3000); HostedSolutionLog.LogInfo("Trying to find mounted disk - first attempt"); FindVdsDisk(serverName, diskInfo.DiskNumber, out advancedDisk, out diskPack); // second attempt if (advancedDisk == null) { Thread.Sleep(20000); HostedSolutionLog.LogInfo("Trying to find mounted disk - second attempt"); FindVdsDisk(serverName, diskInfo.DiskNumber, out advancedDisk, out diskPack); } if (advancedDisk == null) { throw new Exception("Could not find mounted disk"); } // Set disk address diskInfo.DiskAddress = advancedDisk.DiskAddress; var addressParts = diskInfo.DiskAddress.ParseExact("Port{0}Path{1}Target{2}Lun{3}"); var portNumber = addressParts[0]; var targetId = addressParts[2]; var lun = addressParts[3]; // check if DiskPart must be used to bring disk online and clear read-only flag bool useDiskPartToClearReadOnly = false; if (ConfigurationManager.AppSettings[Constants.CONFIG_USE_DISKPART_TO_CLEAR_READONLY_FLAG] != null) { useDiskPartToClearReadOnly = Boolean.Parse(ConfigurationManager.AppSettings[Constants.CONFIG_USE_DISKPART_TO_CLEAR_READONLY_FLAG]); } // determine disk index for DiskPart Wmi cimv2 = new Wmi(serverName, Constants.WMI_CIMV2_NAMESPACE); ManagementObject objDisk = cimv2.GetWmiObject("win32_diskdrive", "Model='Msft Virtual Disk SCSI Disk Device' and ScsiTargetID={0} and ScsiLogicalUnit={1} and scsiPort={2}", targetId, lun, portNumber); if (useDiskPartToClearReadOnly) { // *** Clear Read-Only and bring disk online with DiskPart *** HostedSolutionLog.LogInfo("Clearing disk Read-only flag and bringing disk online"); if (objDisk != null) { // disk found // run DiskPart string diskPartResult = RunDiskPart(serverName, String.Format(@"select disk {0} attributes disk clear readonly online disk exit", Convert.ToInt32(objDisk["Index"]))); HostedSolutionLog.LogInfo("DiskPart Result: " + diskPartResult); } } else { // *** Clear Read-Only and bring disk online with VDS *** // clear Read-Only if ((advancedDisk.Flags & DiskFlags.ReadOnly) == DiskFlags.ReadOnly) { HostedSolutionLog.LogInfo("Clearing disk Read-only flag"); advancedDisk.ClearFlags(DiskFlags.ReadOnly); while ((advancedDisk.Flags & DiskFlags.ReadOnly) == DiskFlags.ReadOnly) { Thread.Sleep(100); advancedDisk.Refresh(); } } // bring disk ONLINE if (advancedDisk.Status == DiskStatus.Offline) { HostedSolutionLog.LogInfo("Bringing disk online"); advancedDisk.Online(); while (advancedDisk.Status == DiskStatus.Offline) { Thread.Sleep(100); advancedDisk.Refresh(); } } } // small pause after getting disk online Thread.Sleep(3000); // get disk again FindVdsDisk(serverName, diskInfo.DiskNumber, out advancedDisk, out diskPack); // find volumes using VDS List <string> volumes = new List <string>(); HostedSolutionLog.LogInfo("Querying disk volumes with VDS"); foreach (Volume volume in diskPack.Volumes) { string letter = volume.DriveLetter.ToString(); if (letter != "") { volumes.Add(letter); } } // find volumes using WMI if (volumes.Count == 0 && objDisk != null) { HostedSolutionLog.LogInfo("Querying disk volumes with WMI"); foreach (ManagementObject objPartition in objDisk.GetRelated("Win32_DiskPartition")) { foreach (ManagementObject objVolume in objPartition.GetRelated("Win32_LogicalDisk")) { volumes.Add(objVolume["Name"].ToString().TrimEnd(':')); } } } HostedSolutionLog.LogInfo("Volumes found: " + volumes.Count); // Set volumes diskInfo.DiskVolumes = volumes.ToArray(); return(diskInfo); }