只获取必要内容
Shell提供了两种方式缩小结果集,它们都被归结为过滤。
- 第一种:尝试指定Cmdlet命令只检索指定的内容,该方式一般称之为左过滤技术。
- 第二种:采用迭代的方法,通过第一个Cmdlet获得所有结果,并使用第二个Cmdlet过滤掉不想要的东西。
考虑到效率,我们应该尽可能提前过滤,即优先使用第一种方式来实现。
例如,使用Get-Service,你可以告诉它你想要的服务名称。
如果你想让Get-Service只返回正在运行的服务,而不考虑它们的服务名称,该Cmdlet就无法做到这一点,因为它没有提供用于设定该部分信息的相关的参数。
如果你使用微软的活动目录模块,所有以Get-开始的Cmdlets都提供了-filter参数。
左过滤
“左过滤”意味着尽可能把过滤条件,放置在左侧或靠近命令行的开始部分。越早过滤不需要的对象,就越能减轻其他Cmdlets命令的工作,并且能减少不必要的信息通过网络传输到你的电脑。
当无法通过一个Cmdlet就可以完成你所需的所有过滤时,可以使用**Where-Object**
(别名Where或 ? )。当需要检索的时候,可使用它过滤任何类型的对象,并把它传入管道。
为了使用Where-Object,需要学会告诉Shell如何过滤出你想要的信息,这还包括使用Shell的比较操作符。有趣的是,一些左过滤技术中使用了相同的比较操作符,如活动目录模块下以Get-开头的命令的-filter参数。
使用比较操作符
PowerShell使用如下比较操作符。请注意,当比较文本字符串时会忽略大小写。
- -eq:相等,例如5 -eq 5(返回true)或者”hello” -eq “help”(返回false)。
- -ne:不等于,例如10 -ne 5(返回true)或者”help” -ne “help”(返回false)。
- -ge和-le:大于等于,小于等于,例如10 -ge 5(返回true)或者
Get-Date -le '2012-12-02'
- -gt和-lt:大于和小于,例如10 -lt 10(返回false)或者100 -gt 10(返回true)。
对于字符串的比较,如果需要区分大小写,可以使用:-ceq, -cne,-cgt, -clt, -cge, -cle。
也可以使用更加传统的编程语言形式的比较运算符:
- = 等于
- <> 不等于
- <= 小于或等于
= 大于或等于
大于
- < 小于
如果想一次比较多个对象,可以使用布尔运算符-and和-or。通常在每个子表达式两边加上圆括号,使得表达式更容易阅读。
(5 -gt 10) -and (10 -gt 100)
返回false,因为一个或两个子表达式返回值为false。(5 -gt 10) -or (10 -lt 100)
返回true,因为最后一个子表达式返回值为true。
另外,布尔值-not对true和false取反。在处理一个变量或者已经包含true或false的属性时,这可能会有用。
例如,需要测试一个进程是否没有响应,可以这样做:
Windows PowerShell定义了$False和$True表示false和true的布尔值。另外一种书写方式如下:
因为Responding通常包含true和false, -not使得false取反变为true。如果进程没有响应,意味着Responding返回false。
-
使用通配符
当需要比较文本字符串时,还有其他几个有用的比较运算符。
-like
:接受作为通配符,如:`”Hello” -like “ll*”`(返回true)。- 它的反义运算符为
-notlike
,它们不区分大小写。 - 区分大小写可以使用
-clike
和-cnotlike
。
- 它的反义运算符为
-match
用于文本字符串与正则表达式进行比较。-notmatch
是个逻辑上的反义词。-cmatch
和-cnotmatch
提供了区分大小写的语法。
在about_comparison_operators
的帮助文件中,可以找到其他可用的比较运算符。
过滤对象的管道:Where-Object
一些Cmdlet的-filter
参数,可以与活动目录中模块以GET-开头的命令共同使用。也可以与Shell的通用过滤命令Where-Object
共同使用。
例如,过滤掉其他信息,只留下正在运行的服务
Get-Service | Where-Object -FilterScript {$_.Status -eq 'Running'}
# 或
Get-Service | Where {$_.Status -eq 'Running'}
# 或
Get-Service | ? {$_.Status -eq 'Running'}
如果阅读上面代码,这会听起来合情合理:“where status equals running”。这就阐述了它的工作原理:
- 当你传递多个对象到Where-Object时,它会使用它的过滤器检查每个对象。
- 一次只放置一个对象到占位符$_,接着运行比较操作从而查看返回值是true还是false。
- 如果是false,该对象就会被管道移除。如果返回true,该对象就会从Where-Object传输到下一个Cmdlet的管道中。
- 在上面的示例中,下一个Cmdlet命令是Out-Default,这会是管道的末尾。
- 接着开始使用格式化过程,从而显示输出结果。
占位符$_
占位符$_是个特殊产物,其只能在PowerShell能查找的特定位置中使用。当它有效时,它一次只包含一个从管道传输到该Cmdlet的对象。
范例:保留那些-status属性为Running的服务
1)命令是以Get-Service开始,但它却不是第一个运行的命令。而是在圆括号内的Get-Content先运行。
2)Get-Content通过管道将输出结果(由简单的String对象组成)传递给Where-Object。
- Where-Object和过滤器处在圆括号内,$_表示从Get-Content管道传输过来的String对象。
- 只要字符串不是以“dc”结尾的,都会被保留并通过Where-Object输出。
3)Where-Object的输出成为圆括号内的结果,所有不是以“dc”结尾的计算机名称,会被发送到Get-Service的-computername参数中。
4)然后运行Get-Service,并且产生的ServiceController对象将会传输到Where-Object。
Where-Object新式写法
PowerShell v3为Where-Object引入了一个新的“简写”语法。当只比较一次时可以使用该语法,如果需要比较多个子项,请保持使用原来的写法。
该语法免除了{},并且不需要使用看起来尴尬的占位符$_。但旧语法,仍然需要在复杂的比较中使用它。
使用迭代命令行模式
此处简单介绍PowerShell迭代命令行模型或者称为PSICLM。PSICLM的核心思想在于你不需要一开始就创建一个大而复杂的命令行,而是从简单的开始。
比方说,要计算正在使用虚拟内存排名前十的进程所占用的虚拟内存总和。如果排名前十的进程中包含PowerShell进程,而又不想在结果中包含PowerShell进程。快速罗列出几个需要的步骤。
1)获取进程列表;
2)排除PowerShell进程;(实际运用中,优先使用“左过滤”技术)
3)按照虚拟内存进行排序;
4)只保存前10个或者最后10个,这取决于排序方式;
5)把剩下进程的虚拟内存相加。