如何使用 Where-Object 匹配 属性 字符串的任何部分

How to match any part of a property string using Where-Object

我有一个包含很多元素的数组 $array,示例如下:

ProfileID         : 100
UID               : 17
Name              : SharePoint
Description       : SharePoint Server Description

现在我尝试按 Name 属性 进行过滤,要匹配的字符串是:

$string
SharePoint Policy Assignment

我试过:

$array | Where-Object {$_.Name -like "$string"}
no match

$array | Where-Object {$_.Name -like "$string*"}
no match

$array | Where-Object {$_.Name -match "$string"}
no match

这可以使用 PowerShell 吗?我错过了什么?

PowerShell中的-like运算符用于通配符匹配,所以需要使用通配符,星号,*.

想象一下这种情况,我正在尝试匹配特定的 Windows 服务。

$svcs = Get-Service | Select-Object -first 15

C:\temp\blog> $svcs

Status   Name               DisplayName                           
------   ----               -----------                           
Stopped  AJRouter           AllJoyn Router Service                
Stopped  ALG                Application Layer Gateway Service     
Running  AMD External Ev... AMD External Events Utility           
Stopped  AppIDSvc           Application Identity                  
Running  Appinfo            Application Information               
Stopped  AppMgmt            Application Management                
Stopped  AppReadiness       App Readiness                         
Stopped  AppVClient         Microsoft App-V Client                
Stopped  AppXSvc            AppX Deployment Service (AppXSVC)     
Stopped  aspnet_state       ASP.NET State Service                 
Stopped  AssignedAccessM... AssignedAccessManager Service         
Running  AsSysCtrlService   ASUS System Control Service           
Running  AudioEndpointBu... Windows Audio Endpoint Builder        
Running  Audiosrv           Windows Audio                         
Running  AUEPLauncher       AMD User Experience Program Launcher  

要使用 -Like 运算符进行匹配,我必须提供通配符,如下所示。

$svcs | Where-Object Name -like App*

Status   Name               DisplayName                           
------   ----               -----------                           
Stopped  AppIDSvc           Application Identity                  
Running  Appinfo            Application Information               
Stopped  AppMgmt            Application Management                
Stopped  AppReadiness       App Readiness                         
Stopped  AppVClient         Microsoft App-V Client                
Stopped  AppXSvc            AppX Deployment Service (AppXSVC)     

使用 WildCard 尝试您的操作,我敢打赌它会成功:)

我注意到的另一件事是,您的 $string 等于 SharePoint Policy Assignment,但是您要比较的 .Name 的列只是 SharePoint

补充:

使用已经在内存中或很容易适应的集合,您可以使用member-access enumeration以获得更方便的语法这也导致执行速度更快:

@($array.Name) -like $string  # returns sub-array of matching elements

-like,当给定一个 array 作为 LHS 时,充当过滤器:只有那些匹配的数组元素RHS 上的通配符表达式是 returned(也作为数组)。

注意需要@(...)来确保$array.Name是一个数组,因为单元素 数组将导致 .Name 属性 得到 returned 作为 标量(单个字符串), 在这种情况下 -like 将 return 一个 布尔值 ($true$false) 而不是充当 过滤器.


另请注意,许多 PowerShell cmdlet 直接 支持通配符表达式作为参数值:

Get-Service为例,其(隐含)-Name参数支持通配符:

Get-Service *router*  # returns all services whose Name contains "router"

确定给定 cmdlet 参数的通配符支持:

PS> Get-Help Get-Service -Parameter Name

-Name <String[]>
    Specifies the service names of services to be retrieved. Wildcards are permitted. By default, this cmdlet gets all of the services on the computer.

    Required?                    false
    Position?                    1
    Default value                None
    Accept pipeline input?       True (ByPropertyName, ByValue)
    Accept wildcard characters?  false

应该Accept wildcard characters?值是true表示支持通配符表达式,然而,不幸的是不可靠,所以还要检查参数描述;在这里,描述部分 Wildcards are permitted 提供了信息。
GitHub issue #4716 描述了问题并要求使通配符支持的编程可发现性可靠。