PowerShell管道应用示例

日期: 2016-05-31 作者:Adam Bertram翻译:邹雅玲 来源:TechTarget中国 英文

管道是一种可以让Windows PowerShell变得与众不同的语言架构。 尽管管道架构长期以来以各种各样的Shell作为主打产品,但是PowerShell通过采用脚本替代简单文本字符串的方式改变了传统产品理念。PowerShell提供了数百个内置 cmdlet支持管道架构运行。通过一种特殊的方式建立定制函数,那么,你便可以创建支持PowerShell管道的命令。

一旦你在活动中看到这些管道案例,那么你就会学会如何将PowerShell管道架构融入到你的函数中。 在旧版的Windows命令提示中,管道架构的概念意味着要将以“STDOUT”方式输出,然后直接以“STDIN”方式进行输……

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

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

敬请读者发表评论,本站保留删除与本文无关和不雅评论的权力。

管道是一种可以让Windows PowerShell变得与众不同的语言架构。

尽管管道架构长期以来以各种各样的Shell作为主打产品,但是PowerShell通过采用脚本替代简单文本字符串的方式改变了传统产品理念。PowerShell提供了数百个内置 cmdlet支持管道架构运行。通过一种特殊的方式建立定制函数,那么,你便可以创建支持PowerShell管道的命令。

一旦你在活动中看到这些管道案例,那么你就会学会如何将PowerShell管道架构融入到你的函数中。

在旧版的Windows命令提示中,管道架构的概念意味着要将以“STDOUT”方式输出,然后直接以“STDIN”方式进行输入处理。一个典型的“管道方案”就是,如果你需要从含有多个文件的文件夹中获取到指定文件,那么你需要一一翻阅这些文件。分页功能是由“more”命令所完成的。“more”命令都可以识别管道输入内容,因此,如果我想要提取同一个页面的某个文件,那么我可以将目录输出内容直接发送到“more”命令:dir C: | more。

与PowerShell不太一样,并不是所有命令都支持这种输入方式,微软公司也没有设计命令提示符来实现这些功能。PowerShell具有一套本地支持系统实现管道安装。例如,也许你喜欢在同一台计算机上运行多个流程。你可以使用“ Get-Process”命令(如图1所示)。

图1. PowerShell Get-Process命令运行结果

图1. PowerShell Get-Process命令运行结果

要是仅仅为了查看运行过程名称,你可以将“Get-Process”输出结果直接传递到另外一个命令“Select-Object”中(如图2所示)。你可以使用PowerShell管道重复以上过程。(如图3所示)

图2. 有了PowerShell管道,用户可以从Get-Process输出结果中只查看进程名称

图2. 有了PowerShell管道,用户可以从Get-Process输出结果中只查看进程名称

图3. 通过Select-Object命令,将Get-Process命令的输出结果直接传递到一个文件中,并且只显示前十行的内容

图3. 通过Select-Object命令,将Get-Process命令的输出结果直接传递到一个文件中,并且只显示前十行的内容

随着更多的研究投入,PowerShell管道可以超越这些内置命令,包括内置的自定义函数。管理人员必须使用一些参数属性,这些属性分别叫做Value From Pipeline 和Value From Pipeline By Property Name。这两种属性都附加在功能参数内,这样便可以直接从管道中获取输入内容,以及使用功能函数内的参数值。虽然有相似之处,但是,每一个属性之间又存在着一些差异。

有了“ ValueFromPipeline”属性,我们可以再次使用“Get-Process”,并将其延伸到定制功能函数中,将“Get-Process ”输出结果作为该流程对象的输入内容。

一个简短的高级功能函数也许看起来是这样的:

function Test-Process

{

               [CmdletBinding()]

               param

               (

                               [Parameter()]

                               [string]$ProcessName

               )            

               if ((Get-Process -Name $ProcessName).Responding -eq $True)

               {

                               $true

               }

               else

               {

                               $false            

               }

}

该功能函数可以让系统通过名称来指定流程,测试该流程某一功能属性,并返回“true ”或者“false”检测结果。这种方法很管用,但是由于其显示方式的原因,我们需要付出双倍的努力。为了让每段程序都可以在计算机上应用,我们使用了另外一种功能函数:

Get-Process | ForEach-Object {Test-Process –ProcessName $_.Name}

这样做仍然效果不是特别明显。为了某个程序对象,你必须运行两次“Get-Process”。最好的方法就是,不再使用“ForEach-Object”,简化“Get-Process”输出结果传递到“Test-Process”的过程。

相反地,我们可以创建一种功能函数,使之接受“Get-Process”输出的每个对象,并将这些输出对象转换为PowerShell管道输入内容。在此提供一段定制功能函数案例:

function Test-Process

{

               [CmdletBinding()]

               param

               (

                               [Parameter(ValueFromPipeline)]

                               [System.Diagnostics.Process]$Process

               )

               process

               {

                               if ($Process.Responding -eq $True)

                               {

                                               $true

                               }

                               else

                               {

                                               $false

                               }

               }

}

最后,直接将“Get-Process”输出结果传输到“Test-Process”中:Get-Process | Test-Process。

不同的解决方案之间,存在一些明显差异。首先,“ValueFromPipeline”参数属性显示在参数声明括号内。这种方式可以使PowerShell查看到管道输出的全部对象,并尝试将每个对象与该参数进行匹配。其次,字符串“System.Diagnostics.Process”类型存在一定的差异。这种差异可以让“Get-Process”输出对象类型与参数类型进行恰当匹配,因此,可以成功完成命令执行。

图4显示了如何通过使用“Get-Member”来查找“Get-Process”输出结果对象类型。

图4. 在PowerShell管道中,Get-Member查找Get-Process输出对象类型

图4. 在PowerShell管道中,Get-Member查找Get-Process输出对象类型

为了处理从PowerShell管道所输出的每个对象,该函数必须包含一种处理模块。没有处理模块脚本,处理完第一个对象后,该函数就会终止运行。

最后,由于该命令接受了整个System.Diagnostics.Process对象,而不是单单几个流程名称,那么,这样我们便可以应用所有属性。PowerShell用户可以简单地读取“Process parameter”的响应属性数值,而不需要再次调用“Get-Process”。

我们可以从BoeProx这样专业的机构得到更多关于管道支持的信息,帮助我们建立一些功能函数,使用“ValueFromPipeline ”参数属性和“ValueFromPipelineByPropertyName”属性。

作者

Adam Bertram
Adam Bertram

自由撰稿人

相关推荐