Where对象,Select对象和ForEach对象-差异和用法

时间:2019-06-04 05:50:45

标签: powershell

Where-ObjectSelect-ObjectForEach-Object

我是PowerShell的初学者。我不太了解。有人可以举例说明它们之间的区别和使用场景吗?

2 个答案:

答案 0 :(得分:3)

如果您完全熟悉 LINQ 或 SQL,那么它应该更容易理解,因为它对相同的词使用相同的概念并稍作调整。

Where-Object

用于过滤管道中的对象,类似于 SQL 过滤行的方式。此处,对象与条件或可选的 ScriptBlock 进行比较,以确定是否应将其传递给管道中的下一个 cmdlet。演示:

# Approved Verbs
Get-Verb | Measure-Object # count of 98
Get-Verb | Where-Object Verb -Like G* | Measure-Object # 3

# Integers 1 to 100
1..100 | Measure-Object # count of 100
1..100 | Where-Object {$_ -LT 50} | Measure-Object # count of 49

使用 ScriptBlock 时,此语法通常是最易读的,但如果您想引用对象本身(不是属性)或更复杂的布尔结果,则这是必要的.注意:许多资源会建议(如@Iftimie Tudor 提到的)尝试在管道中尽早(更多)过滤以提高性能。

Select-Object

用于过滤对象的属性,类似于 SQL 过滤列的方式。重要的是,它将管道对象转换为一个新的 PSCustomObject,该对象仅具有复制对象值的请求属性。演示:

Get-Process
Get-Process | Select-Object Name,CPU

但是请注意,这只是标准用法。使用 Get-Help Select-Object 探索其参数集,其中它具有类似的类似行的过滤功能,例如仅从继续到下一个 cmdlet 的管道(也称为 Get-Process | Select-Object -First 3)中获取前 n 个对象。

ForEach-Object

就像其他语言中的 foreach 循环一样,具有自己的重要风格。事实上,PowerShell 也有自己的 foreach 循环!这些可能很容易混淆,但在操作上却大不相同。主要的视觉差异是 foreach 循环不能在管道中使用,但 ForEach-Object 可以。后者 ForEach-Object 是一个 cmdlet(foreach 不是),可用于转换当前管道或针对管道运行一段代码。它确实是最灵活的 cmdlet。

考虑它的最佳方式是它是循环体,其中当前元素 $_ 来自管道,任何输出都传递到下一个 cmdlet。演示:

# Transform
Get-Verb | ForEach-Object {"$($_.Verb) comes from the group $($_.Group)"
# Retrieve Property
Get-Verb | ForEach-Object Verb
# Call Method
Get-Verb | ForEach-Object GetType
# Run Code
1..100 | ForEach-Object {
    $increment = $_ + 1
    $multiplied = $increment * 3
    Write-Output $multiplied
}

答案 1 :(得分:0)

其中有两件事:过滤和遍历一个集合。

  1. 过滤: 原则:请始终尽可能多地使用过滤功能。这两个命令执行相同的操作,但是第二个命令不会通过管道(或网络)传输大量数据:
  

获取过程| where对象{$ _。Name -like'chrome'} | |导出CSV   'c:\ temp \ processes.csv'

     

获取过程-名称chrome | Export-Csv c:\ temp \ processes.csv

当处理大量计算机或大文件时,这很棒。

许多Commandlet都有自己的过滤功能。运行get Get-Help get-process -full,以查看它们在提供管道之前提供了什么。

  1. 遍历集合

这里有3种可能性:

  • 批处理cmdlet 是内置的Commandlet,可以将集合传递给另一个Commandlet:
  

获取服务的名称BITS,后台处理程序,W32Time |设置服务-启动类型   自动

  • WMI方法-WMI使用它自己的第一个方法(不同的语法)
  

gwmi win32_networkadapterconfiguration -filter“描述类似   '%intel%'“ | EnableDHCP()

  • 枚举对象-遍历列表:
  

Get-WmiObject Win32_Service-过滤器“名称='BITS'” |每个对象   -process {$ _。change($ null,$ null,$ null,$ null,$ null,$ null,$ null,“ P @ ssw0rd”)}

积分: 我在一本名为《 在一个月的午餐中学习Powershell》 (在本例中为第9章和第13章)

的书中找到了可以消除所有这些麻烦的解释。