2

I'm currently studying Powershell and working on a script that grabs Display configuration from windows system. I get 2 question:

Question 1. The script is:

"Display Config" >> system1.txt
"---------------------------------------------------------------------------- 
---------------------------------" >> system1.txt
add-type -assemblyName system.windows.forms 
[system.windows.forms.screen]::AllScreens | Format-List Bounds | out-file -append system1.txt

The output is the result of resolution of 2 monitors, just like that:

Bounds : {X=0,Y=0,Width=1920,Height=1080}
Bounds : {X=1920,Y=0,Width=2560,Height=1440}

But I just want to extract values of 'Width' and 'Height', and the make output show like:

Width:1920
Height:1080

Width:2560
Height:1440 

Question2: For this script:

Get-WmiObject WmiMonitorconnectionparams -Namespace root\wmi  | format-List 
VideoOutputTechnology  | out-file -append system1.txt

I get results:

VideoOutputTechnology : 10
VideoOutputTechnology : 4

But the value 4 and 10 need to be decoded, ie '10 = Displayport External' according to an url: https://technet.microsoft.com/en-us/ff546605(v=vs.89)

How could I decode the value according to the URL and make the result only show like 'Displayport External' in the output txt?

I would greatly appreciate your reply.

mklement0
  • 382,024
  • 64
  • 607
  • 775
SS-WQY
  • 59
  • 4
  • 1
    `([system.windows.forms.screen]::AllScreens).Bounds |Select Width,Height` –  Jul 12 '18 at 21:45
  • [/working-with-enums-in-powershell-5/](https://blogs.technet.microsoft.com/heyscriptingguy/2015/08/27/working-with-enums-in-powershell-5/) –  Jul 12 '18 at 21:49
  • Why not just access the Width and Height on `[system.windows.forms.screen]::AllScreens.Bounds` directly? – Jake H Jul 12 '18 at 21:54

2 Answers2

3

Question 1:

LotPings has effectively provided a solution in a comment (PSv3+):

[system.windows.forms.screen]::AllScreens.Bounds |
  Format-List Width, Height >> system1.txt
  • .Bounds is directly applied to the array returned by ::AllScreens, in which case an array of the array's elements' respective .Bounds property values is conveniently returned, which is a PSv3+ feature called member-access enumeration.

  • Format-List Width, Height then extracts the .Width and .Height property values from the resulting [System.Drawing.Rectangle] instances and displays them as a list.

    • Note: The purpose of all Format-* cmdlets is to create output for display only, i.e., to produce output that is friendly to the human observer, but ill-suited for further programmatic processing.
  • Since you're using Out-File -Append without additional options, >> is a convenient shortcut. (You'll get UTF16-LE-encoded ("Unicode") files.)


Question 2:

PowerShell has great built-in support for .NET enumerations ([enum]-derived types), but what WMI reports in your case are simple integers [System.UInt32], so you have to perform your own mapping.

In PSv5+ you can define your own [enum] types, however, in which case a simple cast to that type can help you:

enum VideoOutputTechnology {
    D3DKMDT_VOT_UNINITIALIZED         = -2
    D3DKMDT_VOT_OTHER                 = -1
    D3DKMDT_VOT_HD15                  = 0
    # ...
    D3DKMDT_VOT_DVI                   = 4
    D3DKMDT_VOT_DISPLAYPORT_EXTERNAL  = 10
    # ...
}
In PSv4- you can use `Add-Type -TypeDefinition` to define the enum via a string containing a _C#_ enum definition.

Note:

  • I've retained the original symbolic constant names from https://technet.microsoft.com/en-us/ff546605(v=vs.89), but you're free to rename to something friendlier; e.g., D3DKMDT_VOT_DISPLAYPORT_EXTERNAL -> Displayport_External - but note that embedded spaces and special characters are not allowed. If that isn't friendly enough, consider Theo's helpful solution.

  • You're creating a static copy of the symbolic constants, so the two sets could get out of sync, though new constants are probably added only rarely. (I'm not aware of any preexisting .NET enum type that defines these constants and they seem to be defined in a *.h file that you cannot assume to be present on every machine; you could web-scrape the URL, but that is brittle.)

You can then apply the cast in the context of a calculated property in order to translate the raw integer into its symbolic name:

Get-WmiObject WmiMonitorconnectionparams -Namespace root\wmi | 
 Format-List @{ 
   n='VideoOutputTechnology'
   e={ [VideoOutputTechnology] $_.VideoOutputTechnology } 
 } >> system1.txt

This should yield:

VideoOutputTechnology : D3DKMDT_VOT_DISPLAYPORT_EXTERNAL
VideoOutputTechnology : D3DKMDT_VOT_DVI
mklement0
  • 382,024
  • 64
  • 607
  • 775
1

As for the VideoOutputTechnology values. Yes, they are values from the D3DKMDT_VIDEO_OUTPUT_TECHNOLOGY enumeration, but i believe you want to return a more descriptive string. In that case you could use a small function to translate the value to string:

function Resolve-VideoOutputTechnology { 
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline = $true, Mandatory = $true, Position = 0)]
        [int64]$VideoOutputTechnology
    )
    switch ($VideoOutputTechnology) { 
        -2          { return 'Uninitialized connector' }                                                   # D3DKMDT_VOT_UNINITIALIZED         
        -1          { return 'Unknown connector' }                                                         # D3DKMDT_VOT_OTHER                 
        0           { return 'VGA connector' }                                                             # D3DKMDT_VOT_HD15                  
        1           { return 'S-video connector' }                                                         # D3DKMDT_VOT_SVIDEO                
        2           { return 'Composite video connector' }                                                 # D3DKMDT_VOT_COMPOSITE_VIDEO       
        3           { return 'Component video connector' }                                                 # D3DKMDT_VOT_COMPONENT_VIDEO       
        4           { return 'Digital Video Interface (DVI) connector' }                                   # D3DKMDT_VOT_DVI                   
        5           { return 'High-Definition Multimedia Interface (HDMI) connector' }                     # D3DKMDT_VOT_HDMI                  
        6           { return 'Low Voltage Differential Swing (LVDS) or Mobile Industry Processor Interface (MIPI) Digital Serial Interface (DSI) connector' }  # D3DKMDT_VOT_LVDS                  
        8           { return 'D-Jpn connector' }                                                           # D3DKMDT_VOT_D_JPN                 
        9           { return 'SDI connector' }                                                             # D3DKMDT_VOT_SDI                   
        10          { return 'External display port' }                                                     # D3DKMDT_VOT_DISPLAYPORT_EXTERNAL  
        11          { return 'Embedded display port' }                                                     # D3DKMDT_VOT_DISPLAYPORT_EMBEDDED  
        12          { return 'External Unified Display Interface (UDI)' }                                  # D3DKMDT_VOT_UDI_EXTERNAL          
        13          { return 'Embedded Unified Display Interface (UDI)' }                                  # D3DKMDT_VOT_UDI_EMBEDDED          
        14          { return 'Dongle cable that supports SDTV connector' }                                 # D3DKMDT_VOT_SDTVDONGLE            
        15          { return 'Miracast connected session' }                                                # D3DKMDT_VOT_MIRACAST              
        0x80000000  { return 'Internally display device (the internal connection in a laptop computer)' }  # D3DKMDT_VOT_INTERNAL              
        default     { return 'Unknown connector' }
    }
}
Theo
  • 57,719
  • 8
  • 24
  • 41