【问题标题】:Extract all users from active directory groups from multiple domains using Powershell?使用Powershell从多个域的活动目录组中提取所有用户?
【发布时间】:2015-10-28 18:22:17
【问题描述】:

我在 Active Directory 或 Powershell 方面没有太多专业知识,我需要提取所有用户以及属于 1000 多个安全组的详细信息。

我尝试了几种不同的在线 PS 脚本,但由于数据量大,脚本需要很长时间才能完成(我在脚本运行 3 天后停止了该脚本)

我还尝试使用 SSIS 分解组列表并一次运行 100 个组,但无济于事。

我正在使用以下第一个脚本来拉取组成员和第二个脚本来拉取其余的用户详细信息

附:组和用户是来自多个子域的混合体。

脚本 1:

$groups = Get-Content c:\temp\Groups.txt      
foreach($Group in $Groups) {            
    Get-ADGroupMember -Id $Group | select  @{Expression=    {$Group};Label="Group Name"},* | Export-CSV c:\temp\GroupsInfo.CSV -    NoTypeInformation
}

脚本 2:

$objForest =     [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()
$DomainList = @($objForest.Domains | Select-Object Name)
$Domains = $DomainList | foreach {$_.Name}
$Users = Import-CSV c:\users\public\users.csv
#Act on each domain
foreach($Domain in ($Domains))
{
    Write-Host "Checking $Domain" -fore blue
    Foreach($mail in ($Users.mail))
    {
        Get-ADUser -filter {mail -eq $mail} -Server $domain -properties     mail | select mail,employeeID,title,department,name

        Export-CSV c:\temp\MemberDetails.CSV -NoTypeInformation
    }
}

【问题讨论】:

  • 您在哪里运行代码?如果您从远程计算机运行它,请尝试在您的 DC 上运行它。
  • @Cavalli - 我无权访问 DC 服务器,我在运行 windows 企业(而不是 windows 服务器)的工作站上运行它。
  • 我遇到了完全相同的问题,我已经通过在我的 DC 上本地运行我的脚本来解决它。您在运行脚本时是否监控过工作站的性能(cpu 使用率、内存...)?
  • 如果您熟悉 PowerShell 工作流,这可能是一个不错的选择。如果不是,您可能想尝试将其作为作业运行以拉动组成员,以便您可以一次查询多个组。另外,您是否确保删除重复的用户引用?假设一个用户在您的 1000 个组中的 8 个中,您是尝试提取用户信息 8 次还是只提取一次?
  • 另外,脚本 1 为每个组一遍又一遍地覆盖同一个文件,因此您将获得输出的唯一结果是列表中的最后一个组。

标签: powershell ssis active-directory ldap active-directory-group


【解决方案1】:

所以我不知道这是多少答案,但它不仅仅是评论可以容纳的。所以我要做的是创建一个空的哈希表,查询一个组的成员,并为哈希表中的每个用户创建一个条目。然后对于每个额外的组,我会获取成员,然后我会检查哈希表以查看我是否已经拥有用户信息,如果没有,我会查询该用户并将其添加到哈希表中。嗯,甚至可能有两个哈希表,一个用于组,每个组将以组名称为键,以用户列表为值,然后您可以交叉引用用户的哈希表,您可以输出所有那种信息。

$GroupList = Get-Contant c:\temp\Groups.txt
$GroupHash = @{}
$UserHash = @{}
ForEach($Group in $Groups){
    $GroupHash.$Group = Get-ADGroupMember $Group

    ForEach($User in ($GroupHash.$Group|Where{!$UserHash.($_.distinguishedName)})){
        $UserHash.($User.distinguishedName) = Get-ADUser $User.distinguishedName -Server $($User.distinguishedName -replace "^.*?DC=" -replace ",DC=", ".") -Prop Mail
    }
}

之后,您将拥有 $GroupHash,其中包含每个组的每个组成员的列表,您将拥有 $UserHash,其中包含可能在任何组中的任何用户的用户详细信息。那么如何输出该信息取决于您...

ForEach($Group in $GroupHash.Keys){
    $GroupHash.$Group.distinguishedName | ForEach{%UserHash.$_} | Select mail,employeeID,title,department,name | Export-CSV C:\Temp\$Group.csv -NoType
}

这将为 C:\Temp 文件夹中的每个组创建一个 CSV 文件,其中将包含该组中每个人的用户详细信息。

现在请注意,这些都不是递归的,所以如果有嵌套组的成员,你不会得到嵌套组的成员,但你的原始脚本不是递归的,所以我没有深入探讨。

【讨论】:

    【解决方案2】:

    针对一个拥有 4300 多名成员的群组进行此操作

    花了几分钟

    $groupname = <whatever your group name is>
    $servername = <whatever domain your group is with>
    
    $dns = get-adgroup $groupname -server $servername -Properties member | select -ExpandProperty member
        $adobjects = @()
        $objqry = {
            param([string[]]$items)
            function GetAdsiObj {
                param($dn)
                $item = [adsi]$("LDAP://$_")
                $item.setinfo()
                return $item
            }
            return $items | select @{n='adsiobj';e={ GetAdsiObj $_}} | `
                select @{n='samaccountname';e={$_.adsiobj.properties.samaccountname[0]}}, `
                       @{n='name';e={$_.adsiobj.properties.name[0]}}, `
                       @{n='objectclass';e={$_.adsiobj.properties.objectclass[$_.properties.adsiobj.objectclass.count - 1]}}, `
                       @{n='dn';e={$_.adsiobj.path}}, `
                       @{n='useraccountcontrol';e={$_.adsiobj.useraccountcontrol[0]}}
        }
        $jobs = @()
    
        for($i= 0; $i -lt $dns.Count;$i += 250){
            $data = $dns[$i..$($i + 249)] 
            $jobs += Start-Job -ScriptBlock $objqry -ArgumentList (,$data)
        }
    
        $runningcount = {
            param($j)
            return $($j | ?{ $_.State -eq "Running" }).Count
        }
        $jobcount = $jobs.Count
        while($(&$runningcount $jobs) -gt 0){
            write-progress -activity "Processing members" -status "Progress:" `
            -percentcomplete (($jobcount- $(&$runningcount $jobs))/$jobcount*100)
        }
        $responses = $jobs | Wait-Job | Receive-Job
        $responses | %{ $adobjects += @($_) }
        $adobjects
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-03
      • 2018-11-06
      • 2019-04-10
      • 1970-01-01
      • 2018-02-12
      • 1970-01-01
      相关资源
      最近更新 更多