Skip to content

PowerShell Device Management

How to use PowerShell cmdlets like Get-PnpDevice, Get-CimInstance, and Get-Disk to monitor, audit, and manage hardware devices, firmware, and storage systems in Windows.

PowerShell provides built-in cmdlets and access to the Common Information Model (CIM) to query, monitor, and manage physical hardware, system firmware, storage drives, and Plug and Play (PnP) peripherals.

Plug and Play (PnP) Device Management

The PnpDevice module provides cmdlets to inspect and change the state of hardware peripherals managed by the Windows Plug and Play subsystem (such as network adapters, USB controllers, audio devices, and Bluetooth radios).

Listing Devices with Get-PnpDevice

The Get-PnpDevice cmdlet enumerates connected and historical PnP devices:

Consolepowershell
Get-PnpDevice -Class "Net" -Status "OK" | Select-Object -First 3
Outputplaintext
Status     Class           FriendlyName                                         InstanceId
------     -----           ------------                                         ----------
OK         Net             Intel(R) Ethernet Connection (7) I219-V              PCI\VEN_8086&D...
OK         Net             WAN Miniport (IP)                                    SWD\MSRRAS\WAN...
OK         Net             WAN Miniport (IPv6)                                  SWD\MSRRAS\WAN...

Key filtering parameters:

  • -Class: Filters devices by hardware category (e.g., Net, USB, Bluetooth, Display, Media).
  • -Status: Filters by operating state (e.g., OK, Error, Degraded, Unknown).
  • -PresentOnly: Restricts the query to devices currently attached and powered on, excluding disconnected peripheral history.

To find all malfunctioning or erroring devices across the system:

Consolepowershell
Get-PnpDevice -PresentOnly | Where-Object { $_.Status -ne "OK" }
Outputplaintext
Status     Class           FriendlyName                                         InstanceId
------     -----           ------------                                         ----------
Error      USB             Unknown USB Device (Device Descriptor Request Failed) USB\VID_0000...

Enabling and Disabling Devices

Hardware devices can be turned on or off programmatically using Disable-PnpDevice and Enable-PnpDevice. These are equivalent to right-clicking a device in Device Manager and selecting Enable or Disable.

Consolepowershell
$TargetDevice = Get-PnpDevice -FriendlyName "*Bluetooth Adapter*" -PresentOnly
Disable-PnpDevice -InstanceId $TargetDevice.InstanceId -Confirm:$false

To re-enable the device:

Consolepowershell
Enable-PnpDevice -InstanceId $TargetDevice.InstanceId -Confirm:$false

where:

  • -InstanceId uniquely identifies the device in the Windows hardware registry tree (retrieved from Get-PnpDevice).
  • -Confirm:$false suppresses the interactive confirmation prompt, useful for unattended scripts.

Hardware Auditing with Get-CimInstance

To query core system specifications (motherboard, CPU, memory modules, firmware), use Get-CimInstance. This cmdlet queries CIM/WMI classes using modern, firewall-friendly WS-Management protocols.

Common CIM Classes

Hardware Target CIM Class Name Useful Properties
System Identity Win32_ComputerSystem Manufacturer, Model, TotalPhysicalMemory, NumberOfProcessors
Processor Win32_Processor Name, NumberOfCores, NumberOfLogicalProcessors, MaxClockSpeed
Firmware / BIOS Win32_BIOS Manufacturer, SMBIOSBIOSVersion, SerialNumber, ReleaseDate
Physical RAM Win32_PhysicalMemory Capacity, Speed, Manufacturer, PartNumber, DeviceLocator
Motherboard Win32_BaseBoard Manufacturer, Product, SerialNumber
Operating System Win32_OperatingSystem Version, InstallDate, LastBootUpTime
Logical Disk Win32_LogicalDisk Legacy disk/partition information
Network Adapter Win32_NetworkAdapter Network adapter details

Quick Queries

Consolepowershell
Get-CimInstance -ClassName Win32_ComputerSystem | Select-Object Manufacturer, Model, TotalPhysicalMemory
Outputplaintext
Manufacturer   Model            TotalPhysicalMemory
------------   -----            --------------------
Dell Inc.      OptiPlex 7090          17179869184
Consolepowershell
Get-CimInstance -ClassName Win32_Processor | Select-Object Name, NumberOfCores, MaxClockSpeed
Outputplaintext
Name                                     NumberOfCores MaxClockSpeed
----                                     ------------- -------------
Intel(R) Core(TM) i7-10700 CPU @ 2.90GHz             8          2904
Consolepowershell
Get-CimInstance -ClassName Win32_BIOS | Select-Object Manufacturer, SMBIOSBIOSVersion, ReleaseDate
Outputplaintext
Manufacturer  SMBIOSBIOSVersion  ReleaseDate
------------  -----------------  -----------
Dell Inc.     2.14.0             8/15/2023 12:00:00 AM

Combined Hardware Metadata Script

