1
votes

I want to incorporate a dropdown menu that is populated with the list of available COM ports. I can't find any way to easily get the names of the available COM ports to put in the place of COM4 that creates the $port.

$port = new-Object System.IO.Ports.SerialPort COM4,19200,None,8,one

By using Win32_SerialPort I am able to easily extract COM1 and COM3.

Get-WmiObject Win32_SerialPort | Select-Object deviceid

Results:

deviceid

COM3
COM1

But my device manager shows 16 available ports from a remote serial hub. Device Manager Snapshot

Here is what I have tried and I am able to narrow down the Name, but can't figure out how to extract just the (COM--) part.

Get-WmiObject Win32_pnpentity  -Filter "Name LIKE 'devicemaster port%'" | Select-Object -Property Name 

Result Screenshot

3

3 Answers

1
votes

Adding a late answer because I just had a need for this...

You can use WMI ClassGuids to get the exact list (COM and LPT) that device manager shows:

$lptAndCom = '{4d36e978-e325-11ce-bfc1-08002be10318}'
get-wmiobject -Class win32_pnpentity | where ClassGuid -eq $lptAndCom | select name

Confirmed to work with a few LPT / COM extension cards (Brain Boxes / Exar), using Windows 8.1 up to server 2019 (Powershell 4 onwards).

The full list of ClassGuids is here: https://docs.microsoft.com/en-us/windows-hardware/drivers/install/system-defined-device-setup-classes-available-to-vendors

1
votes

Here is a more up-to-date solution to get the COM-port details:

cls
$portList = get-pnpdevice -class Ports -ea 0
$portCount = 0
if ($portList) {
    $now = get-date
    foreach($device in $portList) {
        $id = $device.InstanceId
        if ($device.Present) {
            $date = $now
        } else {
            $info = Get-PnpDeviceProperty -InstanceId $id
            $latest = $info | ?{$_.KeyName -eq "DEVPKEY_Device_LastRemovalDate"}
            $date = [datetime]$latest.Data
        }
        $age = $now-$date
        if ($age.Days -lt 14) {
            "port name  : $name"
            "last active: $date"
            ""
            $portCount++
        }
    }
}
"number of active COM-port devices in last 14 days: $portCount"
0
votes

Leaving some work to you to figure out, but based on your Result Screenshot you can do something like this:

$ports = @()
$ports += 'devicemaster port (COM1)'
$ports += 'devicemaster port (COM2)'
$ports += 'devicemaster port (COM3)'
$ports += 'devicemaster port (COM4)'


$ports | % {
    if ($_ -match "devicemaster port \((.*)\)") {
        $matches[1]
    }
}

with that object, assuming you store that in '$ports'. You may need to use '$ports.Name'...

Possibly see regex101.com for how the regex works.