This tool will find a lot of information on remote computers using Powershell’s Get-WmiObject cmdlet.
It can easily find:
- PC Serial Number
- PC Printer Info
- Current User
- OS Info
- System Info
- Add/Remove Program List
- Process List
- Service List
- USB Devices
- Uptime
- Disk Space
- Memory Info
- Processor Info
- Monitor Serial Numbers (registry)
Hopefully someone out there will find this useful. If this won’t work for your needs – it can at least give you a guide to Get-WmiObject with Powershell. I am planning on releasing a Get-WmiObject/wmic cheat sheet sometime soon.
[START CODE]
#########################################################
# Powershell PC Info Script V1.0b #
# Coded By:Trenton Ivey(kno) #
#########################################################
function Pause ($Message="Press any key to continue..."){
""
Write-Host $Message
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
}
function GetCompName{
$compname = Read-Host "Please enter a computer name or IP"
CheckHost
}
function CheckHost{
$ping = gwmi Win32_PingStatus -filter "Address='$compname'"
if($ping.StatusCode -eq 0){$pcip=$ping.ProtocolAddress; GetMenu}
else{Pause "Host $compname down...Press any key to continue"; GetCompName}
}
function GetMenu {
Clear-Host
" /----------------------\"
" | PC INFO TOOL |"
" \----------------------/"
" $compname ($pcip)"
""
""
"1) PC Serial Number"
"2) PC Printer Info"
"3) Current User"
"4) OS Info"
"5) System Info"
"6) Add/Remove Program List"
"7) Process List"
"8) Service List"
"9) USB Devices"
"10) Uptime"
"11) Disk Space"
"12) Memory Info"
"13) Processor Info"
"14) Monitor Serial Numbers"
""
"C) Change Computer Name"
"X) Exit The program"
""
$MenuSelection = Read-Host "Enter Selection"
GetInfo
}
function GetInfo{
Clear-Host
switch ($MenuSelection){
1 { #PC Serial Number
gwmi -computer $compname Win32_BIOS | Select-Object SerialNumber | Format-List
Pause
CheckHost
}
2 { #PC Printer Information
gwmi -computer $compname Win32_Printer | Select-Object DeviceID,DriverName, PortName | Format-List
Pause
CheckHost
}
3 { #Current User
gwmi -computer $compname Win32_ComputerSystem | Format-Table @{Expression={$_.Username};Label="Current User"}
""
#May take a very long time if on a domain with many users
#"All Users"
#"------------"
#gwmi -computer $compname Win32_UserAccount | foreach{$_.Caption}
Pause
CheckHost
}
4 { #OS Info
gwmi -computer $compname Win32_OperatingSystem | Format-List @{Expression={$_.Caption};Label="OS Name"},SerialNumber,OSArchitecture
Pause
CheckHost
}
5 { #System Info
gwmi -computer $compname Win32_ComputerSystem | Format-List Name,Domain,Manufacturer,Model,SystemType
Pause
CheckHost
}
6 { #Add/Remove Program List
gwmi -computer $compname Win32_Product | Sort-Object Name | Format-Table Name,Vendor,Version
Pause
CheckHost
}
7 { #Process Listx
gwmi -computer $compname Win32_Process | Select-Object Caption,Handle | Sort-Object Caption | Format-Table
Pause
CheckHost
}
8 { #Service List
gwmi -computer $compname Win32_Service | Select-Object Name,State,Status,StartMode,ProcessID, ExitCode | Sort-Object Name | Format-Table
Pause
CheckHost
}
9 { #USB Devices
gwmi -computer $compname Win32_USBControllerDevice | %{[wmi]($_.Dependent)} | Select-Object Caption, Manufacturer, DeviceID | Format-List
Pause
CheckHost
}
10 { #Uptime
$wmi = gwmi -computer $compname Win32_OperatingSystem
$localdatetime = $wmi.ConvertToDateTime($wmi.LocalDateTime)
$lastbootuptime = $wmi.ConvertToDateTime($wmi.LastBootUpTime)
"Current Time: $localdatetime"
"Last Boot Up Time: $lastbootuptime"
$uptime = $localdatetime - $lastbootuptime
""
"Uptime: $uptime"
Pause
CheckHost
}
11 { #Disk Info
$wmi = gwmi -computer $compname Win32_logicaldisk
foreach($device in $wmi){
Write-Host "Drive: " $device.name
Write-Host -NoNewLine "Size: "; "{0:N2}" -f ($device.Size/1Gb) + " Gb"
Write-Host -NoNewLine "FreeSpace: "; "{0:N2}" -f ($device.FreeSpace/1Gb) + " Gb"
""
}
Pause
CheckHost
}
12 { #Memory Info
$wmi = gwmi -computer $compname Win32_PhysicalMemory
foreach($device in $wmi){
Write-Host "Bank Label: " $device.BankLabel
Write-Host "Capacity: " ($device.Capacity/1MB) "Mb"
Write-Host "Data Width: " $device.DataWidth
Write-Host "Device Locator: " $device.DeviceLocator
""
}
Pause
CheckHost
}
13 { #Processor Info
gwmi -computer $compname Win32_Processor | Format-List Caption,Name,Manufacturer,ProcessorId,NumberOfCores,AddressWidth
Pause
CheckHost
}
14 { #Monitor Info
#Turn off Error Messages
$ErrorActionPreference_Backup = $ErrorActionPreference
$ErrorActionPreference = "SilentlyContinue"
$keytype=[Microsoft.Win32.RegistryHive]::LocalMachine
if($reg=[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($keytype,$compname)){
#Create Table To Hold Info
$montable = New-Object system.Data.DataTable "Monitor Info"
#Create Columns for Table
$moncol1 = New-Object system.Data.DataColumn Name,([string])
$moncol2 = New-Object system.Data.DataColumn Serial,([string])
$moncol3 = New-Object system.Data.DataColumn Ascii,([string])
#Add Columns to Table
$montable.columns.add($moncol1)
$montable.columns.add($moncol2)
$montable.columns.add($moncol3)
$regKey= $reg.OpenSubKey("SYSTEM\\CurrentControlSet\\Enum\DISPLAY" )
$HID = $regkey.GetSubKeyNames()
foreach($HID_KEY_NAME in $HID){
$regKey= $reg.OpenSubKey("SYSTEM\\CurrentControlSet\\Enum\\DISPLAY\\$HID_KEY_NAME" )
$DID = $regkey.GetSubKeyNames()
foreach($DID_KEY_NAME in $DID){
$regKey= $reg.OpenSubKey("SYSTEM\\CurrentControlSet\\Enum\\DISPLAY\\$HID_KEY_NAME\\$DID_KEY_NAME\\Device Parameters" )
$EDID = $regKey.GetValue("EDID")
foreach($int in $EDID){
$EDID_String = $EDID_String+([char]$int)
}
#Create new row in table
$monrow=$montable.NewRow()
#MonitorName
$checkstring = [char]0x00 + [char]0x00 + [char]0x00 + [char]0xFC + [char]0x00
$matchfound = $EDID_String -match "$checkstring([\w ]+)"
if($matchfound){$monrow.Name = [string]$matches[1]} else {$monrow.Name = '-'}
#Serial Number
$checkstring = [char]0x00 + [char]0x00 + [char]0x00 + [char]0xFF + [char]0x00
$matchfound = $EDID_String -match "$checkstring(\S+)"
if($matchfound){$monrow.Serial = [string]$matches[1]} else {$monrow.Serial = '-'}
#AsciiString
$checkstring = [char]0x00 + [char]0x00 + [char]0x00 + [char]0xFE + [char]0x00
$matchfound = $EDID_String -match "$checkstring([\w ]+)"
if($matchfound){$monrow.Ascii = [string]$matches[1]} else {$monrow.Ascii = '-'}
$EDID_String = ''
$montable.Rows.Add($monrow)
}
}
$montable | select-object -unique Serial,Name,Ascii | Where-Object {$_.Serial -ne "-"} | Format-Table
} else {
Write-Host "Access Denied - Check Permissions"
}
$ErrorActionPreference = $ErrorActionPreference_Backup #Reset Error Messages
Pause
CheckHost
}
1337 { Write-Host "Program Made By Trenton Ivey (Trenton@hackyeah.com)";Pause; CheckHost}
c {Clear-Host;$compname="";GetCompName}
x {Clear-Host; exit}
default{CheckHost}
}
}
#---------Start Main--------------
$compname = $args[0]
if($compname){CheckHost}
else{GetCompName}
[END CODE]

Hi there great script.
I have two queries:
1) When i run the printer info it doesnt show me the networked printer on the users machine.
2) I wish to use this for our service desk users so that they can remote to peoples machines…How do i alter it so hat it asks for a username and password? Also would like the password not to be shown.
Many thanks
Chris,
1) This will only show locally installed printers. If however, the network printer was installed using a tcp/ip port (instead of a network share), it will show up.
2)That is great that you are going to use this for your service desk! Let me know how it works. To get it to work with username/passwords (in case your techs are not local admins on the pc’s) You can have it prompt for a password, and then send it with the get-wmiobject. To do so, you will first need to prompt for a username and password. I think the best way to do this is to change the main area to something like:
$compname = $args[0]
$cred = Get-Credential
if($compname){CheckHost}
else{GetCompName}
And then for each get-wmiobject (gwmi) user the -credential flag. So for the serialnumber it would look like:
gwmi -computer $compname Win32_BIOS -Credential $cred | Select-Object SerialNumber | Format-List
Hope that helps….let me know how it goes.
(P.S. – The monitor serial number uses the registry instead of wmi, and that may take some more tweaking to get it to work with authentication)
Excellent script.
One question. Is there a way to get just the serial numbers of the installed monitor(s)? Some of our systems have had 3 or 4 monitors over their lifetime and it would be nice to get just the currently used monitor info. Or if the systems are imaged it contains the monitor from the original base system.
@Mike – I have found no easy way to keep track of the current monitors. For desktops that are running windows Vista/7 I believe that there is now a WMI object you can query to get monitor serial numbers. For XP however, the only place I have been able to get this information is in the registry. It is possible to sort the registry data by date – and then just assume the current monitor is the most recent one. Although, this is not always the case.
Check out http://www.nirsoft.net/utils/monitor_info_view.html . This tool pulls a lot of monitor information from a PC. It is just an extended version of my powershell script (as an exe), but it is dedicated just to monitors.
Thanks Trenton. I was hoping there might be a way of combining the Get-WMIObject class win32_DesktopMonitor with what you’re pulling from the registry.
I’m an idiot, so forgive me. This is what I’m looking for at work but I’m not a code writer at all. Could you please tell me how I use this and what type of script this is?
Thank you.
Hi there im a noob when it comes to scripting and i like this code but not sure how to set it up. What would be the best way to use this ?
I do like things nice and easy. I found something that is just like that Easy Button that they advertise on TV for Staples. This technology was secretly “copied” from one of the top internet enterprises. The fact is, that this software is 100% legal, “white hat” and ethical, that even giant enterprises use it. And the best part – it is really running on full autopilot. This super affiliate push button software is the real thing, so if you’re planning to use it unethically, or use it for scam purposes, this software isn’t for you! If you can spend no more than 3 minutes to download and setup this software, and then click the ‘Start Button’ just once to start this autopilot push button software… Then you can make money online. This never seen before push button software proved that the best and most profitable traffic on the internet is free traffic. You might be tempted to try to disect this software in order to ‘see the magic’ but why bother? All you really need to know is that you can download it (if the link hasn’t been taken down yet) and then push a button and watch the magic. Try it out -> http://adf.ly/1TyCy
Trenton,
JAmes and I have made a couple changes to the Monitor section of your script. We exported a list of Laptops out od AD to run in the script. We also only wanted the monitor that are currenty connected. We think that the ones whit a control key are the monitor currentl connected. Let us know what you think.
Thanks
Larry
# ***********************************************
# * FindMonitor FindMonitorSN.PS1 *
# * Find Monitor Serial Number *
# * Creaters: Larry Arndorfer & James Hunt *
# * Revisions: 2011-05-23 Created *
# ***********************************************
Clear-Host
function Pause ($Message=”Press any key to continue…”){
“”
Write-Host $Message
$null = $Host.UI.RawUI.ReadKey(“NoEcho,IncludeKeyDown”)
}
function GetCompName{
$list = Import-Csv “C:\AD_Laptops.csv” -Header “Laptops”
foreach($compname in $list)
{
$compname = $($compname.Laptops)
CheckHost
}
}
function CheckHost{
$ping = gwmi Win32_PingStatus -filter “Address=’$compname’”
if($ping.StatusCode -eq 0){$pcip=$ping.ProtocolAddress; GetInfo}
else{“$compname down”}
}
function GetInfo{
# ********* Monitor Info ************
#Turn off Error Messages
$ErrorActionPreference_Backup = $ErrorActionPreference
$ErrorActionPreference = “SilentlyContinue”
$keytype=[Microsoft.Win32.RegistryHive]::LocalMachine
if($reg=[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($keytype,$compname)){
#Create Table To Hold Info
$montable = New-Object system.Data.DataTable “Monitor Info”
#Create Columns for Table
$moncol1 = New-Object system.Data.DataColumn Model,([string])
$moncol2 = New-Object system.Data.DataColumn Serial,([string])
$moncol3 = New-Object system.Data.DataColumn Ascii,([string])
$moncol4 = New-Object system.Data.DataColumn Computer,([string])
#Add Columns to Table
$montable.columns.add($moncol1)
$montable.columns.add($moncol2)
$montable.columns.add($moncol3)
$montable.columns.add($moncol4)
$regKey= $reg.OpenSubKey(“SYSTEM\\CurrentControlSet\\Enum\DISPLAY” )
$HID = $regkey.GetSubKeyNames()
foreach($HID_KEY_NAME in $HID){
$regKey= $reg.OpenSubKey(“SYSTEM\\CurrentControlSet\\Enum\\DISPLAY\\$HID_KEY_NAME” )
$DID1 = $regkey.GetSubKeyNames()
foreach($DID_KEY_NAME in $DID1){
$CheckActive = “False”
$regKey2=$reg.OpenSubKey(“SYSTEM\\CurrentControlSet\\Enum\\DISPLAY\\$HID_KEY_NAME\\$DID_KEY_NAME”)
$DID2=$regKey2.GetSubKeyNames()
foreach($DID2_KEY_NAME in $DID2){
If($DID2_KEY_NAME -EQ “Control”){
$regKey= $reg.OpenSubKey(“SYSTEM\\CurrentControlSet\\Enum\\DISPLAY\\$HID_KEY_NAME\\$DID_KEY_NAME\\Device Parameters” )
$EDID = $regKey.GetValue(“EDID”)
foreach($int in $EDID){
$EDID_String = $EDID_String+([char]$int)
}
#Create new row in table
$monrow=$montable.NewRow()
#ComputerName
$monrow.Computer = $compname
#MonitorName
$checkstring = [char]0×00 + [char]0×00 + [char]0×00 + [char]0xFC + [char]0×00
$matchfound = $EDID_String -match “$checkstring([\w ]+)”
if($matchfound){$monrow.Model = [string]$matches[1]} else {$monrow.Model = ‘-’}
#Serial Number
$checkstring = [char]0×00 + [char]0×00 + [char]0×00 + [char]0xFF + [char]0×00
$matchfound = $EDID_String -match “$checkstring(\S+)”
if($matchfound){$monrow.Serial = [string]$matches[1]} else {$monrow.Serial = ‘-’}
#AsciiString
$checkstring = [char]0×00 + [char]0×00 + [char]0×00 + [char]0xFE + [char]0×00
$matchfound = $EDID_String -match “$checkstring([\w ]+)”
if($matchfound){$monrow.Ascii = [string]$matches[1]} else {$monrow.Ascii = ‘-’}
$EDID_String = ”
$montable.Rows.Add($monrow)
}
}
}
}
$montable | select-object -unique Computer,Serial,Model,Ascii | Where-Object {$_.Serial -ne “-”} | Format-Table
} else {
Write-Host “Access Denied – Check Permissions”
}
$ErrorActionPreference = $ErrorActionPreference_Backup #Reset Error Messages
#Pause
#CheckHost
}
#———Start Main————–
$compname = $args[0]
if($compname){CheckHost}
else{GetCompName}