2024-06-11 18:27:55 +00:00
function Get-Devices {
param (
2024-06-24 21:11:07 +00:00
[ string ] $comp ,
[ Parameter ( Mandatory = $false ) ] [ string ] $status
2024-06-11 18:27:55 +00:00
)
try {
2024-06-24 21:11:07 +00:00
if ( $status -eq " Online " ) {
$usb = Get-WmiObject Win32_USBControllerDevice -ComputerName $comp | ForEach-Object { [ wmi ] ( $_ . Dependent ) } | Sort-Object Manufacturer , Description , DeviceID | Select-Object Manufacturer , Description , @ { N = " DeviceID\SerialNumber " ; E = { $_ . DeviceID } }
} else {
$usb = Get-SCCM_USB $comp | Sort-Object Manufacturer , Description , DeviceID | Select-Object Manufacturer , Description , @ { N = " DeviceID\SerialNumber " ; E = { $_ . DeviceID } }
}
2024-06-11 18:27:55 +00:00
$usb | Add-Member -NotePropertyName Type -NotePropertyValue USB
$usb | Add-Member -NotePropertyName AttachedComputer -NotePropertyValue $comp
foreach ( $item in $usb ) {
$friendlyNames = FindUSBDevice -deviceID $item . 'DeviceID\SerialNumber' . ToString ( )
if ( $friendlyNames ) {
$item . Manufacturer = $friendlyNames [ 0 ]
if ( $item . Manufacturer . Length -le 5 ) {
continue
}
if ( $item . Manufacturer . Substring ( 0 , 5 ) -eq '[SHS]' ) {
$item . Type = 'SHS Issued USB'
$len = $item . Manufacturer . Length -1
$item . Manufacturer = $item . Manufacturer [ 5 . . $len ] -join ''
}
if ( $friendlyNames [ 1 ] ) {
$item . Description = $friendlyNames [ 1 ]
}
}
}
$usb = $usb | Sort-Object Manufacturer , Description
for ( $i = 0 ; $i -lt $usb . Count - 1 ; $i + + ) {
if ( $usb [ $i ] . Manufacturer -eq $usb [ $i + 1 ] . Manufacturer -and $usb [ $i ] . Description -eq $usb [ $i + 1 ] . Description ) {
$usb [ $i ] . Manufacturer = '__DUPE__'
}
}
$usb = $usb | Where-Object -Property Manufacturer -NE '__DUPE__'
$usb = $usb | Sort-Object Type
}
catch {
Write-warning 'Unable to grab USB info'
$usb = $null
}
2024-06-24 21:11:07 +00:00
if ( $status -eq 'Online' ) {
$monitors = @ ( )
$monitors + = Get-Monitor $comp | Select-Object Manufacturer , @ { N = 'Description' ; E = { $_ . Model } } , @ { N = " DeviceID\SerialNumber " ; E = { $_ . SerialNumber } } , AttachedComputer , ActivePort
$monitors | Add-Member -NotePropertyName Type -NotePropertyValue Monitor
2024-06-11 18:27:55 +00:00
2024-06-24 21:11:07 +00:00
$PortsHash = @ {
'DELL P170S' = @ ( 'DVI' , 'VGA' ) ;
'DELL P2317H' = @ ( 'DP' , 'HDMI' , 'VGA' ) ;
'DELL P2314H' = @ ( 'DP' , 'DVI' , 'VGA' ) ;
'DELL P2312H' = @ ( 'DVI' , 'VGA' ) ;
'DELL P2319H' = @ ( 'DP' , 'HDMI' , 'VGA' ) ;
'DELL P2422H' = @ ( 'DP' , 'VGA' ) ;
'DELL P2412H' = @ ( 'DP' , 'VGA' , 'HDMI' ) ;
}
foreach ( $item in $monitors ) {
$portList = ''
$found = $false
foreach ( $port in $PortsHash . ( $item . Description ) ) {
if ( $port -eq $item . ActivePort ) { $portList + = '*' ; $found = $true }
$portList + = $port + ','
}
$portList = $portList -replace " \, $ "
$item . Description = $item . Description + ' (' + $portList + ')'
if ( $found -ne $true ) { $item . Description + = " * " + $item . ActivePort }
2024-06-11 18:27:55 +00:00
}
}
2024-06-24 21:11:07 +00:00
$out = @ ( )
2024-06-11 18:27:55 +00:00
foreach ( $item in ( $monitors + $usb ) ) {
$item . PSObject . TypeNames . Insert ( 0 , 'GetPC.Devices' )
$out + = $item
}
Write-Output $out
}
Function Get-Monitor {
<#
. SYNOPSIS
This powershell function gets information about the monitors attached to any computer . It uses EDID information provided by WMI . If this value is not specified it pulls the monitors of the computer that the script is being run on .
. DESCRIPTION
The function begins by looping through each computer specified . For each computer it gets a litst of monitors .
It then gets all of the necessary data from each monitor object and converts and cleans the data and places it in a custom PSObject . It then adds
the data to an array . At the end the array is displayed .
. PARAMETER ComputerName
Use this to specify the computer ( s ) which you ' d like to retrieve information about monitors from .
. EXAMPLE
PS C: / > Get-Monitor . ps1 -ComputerName SSL1-F1102 - 1G2Z
Manufacturer Model SerialNumber AttachedComputer
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
HP HP E241i CN12345678 SSL1-F1102 - 1G2Z
HP HP E241i CN91234567 SSL1-F1102 - 1G2Z
HP HP E241i CN89123456 SSL1-F1102 - 1G2Z
. EXAMPLE
PS C: / > $Computers = @ ( " SSL7-F108F-9D4Z " , " SSL1-F1102-1G2Z " , " SSA7-F1071-0T7F " )
PS C: / > Get-Monitor . ps1 -ComputerName $Computers
Manufacturer Model SerialNumber AttachedComputer
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
HP HP LA2405x CN12345678 SSL7-F108F - 9D4Z
HP HP E241i CN91234567 SSL1-F1102 - 1G2Z
HP HP E241i CN89123456 SSL1-F1102 - 1G2Z
HP HP E241i CN78912345 SSL1-F1102 - 1G2Z
HP HP ZR22w CN67891234 SSA7-F1071 - 0T7F
. NOTES
This script was written by MaxAnderson95 https : / / github . com / MaxAnderson95 / Get-Monitor -Information / blob / master / Get-Monitor . psm1
#>
[ CmdletBinding ( ) ]
PARAM (
[ Parameter ( ValueFromPipeline = $True , ValueFromPipelineByPropertyName = $True ) ]
[ String[] ] $ComputerName = $env:ComputerName
)
#List of Manufacture Codes that could be pulled from WMI and their respective full names. Used for translating later down.
$ManufacturerHash = @ {
" AAC " = " AcerView " ;
" ACR " = " Acer " ;
" AOC " = " AOC " ;
" AIC " = " AG Neovo " ;
" APP " = " Apple Computer " ;
" AST " = " AST Research " ;
" AUO " = " Asus " ;
" BNQ " = " BenQ " ;
" CMO " = " Acer " ;
" CPL " = " Compal " ;
" CPQ " = " Compaq " ;
" CPT " = " Chunghwa Pciture Tubes, Ltd. " ;
" CTX " = " CTX " ;
" DEC " = " DEC " ;
" DEL " = " Dell " ;
" DPC " = " Delta " ;
" DWE " = " Daewoo " ;
" EIZ " = " EIZO " ;
" ELS " = " ELSA " ;
" ENC " = " EIZO " ;
" EPI " = " Envision " ;
" FCM " = " Funai " ;
" FUJ " = " Fujitsu " ;
" FUS " = " Fujitsu-Siemens " ;
" GSM " = " LG Electronics " ;
" GWY " = " Gateway 2000 " ;
" HEI " = " Hyundai " ;
" HIT " = " Hyundai " ;
" HSL " = " Hansol " ;
" HTC " = " Hitachi/Nissei " ;
" HWP " = " HP " ;
" IBM " = " IBM " ;
" ICL " = " Fujitsu ICL " ;
" IVM " = " Iiyama " ;
" KDS " = " Korea Data Systems " ;
" LEN " = " Lenovo " ;
" LGD " = " Asus " ;
" LPL " = " Fujitsu " ;
" MAX " = " Belinea " ;
" MEI " = " Panasonic " ;
" MEL " = " Mitsubishi Electronics " ;
" MS_ " = " Panasonic " ;
" NAN " = " Nanao " ;
" NEC " = " NEC " ;
" NOK " = " Nokia Data " ;
" NVD " = " Fujitsu " ;
" OPT " = " Optoma " ;
" PHL " = " Philips " ;
" REL " = " Relisys " ;
" SAN " = " Samsung " ;
" SAM " = " Samsung " ;
" SBI " = " Smarttech " ;
" SGI " = " SGI " ;
" SNY " = " Sony " ;
" SRC " = " Shamrock " ;
" SUN " = " Sun Microsystems " ;
" SEC " = " Hewlett-Packard " ;
" TAT " = " Tatung " ;
" TOS " = " Toshiba " ;
" TSB " = " Toshiba " ;
" VSC " = " ViewSonic " ;
" ZCM " = " Zenith " ;
" UNK " = " Unknown " ;
" _YV " = " Fujitsu " ;
}
$ActivePortHash = @ {
'0' = 'VGA' ;
'4' = 'DVI' ;
'5' = 'HDMI' ;
'10' = 'DP' ;
} ;
#Takes each computer specified and runs the following code:
ForEach ( $Computer in $ComputerName ) {
#Grabs the Monitor objects from WMI
$Monitors = Get-WmiObject -Namespace " root\WMI " -Class " WMIMonitorID " -ComputerName $Computer -ErrorAction SilentlyContinue
#Grabs data about the port driving the monitors
$activePortsData = get-ciminstance -namespace root / wmi -classname WmiMonitorConnectionParams -ComputerName $Computer -ErrorAction SilentlyContinue
#Transforms results of $activePortsData into a lookup table
$activePorts = @ { }
foreach ( $data in $activePortsData ) {
#Translates port numeric code to a readable port identifier
$activePorts [ $data . InstanceName ] = $ActivePortHash [ " $( $data . VideoOutputTechnology ) " ]
#Uses the raw code if the code isn't recognized (it's a really weird one)
2024-06-24 21:11:07 +00:00
if ( $null -eq $activePorts [ $data . InstanceName ] ) {
2024-06-11 18:27:55 +00:00
$activePorts [ $data . InstanceName ] = $data . VideoOutputTechnology
}
}
#Creates an empty array to hold the data
$Monitor_Array = @ ( )
#Takes each monitor object found and runs the following code:
ForEach ( $Monitor in $Monitors ) {
#Grabs respective data and converts it from ASCII encoding and removes any trailing ASCII null values
2024-06-24 21:11:07 +00:00
If ( $null -ne [ System.Text.Encoding ] :: ASCII . GetString ( $Monitor . UserFriendlyName ) ) {
2024-06-11 18:27:55 +00:00
$Mon_Model = ( [ System.Text.Encoding ] :: ASCII . GetString ( $Monitor . UserFriendlyName ) ) . Replace ( " $( [ char ] 0x0000 ) " , " " )
} else {
$Mon_Model = $null
}
$Mon_Serial_Number = ( [ System.Text.Encoding ] :: ASCII . GetString ( $Monitor . SerialNumberID ) ) . Replace ( " $( [ char ] 0x0000 ) " , " " )
$Mon_Attached_Computer = ( $Monitor . PSComputerName ) . Replace ( " $( [ char ] 0x0000 ) " , " " )
$Mon_Manufacturer = ( [ System.Text.Encoding ] :: ASCII . GetString ( $Monitor . ManufacturerName ) ) . Replace ( " $( [ char ] 0x0000 ) " , " " )
#Filters out "non monitors". Place any of your own filters here. These two are all-in-one computers with built in displays. I don't need the info from these.
If ( $Mon_Model -like " *800 AIO* " -or $Mon_Model -like " *8300 AiO* " ) { Break }
#Sets a friendly name based on the hash table above. If no entry found sets it to the original 3 character code
$Mon_Manufacturer_Friendly = $ManufacturerHash . $Mon_Manufacturer
2024-06-24 21:11:07 +00:00
If ( $null -eq $Mon_Manufacturer_Friendly ) {
2024-06-11 18:27:55 +00:00
$Mon_Manufacturer_Friendly = $Mon_Manufacturer
}
$Mon_Active_Port = $activePorts [ $Monitor . InstanceName ]
#Creates a custom monitor object and fills it with 4 NoteProperty members and the respective data
$Monitor_Obj = [ PSCustomObject ] @ {
Manufacturer = $Mon_Manufacturer_Friendly
Model = $Mon_Model
SerialNumber = $Mon_Serial_Number
AttachedComputer = $Mon_Attached_Computer
ActivePort = $Mon_Active_Port
}
#Appends the object to the array
$Monitor_Array + = $Monitor_Obj
} #End ForEach Monitor
#Outputs the Array
$Monitor_Array
} #End ForEach Computer
}
function Get-VIDPID {
param (
$deviceID
)
if ( $deviceID ) {
$bool = $deviceID -match '(?<=VID_)(....)'
if ( ! $bool ) {
return $null
}
$vid = $Matches [ 0 ]
$deviceID -match '(?<=PID_)(....)' | Out-Null
$p = $Matches [ 0 ]
return ( $vid , $p )
}
else {
return $null
}
}
function FindUSBDevice {
param (
[ string ] $vid ,
[ string ] $p ,
[ string ] $deviceID
)
if ( $deviceID ) {
$bool = $deviceID -match '(?<=VID_)(....)'
if ( ! $bool ) {
return $null
}
$vid = $Matches [ 0 ]
$deviceID -match '(?<=PID_)(....)' | Out-Null
$p = $Matches [ 0 ]
}
$SHSEquip = MatchSHSEquipment $vid $p
if ( $SHSEquip ) {
return ( $SHSEquip [ 0 ] , $SHSEquip [ 1 ] )
}
$lookupTablePath = Join-Path ( get-item $PSScriptRoot ) . Parent . FullName 'Data\USBIDs.txt'
$usbIDs = Get-Content $lookupTablePath
for ( $i = 0 ; $i -lt $usbIDs . Count ; $i + + ) {
if ( $usbIDs [ $i ] -match $vid ) {
if ( $usbIDs [ $i ] [ 0 ] -eq " `t " ) {
}
else {
$man = ( $usbIDs [ $i ] -split ' ' )
$man = $man [ 2 . . $man . count ] -join ' '
for ( $y = $i + 1 ; $y -lt $usbIDs . Count ; $y + + ) {
if ( $usbIDs [ $y ] [ 0 ] -ne " `t " ) {
return ( $man , $null )
}
if ( $usbIDs [ $y ] -match $p ) {
$dev = ( $usbIDs [ $y ] -split ' ' )
$dev = $dev [ 2 . . $dev . count ] -join ' '
return ( $man , $dev )
}
}
return ( $man , $null )
}
}
}
}
function MatchSHSEquipment {
param (
$vid ,
$p
)
$lookupTablePath = Join-Path ( get-item $PSScriptRoot ) . Parent . FullName 'Data\SHSEquipmentLookup.txt'
$usbIDs = Get-Content $lookupTablePath
for ( $i = 0 ; $i -lt $usbIDs . Count ; $i + + ) {
if ( $usbIDs [ $i ] -match $vid ) {
if ( $usbIDs [ $i ] [ 0 ] -eq " `t " ) {
}
else {
$man = ( $usbIDs [ $i ] -split ' ' )
$man = $man [ 2 . . $man . count ] -join ' '
for ( $y = $i ; $y -lt $usbIDs . Count ; $y + + ) {
if ( $usbIDs [ $y ] -match $p ) {
$dev = ( $usbIDs [ $y ] -split ' ' )
$dev = $dev [ 2 . . $dev . count ] -join ' '
return ( $man , $dev )
}
}
return $null
}
}
}
return $null
}