PowerShell处理XML(三)浏览扩展类型系统 2


PowerShell处理XML系列文章

  1. XML 结构
  2. 加载和处理XML文件
  3. 浏览扩展类型系统

PowerShell扩展类型系统(ETS)确保了对象可以被转换成有意义的文本。此外,它还可以传递额外的属性和方法给对象。这些操作的精确定义被存放在扩展名为.ps1xml的文件中。

扩展类型系统的XML数据

不论何时,PowerShell要将对象转换成文本,都会搜索它自己的内置纪录中关于对象的描述和转换。正确的文件包含了XML:它的文件名以.format.ps1xml收尾,这些文件位于PowerShell的根目录$pshome下。

PS> Dir $pshome\*.format.ps1xml

    Directory: C:\Windows\System32\WindowsPowerShell\v1.0

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---         2013/6/18     22:50      27338 Certificate.format.ps1xml
-a---         2013/6/18     22:50      27106 Diagnostics.Format.ps1xml
-a---         2013/6/18     22:50     147702 DotNetTypes.format.ps1xml
-a---         2013/6/18     22:50      14502 Event.Format.ps1xml
-a---         2013/6/18     22:50      21293 FileSystem.format.ps1xml
-a---         2013/6/18     22:50     287938 Help.format.ps1xml
-a---         2013/6/18     22:50      97880 HelpV3.format.ps1xml
-a---         2013/6/19      2:30     105230 PowerShellCore.format.ps1xml
-a---         2013/6/18     22:50      18612 PowerShellTrace.format.ps1xml
-a---         2013/6/18     22:50      13659 Registry.format.ps1xml
-a---         2013/6/18     22:50      17731 WSMan.Format.ps1xml

所有的这些文件包含了众多的视图,你可以使用PowerShell 支持的XML方法来检验它。

[xml]$file = Get-Content "$pshome\dotnettypes.format.ps1xml"
$file.Configuration.ViewDefinitions.View
Name                                                                                         ViewSelectedBy ListControl
----                                                                                         -------------- -----------
System.CodeDom.Compiler.CompilerError                                                        ViewSelectedBy ListControl
System.Reflection.Assembly                                                                   ViewSelectedBy
System.Reflection.AssemblyName                                                               ViewSelectedBy
System.Globalization.CultureInfo                                                             ViewSelectedBy
System.Diagnostics.FileVersionInfo                                                           ViewSelectedBy
System.Management.ManagementObject#root\cimv2\Win32_PingStatus                               ViewSelectedBy
Microsoft.Management.Infrastructure.CimInstance#root/cimv2/Win32_PingStatus                  ViewSelectedBy
System.Management.ManagementObject#root\default\SystemRestore                                ViewSelectedBy
Microsoft.Management.Infrastructure.CimInstance#root/default/SystemRestore                   ViewSelectedBy
Microsoft.Management.Infrastructure.CimInstance#root/cimv2/Win32_Product                     ViewSelectedBy
System.Net.NetworkCredential                                                                 ViewSelectedBy
System.Management.Automation.PSMethod                                                        ViewSelectedBy
Microsoft.Management.Infrastructure.CimInstance#__PartialCIMInstance                         ViewSelectedBy

查找预定义的视图

预定义的视图非常有意思,因为你可以在像format-table和format-list这样的格式化命令中使用-View参数来对指定的结果做出丰富的调整和更改。

Get-Process | Format-Table -view Priority
Get-Process | Format-Table -view StartTime

很遗憾,没人告诉你像Priority 和 StartTime这样的视图或者其它视图已经存在。你可以查看相关的XML文件,视图文件显示每一个视图结点包含了子结点:Name,ViewSelectedBy,TableControl。但是开始,视图的原始XML数据可能看起来费解,不清楚。

使用一行命令即可重新格式化文本,让它方便阅读:

