PowerShell 语法笔记/03 管道数据流

内容纲要

Get-service 查询Windows服务
Start-Service 启动Windows 服务。
PowerShell 的 管道 不仅可以传递字符串,还可以传递对象。

将现有服务通过管道传给启动服务命令。

Get-Service -Name 'wuauserv' | start-service

也可以

'wuauserv' | Get-Service | Start-Service

因此,一行代码可以启动任意多个任务。

01 Get-Content

Get-Content -Path C:\Service.txt

Get-content 可以逐行读取文件,并分别将各行添加到一个数组中,然后返回该数组。

Get-Content -Path C:\Services.txt | Get-Service 

3.1 参数绑定

在PowerShell中,传给命令的参数需要经过 参数绑定 这一处理。这个过程会将传入的各个对象和命令创建者指定的各个参数建立对应关系。但是你必须清楚的哪些参数支持管道,有些是不行的,例如:

 'string' | Get-Process
Get-Process : 无法将输入对象绑定到命令的任何参数,可能是因为该命令没有采用管道输入,或者输入及其属性与采用管道输入的任何参数均不匹配。
所在位置 行:1 字符: 12
+ 'string' | Get-Process
+            ~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (string:String) [Get-Process],ParameterBindingException
    + FullyQualifiedErrorId : InputObjectNotBound,Microsoft.PowerShell.Commands.GetProcessCommand

Get-Process 不接受管道输入,如果你想知道一个命令能否用于管道,必须

Get-help -Name [命令] - Full

去找到PARAMETERS 部分,这部分列出了各个参数的信息,

例如命令 Get-Service

参数
    -ComputerName <System.String[]>
        Gets the services running on the specified computers. The default is the local computer.

        Type the NetBIOS name, an IP address, or a fully qualified domain name (FQDN) of a remote computer. To specify the local computer, type the computer name, a dot (`.`), or `localhost`.

        This parameter does not rely on Windows PowerShell remoting. You can use the ComputerName parameter of `Get-Service` even if your computer is not configured to run remote commands.

        是否必需?                    False
        位置?                        named
        默认值                None
        是否接受管道输入?            True (ByPropertyName)
        是否接受通配符?              False
    -Name <System.String[]>
        Specifies the service names of services to be retrieved. Wildcards are permitted.

        是否必需?                    False
        位置?                        0
        默认值                None
        是否接受管道输入?            True (ByPropertyName, ByValue)
        是否接受通配符?              True

截取了一个参数 -ComputerName 的信息,这个参数需要我们指定计算机名,以进一步确定是在哪台主机上Get-Service

截取了一个 -Name 参数的信息,可以看到这个指令可以通过ByValue 或者 ByPropertyName 方式接受值。

PowerShell 会通过两种方式建立起管道输入和参数之间的对应关系。
第一种方式是 ByVAlue,PowerShell根据传入的对象类型做相应的解释。因此传入字符串就行。

第二种是ByPropertyName,

输入 :     Get-Service 'wuauserv'
输出 :
Status   Name               DisplayName                           
------   ----               -----------                           
Running  wuauserv           Windows Update                        

那么使用管道输入呢?

PS C:\Users\Lsz\Documents\BaiduSyncdisk\PowerShell反混淆与分类\dataset> 'wuauserv' | Get-Service

Status   Name               DisplayName                           
------   ----               -----------                           
Running  wuauserv           Windows Update       

问题是,我们是如何将字符串传入给 Get-Service的哪个参数上的?

答案是 通过 Get-Service 的参数 -Name,因为-Name可以通过管道的ByValue参数 传入 “wuauserv”这个字符串。

如果我们想进一步对 -Computername 使用管道传输,那么只能新建一个对象了,并且在对象中指定一个属性 ComputerName

$serviceObject = [PSCustomObject]@{
    Name = ‘wuauserv’
    ComputerName = "SERV1"
}
$serviceObject | Get-Service

因此,我们可以查看命令的参数规范,使用哈希表存储参数信息,通过管道将命令串接起来。