1
votes

How do I link unmounted volumes to physical disks?

Say I need to find and mount unmounted volumes on disk 3 as numbered by Diskpart or WMIC, or PowerShell WMI. How do I find out, with a script, what volumes of disk 3 aren't mounted? Or, alternatively, what physical disk a given unmounted volume (having no DriveLetter) resides on?

When a volume is unmounted, no logical disk or mount point exist for it. I suppose the relation can be found with GetRelated method, but I can't find such a code example suited for the task.

2

2 Answers

2
votes

Give this a try, it will:

  • Get all unmounted partitions for a given drive index $targetDisk using WMI
  • Mount the discovered partitions on the target disk to the next available drive letter using a diskpart script.

Using the GetRelated method is all about knowing what you need to relate. It helps to know what WMI class represents what you are looking for Win32_DiskPartition. In your case you want to find the partitions which are not associated with a logical disk (unmounted) so we look for instances of Win32_DiskPartition which don't have an associated Win32_LogicalDisk.

Since you only want unmounted volumes on a particular physical disk we need to further associate classes. To do this we need to get Win32_DiskPartition's associated Win32_DiskDrive instance.

$targetDisk = 3

$unmounted = gwmi -class win32_DiskPartition | ? {
    ($_.GetRelated('Win32_LogicalDisk')).Count -eq 0 
}

if ($unmounted) {
    $commands = @()
    $unmounted | ? { $_.GetRelated('Win32_DiskDrive') | ? { $_.Index -eq $targetDisk} } | % {
        $commands += "select disk {0}" -f $_.DiskIndex
        $commands += "select partition {0}" -f ($_.Index + 1)
        $commands += "assign"
    }

    $tempFile = [io.path]::GetTempFileName()
    $commands | out-file $tempFile -Encoding ASCII

    $output = & diskpart.exe /s $tempFile 2>&1
    if ($LASTEXITCODE -ne 0) {
        Write-Error $output
    }
}
0
votes

Integrate this code into the above answer:

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

Set colItems = objWMIService.ExecQuery _
    ("Select * From Win32_Volume Where Name = 'D:\\'")

For Each objItem in colItems
    objItem.AddMountPoint("W:\\Scripts\\")
Next

It looks in Windows 7 PowerShell by using the Volume DeviceID instead of its DriveLetter, and relating the Volume to Disk 3 as shown in the above answer. A similar approach (AddMountPoint or Mount) can be used as above, but without using Diskpart.