在 Powershell 中过滤一长串列表

Posted

技术标签:

【中文标题】在 Powershell 中过滤一长串列表【英文标题】:Filter a long list in Powershell 【发布时间】:2014-12-26 15:39:38 【问题描述】:

如果您想过滤包含第一个字母 w 并且后跟“x”个数字的名称,那么如何过滤呢?

例如:

w34593 w44569a 我们5552 w01123 w85532

我已经开始了

$userIDs = Get-Aduser -filter name -like "w3*" -or name -like "w4*" -Properties * | Select name, SurName, DisplayName 

问题是一些从 w1、w2、w3、w0 开始的地方变得很长,我不想过滤每一个或代码太长。

有什么建议吗?每个名称通常有 6 到 7 个字符长,所以有一个范围长度可以帮助我吗?我试过 .length 但它似乎不适用于我的 powershell 版本

更新:

$userIDs = Get-Aduser -filter (name -gt "w30000*" -and name -lt "w99999*") -or (name -gt "we0000*" -and name -lt "we9999*") `
         -or (name -gt "cr0000*" -and name -lt "cr9999*") -or (name -gt "ac0000**" -and name -lt "ac9999*")`
         -or (name -gt "cm0000*" -and name -lt "cm9999*") -or (name -gt "do0000*" -and name -lt "do9999*") `
         -or (name -gt "ec0000*" -and name -lt "ec9999*") -or (name -gt "ev0000*" -and name -lt "ev9999*") `
         -or (name -gt "fm0000*" -and name -lt "fm9999*") -or (name -gt "ia0000*" -and name -lt "ia9999*") `
         -or (name -gt "in0000*" -and name -lt "in9999*") -or (name -gt "le0000*" -and name -lt "le9999*") `
         -or (name -gt "md0000*" -and name -lt "md9999*") -or (name -gt "mk0000*" -and name -lt "mk9999*") `
         -or (name -gt "np0000*" -and name -lt "np9999*") -or (name -gt "pb0000*" -and name -lt "pb9999*") `
         -or (name -gt "ps0000*" -and name -lt "ps9999*") -or (name -gt "re0000*" -and name -lt "re9999*") `
         -or (name -gt "sf0000*" -and name -lt "sf9999*") -or (name -gt "so0000*" -and name -lt "so9999*") `
         -or (name -gt "tr0000*" -and name -lt "tr9999*") -or (name -gt "wn0000*" -and name -lt "wn9999*")  `
         -Properties * | Select name, SurName, DisplayName, enabled

错误:

Get-ADUser : Error parsing query: '(name -gt "w30000*" -and name -lt "w99999*")
-or (name -gt "we0000*" -and name -lt "we9999*") `
         -or (name -gt "cr0000*" -and name -lt "cr9999*") -or (name -gt "ac
0000**" -and name -lt "ac9999*")`
         -or (name -gt "cm0000*" -and name -lt "cm9999*") -or (name -gt "do
0000*" -and name -lt "do9999*") `
         -or (name -gt "ec0000*" -and name -lt "ec9999*") -or (name -gt "ev
0000*" -and name -lt "ev9999*") `
         -or (name -gt "fm0000*" -and name -lt "fm9999*") -or (name -gt "ia
0000*" -and name -lt "ia9999*") `
         -or (name -gt "in0000*" -and name -lt "in9999*") -or (name -gt "le
0000*" -and name -lt "le9999*") `
         -or (name -gt "md0000*" -and name -lt "md9999*") -or (name -gt "mk
0000*" -and name -lt "mk9999*") `
         -or (name -gt "np0000*" -and name -lt "np9999*") -or (name -gt "pb
0000*" -and name -lt "pb9999*") `
         -or (name -gt "ps0000*" -and name -lt "ps9999*") -or (name -gt "re
0000*" -and name -lt "re9999*") `
         -or (name -gt "sf0000*" -and name -lt "sf9999*") -or (name -gt "so
0000*" -and name -lt "so9999*") `
         -or (name -gt "tr0000*" -and name -lt "tr9999*") -or (name -gt "wn
0000*" -and name -lt "wn9999*") ' Error Message: 'Operator Not supported: ' at 
position: '95'.
At J:\DATA\IR\ITSecurity\Intern\AlyssaC 2014\Part-time 2014-2015 task\AD\AD cle
an-up\Daily Script\AD-User.MonitorOwnership.ps1:3 char:22
+ $userIDs = Get-Aduser <<<<  -filter (name -gt "w30000*" -and name -lt "w9999
9*") -or (name -gt "we0000*" -and name -lt "we9999*") `
   + CategoryInfo          : ParserError: (:) [Get-ADUser], ADFilterParsingEx 
   ception
 + FullyQualifiedErrorId : Error parsing query: '(name -gt "w30000*" -and n 
 ame -lt "w99999*") -or (name -gt "we0000*" -and name -lt "we9999*") `
             -or (name -gt "cr0000*" -and name -lt "cr9999*") -or (name -g 
t "ac0000**" -and name -lt "ac9999*")`
             -or (name -gt "cm0000*" -and name -lt "cm9999*") -or (name -g 
t "do0000*" -and name -lt "do9999*") `
             -or (name -gt "ec0000*" -and name -lt "ec9999*") -or (name -g 
t "ev0000*" -and name -lt "ev9999*") `
             -or (name -gt "fm0000*" -and name -lt "fm9999*") -or (name -g 
t "ia0000*" -and name -lt "ia9999*") `
             -or (name -gt "in0000*" -and name -lt "in9999*") -or (name -g 
t "le0000*" -and name -lt "le9999*") `
              -or (name -gt "md0000*" -and name -lt "md9999*") -or (name -g 
t "mk0000*" -and name -lt "mk9999*") `
             -or (name -gt "np0000*" -and name -lt "np9999*") -or (name -g 
t "pb0000*" -and name -lt "pb9999*") `
             -or (name -gt "ps0000*" -and name -lt "ps9999*") -or (name -g 
t "re0000*" -and name -lt "re9999*") `
             -or (name -gt "sf0000*" -and name -lt "sf9999*") -or (name -g 
 t "so0000*" -and name -lt "so9999*") `
             -or (name -gt "tr0000*" -and name -lt "tr9999*") -or (name -g 
 t "wn0000*" -and name -lt "wn9999*") ' Error Message: 'Operator Not suppor  
ted: ' at position: '95'.,Microsoft.ActiveDirectory.Management.Commands.Ge   
 tADUser

更新 2:这一次我分别做了每一个,他们工作了????我不明白为什么我的主过滤器不工作,除非它们被单独过滤

其中一些:

$wIDs = Get-Aduser -filter (name -gt "w30000*" -and name -lt "w99999*") -Properties * | Select name, SurName, DisplayName, enabled
$weIDs = Get-Aduser -filter (name -gt "we0000*" -and name -lt "we9999*") -Properties * | Select name, SurName, DisplayName, enabled

foreach ($user in $wIDs) 

if ($user.DisplayName -like "*-DISABLED")

#$groups = get-Adgroup -properties managedby -filter managedby -eq $user.name

write-host "User ID: " $user.name
write-host "Last Name: " $user.SurName
write-host "Display Name: " $user.DisplayName

write-host $break1 "Next User:" $break1
#end of if statement

#end foreach

foreach ($user in $weIDs) 

if ($user.DisplayName -like "*-DISABLED")

#$groups = get-Adgroup -properties managedby -filter managedby -eq $user.name

write-host "User ID: " $user.name
write-host "Last Name: " $user.SurName
write-host "Display Name: " $user.DisplayName
#write-host "Managed Groups: " $groups

write-host $break1 "Next User:" $break1
#end of if statement

#end foreach

这些打印正确没有错误???

【问题讨论】:

w ID 有效,但其余无效。我收到了这个巨大的错误 我删除了 * 并且错误仍然存​​在...我将再次显示我的更新:这次我单独过滤了每一个(非常糟糕,因为我的脚本很长,但是如果我是单独做的,所以我的主过滤器有问题) 【参考方案1】:

出于性能原因,首选使用-Filter,因为Get-ADUser 不会返回所有用户对象。但是,在这种情况下,我认为由于事实后基于正则表达式的条件标准的数量可能更适合此情况。因此,除非您有 1000 个用户中的 10 个,否则这应该可以正常工作。此外,您正在恢复 所有 用户属性,但只占用 4 个。这本身就是性能损失。唯一不默认的是Enabled,所以我们一定会接受。

$prefixes = "cr","cm","ec","fm","in","md","np","ps","sf","tr","ac","do","ev","ia","le","mk","pb","re","so","wn","we","w[3-9]"
$regex = "^($($prefixes -Join "|"))\d*"
$results = Get-ADUser -Filter * -Properties Enabled,DisplayName | 
    Where-Object$_.Name -match $regex | 
    Select Name,SurName,DisplayName,Enabled
$results

基本上构建一个正则表达式匹配字符串,其中名称必须以两个字符组之一开头*(w30000 标准与另一个不同,这就是为什么最后你会看到w[3-9],这意味着“w”跟在后面由“3 到 9”的数字)后跟一些数字。该字符串由$prefixes 的数组构建而成,您可以随意添加和删除。

这可能不符合您的确切标准,但可以根据匹配的内容轻松更改。很确定-lt-gt等不支持通配符。认为它将它们视为文字星号字符。 -like-notlike 支持通配符。

是否存在具有不同 2 个字符前缀的帐户?如果不是,这可以通过一个非常简单的正则表达式来完成,比如^\w2\d+,它是 2 个字符后跟至少一个数字。

【讨论】:

感谢您提供如此详细的信息和解释。我以前从未见过 \d+ 代码。我尝试打印您的示例以了解它是如何工作的,但什么也没发生。我还认为前缀变量对我不起作用,因为还有其他以 cr..cm 等开头但没有数字的 id。嗯... 我将+ 更改为*,以便匹配“cm”和“ec0000”。你能告诉我一个其他匹配的名字的例子吗?这些也是实际名称还是samaccountnames? @AlyssaCooke 调频:fmsad。用于:install99,安装...。 for ev: evaltes... 等等。这些也是实际名称 在将数字更改为可选(顺便说一句,您的问题中没有提到)并在我自己的组织上运行测试后,这对我有用。我的括号也错了@AlyssaCooke。复制我更新的代码并告诉我 好吧,是的,你的确实有效。我看到你现在用括号做了什么。你的例子更容易理解。我很感激。我会玩你的例子,看看我可以从这里去哪里。非常感谢您解释了很多。【参考方案2】:

这对你有用吗?

Get-Aduser -filter name -gt "w3000" -and name -lt "w9999" 

编辑:

鉴于新要求:

$prefixes = "cr","cm","ec","fm","in","md","np","ps","sf","tr","ac","do","ev","ia","le","mk","pb","re","so","wn","we"

#Create filter for searches
$DNFilters = $prefixes -replace '^','(Name=' -replace '$','*)'
$Filter = "(|$DNFilters)"


Get-ADUser -LDAPFilter $Filter -Properties Enabled |
 Where-Object $_.name -like '??[0-9][0-9][0-9][0-9]'

这将使您可以使用早期过滤来仅返回名称与前缀匹配的帐户。后期过滤器(Where-Object) 将过滤后面没有 4 位数字的过滤器。

编辑: 这一行:

$DNFilters = $prefixes -replace '^','(Name=' -replace '$','*)'

获取每个前缀,并预先添加字符串 '(Name=',然后将字符串 '*)' 附加到它。结果是,例如前缀 'cr' 将变为 '(Name=cr*)' 。这是任何以“cr”开头的名称的 LDAP 过滤器。

然后这一行:

$Filter = "(|$DNFilters)"

将它们包装在 '(|' 和 ')' 中。 '|'在 LDAP 过滤器中表示“或”。生成的过滤器如下所示:

(|(Name=cr*) (Name=cm*) (Name=ec*) (Name=fm*) (Name=in*) (Name=md*) (Name=np*) (Name=ps*) (Name=sf*) (Name=tr*) (Name=ac*) (Name=do*) (Name=ev*) (Name=ia*) (Name=le*) (Name=mk*) (Name=pb*) (Name=re*) (Name=so*) (Name=wn*) (Name=we*))

所有单独的 LDAP 过滤器都被 ORed 到一个过滤器中。

在这一行:

Where-Object $_.name -like '??[0-9][0-9][0-9][0-9]'

?? 表示“任意两个字符”。在通配符匹配 (-like) 中,? 表示“任何单个字符”。

【讨论】:

它运行得非常慢,我不得不重新启动它:/哇 好吧,我意外地没有更改为 -and 并且有 -le 而不是 -lt。它有效..谢谢!!! 出现错误。我认为这是因为 w 因为 gt 和 lt 仅用于数字 如果您查看technet.microsoft.com/en-us/library/hh847759.aspx @AlyssaCooke,您会发现它适用于字符串和数字。这完全取决于左侧的内容。 在使用 LDAP 过滤器后,您可能无法准确地获得您想要的结果,但您可以使用它来修剪结果,这样您就可以使用后期过滤来过滤掉。

以上是关于在 Powershell 中过滤一长串列表的主要内容,如果未能解决你的问题,请参考以下文章

设计带有一长串查询参数的 RESTful 查询 API [关闭]

我想滚动到页面顶部,因为我的列表包含一长串数据,我该怎么做?

存储一长串值的最佳方法

如何在 selectInput R Shiny 中为一长串选项设置值

为啥有一长串没有任何底片的 PolygonVertexIndex(在一个 Fbx 文件中)?

如何在 VueJS 中将一长串“手表”转换为功能方式?