SuperJMN
SuperJMN

Reputation: 13962

Given a PowerShell Disk, how do I know if it's removable or not?

Is there any cmdlet way to get if a Disk is fixed or removable given a code like this?

$disk = Get-Disk -Number 1
Get-DiskDriveType $disk

Where Get-DiskDriveType should return either Removable or Fixed.

Upvotes: 0

Views: 2158

Answers (3)

Jroonk
Jroonk

Reputation: 1471

I had to solve this in c# too, for that my answer is here: Get List of connected USB Devices

Many USB Drives these days have some other controller under the USB connection. You might have a USB to IDE, USB to SCSI, USB to SATA, or USB to NVME adapter that completely masks the 3 or 4 devices under it where your logical drive actually shows up, and doesn't show up as removeable nor as USB at all.

This code uses (Get-PnpDeviceProperty -InstanceId $ParentID -KeyName "DEVPKEY_Device_Parent").Data to get the WMI DeviceIDs of parent devices. I was able to recursively enumerate parent devices all the way back to the host computer to figure out if USB was anywhere in it's connection path.

The simple psuedo-code is this:

  • Enumerate the WMI Logical Disks (have a drive letter in Windows).
  • Enumerate the WMI Partions that those logical disks are stored on.
  • Enumerate the WMI Physical Drives that those partitions are stored on.
  • Enumerate the WMI Parent tree of the Physical Drive all the way to the host computer.
  • If any device along the Parent tree is USB, then this is a USB Attached Drive.
  • Otherwise, this is NOT a USB Attached Drive

Here is the code (with added comments, it looks longer than it is):

## Finds all Drives on the computer that are connected through USB no matter how indirect.
function Get-USBAttachedDriveLetters {
    $result = [System.Collections.Generic.List[string]]::new()

    # Find all of the LogicalDiskToPartion WMI object converters. This will find
    # all of the Logical Drive letters on the system that are connected to a physical
    # disk partition, and provide the WMI IDs for each Logical Disk and matching Partitions.
    $LD2Ps = Get-WmiObject -Class "Win32_LogicalDiskToPartition" -Property @("Antecedent", "Dependent")
    ForEach ($LD2P in $LD2Ps) {
        # Get the DiskDriveToDiskPartition WMI object converter for this logical drive.
        $DD2Ps = (Get-WmiObject -Class "Win32_DiskDriveToDiskPartition" -Property @("Antecedent", "Dependent") -Filter "Dependent = `"$($LD2P.Antecedent.Replace('\', '\\').Replace('"', '\"'))`"")
        ForEach ($DD2P in $DD2Ps) {
            # Get the WMI DiskDrive object for this logical drive, and get its
            # PNPDeviceID, a unique identifier for every Windows device.
            $DD = [System.Management.ManagementObject]::new($DD2P.Antecedent)
            $DD_PNPDeviceId = $DD.PNPDeviceId
            # If any of the devices on the device tree are "USB" then this is a USBAttachedDrive
            # and should be added to the result.
            if (PnpEntityIsUSB -InstanceId $DD_PNPDeviceId) {
                # The drive letter to add comes from WMI Logical Disk object, Name property.
                $LD = [System.Management.ManagementObject]::new($LD2P.Dependent)
                $result.Add($LD.Name)
            }
        }
    }
    return $result
}

## Recursive function that follows device parent connections until it finds a USB 
## connecting host (returns TRUE) or reaches the root host computer (returns FALSE).
function PnpEntityIsUSB {
    [CmdletBinding()]
    param(
        [string]$InstanceId
    )
    if ($InstanceId.ToUpper().Contains("USB")) { return $true }
    
    [string]$ParentId = (Get-PnpDeviceProperty -InstanceId $InstanceId -KeyName "DEVPKEY_Device_Parent").Data
    
    # If there is no ParentId, then this is the host computer, so return false.
    if ([string]::IsNullOrWhiteSpace($ParentId)) { return $false }

    return (PnpEntityIsUSB $ParentID)
}

Upvotes: 0

Manuel Amstutz
Manuel Amstutz

Reputation: 1388

 Get-Volume | Where-Object {$_.DriveType -eq 'removable'} | Get-Partition | Get-Disk | Where-Object {$_.Number -eq $diskNumber}

Upvotes: 1

postanote
postanote

Reputation: 16076

Inventory Drive Types by Using PowerShell

https://blogs.technet.microsoft.com/heyscriptingguy/2014/09/10/inventory-drive-types-by-using-powershell

Two methods:

Get-Volume

DriveLetter FileSystemLabel FileSystem  DriveType  HealthStatus SizeRemaining Size
----------- ----------- ----------  ---------  ---------- ----------       ----

C           SSD         NTFS        Fixed      Healthy      75.38 GB  148.53 GB
E           HybridTe... NTFS        Fixed      Healthy     560.71 GB  931.39 GB
D           FourTB_B... NTFS        Fixed      Healthy        1.5 TB    3.64 TB
F           TwoTB_BU... NTFS        Fixed      Healthy     204.34 GB    1.82 TB
G           USB3        NTFS        Removable  Healthy       6.73 GB   58.89 GB
            Recovery    NTFS        Fixed      Healthy      22.96 MB     300 MB
H                                   CD-ROM     Healthy           0 B        0 B

Or

$hash = @{
    2 = "Removable disk"
    3 = "Fixed local disk"
    4 = "Network disk"
    5 = "Compact disk"
}

Get-CimInstance Win32_LogicalDisk |
Select DeviceID, VolumeName,
@{LABEL='TypeDrive';EXPRESSION={$hash.item([int]$_.DriveType)}}

Upvotes: 3

Related Questions