如何查看 Get-ADUser 执行的 LDAP 查询幕后,即此命令
Get-ADUser -Filter * -Properties * | Where { $_.Enabled -eq $True } | Where { $_.PasswordNeverExpires -eq $False } | Where { $_.PasswordExpired -eq $False }
我想知道发送到 Active Directory 服务器的确切 LDAP 查询。
编辑:我正在尝试将一些 Powershell 脚本转换为 Python,因此我需要可以提供给 python-ldap 的原始 LDAP 查询。
编辑 2:Active Directory 管理中心具有学习 LDAP 查询的出色功能。在全局搜索中,您可以使用关键字和勾选复选框来构建查询,然后单击转换为 LDAP. 享受美好而复杂的 LDAP 查询。
答案1
该ActiveDirectory
模块具有巧妙的逻辑,可以计算“流行”属性,例如用户帐户是否Enabled
设置PasswordNeverExpires
,并将它们像常规属性一样呈现。
在内部,它们源自实际的帐户属性,例如userAccountControl
和pwdLastSet
。
帐号设定
userAccountControl
是一个位域,包含一长串与帐户安全相关的设置,例如“用户不能更改密码”和帐户“已禁用”。
Microsoft 的 LDAP 实现允许您使用按位运算符过滤此类属性,并由对象标识符 (OID) 标识:
LDAP_MATCHING_RULE_BIT_AND: 1.2.840.113556.1.4.803
LDAP_MATCHING_RULE_BIT_OR : 1.2.840.113556.1.4.804
为了查找Disabled
帐户,我们可以使用以下过滤语法:
(&(userAccountControl:1.2.840.113556.1.4.803:=2))
与往常一样,您可以使用来否定 ldap 表达式!
,在此示例中检索所有Enabled
帐户:
(!(userAccountControl:1.2.840.113556.1.4.803:=2))
同样,名为的设置DONT_EXPIRE_PASSWORD
具有值 65536 (0x10000),我们可以使用以下命令找到这些帐户:
(&(userAccountControl:1.2.840.113556.1.4.803:=65536))
密码过期
计算密码过期时间有点复杂。为了帮助开发人员和集成商,微软实现了一个名为msDS-User-Account-Control-Computed
。
msDS-User-Account-Control-Computed
透明地返回与相同的值userAccountControl
,但添加了以下位,在查找时动态计算:
UF_LOCKOUT 0x0010
UF_PASSWORD_EXPIRED 0x800000
UF_PARTIAL_SECRETS_ACCOUNT 0x4000000
UF_USE_AES_KEYS 0x8000000
我还没有测试过,但如果我没记错的话,这应该对你有帮助可靠地使用此过滤器识别密码过期的帐户:
(&(msDS-User-Account-Control-Computed:1.2.840.113556.1.4.803:=8388608))
不幸的是,您不能在 LDAP 查询过滤器中使用构造属性,因此您必须做的是根据前两个语句进行过滤:
(&(!userAccountControl:1.2.840.113556.1.4.803:=2)(!userAccountControl:1.2.840.113556.1.4.803:=65536))
请务必向目录服务器询问该msDS-User-Account-Control-Computed
值,然后在客户端对结果执行按位与掩码。
答案2
如果您真的想知道 Powershell Cmdlet 正在执行哪些具体的 LDAP 查询,那么您可以使用 DotPeek 对它们进行反编译,使用我在此处概述的方法:
https://www.myotherpcisacloud.com/post/2013/07/08/Taking-a-Peek-Inside-Powershell-Cmdlets.aspx
使用$(Get-Command Get-ADUser).DLL
查看 Cmdlet 是从哪个 DLL 导入的。然后使用Trace-Command
查看 调用的 DLL 中的方法的名称Get-ADUser
。
Trace-Command -Name CommandDiscovery -Expression { Get-ADUser bob } -PSHost
现在使用 JetBrains DotPeek 反编译该 DLL 并亲自查看代码。
或者,为了避免经历所有这些混乱,你为什么不这样做呢:
Get-ADUser -LDAPFilter "(objectCategory=person)"
现在您知道(并可以控制)它正在使用的 LDAP 查询。
答案3
我认为你最好花些时间了解一下AD 架构并自行构建查询,而不是尝试对 Microsoft 自己的工具进行逆向工程。AD 足以成为普通的 LDAP 目录,因此参考有关 LDAP 的文章通常适用。是一些奇怪的事情,例如位字段在从 Windows NT 4.0 继承的属性例如,这对于系统管理员类型的查询相当重要。