首页 > 解决方案 > Powershell:提取部分值并以新格式输出

问题描述

我目前正在研究 Powershell 并正在编写一个从 Windows 系统获取显示配置的脚本。我得到2个问题:

问题 1. 脚本是:

"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

输出是 2 台显示器分辨率的结果,就像这样:

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

但我只想提取“宽度”和“高度”的值,生成输出显示如下:

Width:1920
Height:1080

Width:2560
Height:1440 

问题2:对于这个脚本:

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

我得到结果:

VideoOutputTechnology : 10
VideoOutputTechnology : 4

但是值 4 和 10 需要解码,即'10 = Displayport External'根据 url:https://technet.microsoft.com/en-us/ff546605(v=vs.89)

如何根据 URL 解码值并使结果仅显示'Displayport External'在输出 txt 中?

非常感谢您的回复。

标签: powershell

解决方案


问题一

LotPings在评论中有效地提供了解决方案(PSv3+):

[system.windows.forms.screen]::AllScreens.Bounds | Format-List Width, Height >> system1.txt
  • .Bounds直接应用于由返回的数组::AllScreens,在这种情况下,可以方便地返回数组元素各自.Bounds属性值的数组,这是一个称为成员枚举的 PSv3+ 功能。

  • Format-List Width, Height然后从结果实例中提取.Width.Height属性值 [System.Drawing.Rectangle]并将它们显示为列表。

    • 注意:所有Format-*cmdlet 的目的是创建仅用于显示的输出,即生成对人类观察者友好但不适合进一步编程处理的输出。
  • 由于您在Out-File -Append没有其他选项的情况下使用,>>是一个方便的快捷方式。(您将获得 UTF16-LE 编码(“Un​​icode”)文件。)


问题 2

PowerShell 对 .NET 枚举( - 派生类型)具有很好的内置支持[enum],但在您的情况下 WMI 报告的是简单整数 [System.UInt32],因此您必须执行自己的映射。

但是,在 PSv5+ 中,您可以定义自己的[enum]类型,在这种情况下,对该类型的简单转换可以帮助您

enum VideoOutputTechnology {
    D3DKMDT_VOT_UNINITIALIZED         = -2
    D3DKMDT_VOT_OTHER                 = -1
    D3DKMDT_VOT_HD15                  = 0
    # ...
    D3DKMDT_VOT_DVI                   = 4
    D3DKMDT_VOT_DISPLAYPORT_EXTERNAL  = 10
    # ...
}

在 PSv4- 中,您可以使用Add-Type -TypeDefinition包含C#枚举定义的字符串来定义枚举。

笔记:

  • 我保留了https://technet.microsoft.com/en-us/ff546605(v=vs.89)中的原始符号常量名称,但您可以自由重命名为更友好的名称;例如D3DKMDT_VOT_DISPLAYPORT_EXTERNAL-> Displayport_External- 但请注意不允许嵌入空格和特殊字符。如果这还不够友好,请考虑Theo 的有用解决方案

  • 您正在创建符号常量的静态副本,因此这两组可能会不同步,尽管可能很少添加新常量。(我不知道任何预先存在的定义这些常量的 .NET 枚举类型,它们似乎是在一个*.h文件中定义的,你不能假设它存在于每台机器上;你可以从网络上抓取 URL,但这很脆弱。 )

然后,您可以在计算属性的上下文中应用强制转换,以便将原始整数转换为其符号名称:

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

这应该产生:

VideoOutputTechnology : D3DKMDT_VOT_DISPLAYPORT_EXTERNAL
VideoOutputTechnology : D3DKMDT_VOT_DVI

推荐阅读