$xmldata.get_OuterXML().Replace("<", "`t<").Replace(">", ">`t").Replace(">`t`t<", ">`t<").Split("`t") |
ForEach-Object {$x=0}{ If ($_.StartsWith("</")) {$x--} `
ElseIf($_.StartsWith("<")) { $x++}; (" " * ($x)) + $_; `
if ($_.StartsWith("</")) { $x--} elseif `
($_.StartsWith("<")) {$x++} }
<View>
  <Name>
   System.CodeDom.Compiler.CompilerError
  </Name>
  <ViewSelectedBy>
    <TypeName>
     System.CodeDom.Compiler.CompilerError
    </TypeName>
  </ViewSelectedBy>
  <ListControl>
    <ListEntries>
      <ListEntry>
        <ListItems>
          <ListItem>
            <PropertyName>
             ErrorText
            </PropertyName>
          </ListItem>
          <ListItem>
            <PropertyName>
             Line
            </PropertyName>
          </ListItem>
          <ListItem>
            <PropertyName>
             Column
            </PropertyName>
          </ListItem>
          <ListItem>
            <PropertyName>
             ErrorNumber
            </PropertyName>
          </ListItem>
          <ListItem>
            <PropertyName>
             LineSource
            </PropertyName>
          </ListItem>
        </ListItems>
      </ListEntry>
    </ListEntries>
  </ListControl>
</View>

每一个视图由一个Name,一个ViewSelectedBy中的.NET类型组成,作为视图合格的条件,TableControl结点也一样,指定对象被支持转换成文本。如果你想在一列中输出定义在XML文件中的所有的视图,Format-Table命令足矣,然后选择你想在摘要中显示的属性。

[xml]$file = Get-Content "$pshome\dotnettypes.format.ps1xml"
$file.Configuration.ViewDefinitions.View |
Format-Table Name, {$_.ViewSelectedBy.TypeName}

 

Name                                                        $_.ViewSelectedBy.TypeName
----                                                        --------------------------
System.CodeDom.Compiler.CompilerError                       System.CodeDom.Compiler.CompilerError
System.Reflection.Assembly                                  System.Reflection.Assembly
System.Reflection.AssemblyName                              System.Reflection.AssemblyName
System.Globalization.CultureInfo                            System.Globalization.CultureInfo
System.Diagnostics.FileVersionInfo                          System.Diagnostics.FileVersionInfo
System.Diagnostics.EventLogEntry                            System.Diagnostics.EventLogEntry
System.Diagnostics.EventLog                                 System.Diagnostics.EventLog
System.Version                                              System.Version
System.Drawing.Printing.PrintDocument                       System.Drawing.Printing.PrintDocument
Dictionary                                                  System.Collections.DictionaryEntry
ProcessModule                                               System.Diagnostics.ProcessModule
process                                                     System.Diagnostics.Process
ProcessWithUserName                                         System.Diagnostics.Process#IncludeUserName
DirectoryEntry                                              System.DirectoryServices.DirectoryEntry
PSSnapInInfo                                                System.Management.Automation.PSSnapInInfo
PSSnapInInfo                                                System.Management.Automation.PSSnapInInfo
Priority                                                    System.Diagnostics.Process
StartTime                                                   System.Diagnostics.Process
service                                                     System.ServiceProcess.ServiceController
System.Diagnostics.FileVersionInfo                          System.Diagnostics.FileVersionInfo
System.Diagnostics.EventLogEntry                            System.Diagnostics.EventLogEntry
System.Diagnostics.EventLog                                 System.Diagnostics.EventLog
System.TimeSpan                                             System.TimeSpan
System.TimeSpan                                             System.TimeSpan
System.TimeSpan                                             System.TimeSpan
System.AppDomain                                            System.AppDomain
System.ServiceProcess.ServiceController                     System.ServiceProcess.ServiceController
System.Reflection.Assembly                                  System.Reflection.Assembly
System.Collections.DictionaryEntry                          System.Collections.DictionaryEntry
process                                                     System.Diagnostics.Process
DateTime                                                    System.DateTime
System.Security.AccessControl.ObjectSecurity                System.Security.AccessControl.ObjectSecurity
System.Security.AccessControl.ObjectSecurity                System.Security.AccessControl.ObjectSecurity
System.Management.ManagementClass                           System.Management.ManagementClass
Microsoft.Management.Infrastructure.CimClass                Microsoft.Management.Infrastructure.CimClass
System.Guid                                                 System.Guid
System.Management.ManagementObject#root\cimv2\Win32_Ping... System.Management.ManagementObject#root\cimv2\Win32_Ping...
...............

你所看到是XML文件中定义的所有的视图了,第二列显示的就是视图定义的对象类型。其中的Priority和StartTime就是我们之前在上一个例子中使用的两个视图。看了第二列应当就会非常清楚,该视图是针对System.Diagnostics.Process对象,恰恰就是命令Get-Process获取的对象。

(Get-Process | Select-Object -first 1).GetType().FullName
System.Diagnostics.Process

你可能会惊讶有些Name是成对出现的,例如System.TimeSpan。其原因正是上一个例子中提到的TableControl结点,一起的还有其它类型转换的结点ListControl, WideControl 和 CustomControl。这些结点在第一次概览时,不会被显示。原因是每一个视图只允许出现一个这样的结点。TableControl被输出时或多或少带有随机性,因为在转换第一条记录时,PowerShell是基于未知对象的转换。

接下来我们会提取出XML文件中所有的必须的信息。首先对视图按照ViewSelectedBy.TypeName排序,接着根据criterion(标准)来分组。你也可以按照只匹配出一次确定的对象类型来排序。你只需要那些值得在-view参数中指定的,存在多个对象类型的视图。

[xml]$file = Get-Content "$pshome\dotnettypes.format.ps1xml"
$file.Configuration.ViewDefinitions.View |
Sort-Object {$_.ViewSelectedBy.TypeName} |
Group-Object {$_.ViewSelectedBy.TypeName} |
Where-Object { $_.Count -gt 1} |
ForEach-Object { $_.Group} |
Format-Table Name, {$_.ViewSelectedBy.TypeName}, `
@{expression={if ($_.TableControl) { "Table" } elseif `
($_.ListControl) { "List" } elseif ($_.WideControl) { "Wide" } `
elseif ($_.CustomControl) { "Custom" }};label="Type"} -wrap

如果对于这几行的格式化命令有任何疑问,可以参考第五章,主要讲格式化。关于像Format-Table与其它这样的格式化命令,其重要性在于可以让你在表格的列中显示特定的对象,属性,或者脚本块。如果你想在表格列中不直接显示属性,而是显示属性的子属性,那么子表达式是必须的。因为你对ViewSelectedBy属性不感兴趣,但是对它的子属性TypeName感兴趣,所以列必须定义在脚本块中。第三列也是脚本块。因为它的长度和列头冲突,一个用于格式化的哈希表应当应用到这里,允许你能选择列的标题。

提供给你的结果是一个可编辑的列表。第一列显示的是所有视图的名称;视图被适用的对象类型位于第二列;第三列展示这些格式化命令Format-Table, Format-List, Format-Wide 或者 Format-Custom那个会应用到它。

Name                                    $_.ViewSelectedBy.TypeName              Type
----                                    --------------------------              ----
System.Collections.DictionaryEntry      System.Collections.DictionaryEntry      List
Dictionary                              System.Collections.DictionaryEntry      Table
System.Diagnostics.EventLog             System.Diagnostics.EventLog             Table
System.Diagnostics.EventLog             System.Diagnostics.EventLog             List
System.Diagnostics.EventLogEntry        System.Diagnostics.EventLogEntry        List
System.Diagnostics.EventLogEntry        System.Diagnostics.EventLogEntry        Table
System.Diagnostics.FileVersionInfo      System.Diagnostics.FileVersionInfo      Table
System.Diagnostics.FileVersionInfo      System.Diagnostics.FileVersionInfo      List
Priority                                System.Diagnostics.Process              Table
StartTime                               System.Diagnostics.Process              Table
process                                 System.Diagnostics.Process              Wide
process                                 System.Diagnostics.Process              Table
PSSnapInInfo                            System.Management.Automation.PSSnapInIn List
                                        fo
PSSnapInInfo                            System.Management.Automation.PSSnapInIn Table
                                        fo
System.Reflection.Assembly              System.Reflection.Assembly              List
System.Reflection.Assembly              System.Reflection.Assembly              Table
System.Security.AccessControl.ObjectSec System.Security.AccessControl.ObjectSec Table
urity                                   urity
System.Security.AccessControl.ObjectSec System.Security.AccessControl.ObjectSec List
urity                                   urity
service                                 System.ServiceProcess.ServiceController Table
System.ServiceProcess.ServiceController System.ServiceProcess.ServiceController List
System.TimeSpan                         System.TimeSpan                         Wide
System.TimeSpan                         System.TimeSpan                         List
System.TimeSpan                         System.TimeSpan                         Table

记住这些包含格式化信息的XML文件。你只有在生成了所有格式化XML文件列表时,才可以得到一个完整的概览。

原文链接:Chapter 14. XML

本文链接: https://www.pstips.net/exploring-the-extended-type-system.html
请尊重原作者和编辑的辛勤劳动,欢迎转载,并注明出处!

关于 Mooser Lee

我是一个Powershell的爱好者,创建了PowerShell中文博客,热衷于Powershell技术的搜集和分享。本站部分内容来源于互联网,不足之处敬请谅解,并欢迎您批评指正。

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

2 条评论 “PowerShell处理XML(三)浏览扩展类型系统

    • Mooser Lee 文章作者

      一句话ETS就是定义对象那些属性应当显示,那些属性应当隐藏。
      比如:

      PS C:\> dir
      
      
          Directory: C:\
      
      
      Mode                LastWriteTime     Length Name
      ----                -------------     ------ ----
      d----         2012/12/6     14:50            inetpub
      d----         2012/9/14     20:52            Intel
      d----        2013/11/22      1:03            kunlun
      

      为什么默认只显示Mode,LastWriteTime,Length,Name这几个属性? 谁规定的,就是ETS(扩展类型系统)配置的。