1、选择数据

运行命令可以很强大,可以从本地计算机或整个网络获取数据。 为使工作更高效,需要了解如何获取所需的数据。 大多数命令对对象执行操作,作为输入和/或输出。 对象具有属性,你可能需要访问这些属性的子集,并将它们呈现在报表中。 你可能还需要根据一个或多个属性对数据进行排序。 但是,如何实现呢?

1.1、使用 Get-Member 检查输出

当你将命令的结果传递给 Get-Member 时,Get-Member 会返回有关对象的信息,例如:

  • 要传递给 Get-Member 的对象的类型。
  • 可计算的对象的“属性”。
  • 可执行的对象的“方法”。

让我们通过在命令 Get-Process 上运行 Get-Member 来证明这一事实。

Get-Process | Get-Member

请注意如何使用管道 |,通过调用 Get-Member,实际上你已在创建管道。 前面的语句的前几行输出如下所示:

TypeName: System.Diagnostics.Process

Name                       MemberType     Definition
----                       ----------     ----------
Handles                    AliasProperty  Handles = Handlecount
Name                       AliasProperty  Name = ProcessName
NPM                        AliasProperty  NPM = NonpagedSystemMemorySize64
PM                         AliasProperty  PM = PagedMemorySize64
SI                         AliasProperty  SI = SessionId
VM                         AliasProperty  VM = VirtualMemorySize64
WS                         AliasProperty  WS = WorkingSet64
...

输出显示 Get-Process 命令返回的对象类型 (System.Diagnostics.Process)。 响应的其余部分显示对象成员的名称、类型和定义。 你可以看到,如果你需要使 Get-Process 适应管道中的其他命令,将其与 Get-Member 配对是不错的第一步。

1.2、Select-Object

默认情况下,当你运行将输出到屏幕的命令时,PowerShell 会自动添加命令 Out-Default。 如果输出数据是对象集合,PowerShell 会查看对象类型,以确定该对象类型是否有已注册的视图。 如果有,则使用该视图。

视图通常不会包含一个对象的所有属性,因为它不会在屏幕上正确显示,因此视图中仅包含了一些最常见的属性。

你可以使用 Select-Object 并选择自己的属性列表来替代默认视图。 然后,可以将这些属性发送到 Format-Table 或 Format-List,以你喜欢的方式显示表。

考虑在进程 zsh 上运行 Get-Process 的结果:

NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
 ------    -----      -----     ------      --  -- -----------
      0     0.00       0.01       0.38     644 620 zsh
      0     0.00       0.01       0.38     727 727 zsh
      0     0.00       0.01       0.38     731 731 zsh
      0     0.00       0.01       0.38     743 743 zsh
      0     0.00       0.01       0.38     750 750 zsh
      0     0.00       0.88       0.91   15747 …47 zsh
      0     0.00       0.01       0.29   41983 …83 zsh
      0     0.00       1.16       0.31   68298 …98 zsh

你看到的是一个视图,它代表你最可能希望从此命令中看到的内容。 但是,此视图不会显示完整的信息集。 如需查看不同的内容,你可以明确指定你希望在结果中看到的属性。

1.3、获取完整响应

到目前为止,你所看到的响应是有限的。 若要显示完整响应,请使用通配符 *,如下所示:

Get-Process zsh | Format-List -Property *

* 字符显示每个属性及其值,可用于调查所需的值。 完整的响应还使用属性的表示名称(而不是实际的属性名),并且报表中的表示名称看起来很不错。

尽管有这些好处,但你可能不希望完整输出数据,但你也可能对默认响应不满意。

1.4、选择特定列

若要限制响应并找到默认响应与完整响应之间的中间点,你需要选择一些感兴趣的属性,并将其作为到 Select-Object 的参数输入。 但是,这里有一个问题,你需要使用列的实际名称。 如何找出实际名称? 请使用 Get-Member。 调用 Get-Member 会提供所有属性及其实际名称。

1.5、查找实际属性名称

让我们通过下面的子集快速回顾一下默认响应:

NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
 ------    -----      -----     ------      --  -- -----------
      0     0.00       0.01       0.38     644 620 zsh

从默认的响应来看,属性 Id 和 ProcessName 很可能名称相同,但 CPU 是演示名称,实际属性名称往往只包含文本字符,而无空格。 若要确定特定属性的真实名称,可以使用 Get-Member

Get-Process zsh | Get-Member -Name C*

现在,可以获取名称以 C 开头的所有成员的列表。 其中一个是 CPU,这可能是你想要的:

TypeName: System.Diagnostics.Process

Name             MemberType     Definition
----             ----------     ----------
CancelErrorRead  Method         void CancelErrorRead()
CancelOutputRead Method         void CancelOutputRead()
Close            Method         void Close()
CloseMainWindow  Method         bool CloseMainWindow()
Container        Property       System.ComponentModel.IContainer Container {get;}
CommandLine      ScriptProperty System.Object CommandLine {get=…
Company          ScriptProperty System.Object Company {get=$this.Mainmodule.FileVersionInfo.CompanyName;}
CPU              ScriptProperty System.Object CPU {get=$this.TotalProcessorTime.TotalSeconds;}

你现在知道如何使用 Select-Object 确切查找你所需的正确属性名称,如下所示:

Get-Process zsh | Select-Object -Property Id, Name, CPU

如下所示:

Id Name       CPU
-- ----       ---
644 zsh  0.3812141
727 zsh  0.3826498
731 zsh  0.3784953
743 zsh  0.3776352
750 zsh  0.3824036
15747 zsh  0.9097993
41983 zsh  0.2934763
68298 zsh  0.3121695

此命令序列提供与默认输出不同但包含你关注的属性的输出。

1.6、排序

在管道中使用 Sort-Object 时,PowerShell 先使用默认属性对输出数据排序。 如果不存在此类属性,它会尝试比较对象本身。 排序是按升序或降序进行的。

通过提供属性,可以选择按特定列排序,如下所示:

Get-Process | Sort-Object -Descending -Property Name

在上述命令中,我们将按降序对列 Name 进行排序。 若要按多个列进行排序,请用逗号分隔列名称,如下所示:

Get-Process | Sort-Object -Descending -Property Name, CPU

除了按列名排序外,你还可以提供自己的自定义表达式。 在此示例中,我们使用自定义表达式按列 Name 和 CPU 进行排序,并控制每列的排序顺序。

Get-Process 'some process' | Sort-Object -Property @{Expression = "Name"; Descending = $True}, @{Expression = "CPU"; Descending = $False}

前面的示例演示了 Sort-Object 的强大和灵活性。 此主题有点超前,超出了本模块的范围,但将在更高级的模块中重新讨论。