當您在一個對象集合中處理 PowerShell 屬性值時,有時您需要一種方法來過濾掉所有您不需要的東西。知道如何使用 PowerShell 的 Where-Object
命令是您 PowerShell 工具箱中重要的技能。
Where-Object
命令是一種方便的過濾對象的方法。在本教程中,您將學習不同的構造 Where-Object
命令的方法,以及它的可用參數、語法,以及如何像專業人士一樣使用多個條件!
先決條件
本文只有一個先決條件。您應該對 PowerShell 命令和語法有一些基本的熟悉。
本文中的所有示例都基於 當前穩定版本的 PowerShell(撰寫時為 7.1.0)。但只要您使用的是 Windows PowerShell 4.0 或更高版本,這些命令將運作相同。
理解 PowerShell Where-Object 的工作原理
PowerShell 的 Where-Object
命令的唯一目標是過濾命令返回的輸出,只返回您想要看到的信息。
簡而言之,Where-Object
命令是一個過濾器;就這樣。它允許您構造一個返回 True 或 False 的條件。根據該條件的結果,該命令要麼返回輸出,要麼不返回。
您可以用两种方式之一来创建这个条件;“旧”方式使用脚本块,以及使用参数或比较语句的“新”方式。
使用脚本块创建筛选条件
脚本块是PowerShell中的一个关键组件。脚本块在语言的许多地方都有使用。脚本块是一个匿名函数,它可以将代码分隔开并在不同的地方执行。您可以通过脚本块构建Where-Object
的筛选器。
要将脚本块用作筛选器,您需要使用FilterScript
参数。该参数允许您创建和传递一个脚本块给FilterScript
参数,然后执行该脚本块。
如果脚本块返回的值不是布尔值False或空变量,则被视为True。否则被视为False。
例如,假设您需要找到当前启动类型为Automatic的所有Windows服务。您可以首先使用Get-Service
获取所有当前服务。然后,Get-Service
将返回许多不同的服务对象以及各种属性。
使用 PowerShell 管線,您可以將這些物件傳送到 Where-Object
cmdlet,並使用 FilterScript
參數。由於 FilterScript
參數接受一個 scriptblock,您可以建立一個條件來檢查每個物件的 StartType
屬性是否等於 Automatic,如下所示。
一旦您有了篩選的 scriptblock,您就可以將該 scriptblock 提供給 FilterScript
參數。Where-Object
將會對管線中的每個物件執行該 scriptblock,並評估每個 StartType
屬性。如果該屬性等於 Automatic,則 Where-Object
會通過該物件。如果不是,該物件將被丟棄。
您可以在下面看到一個簡單的例子。

許多人在使用
Where-Object
cmdlet 時使用位置參數,並且不包含FilterScript
參數名稱。相反,他們只提供 scriptblock,例如Where-Object {$_.StartType -eq 'Automatic'}
。
雖然這種構造對於這個特定的情境可以工作,但 scriptblock 的概念使用大括號或者 管線變數 $_
使得代碼不易閱讀,對於較不熟悉 PowerShell 的使用者來說更加困難。這種可讀性問題是 PowerShell 團隊引入參數或比較語句的原因。
比較語句
在Windows PowerShell 3.0中引入的比較語句的結構更加自然。使用與前面例子相同的情境,讓我們使用比較語句結構來查找所有啟動類型為「自動」的Windows服務:
注意上面的例子中,命令中指定了對象屬性作為Property
參數的值。現在,eq
運算符也是一個參數,允許你將「自動」的值傳遞給它。
使用這種方式的參數現在完全消除了對腳本塊的需求。
A scriptblock is a better choice when defining more complex filtering conditions. The
Property
parameter may not always be the best choice. If using a scriptblock, just remember to document your code using comments!
在下一節中,你將學習可以與Where-Object
一起使用的可用比較運算符類型,以便對所有事物進行過濾。
過濾基礎知識
使用參數,Where-Object
使用常見的比較運算符對對象集合進行過濾。讓我們深入了解一些它們的工作原理的例子。
包含運算符
在處理集合時,包含運算符非常有用。包含運算符允許你定義一個條件,用於判斷集合是否包含某個項目。
舉個例子,假設你想要在集合中過濾特定的屬性值。你可以使用包含運算符。
在PowerShell中,你會找到幾個不同的包含運算符:
-contains
/-ccontains
– 過濾包含某個屬性值的集合。-notcontains
/-cnotcontains
– 篩選不包含某屬性值的集合。-in
/-cin
– 值存在於集合中,如果找到匹配則返回屬性值。-notin
/-cnotin
– 值不存在於集合中,如果沒有屬性值則返回null
/$false
。
對於大小寫敏感性,請使用以 -c[運算符]
開頭的包含運算符
假設您想檢查 BITS Windows 服務的狀態。您可以使用 contains
參數(運算符),將 BITS 的值傳遞給它,如下所示。
以下是您預期看到的結果:

