Daybreak Faction - code beauty at it's best - Puzzle 1

This topic contains 18 replies, has 7 voices, and was last updated by  Alex Aymonier 3 days, 7 hours ago.

  • Author
    Posts
  • #91372

    Alex Aymonier
    Participant

    A place for beautiful code

  • #91373

    Alex Aymonier
    Participant

    I don't have 2 monitors so can't test the Multi Monitor. Written in PS 5.1. Looks FAB 🙂

    $Monitor  = Get-WmiObject -Namespace root\wmi   -Class 'wmiMonitorID' 
    $Computer = Get-WmiObject -Namespace root\cimv2 -Class 'Win32_ComputerSystem'
    $Bios     = Get-WmiObject -Namespace root\cimv2 -class 'win32_bios' 
    
    $Monitor | ForEach-Object -Process { 
        
        $PSObject = New-Object PSObject
    
        $PSObject | Add-Member -MemberType 'NoteProperty' -value "" -name 'ComputerName'
        $PSObject | Add-Member -MemberType 'NoteProperty' -value "" -name 'ComputerType'
        $PSObject | Add-Member -MemberType 'NoteProperty' -value "" -name 'ComputerSerial'
        $PSObject | Add-Member -MemberType 'NoteProperty' -value "" -name 'MonitorSerial'
        $PSObject | Add-Member -MemberType 'NoteProperty' -value "" -name 'MonitorType'
        
        $PSObject.ComputerName   =  $env:computername 
        $PSObject.ComputerType   =  $Computer.Model 
        $PSObject.ComputerSerial =  $bios.SerialNumber
        $PSObject.MonitorSerial  =  If ($Monitor.SerialNumberID -ne 0) 
                                    {  
                                      ($Monitor.SerialNumberID) -join ""
                                    } 
        $PSObject.MonitorType    =  If ($Monitor.UserFriendlyName -ne 0)
                                    {
                                        ($Monitor.UserFriendlyName |  
                                        ForEach-Object -Process {[char]$_}) -join "" 
                                    }
        Write-Output -InputObject $PSObject
        
    }
    
    • #91379

      Brandon Lundt
      Participant

      I went with a function.

    • #91390

      Alex Aymonier
      Participant

      Now that is beautiful

    • #91456

      Alex Aymonier
      Participant

      Tested this and it works beautifully. I hope you don't mind but i just did a little editing to make it look even better. Hopefully this translates when pasting in the code. Mainly with the Get-CimInstance cmdlets used and the placement of the name spaces and the splatting.

      Function Get-MonitorStatistics {
          Get-MonitorStatistics
      
                      ComputerName   : Computer01
                      ComputerType   : GA-990FXA-UD3
                      ComputerSerial :  
                      MonitorSerial  : 48000000000000000
                      MonitorType    : 80727376748083000000
              .EXAMPLE
                 PS C:\>Computer01,Computer02 | Get-MonitorStatistics
      
                      ComputerName   : Computer01
                      ComputerType   : GA-990FXA-UD3
                      ComputerSerial :  
                      MonitorSerial  : 48000000000000000
                      MonitorType    : Sony
      
                      ComputerName   : Computer02
                      ComputerType   : GA-980FXA-UD3
                      ComputerSerial :  
                      MonitorSerial  : 48000230000000000
                      MonitorType    : Philips
      
                      ComputerName   : Computer01
                      ComputerType   : GA-980FXA-UD3
                      ComputerSerial :  
                      MonitorSerial  : 48004500000000000
                      MonitorType    : Philips
              .INPUTS
                 ComputerName
              .OUTPUTS
                 PSCustomObject
          #>
          [cmdletbinding(SupportsShouldProcess = $False)]
          Param(
              [Parameter(Mandatory = $False,
                         ValueFromPipeline = $True)]
              [String]$ComputerName = $env:COMPUTERNAME
              
          )#Param
          Begin{
              
              New-Variable -Name Cim_Parameters
              New-Variable -Name Computer
              New-Variable -Name ComputerSerial
              New-Variable -Name MonitorSerial
              New-Variable -Name MonitorType
      
          }#Begin
          Process{
              
              if( $ComputerName -eq $env:COMPUTERNAME){
                  $Cim_Parameters = @{}
              }#if ComputerName is local machine
              else{
                  $Cim_Parameters = @{
                      ComputerName = $ComputerName
                  }#Cim_Parameters
              }#else ComputerName is not local machine
              $Computer       = Get-CimInstance @Cim_Parameters -Namespace 'root/cimv2' -ClassName 'Win32_ComputerSystem'
              $ComputerSerial = Get-CimInstance @Cim_Parameters -Namespace 'root/cimv2' -ClassName 'Win32_Bios' |
                                Select-Object -ExpandProperty 'SerialNumber'
              
              Get-CimInstance @Cim_Parameters -Namespace 'root\wmi' -ClassName 'wmiMonitorID' |
              ForEach-Object {
                  
                  $MonitorSerial = ""
                  Foreach($Item in $PSItem.SerialNumberID){
                      $MonitorSerial += $Item.ToString()
                  }
                  
                  $MonitorType = ""
                  Foreach($Item in $PSItem.UserFriendlyName){
                      $MonitorType += [char]$Item
                  }
                  $psObject = New-Object -TypeName PSObject
                  Add-Member -InputObject $psObject -MemberType NoteProperty -Name 'ComputerName'   -Value $env:COMPUTERNAME
                  Add-Member -InputObject $psObject -MemberType NoteProperty -Name 'ComputerType'   -Value $Computer.model
                  Add-Member -InputObject $psObject -MemberType NoteProperty -Name 'ComputerSerial' -Value $ComputerSerial
                  Add-Member -InputObject $psObject -MemberType NoteProperty -Name 'MonitorSerial'  -Value $MonitorSerial
                  Add-Member -InputObject $psObject -MemberType NoteProperty -Name 'MonitorType'    -Value $MonitorType
                  
                  Write-Output -InputObject $psObject
              }#ForEach-Object Get-CimInstance
          }#Process
          End{
              
              Remove-Variable -Name psObject
              Remove-Variable -Name Computer
              Remove-Variable -Name ComputerSerial
              Remove-Variable -Name MonitorSerial
              Remove-Variable -Name MonitorType
          }
      }#Function
      
    • #91460

      Brandon Lundt
      Participant

      I don't mind at all. In fact, I dig it.

  • #91376

    Alex Aymonier
    Participant

    That was thrown together quickly (Sunday afternoon here in Sydney) but thinking more on it we could use the pscustom object type accelerator and make the script even more beautiful. Got to get back to the kids at the moment but will pop back in later on.

    • #91391

      ck
      Participant

      My refactor of Alex's code mixing with mine.

      function Get-MonitorAndComputerInformation {
        param ($ComputerName)
      
        $PSDefaultParameterValues = @{
          'Get-WmiObject:ComputerName'= $ComputerName
        }
        $Monitor  = Get-WmiObject -Namespace root\wmi   -Class 'wmiMonitorID'
        $Computer = Get-WmiObject -Namespace root\cimv2 -Class 'Win32_ComputerSystem'
        $Bios     = Get-WmiObject -Namespace root\cimv2 -Class 'win32_bios'
        $Monitor | ForEach-Object -Process {
          @{
            ComputerName   =  $Computer.name;
            ComputerType   =  $Computer.Model;
            ComputerSerial =  $Bios.SerialNumber;
            MonitorSerial  =
              if ($Monitor.SerialNumberID -ne 0){
                ($Monitor.SerialNumberID  |
                  ForEach-Object -Process {
                    [char]$_
                  }
                ) -join ""
              };
            MonitorType =
              if ($Monitor.UserFriendlyName -ne 0){
                ( $Monitor.UserFriendlyName |
                  ForEach-Object -Process {
                    [char]$_}
                ) -join ""
              };
          }
        }
      }
      
      Get-MonitorAndComputerInformation -ComputerName localhost
      
  • #91388

    ck
    Participant

    I might need to switch to a different faction :p

    function Get-ComputerMetaData {
      param (
        $ComputerName
      )
      $PSDefaultParameterValues = @{
        'Get-WmiObject:ComputerName'= $ComputerName
      }
    
      Get-WmiObject -Class 'wmiMonitorID' -namespace root\wmi |
      Select-Object @{
        Name = 'MonitorSerial'
        Expression = {(
          $_.SerialNumberID |
          ForEach-Object {
            [char]$_
          }
        ) -join ''}
      },
      @{
        Name = 'MonitorType'
        Expression = {(
          $_.UserFriendlyName |
          ForEach-Object {
            [char]$_
          }
        ) -join ''}
      },
      @{
        Name= 'ComputerName'
        Expression = {
          Get-WMIObject -Class 'Win32_ComputerSystem' |
          Select-Object -ExpandProperty Name
        }
      },
      @{
        Name = 'ComputerModel'
        Expression = {
          Get-WmiObject -Class 'Win32_ComputerSystem' |
          Select-Object -ExpandProperty Model
        }
      },
      @{
        Name = 'ComputerSerialNumber'
        Expression = {
          Get-WmiObject -Class 'Win32_Bios' |
          Select-Object -ExpandProperty SerialNumber
        }
      }
    }
    
    Get-ComputerMetaData -ComputerName localhost
    
  • #91393

    Brandon Olin
    Participant

    This should support remote machine names passed via the pipeline as well as an array to -ComputerName.

    • #91457

      Alex Aymonier
      Participant

      Hey Brandon, another beautiful function but for some reason it fails on my laptop's monitor, probably because it does not have a type. Might need to revisit the error handling in there.

    • #91465

      Jaykul
      Participant

      Props to Brandon, a single function without needing to branch for remoting is a nice touch. Using

      [PSCustomObject]@{ ... }

      instead of Add-Member is my kind of code-beauty. You missed my bonus points though, because although you assigned a custom PSTypeName, you didn't specify it in the

      [OutputType('PSCustomObject')]

      😉

    • #91466

      Brandon Olin
      Participant

      Do we get to amend our answers or is this an immutable contest? 🙂

    • #91562

      Alex Aymonier
      Participant

      I'd say by all means upload a updated version of the script for prosperity reasons.

    • #91725

      Alex Aymonier
      Participant

      Started using this going forward, thanks.

      [OutputType('PSCustomObject')]
    • #91471

      Brandon Olin
      Participant

      I noticed that

      $monitors = Get-CimInstance -ClassName wmiMonitorID -Namespace root\wmi

      fails in a VM (At least a Win10 VM running with Fusion on macOS. Works fine when booted to Windows directly.

  • #91406

    Willy Moselhy
    Participant

    Here's my contribution

    • #91463

      Alex Aymonier
      Participant

      Good looking but i get a weired error when running it.

      PS C:\> Get-MonitorInformation
      
      
      ComputerName   : PC03Z4EN
      ComputerType   : 20BV0022AU
      ComputerSerial : PC03Z4EN
      MonitorSerial  : G462H87IBFXS
      MonitorType    : DELL 2208WFP
      
      ComputerName   : PC03Z4EN
      ComputerType   : 20BV0022AU
      ComputerSerial : PC03Z4EN
      MonitorSerial  : VN-A03TNY
      MonitorType    : LEN T2254pC
      
      Cannot convert value "True" to type "System.Char". Error: "Invalid cast from 'Boolean' to 'Char'."
      At line:22 char:89
      + ... pe     = ($_.UserFriendlyName -ne 0 | ForEach-Object{[char]$_}) -join ...
      +                                                          ~~~~~~~~
          + CategoryInfo          : InvalidArgument: (:) [], RuntimeException
          + FullyQualifiedErrorId : InvalidCastIConvertible
       
      ComputerName   : PC03Z4EN
      ComputerType   : 20BV0022AU
      ComputerSerial : PC03Z4EN
      MonitorSerial  : 0
      MonitorType    : 
  • #91603

    John Steele
    Participant

    My attempt at the Prequel 1 challenge. The computer info is displayed only once. All connected monitors are looped through and numbered as part of the output. Threw in some splatting to slim it down a bit.

You must be logged in to reply to this topic.