Formatting my Output. My replace, doesn't

This topic contains 1 reply, has 2 voices, and was last updated by Profile photo of Don Jones Don Jones 3 years, 6 months ago.

  • Author
    Posts
  • #11788
    Profile photo of notarat
    notarat
    Participant

    I'm currently working on a script that will query a list of computers and record the monitor information.

    Simple enough one would think and, for you experts, it probably is. For me, however, I am having a hard time grasping the formatting of the output when the script finds a computer that has two monitors connected.

    $$monitor = gwmi WmiMonitorID -Namespace root\wmi | select pscomputername,ManufacturerName,UserFriendlyName,SerialNumberID
    $Mfgr=($monitor.ManufacturerName | foreach {[char]$_}) -join ""
    $Model=($monitor.UserFriendlyName | foreach {[char]$_}) -join ""
    $Ser=($monitor.SerialNumberID | foreach {[char]$_}) -join ""
    $cname=($monitor.PSComputerName | foreach {($_.Split('='))[0]}) -Join ","
    #just to see what the output is
    write-host $cname,$mfgr,$model,$ser
    

    Output from this script does show information for two connected monitors, and does so on one line, but the formatting of the fields that contain information for more than one monitor is "off", in that there is a large gap between values.

    Example:

    $mfgr shows SAMDEL and I want it to show as SAM,DEL

    There is a space 13 characters wide between SAM and DEL that the post will not reproduce

    Same thing with the Model Number, as well as Serial Number

    I've tried doing a replace, similar to the following:

    $mfgr=($mfgr -replace '             ',',')  
    

    but the result is still SAM DEL

    It's like the replace doesn't "see" the large gap.

    I've read about formatting on multiple sites, but I cannot seem to grasp this particular concept.

    Could someone explain it to me and maybe show me why my replace statement didn't find the large empty gap between the mfgr?

  • #11789
    Profile photo of Don Jones
    Don Jones
    Keymaster

    Ah. Yeah, that's a bit tricky. And different versions of PowerShell will "do some of this for you" which makes it harder to see what's going wrong.

    $monitor will contain two complete objects if the computer has more than one monitor. That's where you're going wrong on this. This:

    $Mfgr=($monitor.ManufacturerName | foreach {[char]$_}) -join ""
    

    If $monitor contains two things, then $monitor.manufacturername doesn't technically work. Now, in PowerShell v3, it'll implicitly enumerate the collection and spit out the two strings from each object's ManufacturerName – that's the under-the-hood magic that makes this hard to figure out. So in v3 or later:

    $Mfgr=($monitor.ManufacturerName | foreach {[char]$_}) -join ","
    

    Ought to get you closer. But I guess more traditionally someone would do:

    $Mfgr = @()
    ForEach ($one_monitor in $monitor) {
     $mfgr += $one_monitor.manufacturername
    }
    $all_mfgr = $mfgr -join ","
    

    So, create an empty array for names, populate the names from each monitor, and then join them into a comma-separated list. Whether you do it exactly like that or not doesn't matter, but I think the logic is a bit easier to follow that way. You could obviously do your model, serial number, and other items the same way, and populate them all in the same ForEach loop. That'd perform better than what you're doing now.

    $Mfgr = @()
    $Model = @()
    ForEach ($one_monitor in $monitor) {
     $mfgr += $one_monitor.manufacturername
     $model += $one_monitor.userfriendlyname
    }
    $all_mfgr = $mfgr -join ","
    $all_model = $model -join ","
    

    Only one loop, that way, instead of the four you've got.

You must be logged in to reply to this topic.