Virtual Disk Service (VDS) Powershell Script Version 2 - Previously Created Volume Support + Mount Points + Bug Fixes
I got a lot of great feedback on the last VDS script - sounds like more than a few people have faced this issue... I also got more than a few request to just post the script next time without the functions - if you liked the functions tell me now or forever hold your peace :-)...
Here's the next version of the script - it now supports mount points as well as VHD's that already have volumes created on them...
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:\testNew.vhd" $vhdMountPoint = $null $vhdDiskLetter = "T" $vhdVolumeName = "MyVolume"
$Msvm_ImageManagementService = $null $Msvm_StorageJob = $null $Msvm_MountedStorageImage = $null $FormatedDiskAddress = $null $VdsServiceLoader = $null $VdsService = $null $VdsAdvancedDisk = $null $VdsDiskPack = $null $VdsVolume = $null
################################################################################################################## ###MOUNT VHD ################################################################################################################## $Msvm_ImageManagementService = Get-WmiObject -Namespace "root\virtualization" -Class "Msvm_ImageManagementService" $Msvm_StorageJob = [WMI]($Msvm_ImageManagementService.Mount($vhdToMount) | ProcessWMIJob $Msvm_ImgMgmtService "Mount").Job $Msvm_MountedStorageImage = Get-WmiObject -Namespace "root\virtualization" -Query "Associators of {$Msvm_StorageJob} Where AssocClass=Msvm_AffectedStorageJobElement ResultClass=Msvm_MountedStorageImage" $FormatedDiskAddress = "Port" + $Msvm_MountedStorageImage.PortNumber + ` "Path" + $Msvm_MountedStorageImage.PathId + ` "Target" + $Msvm_MountedStorageImage.TargetId + ` "Lun" + $Msvm_MountedStorageImage.Lun
################################################################################################################## ###Identify Mounted VHD in VDS ################################################################################################################## [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Storage.Vds") | Out-Null $VdsServiceLoader = New-Object Microsoft.Storage.Vds.ServiceLoader $VdsService = $VdsServiceLoader.LoadService($null) $VdsService.WaitForServiceReady()
$VdsService.UnallocatedDisks | foreach{ if (([Microsoft.Storage.Vds.Advanced.AdvancedDisk]$_).DiskAddress -ilike $formatedDiskAddress) { $VdsAdvancedDisk = ([Microsoft.Storage.Vds.Advanced.AdvancedDisk]$_) } }
if ($VdsAdvancedDisk -eq $null) { $VdsService.HardwareProvider = $false $VdsService.SoftwareProvider = $true $VdsService.Providers| foreach{ $_.Packs | foreach{ $tempPack = $_ $_.Disks | foreach{ if (([Microsoft.Storage.Vds.Advanced.AdvancedDisk]$_).DiskAddress -ilike $formatedDiskAddress) { $VdsDiskPack = $tempPack $VdsAdvancedDisk = ([Microsoft.Storage.Vds.Advanced.AdvancedDisk]$_) } } } } } if ($VdsAdvancedDisk -eq $null) {Throw "Failed to Find Disk!"}
################################################################################################################## ###Online Disk if Offline ################################################################################################################## if ($VdsAdvancedDisk.Status -eq [Microsoft.Storage.Vds.DiskStatus]::Offline) { $VdsAdvancedDisk.Online() while ($VdsAdvancedDisk.Status -eq [Microsoft.Storage.Vds.DiskStatus]::Offline) { Start-Sleep -Milliseconds 100 $VdsAdvancedDisk.Refresh() } }
################################################################################################################## ###Clear Readonly Bit ################################################################################################################## if (($VdsAdvancedDisk.Flags -band [Microsoft.Storage.Vds.DiskFlags]::ReadOnly) -eq [Microsoft.Storage.Vds.DiskFlags]::ReadOnly) { $VdsAdvancedDisk.ClearFlags([Microsoft.Storage.Vds.DiskFlags]::ReadOnly) while (($VdsAdvancedDisk.Flags -band [Microsoft.Storage.Vds.DiskFlags]::ReadOnly) -eq [Microsoft.Storage.Vds.DiskFlags]::ReadOnly) { Start-Sleep -Milliseconds 100 $VdsAdvancedDisk.Refresh() } }
################################################################################################################## ###Create Partion If Not Present ################################################################################################################## if ($VdsDiskPack -eq $null) { $vdsBasicProvidorGuid = "ca7de14f-5bc8-48fd-93de-a19527b0459e" $VdsService.HardwareProvider = $false $VdsService.SoftwareProvider = $true $VdsService.Providers| foreach{ if ($vdsBasicProvidorGuid -ieq $_.Id) { $VdsDiskPack = $_.CreatePack() $VdsDiskPack.AddDisk($VdsAdvancedDisk.Id, [Microsoft.Storage.Vds.PartitionStyle]::Mbr, $false) } } }
################################################################################################################## ###Create Volume and Format If Not Present ################################################################################################################## $tempEnumerator = $VdsDiskPack.Volumes.GetEnumerator() $tempEnumerator.Reset() if(-not $tempEnumerator.MoveNext()) { $vdsInputDiskObject = New-Object Microsoft.Storage.Vds.InputDisk $vdsInputDiskObject.DiskId = $VdsAdvancedDisk.Id $vdsInputDiskObject.Size = ($VdsAdvancedDisk.Size - 1080832) $vdsInputDiskObjects = [Microsoft.Storage.Vds.InputDisk[]]@($vdsInputDiskObject) $volumeCreationEvent = $vdsDiskPack.BeginCreateVolume([Microsoft.Storage.Vds.VolumeType]::Simple, $vdsInputDiskObjects, [UInt32]0, $null, $null) while ($volumeCreationEvent.IsCompleted -eq $false) {Start-Sleep -Milliseconds 100} $VdsVolume = $vdsDiskPack.EndCreateVolume($volumeCreationEvent) $formatCreationEvent = $VdsVolume.BeginFormat([Microsoft.Storage.Vds.FileSystemType]::Ntfs, $vhdVolumeName, 512, $true, $true, $false, $null, $null) while ($formatCreationEvent.IsCompleted -eq $false) {Start-Sleep -Milliseconds 100} $VdsVolume.EndFormat($formatCreationEvent) } else { $VdsVolume = $tempEnumerator.Current }
################################################################################################################## ###Assign DriveLetter or Mountpoint ################################################################################################################## if($vhdDiskLetter -ne $null) { if($VdsVolume.DriveLetter -ne [Char]::Parse($vhdDiskLetter)) { $VdsVolume.DriveLetter = [Char]::Parse($vhdDiskLetter) } } elseif (-not[Char]::IsWhiteSpace($VdsVolume.DriveLetter)) { $VdsVolume.DeleteAccessPath(($VdsVolume.DriveLetter + ":\"), $true) }
if ($vhdMountPoint -ne $null) { if($VdsVolume.AccessPaths -notcontains ($vhdMountPoint+"\")) { $VdsVolume.AddAccessPath(($vhdMountPoint+"\")) } }
|
Taylor Brown
Hyper-V Integration Test Lead
http://blogs.msdn.com/taylorb

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