在多个子域中使用SID搜索Active Directory用户

时间:2019-10-08 10:55:44

标签: powershell active-directory

对于给定的Active Directory林(我们称其为forest1),我确实有多个子域(domain1,domain2等)。

我的应用程序中的用户可以在每个域上创建一个帐户(具有相同的cn,但具有唯一的userPrincipalName)。

创建第一个帐户时,我将存储此帐户的objectSid,以便终身使用。

在我的一个PowerShell脚本中,我想将objectSid用作forest1的筛选器,以便检索创建的第一个帐户。

当我为cn=test的用户运行以下脚本时,我得到了

  

在DC = forest1,DC = com

中找不到标识为'test'的对象

$forest = (Get-ADDomainController -DomainName \'forest1.local\' -Discover).Hostname;
$pw = ConvertTo-SecureString '${password}' -AsPlainText -Force;
$mycred = New-Object -Typename System.Management.Automation.PSCredential -ArgumentList 'forest1\ServiceAccountUser',$pw;
$User = Get-ADUser -Identity '${user.username}' -Server $forest -Credential $mycred -ErrorAction SilentlyContinue |
        Where-Object -Property SID -like '${user.firstSid}';

如果我按以下方式定位一个子域,则效果很好:

$domain = (Get-ADDomainController -DomainName \'domain1.forest1.local\' -Discover).Hostname;
$pw = ConvertTo-SecureString '${password}' -AsPlainText -Force;
$mycred = New-Object -Typename System.Management.Automation.PSCredential -ArgumentList 'forest1\ServiceAccountUser',$pw;
$User = Get-ADUser -Identity '${user.username}' -Server $domain -Credential $mycred -ErrorAction SilentlyContinue |
        Where-Object -Property SID -like '${user.firstSid}';

因此,我需要一些帮助:

  • 我们如何在脚本中指定以浏览Get-ADUser中的所有子域?
  • 如果删除该帐户,我们仍然可以使该脚本正常工作吗?

2 个答案:

答案 0 :(得分:1)

您可以执行以下操作:

$domains = Get-ADForest | Select-Object -ExpandProperty Domains
$SID = 'some sid value'
$CN = 'user CN'
foreach ($domain in $domains) {
    $DC = (Get-ADDomainController -DomainName $domain -Discover).Hostname
    $User = Get-ADObject -filter "CN -eq '$CN' -and ObjectSID -eq '$SID'" -Server $DC -IncludeDeletedObjects -Credential $mycred -ErrorAction SilentlyContinue
}

说明:

  • 您可以使用Get-ADForest命令列出所有子域,并且该集合存储在$domains中。
  • foreach循环可以遍历每个域,而当前域为$domain
  • 对于每个域,您可以查询要存储在$DC中的域控制器,然后对Get-ADObject执行-IncludeDeletedObjects
  • 要加快查询速度,可以使用-filter开关,而不是通过管道传递到Where-Object
  • 您可以过滤CNObjectSID属性。

其他注意事项:

在此脚本中,对发现的数据不执行任何操作。我不确定您要从这里去哪里。您将需要添加其他逻辑,例如if语句来检查$User的值。因为我们正在使用-filter,所以如果没有找到对象而不是抛出错误,则$user将是$null,使用Get-ADObject -Identity时会看到错误。从那里您可以进行其他处理,即使这意味着要使用break语句。

if ($user) {
    # User was found. Process code here.
    break # Exit the foreach loop because further loop processing is not needed
}
else {
    # User was not found. Process code here
}

由于所有查询的数据都存储在变量中,因此在解决方案中不会生成任何输出。 $DC$User的值将在每次循环迭代期间被覆盖。最好将发现的用户数据存储在具有一组特定属性的集合中。您可以检索DistinguishedNameCanonicalName以及SamAccountNameObjectSID来知道哪个域和容器具有用户对象。

$Users = foreach ($domain in $domains) {
    $DC = (Get-ADDomainController -DomainName $domain -Discover).Hostname
    Get-ADObject -filter "CN -eq '$CN' -and ObjectSID -eq '$SID'" -Server $DC -IncludeDeletedObjects -Properties CanonicalName,SamAccountName,ObjectSID -Credential $mycred -ErrorAction SilentlyContinue |
        Select-Object SamAccountName,ObjectSID,CanonicalName
}

在上面的代码段中,$users现在将包含具有每个对象的SamAccountNameObjectSIDCanonicalName属性的已找到用户的集合。

Get-ADUser一样,Get-ADObject的默认显示属性集也很有限。您将需要使用-Properties参数来显示所需的内容。您可以从-Properties *开始测试可用的内容。

关于如何将AD用户数据输入到脚本中的信息很少。您可能有CN个值或CSV文件的集合。您将必须考虑如何迭代这些值。

答案 1 :(得分:0)

我可能是错的,但是您可以使用SID =作为参数来调用WMI Win32_SID类。通过双向信任为我工作。