Author Posts

October 17, 2017 at 11:56 am

Hi All,
I came across the below script and tried modifying it to instead of just use the one Hostname, use a Text file with get-content,
However i keep getting errors no mater which way i try to format it,
Is someone able to tell me what im doing wrong please.
Thanks,

I changed from the original code below to be: [String[]]$ComputerName = get-content c:\temp\machinelist.txt
I tried moving down a few lines as well but same issue,
Any help would be great.
Thanks.
—————————-

 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
  #>


  [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";
      }
      
  
  #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
    
    #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
      If ([System.Text.Encoding]::ASCII.GetString($Monitor.UserFriendlyName) -ne $null) {
        $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
      If ($Mon_Manufacturer_Friendly -eq $null) {
        $Mon_Manufacturer_Friendly = $Mon_Manufacturer
      }
      
      #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
      }
      
      #Appends the object to the array
      $Monitor_Array += $Monitor_Obj

    } #End ForEach Monitor
  
    #Outputs the Array
    $Monitor_Array
    
} #End ForEach Computer

October 17, 2017 at 2:07 pm

Since it's a little hard to cold-read someone else's code, can you share the problem your'e having and any error message?

October 17, 2017 at 10:42 pm

Hi Don,
Thanks for the prompt response.
I am finding that it is only working for the first machine listed in the text file, not the additional machines, even if ii change hostnames etc. I had a colleague look at it and was advised when trying to debug it, that it only seems to pass through the first machine, not additional ones.
One recommendation given to me was to try invoke the script remotely on our office machines however was advised by a colleague that we aren't able to do that, instead I would need to log into one machine with my admin and run it from there to remotely capture the details.

I need to do an AssetManagement capture, so I am after a script that I can run on one machine, feed in a Text file of the hostnames and capture the results into a txt or csv file – I need the Hostname, and MOnitor Make as well as Serial Numbers to be all displayed,
THings such as Last Logged in User or OS would be a great extra but not a necessity at this stage.

Thanks,

*************************************************************************************
Error:
PS T:\AU_Support\_Scripts_And_Batch Files\Asset_Scans> C:\Temp\MonitorScan_v8.ps1

Manufacturer Model SerialNumber AttachedComputer
———— —– ———— —————-
Dell DELL U2415 G7W7975D35RS SYDAC02955D
Dell DELL U2415 G7W797680YJS SYDAC02955D
Get-WmiObject : Not supported
At C:\Temp\MonitorScan_v8.ps1:116 char:17
+ $Monitors = Get-WmiObject -Namespace "root\WMI" -Class "WMIMonitorID" -Compu ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Get-WmiObject], ManagementException
+ FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

PS T:\AU_Support\_Scripts_And_Batch Files\Asset_Scans>

October 17, 2017 at 10:47 pm

So, I guess I should point out that you're taking kind of a non-PowerShell approach to the way you've designed your script. You're accumulating data in an array, for example, which is kind of a Bad Sign (https://devops-collective-inc.gitbooks.io/the-big-book-of-powershell-gotchas/content/manuscript/accumulating-output-in-a-function.html). The approach is a bit of what makes this harder to debug.

You've also got SilentlyContinue enabled, which is a terrible idea, because any useful errors we might be seeing are being suppressed.

I realize you didn't write this, just pointing it out 😉

The "Not supported" error is telling you that the remote computer doesn't want to provide a response. It's possible it lacks a root\WMI namespace, or that the WMIMonitorID class doesn't exist. That information has to be exposed by the vendor to Windows; it's not something Windows itself provides. So support does differ across machines.

October 18, 2017 at 2:32 am

ok np,
Yeh, as I'm still trying to learn in my spare time, I basically copied and tried modifying someone else's script.
I came across another one that I was thinking I may be able to edit and source out the Monitor details?
Any suggestions please?

A)I just get numbers for the Monitor Details instead of the actual Text,
B)Not sure how this will handle multiple Monitors as i am testing on a Laptop at the moment
C)Still trying to figure out how to make it output to a Text file instead of screen
Thanks
———

# Remote System Information
# Shows hardware and OS details from a list of PCs

#$ArrComputers =  "."
$ArrComputers =  get-content c:\scripts\machinelist.txt
#Specify the list of PC names in the line above. "." means local system

Clear-Host
foreach ($Computer in $ArrComputers) 
{
    $computerSystem = get-wmiobject Win32_ComputerSystem -Computer $Computer
    $computerBIOS = get-wmiobject Win32_BIOS -Computer $Computer
    $computerOS = get-wmiobject Win32_OperatingSystem -Computer $Computer
    $MonitorInfo = Get-WmiObject -Namespace root\wmi -Class WmiMonitorID -ComputerName $Computer
    #$computerCPU = get-wmiobject Win32_Processor -Computer $Computer
    $computerHDD = Get-WmiObject Win32_LogicalDisk -ComputerName $Computer -Filter drivetype=3
        write-host "System Information for: " $computerSystem.Name -BackgroundColor DarkCyan
        "-------------------------------------------------------"
        "Manufacturer: " + $computerSystem.Manufacturer
        "Model: " + $computerSystem.Model
        "Serial Number: " + $computerBIOS.SerialNumber
        #"CPU: " + $computerCPU.Name
        #"HDD Capacity: "  + "{0:N2}" -f ($computerHDD.Size/1GB) + "GB"
        "HDD Space: " + "{0:P2}" -f ($computerHDD.FreeSpace/$computerHDD.Size) + " Free (" + "{0:N2}" -f ($computerHDD.FreeSpace/1GB) + "GB)"
        "RAM: " + "{0:N2}" -f ($computerSystem.TotalPhysicalMemory/1GB) + "GB"
        "Operating System: " + $computerOS.caption + ", Service Pack: " + $computerOS.ServicePackMajorVersion
        "User logged In: " + $computerSystem.UserName
        "Last Reboot: " + $computerOS.ConvertToDateTime($computerOS.LastBootUpTime)
        "Monitor Make: " + $MonitorInfo.ManufacturerName
        "Monitor Model: " + $MonitorInfo.ManufacturerName
        "Monitor Serial: " + $MonitorInfo.SerialNumberid
}        
        ""
        "-------------------------------------------------------"

Thanks again

October 18, 2017 at 11:56 am

Update- I tried using "| Out-File -FilePath C:\scripts\testlog.txt -Append", however it only seems to output some of the details into a text file, not all that i can see on the screen.
Is it technically not possible to output this type of script to a text file?
Thanks

October 18, 2017 at 12:57 pm

Grab a copy of "Learn Windows PowerShell in a Month of Lunches" sometime; it explains the formatting system. Short answer: If you don't tell it which properties to include, it defaults to an 80-column output files and chooses as many properties as will fit. It isn't intended to be a duplicate of what's on screen. Solution? Pipe to Format-Table first, and indicate which properties you want.