始終記得向左篩選!前面的示例相當於運行
Get-Service -ServiceName 'BITS'
。
也許您想更進一步,查找所有狀態不是 Running 且 StartType 是一個名為 Manual 的字串(或可能是一個數組)的服務。使用以下腳本塊,命令使用 FilterScript
參數傳遞一個腳本塊來評估這兩個條件。
當您執行上述命令時,您只會看到已停止且具有手動的StartType的服務。

使用包含運算子對包含許多屬性值的集合進行篩選非常有效。由於Get-Service
返回的屬性數量很多,當您結合包含和邏輯運算子時,通過所有這些屬性進行篩選變得更加容易。
匹配運算子
類似於使用Where-Object
時使用包含運算子,您也可以使用匹配運算子。匹配運算子允許您在字符串中匹配子字符串。例如,'foofoo' -like '*foo*'
返回True,或'foofoo' -match 'foo'
返回True。匹配運算子在字符串中匹配子字符串。
在PowerShell中,您可以在Where-Object
中使用幾種不同的匹配運算子。
-like
/-clike
– 字符串匹配通配符模式。-notlike
/-cnotlike
– 字符串不匹配通配符模式。-match
/-cmatch
– 字符串匹配正則表達式模式。-notmatch
/-cnotmatch
– 字符串不匹配正則表達式模式。
要進行區分大小寫的比較,請使用以
-c[operator]
開頭的匹配運算子。
幾乎與包含運算子具有相同的形式,您可以按照下面所示使用匹配運算子。下面的示例是找出所有具有Windows在DisplayName屬性值中的服務。

match
operator uses regular expressions to match on certain values.您還可以使用like
運算子使用常見的匹配技術,例如使用萬用字元(*
)匹配任何字符,或者使用?
匹配單個字符。
現在結果已過濾為只顯示以“Win”作為前三個字符的服務名稱:

使用萬用字元意味著您不必知道服務的完整名稱。只需幾個字母即可。這些運算子還可以與邏輯運算子結合使用,以進一步增強過濾功能。
等於運算子
與使用包含和比較運算子的方式類似,您也可以在Where-Object
中使用等於運算子。當需要比較數值時,等於運算子非常有用。
例如,1 -eq 1
為True,而1 -gt 2
為False。PowerShell有許多不同的等於運算子,您可以將其用作Where-Object
的參數或在條件腳本塊中使用。
-eq
/-ceq
– 值等於指定值。-ne
/-cne
– 值不等於指定的值。-gt
/-cgt
– 值大於指定的值。-ge
/-cge
– 值大於或等於指定的值。-lt
/-clt
– 值小於指定的值。-le
/-cle
– 值小於或等於指定的值。
例如,也許您想要找到佔用 CPU 百分之二到百分之十的所有正在運行的進程。 使用 Get-Process
和 Where-Object
PowerShell cmdlet,這不是問題。
使用腳本區塊,您可以使用 and
運算子將兩個條件結合在一起,該運算子將對它們進行評估。 如果它們都返回 True,Where-Object
就會返回在管道上傳遞的進程物件。 如果至少有一個條件返回 False,Where-Object
就會丟棄該物件。
這是您所期望看到的:

使用 Where-Object
相等運算子進行過濾將有助於構建系統報告或比較值。
下一步操作
現在您已經更了解如何使用 PowerShell 的 Where-Object
命令來過濾各種東西,還可以做什麼呢?嘗試使用多個條件和運算符對集合進行更複雜的過濾任務,以過濾出屬性值並按照您的喜好格式化輸出。
Source:
https://adamtheautomator.com/powershell-where-object/