Advertisement

《Learn Windows PowerShell in a Month of Lunches Third Edition》读书笔记——CHAPTER 9 The pipeline, deeper

阅读量:

9.2 How PowerShell passes data down the pipeline

对于形如 PS C:\> CommandA | CommandB 的命令行脚本,在PowerShell中需要指定如何将第一个命令的输出作为第二个命令的输入参数传递给第二个命令。具体而言,在这种情况下,Powershell指示用户指定如何将第一个命令的输出作为第二个命令的第一个输入参数进行传递,这一操作被称为 pipeline parameter binding 。Powershell提供了两种实现该功能的方法,其第一种方法称为 ByValue,第二种方法则称为 ByPropertyName

9.3 Plan A: pipeline input ByValue

By employing this method of pipeline parameter binding, PowerShell examines the output type resulting from Command A and determines if any parameter in Command B can accept objects of that output type.

在此方法中, 通过PowerShell工具获取由Command A生成的对象, 进而尝试将该对象与Command B中的相应参数进行匹配.

我们可以通过人工模拟的方式来展现这一过程,并基于以下命令作为示例进行展示:
Get-Content .\computers.txt | Get-Service
其中计算机.txt的具体内容如下:

复制代码
    SERVER2
    WIN8
    CLIENT17
    DONJONES1D96
  1. 第一步是将Command A的输出连接到Get-Member命令,并识别其输出的对象类型。
  2. 通过帮助文档查找是否接受某个特定参数的数据。
Comparing the output of Get-Content to the input parameters of Get-Service

当尝试通过 ByValue 参数进行查询但未找到匹配项时,默认 PowerShell 会切换至 ByPropertyName 进行查找操作。例如,在执行命令 get-service -name s* | stop-process 时就无法采用 ByValue 方式获取服务信息

9.4 Plan B: pipeline input ByPropertyName

Let's clearly understand how simple this shell is. The shell seeks property name matches with parameter names. Essentially, it relies on spelling consistency between 'Name' and '-Name'.

PowerShell所做的是搜索与Command B名称对应的对象属性名称。

我们可以人工模拟这一过程,并以命令 get-service -name s* | stop-process 为例进行说明:

  1. 将命令A的输出结果管道连接到 Get-Member 运行
  2. 分析命令B的语法结构
Checking to see whether the Stop-Process object’s -Name parameter accepts pipeline input ByPropertyName

在发现相同项后, PowerShell还需要检查Command B的该参数是否支持pipeline输入 ByPropertyName

不只 ByValue 通常仅处理单个输入,在这种情况下

9.6 Parenthetical command

存在一些命令的参数无法采用pipeline输入的方式

9.7 Extracting the value from a single property

当调用包含参数的操作时,在使用圆括号指定这些参数时,请务必确保传递给操作的参数的数据类型与操作内部计算得到的结果数据类型一致。例如,在以下命令中:Get-Service -computerName (Get-ADComputer -filter * -searchBase "ou=domain controllers,dc=company,dc=pri") ,由于 -computerName 参数期望接受 String 类型的值而 Get-ADComputer -filter * -searchBase "ou=domain controllers,dc=company,dc=pri" 返回的是 ADComputer 对象类型的实体,则会导致此命令无法成功执行。

要使该句得以执行成功,则可尝试从对象的单一属性中提取相应的值。例如,在对象ADComputer中存在一个名为Name的属性能够满足-ComputerName参数所需的特定信息内容,则我们的目标便是从该属性中提取Name属性的具体数值。

要达到上述抽取的目的,该命令可以采用cmdlet Select-Object的形式,并带有名称的参数选项来选择属性。例如,在执行命令时指定 -expandProperty name 参数后,则会获取指定属性值。例如:
cmdlet = "Get-ADComputer -filter * -searchbase 'ou=domain controllers,dc=company,dc=pri'" result = $cmdlet | Select-Object -expand name

至于其参数 -expandProperty-Property 的区别是:

Using the Select -Property option, you can specify which boxes to include, though they will remain on screen.
When using Select -ExpandProperty, you access the contents within the box and discard the box itself, leaving only its internal data.
From my experience, using -Property retains the original object's attributes, meaning it remains an object type.
However, -ExpandProperty converts the original attributes into a string format.

全部评论 (0)

还没有任何评论哟~