使用问号通配符过滤 Get-ADGroups 似乎不起作用
Filtering Get-ADGroups with question mark wildcard doesn't seem to work
我正在尝试获取名称以“Users-####-”(# 是数字 0-9)开头的 AD 组列表。
我试过使用 Get-ADGroup -Filter {name -like "Users-[0-9][0-9][0-9][0-9]-*"}
和 Get-ADGroup -Filter {name -like "Users-????-*"}
,但没有结果。
我当然可以使用 Get-ADGroup -Filter {name -like "Users-*"}
,但这也将包括所有在 Users- 后有四个字符以外的组。
然后我决定尝试使用 Where-Object,此代码返回了预期的组
Get-ADGroup -Filter * | Where-Object {$_.Name -like "Users-[0-9][0-9][0-9][0-9]-*"}
根据关于 wildcards 的 Microsoft 文档,我尝试的两种方法 应该 有效,但它们实际上不起作用。
任何人都知道我做错了什么,或者这只是 ADGroup 过滤工作方式中的一个错误?
Powershell Active Directory 模块中的过滤器有 odd behaviors.
过滤器或 Where 子句
There are two ways to restrict the output of an AD cmdlet like
Get-ADUser. First, you can use the -LDAPFilter or -Filter parameters
to filter the output. Second, you can pipe the results to the
Where-Object cmdlet. Where possible, the first method is more
efficient for two reasons.
Filtering is done on the domain controller instead of the local
client. The domain controller is more likely to be a server class
computer optimized for queries. Filtering results in a smaller
resultset sent over the network from the domain controller to the
client. In contrast, the Where-Object cmdlet only filters on the local
client after the resultset has been sent from the remote computer. For
example, you could retrieve all users with a department that starts
with "IT" using the Where-Object cmdlet as follows:
Get-ADUser -Filter * -Properties department | Where-Object {$_.department -Like "it*"} | Select sAMAccountName, department
The
resultset from the Get-ADUser statement includes all users in the
domain. A more efficient method to get the same results would use a
filter, similar to below:
Get-ADUser -Filter {department -Like "it*"} -Properties department | Select sAMAccountName, department
Now only the users needed are
included in the resultset from Get-ADUser. In a test domain with 2,150
users (7 of which have "IT" departments) the first command above took
4 times as long as the second (average of 10 trials each with 16
minutes between trials). The difference could be substantial in a
domain with ten's of thousands of users.
Also, note that the statements above use the -Properties parameter to
specify only the properties needed. The default properties exposed by
the cmdlet are always included, like sAMAccountName in this case. If
you request all properties, with -Properties *, the resultset will
include many properties for each user. The resultset will be much
smaller if you only specify the extended properties needed, like
department in this case. Repeating the last command above in the test
domain with 2,150 users, but requesting all properties (with
-Properties *) required 75% more time on average to complete. The default and extended properties exposed by the Get-ADUser cmdlet are
documented in Active Directory: Get-ADUser Default and Extended
Properties.
PowerShell 过滤器语法
The PowerShell Active Directory module cmdlets support an extended
form of the PowerShell Expression Language. PowerShell documentation
indicates that PowerShell syntax filters should be enclosed in braces.
But there are many examples where single quotes or double quotes are
used instead. As you might expect, this affects how the filter is
interpreted.
Using String Attributes The following table shows some example
PowerShell syntax filters using string properties, like Department.
Some filters result in error, others do not raise an error but never
produce results. The variable $Dept is defined as previously.
Filter Result
-Filter {department -eq "IT Department"} Works
-Filter {department -eq $Dept} Works
-Filter {department -eq "$Dept"} No Results
-Filter {department -eq '$Dept'} No Results
-Filter "department -eq $Dept" Error
-Filter 'department -eq $Dept' Works
-Filter {department -eq "it*"} No Results
-Filter {department -Like "it*"} Works
-Filter "department -Like ""it*""" Works
-Filter "department -Like 'it*'" Works
-Filter 'department -Like "it*"' Works
-Filter 'department -Like ''it*''' Works
-Filter {department -ge "IT"} Works
Some of these results may not be expected.
For example, you might expect enclosing a variable in a quoted string
to work. The best policy might be to always enclose PowerShell syntax
filters in braces, and to refrain from quoting variables.
The last example using the "-ge" operator is only useful in rare
situations. The filter will result in any departments that are
lexicographically greater than or equal to "IT". For example, it will
return "Test Department", because "T" is greater than "I".
在这种情况下,您可以将 -Filter
用作 pre-filter,因此至少您只会获得名称以 Users-
.
开头的组
然后在进一步的 Where-Object 子句中你可以进一步指定,在这种情况下我会使用正则表达式 -match
就像:
Get-ADGroup -Filter "Name -like 'Users-*'" | Where-Object { $_.Name -match '^Users-\d{4}-.*' }
P.S。 -Filter
应该是 字符串 ,而不是脚本块
如about_ActiveDirectory_Filter所述:
Note: PowerShell wildcards, other than "*", such as "?" are not
supported by the -Filter
parameter syntax.
在这种情况下,您可以结合使用 -LDAPFilter
和 Where-Object
来保持查询的兼容性和效率:
Get-ADGroup -LDAPFilter "(name=Users-*-*)" | Where-Object {
$_.Name -like "Users-[0-9][0-9][0-9][0-9]-*"
}
According to Microsoft documentation about wildcards, both ways I tried should work, but they actually don't.
这是一个合理的假设,但是 ActiveDirectory
模块中某些 cmdlet 公开的 -Filter
参数是一个 欺骗性结构 - 它旨在 看起来像 PowerShell 的本机运算符语法,但“在引擎盖下”cmdlet 将过滤器表达式转换为有效的 LDAP 查询过滤器:
name -like "Users-*"
# is translated to
(name=Users-*)
$_.Name -like "Users-[0-9][0-9][0-9][0-9]-*"
# is translated to
(Name=Users-[0-9][0-9][0-9][0-9]-*)
由于 LDAP 无法识别通配符范围构造 [0-9]
,它最终查询目录存储以查找名称 字面上 以 [=16= 开头的对象] - 同样适用于 ?
.
由于 *
是 LDAP 唯一接受的通配符,最接近的是:
Get-ADGroup -Filter {name -like "Users-*-*"}
然后在客户端使用 Where-Object
进一步过滤结果(在这种情况下,我们返回到 PowerShell 执行比较,我们可以再次使用所有通配符):
Get-ADGroup -Filter {name -like "Users-*-*"} | Where-Object Name -like 'Users-[0-9][0-9][0-9][0-9]-*'
我正在尝试获取名称以“Users-####-”(# 是数字 0-9)开头的 AD 组列表。
我试过使用 Get-ADGroup -Filter {name -like "Users-[0-9][0-9][0-9][0-9]-*"}
和 Get-ADGroup -Filter {name -like "Users-????-*"}
,但没有结果。
我当然可以使用 Get-ADGroup -Filter {name -like "Users-*"}
,但这也将包括所有在 Users- 后有四个字符以外的组。
然后我决定尝试使用 Where-Object,此代码返回了预期的组
Get-ADGroup -Filter * | Where-Object {$_.Name -like "Users-[0-9][0-9][0-9][0-9]-*"}
根据关于 wildcards 的 Microsoft 文档,我尝试的两种方法 应该 有效,但它们实际上不起作用。
任何人都知道我做错了什么,或者这只是 ADGroup 过滤工作方式中的一个错误?
Powershell Active Directory 模块中的过滤器有 odd behaviors.
过滤器或 Where 子句
There are two ways to restrict the output of an AD cmdlet like Get-ADUser. First, you can use the -LDAPFilter or -Filter parameters to filter the output. Second, you can pipe the results to the Where-Object cmdlet. Where possible, the first method is more efficient for two reasons.
Filtering is done on the domain controller instead of the local client. The domain controller is more likely to be a server class computer optimized for queries. Filtering results in a smaller resultset sent over the network from the domain controller to the client. In contrast, the Where-Object cmdlet only filters on the local client after the resultset has been sent from the remote computer. For example, you could retrieve all users with a department that starts with "IT" using the Where-Object cmdlet as follows:
Get-ADUser -Filter * -Properties department | Where-Object {$_.department -Like "it*"} | Select sAMAccountName, department
The resultset from the Get-ADUser statement includes all users in the domain. A more efficient method to get the same results would use a filter, similar to below:
Get-ADUser -Filter {department -Like "it*"} -Properties department | Select sAMAccountName, department
Now only the users needed are included in the resultset from Get-ADUser. In a test domain with 2,150 users (7 of which have "IT" departments) the first command above took 4 times as long as the second (average of 10 trials each with 16 minutes between trials). The difference could be substantial in a domain with ten's of thousands of users.Also, note that the statements above use the -Properties parameter to specify only the properties needed. The default properties exposed by the cmdlet are always included, like sAMAccountName in this case. If you request all properties, with -Properties *, the resultset will include many properties for each user. The resultset will be much smaller if you only specify the extended properties needed, like department in this case. Repeating the last command above in the test domain with 2,150 users, but requesting all properties (with -Properties *) required 75% more time on average to complete. The default and extended properties exposed by the Get-ADUser cmdlet are documented in Active Directory: Get-ADUser Default and Extended Properties.
PowerShell 过滤器语法
The PowerShell Active Directory module cmdlets support an extended form of the PowerShell Expression Language. PowerShell documentation indicates that PowerShell syntax filters should be enclosed in braces. But there are many examples where single quotes or double quotes are used instead. As you might expect, this affects how the filter is interpreted.
Using String Attributes The following table shows some example PowerShell syntax filters using string properties, like Department. Some filters result in error, others do not raise an error but never produce results. The variable $Dept is defined as previously.
Filter Result
-Filter {department -eq "IT Department"} Works
-Filter {department -eq $Dept} Works
-Filter {department -eq "$Dept"} No Results
-Filter {department -eq '$Dept'} No Results
-Filter "department -eq $Dept" Error
-Filter 'department -eq $Dept' Works
-Filter {department -eq "it*"} No Results
-Filter {department -Like "it*"} Works
-Filter "department -Like ""it*""" Works
-Filter "department -Like 'it*'" Works
-Filter 'department -Like "it*"' Works
-Filter 'department -Like ''it*''' Works
-Filter {department -ge "IT"} Works
Some of these results may not be expected.
For example, you might expect enclosing a variable in a quoted string to work. The best policy might be to always enclose PowerShell syntax filters in braces, and to refrain from quoting variables.
The last example using the "-ge" operator is only useful in rare situations. The filter will result in any departments that are lexicographically greater than or equal to "IT". For example, it will return "Test Department", because "T" is greater than "I".
在这种情况下,您可以将 -Filter
用作 pre-filter,因此至少您只会获得名称以 Users-
.
开头的组
然后在进一步的 Where-Object 子句中你可以进一步指定,在这种情况下我会使用正则表达式 -match
就像:
Get-ADGroup -Filter "Name -like 'Users-*'" | Where-Object { $_.Name -match '^Users-\d{4}-.*' }
P.S。 -Filter
应该是 字符串 ,而不是脚本块
如about_ActiveDirectory_Filter所述:
Note: PowerShell wildcards, other than "*", such as "?" are not supported by the
-Filter
parameter syntax.
在这种情况下,您可以结合使用 -LDAPFilter
和 Where-Object
来保持查询的兼容性和效率:
Get-ADGroup -LDAPFilter "(name=Users-*-*)" | Where-Object {
$_.Name -like "Users-[0-9][0-9][0-9][0-9]-*"
}
According to Microsoft documentation about wildcards, both ways I tried should work, but they actually don't.
这是一个合理的假设,但是 ActiveDirectory
模块中某些 cmdlet 公开的 -Filter
参数是一个 欺骗性结构 - 它旨在 看起来像 PowerShell 的本机运算符语法,但“在引擎盖下”cmdlet 将过滤器表达式转换为有效的 LDAP 查询过滤器:
name -like "Users-*"
# is translated to
(name=Users-*)
$_.Name -like "Users-[0-9][0-9][0-9][0-9]-*"
# is translated to
(Name=Users-[0-9][0-9][0-9][0-9]-*)
由于 LDAP 无法识别通配符范围构造 [0-9]
,它最终查询目录存储以查找名称 字面上 以 [=16= 开头的对象] - 同样适用于 ?
.
由于 *
是 LDAP 唯一接受的通配符,最接近的是:
Get-ADGroup -Filter {name -like "Users-*-*"}
然后在客户端使用 Where-Object
进一步过滤结果(在这种情况下,我们返回到 PowerShell 执行比较,我们可以再次使用所有通配符):
Get-ADGroup -Filter {name -like "Users-*-*"} | Where-Object Name -like 'Users-[0-9][0-9][0-9][0-9]-*'