《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必须指出如何将第一个命令的输出作为第二个命令的输入,即得指出 CommandB
的哪个参数来接受 CommandA
的输出。这个指出的过程叫做 pipeline parameter binding
。PowerShell有两种方法来达到这个目的,其首先尝试的方法叫 ByValue
,其次会尝试 ByPropertyName
9.3 Plan A: pipeline input ByValue
With this method of pipeline parameter binding, PowerShell looks at the type of object produced by Command A and tries to see whether any parameter of Command B can accept that type of object from the pipeline.
在此方法中,PowerShell查看Command A产生的对象,然后尝试匹配到Command B的某个可以接受该对象的参数上。
我们可以人为的模拟这个过程,以 Get-Content .\computers.txt | Get-Service
为例:
computer.txt内容如下:
SERVER2
WIN8
CLIENT17
DONJONES1D96
- 首先将Command A的输出pipe到
Get-Member
,查看Command A输出的对象类型 - 查看Command B完整的帮助查找是否有某一参数接受该类型的数据,如
Help Get-Service -full
如果使用 ByValue
无法找到匹配的参数,那么PowerShell会使用 ByPropertyName
来查找。比如例子 get-service -name s* | stop-process
就不能使用 ByValue
9.4 Plan B: pipeline input ByPropertyName
so let’s be clear on how simple the shell is being: It’s looking for property names that match parameter names. That’s it. Because the property Name is spelled the same as the parameter -Name, the shell tries to connect the two.
对于这种方法,PowerShell所做的就是寻找和Command B参数名字 匹配的 由Command A输出的对象的属性的名字。
我们也可以人为的模拟该过程,以 get-service -name s* | stop-process
为例:
1. 首先将Command A的输出pipe到 Get-Member
2. 查看Commad B的语法
找到相同的之后,PowerShell还要查看Command B的该参数是否接受pipeline输入 ByPropertyName
。
不过,不像 ByValue
只涉及到一个参数。在每个参数都允许受pipeline输入 ByPropertyName
的时候,ByPropertyName
会连接每个匹配的属性和参数。
9.6 Parenthetical command
有些命令的参数是不支持pipeline input的,比如 Get-WmiObject
的 -ComputerName
参数。所以说 get-content .\computers.txt | get-wmiobject -class win32_bios
是不行的。想要从文件中读取内容到该参数中,就要使用圆括号来改变命令的运算顺序,如 Get-WmiObject -class Win32_BIOS -ComputerName (Get-Content .\computers.txt)
。
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
。该cmdlet有一个 -expandProperty
参数可以接受属性的名字。如 Get-ADComputer -filter * -searchbase "ou=domain controllers,dc=company,dc=pri" | Select-Object -expand name
至于其参数 -expandProperty
和 -Property
的区别是:
With
Select -Property
, you’re deciding what boxes you want, but you still have boxes.
WithSelect -ExpandProperty
, you’re extracting the contents of the box and getting rid of the box entirely. You’re left with the contents.
个人的理解是,-Property
会保留原来对象的类型,也就是还是个对象。但是-ExpandProperty
就把原来的类型便成了字符串。
上一篇: 明年春节前的软件开发学习计划
下一篇: 学习xsd 2