query-bios.ps1powershell
$Bios = Get-CimInstance -ClassName Win32_BIOS
$Cpu  = Get-CimInstance -ClassName Win32_Processor

[PSCustomObject]@{
    Manufacturer  = $Bios.Manufacturer
    BIOSVersion   = $Bios.SMBIOSBIOSVersion
    SerialNumber  = $Bios.SerialNumber
    Processor     = $Cpu.Name
    PhysicalCores = $Cpu.NumberOfCores
    LogicalCores  = $Cpu.NumberOfLogicalProcessors
}
Consolepowershell
pwsh ./query-bios.ps1
Outputplaintext
Manufacturer  : Dell Inc.
BIOSVersion   : 1.15.1
SerialNumber  : 8XYZ123
Processor     : 12th Gen Intel(R) Core(TM) i7-12700
PhysicalCores : 12
LogicalCores  : 20

Storage Subsystem: Get-Disk and Get-Volume

PowerShell separates storage architecture into two layers:

  1. Physical Disks (Get-Disk): Represents the raw physical drive, NVMe SSD, or virtual hard disk (VHD) hardware.
  2. Logical Volumes (Get-Volume): Represents the formatted file system partitions (C:, D:) residing on those physical disks.

Querying Physical Disks with Get-Disk

Get-Disk retrieves physical drive metadata, partition styles, and operational health:

Consolepowershell
Get-Disk
Outputplaintext
Number Friendly Name            Serial Number                    HealthStatus         OperationalStatus      Total Size Partition
                                                                                                                        Style
------ -------------            -------------                    ------------         -----------------      ---------- ----------
0      Samsung SSD 980 PRO 1TB  S5GXNF0R123456                   Healthy              Online                  931.51 GB GPT
1      Crucial CT2000P3SSD8     2240E6789012                     Healthy              Online                    1.82 TB GPT

Key properties to monitor:

  • HealthStatus: Reports SMART status (Healthy, Warning, Unhealthy).
  • OperationalStatus: Reports device link status (Online, Offline, Read Only).
  • PartitionStyle: Displays modern GPT or legacy MBR.

Querying Logical Volumes with Get-Volume

Get-Volume inspects formatted file systems, partition labels, and remaining free space:

Consolepowershell
Get-Volume
Outputplaintext
DriveLetter FriendlyName FileSystemType DriveType HealthStatus OperationalStatus SizeRemaining      Size
----------- ------------ -------------- --------- ------------ ----------------- -------------      ----
C           OS           NTFS           Fixed     Healthy      OK                    145.22 GB 930.85 GB
D           DataStore    ReFS           Fixed     Healthy      OK                      1.25 TB   1.82 TB
            Recovery     NTFS           Fixed     Healthy      OK                      85.4 MB    650 MB

Practical Example: Automated Hardware Health and Peripheral Audit

The following script audits physical hardware specifications, verifies disk health, and flags any failing Plug and Play devices:

audit-device-health.ps1powershell
$System = Get-CimInstance -ClassName Win32_ComputerSystem
$Processor = Get-CimInstance -ClassName Win32_Processor | Select-Object -First 1

$UnhealthyDisks = Get-Disk | Where-Object { $_.HealthStatus -ne "Healthy" -or $_.OperationalStatus -ne "Online" }

$FailedPeripherals = Get-PnpDevice -PresentOnly | Where-Object { $_.Status -notin @("OK", "Degraded") }

[PSCustomObject]@{
    Hostname           = $System.Name
    Model              = "$($System.Manufacturer) $($System.Model)"
    CPU                = $Processor.Name.Trim()
    TotalRAM_GB        = [math]::Round($System.TotalPhysicalMemory / 1GB, 2)
    TotalPhysicalDisks = (Get-Disk).Count
    DisksDegraded      = $UnhealthyDisks.Count
    PeripheralsInError = $FailedPeripherals.Count
    SystemHealthy      = ($UnhealthyDisks.Count -eq 0 -and $FailedPeripherals.Count -eq 0)
    AuditTimestamp     = (Get-Date -Format "yyyy-MM-dd HH:mm:ss")
}

where:

  • Get-CimInstance queries identity and core processor details.
  • Get-Disk | Where-Object ... filters for any drive exhibiting hardware failure or an offline state.
  • Get-PnpDevice -PresentOnly scans attached hardware for error states.
  • [PSCustomObject] compiles the metrics into a single inventory record.

Run the script from the console:

Consolepowershell
pwsh ./audit-device-health.ps1
Outputplaintext
Hostname           : WORKSTATION-01
Model              : Dell Inc. Precision 3660
CPU                : 12th Gen Intel(R) Core(TM) i7-12700
TotalRAM_GB        : 31.68
TotalPhysicalDisks : 2
DisksDegraded      : 0
PeripheralsInError : 0
SystemHealthy      : True
AuditTimestamp     : 2026-10-24 18:20:15
Navigation