从AD用户获取顶级OU

我在问这个问题主要是问是否有更好的方式去做我的工作。 我也想知道是否有人通过这种方式看到这个信息的任何问题。

我正在尝试获取用户所在的顶级OU,以及任何较低级别的OU。 主要问题是我们有多个站点,其中一些站点有多个用户帐户的OU( ou=doctors,ou=Users,ou=Site,dc=example,dc=com ),有些站点只有一个单个OU( ou=Users,ou=Site,dc=example,dc=com )。 我使用下面的脚本获取DNpath,将其拆分,并用最后三个部分向后重build。 任何人都可以看到这样做的任何问题。 有些事情只是感觉错误….

 $user = Get-ADUser CKnutson $user.DistinguishedName # Returns: CN=Cory Knutson,OU=IT,OU=Users,OU=Site,DC=example,DC=com $split = $user.DistinguishedName.Split(',') $path = "$($split[-3]),$($split[-2]),$($split[-1])" Write-Host $path # Returns: OU=Site,DC=example,DC=com 

只是说明,最终的目标是让我走到我们刚才在每个“Site”OU里面的“Disabled”OU。 所以我的脚本可以移动对象,当禁用帐户到适当的地方,在该网站的顶级OU( OU=Disabled,OU=Site,DC=example,DC=com )。

任何人都可以看到这样做的任何问题。

是的,我看到你目前的方法可能出现两个直接的问题。


1.转义逗号

考虑名称中带有逗号的OU,例如: OU=Users\, Admin,DC=corp,DC=example

你使用string.Split()不会关心转义序列,你最终得到:

  Admin,DC=corp,DC=example 

使用-split正则expression式运算符以确保忽略转义逗号:

 $parts = $user.DistinguishedName -split '(?<!\\),' 

2.可移植性

你的代码假定DN的NC部分(例如DC=example,DC=com )总是只有2个标签宽。 这意味着如果您在可能希望在其他域/环境中重用的脚本中使用该代码,则代码将失败。

我会抓住每个部分,从右到左,直到我find一个没有 DC RDN前缀:

 $topParts = foreach($part in $parts[-1..-$parts.Length]){ $part if($part -notlike 'DC=*'){ break } } # Remember to reverse the RDNs again $path = $topParts[-1..-$topParts.Length] -join ',' 

在我看来,使用Pathname COM对象更简单,只需要请求DN的父对象。 你可以把它放在while循环中来获得对象的层次结构。 使用我的ADName模块的示例:

 $dn = Get-ADUser user | Select-Object -ExpandProperty DistinguishedName $parent = $dn | Get-ADName -Format Parent while ( $parent -like "OU=*" ) { $parent $parent = $parent | Get-ADName -Format Parent } 

示例输出:

 OU=Level 3,OU=Level 2,OU=Level 1,DC=fabrikam,DC=com OU=Level 2,OU=Level 1,DC=fabrikam,DC=com OU=Level 1,DC=fabrikam,DC=com 

那么你是在通往账户path的DN之后? 你可以使用正则expression式来使用(?)ungreedy限定符。 没有分裂,所以转义的逗号不是问题。

 "CN=Cory Knutson,ou=doctors,ou=Users,ou=Site,dc=example,dc=com" -match ".+?,(OU=.+)" $matches[1] ou=doctors,ou=Users,ou=Site,dc=example,dc=com "CN=Knutson\, Cory,ou=doctors,ou=Users,ou=Site,dc=example,dc=com" -match ".+?,(OU=.+)" $matches[1] ou=doctors,ou=Users,ou=Site,dc=example,dc=com "CN=Cory Knutson,ou=Site,dc=example,dc=com" -match ".+?,(OU=.+)" $matches[1] ou=Site,dc=example,dc=com 

编辑
我从the top level OU that a user is in, and any lower level OUs.中不清楚the top level OU that a user is in, and any lower level OUs. 你也可以这样做:

 $dn = "CN=Cory Knutson,ou=doctors,ou=Users,ou=Site,dc=example,dc=com" $last = ($dn.toUpper()).lastIndexOf("OU=") $dn.substring($last) ou=Site,dc=example,dc=com