Powershell ... 'enabled eq $true' vs where {$_.Enabled -eq $true} [英] Powershell... 'enabled eq $true' vs where {$_.Enabled -eq $true}

查看:48
本文介绍了Powershell ... 'enabled eq $true' vs where {$_.Enabled -eq $true}的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 powershell 知之甚少.

我想知道是否有人可以指出我需要了解的内容来解释以下内容:

PS C:\Users\username>(Get-Aduser -Filter 'Enabled -eq $true').count1234PS C:\用户\用户名>(Get-Aduser -filter * | where {$_.Enabled -eq $true }).count13

他们读起来非常相似......?什么是已启用",它与我读取的 $_ 有何不同,它指的是管道上的当前对象",我认为它是用where"迭代的.

谢谢!

解决方案

一般 - 这个

Get-Aduser -Filter "something -eq 'some value'"

将过滤器发送给服务器(即域控制器),服务器只返回匹配的用户,而这个

Get-Aduser -filter *

从服务器获取所有用户,并在脚本的第二步中过滤他们(使用where).

显然第一种方法效率更高,即使结果相同.

<小时>

至于 Enabled 检查,事情有点复杂.AD 中的用户对象实际上没有 Enabled 属性 - 该属性是在客户端添加的.这意味着您不能将 Enabled -eq $true 传递给服务器,它不知道如何处理.

AD 用户帐户对象具有 收集各种标志的userAccountControl 属性:

<块引用>

脚本 0x0001 1帐户禁用 0x0002 2HOMEDIR_REQUIRED 0x0008 8锁定 0x0010 16PASSWD_NOTREQD 0x0020 32

还有很多.设置标志 2 时,帐户被禁用.如果使用 LDAP 过滤器设置了此标志,您可以专门查询服务器:

# 所有被禁用的用户Get-ADUser -LdapFilter "(userAccountControl:1.2.840.113556.1.4.803:=2)"# 所有未禁用的用户Get-ADUser -LdapFilter "(!(userAccountControl:1.2.840.113556.1.4.803:=2))"

这有点笨拙,但这是 LDAP 的方式.(:1.2.840.113556.1.4.803: 代表 LDAP 中的按位与"运算符.他们不知何故没有为它制作一个更简单的符号.)

使用此过滤器,过滤实际上再次发生在服务器端,这意味着它应该比替代方法快得多,尤其是当 AD 中有很多用户帐户时.

我不认为有一种方法可以在 Get-ADUser 的友好"-Filter 语法中表达这个特定的东西,但其他过滤器可以在服务器上工作-边

#名字以A开头的所有用户Get-ADUser -Filter "givenName -like 'A*'"

<小时>

Get-ADUser 在内部做的是,它解析 -Filter 字符串,并从中构建一个 LDAP 过滤器,因为 LDAP 过滤器语法是唯一的服务器理解:

PowerShell 风格"过滤器 givenName -like 'A*' 将被转换为 LDAP 过滤器 (givenName=A*).

但是当尝试使用 Enabled -eq $true 时,Get-ADUser 出现问题,它似乎完全忽略了它,可能是因为它不聪明足以将其转换为 (!(userAccountControl:1.2.840.113556.1.4.803:=2)).因此 LDAP 过滤器保持为空,服务器返回所有帐户.

这就是我从一开始就倾向于编写 LDAP 过滤器的原因.学习起来并不难,比 PowerShell 语法更通用,比客户端过滤更快,并且按原样发送到服务器,事先没有任何问题.

I know very very little about powershell.

I'm wondering if anyone can point me at what I need to learn about to explain the following:

PS C:\Users\username> (Get-Aduser -Filter 'Enabled -eq $true').count
1234
PS C:\Users\username> (Get-Aduser -filter * | where {$_.Enabled -eq $true }).count
13

They read pretty similar... ? What is 'Enabled' and how can it be different to the $_ which I read refers to the 'current object on the pipeline' which I assume is iterated through with the 'where'.

Thanks!

解决方案

In general - This

Get-Aduser -Filter "something -eq 'some value'"

sends the filter to the server (i.e. the domain controller), and the server only returns the matching users, whereas this

Get-Aduser -filter *

gets all users from the server, and filters them in a second step inside the script (using where).

Obviously the first approach is much more efficient, even if the result is the same.


As for the Enabled check, things are a bit more complicated. User objects in AD do not actually have an Enabled property - that property is added on the client side. Which means that you can't pass Enabled -eq $true to the server, it would not know what to do with that.

AD user account objects have the userAccountControl property which collects all kinds of flags:

SCRIPT            0x0001   1
ACCOUNTDISABLE    0x0002   2
HOMEDIR_REQUIRED  0x0008   8
LOCKOUT           0x0010  16
PASSWD_NOTREQD    0x0020  32

and quite a few more. An account is disabled when flag 2 is set. You can query the server specifically if this flag is set by using an LDAP filter:

# all disabled users
Get-ADUser -LdapFilter "(userAccountControl:1.2.840.113556.1.4.803:=2)"

# all NOT disabled users
Get-ADUser -LdapFilter "(!(userAccountControl:1.2.840.113556.1.4.803:=2))"

This is a bit unwieldy but it's the way LDAP does it. (The :1.2.840.113556.1.4.803: represents the "bitwise AND" operator in LDAP. They somehow did not make a simpler symbol for it.)

With this filter, the filtering actually happens on the server side again, which means it should be significantly faster than the alternative, especially when there are many user accounts in AD.

I don't think there is a way to express this particular thing in the "friendly" -Filter syntax of Get-ADUser, but other filters would work server-side

# all users whose first name starts with an A
Get-ADUser -Filter "givenName -like 'A*'"


What Get-ADUser does internally is, it parses the -Filter string, and builds an LDAP filter from that, because the LDAP filter syntax is the only thing the server understands:

The "PowerShell-style" filter givenName -like 'A*' will be translated to the LDAP filter (givenName=A*).

But it appears when trying that with Enabled -eq $true, something goes wrong inside Get-ADUser, it seems to ignore it entirely, probably because it's not smart enough to translate that into (!(userAccountControl:1.2.840.113556.1.4.803:=2)). And so the LDAP filter stays empty and the server returns all accounts.

This is the reason why I tend to write LDAP filters from the start. It's not too hard to learn, more versatile than the PowerShell syntax, faster than client-side filtering and it's sent to the server as-is, nothing messes with it beforehand.

这篇关于Powershell ... 'enabled eq $true' vs where {$_.Enabled -eq $true}的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