Created
November 5, 2013 10:01
-
-
Save ararog/7316613 to your computer and use it in GitHub Desktop.
This script does a computer monitor lookup.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[CmdletBinding(DefaultParameterSetName="ComputerName")] | |
param ( | |
[Parameter(Mandatory = $FALSE, ParameterSetName="ComputerName", HelpMessage="Name of computer to check")] | |
[String] | |
$ComputerName | |
) | |
Function InArray($element, $array, $position) { | |
If($array.Count -eq 0) { | |
return $False | |
} | |
foreach($item in $array) { | |
If($item.Count -gt 0) { | |
If($item[$position] -eq $element) { | |
return $True | |
} | |
} | |
} | |
return $False | |
} | |
Function EchoAndLog ($message) { | |
#Echo output and write to log | |
write-output $message | |
$message >> $logFile | |
} | |
Function Show-Msgbox { | |
Param([string]$message=$(Throw "You must specify a message"), | |
[string]$button="okonly", | |
[string]$icon="information", | |
[string]$title="Message Box" | |
) | |
#Buttons: OkOnly, OkCancel, AbortRetryIgnore, YesNoCancel, YesNo, RetryCancel | |
#Icons: Critical, Question, Exclamation, Information | |
[Reflection.Assembly]::LoadWithPartialName("Microsoft.Visualbasic") | Out-Null | |
[Microsoft.Visualbasic.Interaction]::Msgbox($message, "$button, $icon", $title) | |
} | |
$batch = $false | |
If(! $ComputerName) { | |
[Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null | |
$ComputerName = [Microsoft.VisualBasic.Interaction]::InputBox("Check Monitor info for what PC", "PC Name?", "$env:computername") | |
} | |
else { | |
$batch = $true | |
} | |
If(! $ComputerName) { | |
exit | |
} | |
$ComputerName = $ComputerName.ToUpper() | |
$MonitorCount = 0 | |
$StringArrayRawEDIDs = @() | |
$logFile = "$env:userprofile\Desktop\MonitorInfo.csv" | |
$message = "" | |
If($batch) { | |
$header = $false | |
$file_exists = test-path $logFile | |
If(! $file_exists) { | |
$header = $true | |
} | |
if($header) { | |
"Computer,Model,Serial #,Vendor ID,Manufacture Date,Messages" > $logFile | |
} | |
} | |
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("LocalMachine", "$ComputerName") | |
$displayKey = $reg.OpenSubKey("SYSTEM\\CurrentControlSet\\Enum\\DISPLAY\\") | |
foreach ($displayKeyValue in $displayKey.GetSubKeyNames()) { | |
$monitorIdKey = $displayKey.OpenSubKey("$displayKeyValue") | |
foreach ($pnpIdKeyValue in $monitorIdKey.GetSubKeyNames()) { | |
$pnpIdKey = $monitorIdKey.OpenSubKey("$pnpIdKeyValue") | |
foreach($hardwareIdKeyValue in $pnpIdKey.GetValue("HardwareID")) { | |
If($hardwareIdKeyValue.ToLower().IndexOf("monitor\") -gt -1) { | |
foreach ($pnpDetailsKeyValue in $pnpIdKey.GetSubKeyNames()) { | |
$strRawEDID = "" | |
If($pnpDetailsKeyValue -eq "Control") { | |
$deviceParametersKey = $pnpIdKey.OpenSubKey("Device Parameters") | |
$edid = $deviceParametersKey.GetValue("EDID") | |
if(! $edid) { | |
$strRawEDID = "EDID Not Available" | |
} | |
else { | |
foreach($byteValue in $edid) { | |
$strRawEDID = $strRawEDID + [char]$byteValue | |
} | |
} | |
$StringArrayRawEDIDs += $strRawEDID | |
$MonitorCount += 1 | |
} | |
} | |
} | |
} | |
} | |
} | |
$ArrayMonitorInfo = @() | |
$Location = @("", "", "", "") | |
$intSerFoundAt, $intMdlFoundAt, $findit = 0 | |
$tmp, $tmpser, $tmpmdl, $tmpctr = "" | |
foreach($string in $StringArrayRawEDIDs) { | |
if($string -ne "EDID Not Available") { | |
$Location[0] = $string.Substring(0x36, 19) | |
$Location[1] = $string.Substring(0x48, 19) | |
$Location[2] = $string.Substring(0x5a, 19) | |
$Location[3] = $string.Substring(0x6c, 19) | |
#you can tell If the location contains a serial number If it starts with &H00 00 00 ff | |
$strSerFind = ([char](0x00)) + ([char](0x00)) + ([char](0x00)) + ([char](0xff)) | |
#or a model description If it starts with &H00 00 00 fc | |
$strMdlFind = ([char](0x00)) + ([char](0x00)) + ([char](0x00)) + ([char](0xfc)) | |
$intSerFoundAt = -1 | |
$intMdlFoundAt = -1 | |
for($findit = 0; $findit -le 3; $findit++) { | |
If($Location[$findit].IndexOf($strSerFind) -gt -1) { | |
$intSerFoundAt = $findit | |
} | |
If($Location[$findit].IndexOf($strMdlFind) -gt -1) { | |
$intMdlFoundAt = $findit | |
} | |
} | |
#If a location containing a serial number block was found then store it | |
If($intSerFoundAt -ne -1) { | |
$tmp = $Location[$intSerFoundAt] | |
$tmp = $tmp.substring($tmp.length - 14, 14) | |
If($tmp.IndexOf([char](0x0a)) -gt -1) { | |
$tmpser = $tmp.substring(0, $tmp.IndexOf([char](0x0a))).Trim() | |
} | |
else { | |
$tmpser = $tmp.Trim() | |
} | |
#although it is not part of the edid spec it seems as though the | |
#serial number will frequently be preceeded by &H00, this | |
#compensates for that | |
If($tmpser.substring(0, 1) -eq [char](0)) { | |
$tmpser = $tmpser.substring($tmpser.length - 1, 1) | |
} | |
} | |
else { | |
$tmpser = "Not Found" | |
} | |
#If a location containing a model number block was found then store it | |
If($intMdlFoundAt -ne -1) { | |
$tmp = $Location[$intMdlFoundAt] | |
$tmp = $tmp.substring($tmp.length - 14, 14) | |
If($tmp.IndexOf([char](0x0a)) -gt -1) { | |
$tmpmdl = $tmp.substring(0, $tmp.IndexOf([char](0x0a))).Trim() | |
} | |
else { | |
$tmpmdl = $tmp.Trim() | |
} | |
#although it is not part of the edid spec it seems as though the | |
#serial number will frequently be preceeded by &H00, this | |
#compensates for that | |
If($tmpmdl.substring(0, 1) -eq [char](0)) { | |
$tmpmdl = $tmpmdl.substring($tmpmdl.length - 1, 1) | |
} | |
} | |
else { | |
$tmpmdl = "Not Found" | |
} | |
#************************************************************** | |
#Next get the mfg date | |
#************************************************************** | |
$tmpmfgweek, $tmpmfgyear, $tmpmdt = "" | |
#the week of manufacture is stored at EDID offset &H10 | |
$tmpmfgweek = [byte][char]($string.substring(0x10, 1)) | |
#the year of manufacture is stored at EDID offset &H11 | |
#and is the current year -1990 | |
$tmpmfgyear = ([byte][char]($string.substring(0x11, 1))) + 1990 | |
#store it in month/year format | |
$calendar = [System.Globalization.CultureInfo]::InvariantCulture.Calendar | |
$date = $calendar.AddWeeks([datetime]("1/1/" + $tmpmfgyear), $tmpmfgweek) | |
$tmpmdt = $date.ToString("MM") + "/" + $tmpmfgyear | |
#************************************************************** | |
#Next get the edid version | |
#************************************************************** | |
#the version is at EDID offset &H12 | |
$tmpEDIDMajorVer, $tmpEDIDRev, $tmpVer = "" | |
$tmpEDIDMajorVer = [byte][char]($string.substring(0x12, 1)) | |
#the revision level is at EDID offset &H13 | |
$tmpEDIDRev = [byte][char]($string.substring(0x13, 1)) | |
#store it in month/year format | |
$tmpver = [char](48 + $tmpEDIDMajorVer) + "." + [char](48 + $tmpEDIDRev) | |
#************************************************************** | |
#Next get the mfg id | |
#************************************************************** | |
#the mfg id is 2 bytes starting at EDID offset &H08 | |
#the id is three characters long. using 5 bits to represent | |
#each character. the bits are used so that 1=A 2=B etc.. | |
# | |
#get the data | |
$tmpEDIDMfg, $tmpMfg | |
$Char1, $Char2, $Char3 | |
$Byte1, $Byte2 | |
$tmpEDIDMfg = $string.substring(0x08, 2) | |
$Char1, $Char2, $Char3 = 0 | |
$Byte1 = [byte][char]($tmpEDIDMfg.substring(0, 1)) #get the first half of the string | |
$Byte2 = [byte][char]($tmpEDIDMfg.substring($tmpEDIDMfg.length - 1, 1)) #get the first half of the string | |
#now shift the bits | |
#shift the 64 bit to the 16 bit | |
If (($Byte1 -band 64) -gt 0) { | |
$Char1 = $Char1 + 16 | |
} | |
#shift the 32 bit to the 8 bit | |
If (($Byte1 -band 32) -gt 0) { | |
$Char1 = $Char1 + 8 | |
} | |
#etc.... | |
If (($Byte1 -band 16) -gt 0) { | |
$Char1 = $Char1 + 4 | |
} | |
If (($Byte1 -band 8) -gt 0) { | |
$Char1 = $Char1 + 2 | |
} | |
If (($Byte1 -band 4) -gt 0) { | |
$Char1 = $Char1 + 1 | |
} | |
#the 2nd character uses the 2 bit and the 1 bit of the 1st byte | |
If (($Byte1 -band 2) -gt 0) { | |
$Char2 = $Char2 + 16 | |
} | |
If (($Byte1 -band 1) -gt 0) { | |
$Char2 = $Char2 + 8 | |
} | |
#and the 128,64 and 32 bits of the 2nd byte | |
If (($Byte2 -band 128) -gt 0) { | |
$Char2 = $Char2 + 4 | |
} | |
If (($Byte2 -band 64) -gt 0) { | |
$Char2 = $Char2 + 2 | |
} | |
If (($Byte2 -band 32) -gt 0) { | |
$Char2 = $Char2 + 1 | |
} | |
#the bits for the 3rd character don't need shifting | |
#we can use them as they are | |
$Char3 = $Char3 + ($Byte2 -band 16) | |
$Char3 = $Char3 + ($Byte2 -band 8) | |
$Char3 = $Char3 + ($Byte2 -band 4) | |
$Char3 = $Char3 + ($Byte2 -band 2) | |
$Char3 = $Char3 + ($Byte2 -band 1) | |
$tmpmfg = [char]($Char1 + 64) + [char]($Char2 + 64) + [char]($Char3 + 64) | |
#************************************************************** | |
#Next get the device id | |
#************************************************************** | |
#the device id is 2bytes starting at EDID offset &H0a | |
#the bytes are in reverse order. | |
#this code is not text. it is just a 2 byte code assigned | |
#by the manufacturer. they should be unique to a model | |
$tmpEDIDDev1, $tmpEDIDDev2, $tmpDev | |
$tmpEDIDDev1 = "{0:X}" -f ([byte][char]($string.substring(0x0a, 1))) | |
$tmpEDIDDev2 = "{0:X}" -f ([byte][char]($string.substring(0x0b, 1))) | |
If($tmpEDIDDev1.length -eq 1) { | |
$tmpEDIDDev1 = "0" + $tmpEDIDDev1 | |
} | |
If($tmpEDIDDev2.length -eq 1){ | |
$tmpEDIDDev2 = "0" + $tmpEDIDDev2 | |
} | |
$tmpdev = $tmpEDIDDev2 + $tmpEDIDDev1 | |
#************************************************************** | |
#finally store all the values into the array | |
#************************************************************** | |
#Kaplan adds code to avoid duplication... | |
$test = InArray($tmpser, $arrayMonitorInfo, 3) | |
If(! $test) { | |
$monitorInfo = @($tmpmfg, $tmpdev, $tmpmdt, $tmpser, $tmpmdl, $tmpVer) | |
$arrayMonitorInfo += (,$monitorInfo) | |
} | |
} | |
} | |
#For now just a simple screen print will suffice for output. | |
#But you could take this output and write it to a database or a file | |
#and in that way use it for asset management. | |
$i = 0 | |
foreach($info in $arrayMonitorInfo) { | |
If ($info[1] -ne "" -and $info[0] -ne "PNP") { | |
If ($batch) { | |
EchoAndLog($ComputerName + "," + $info[4] + "," + $info[3] + "," + $info[0] + "," + $info[2]) | |
} | |
Else { | |
$message = $message + "Monitor " + [char]($i+65) + ")`nModel Name: " + $info[4] + "`nSerial Number: " + $info[3] + "`nVESA Manufacturer ID: " + $info[0] + "`nManufacture Date: " + $info[2] + "`n`n" | |
$i += 1 | |
} | |
} | |
} | |
If(! $batch) { | |
show-msgbox -message $message -icon "information" -button "OKOnly" -title $ComputerName + " Monitor Info" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment