使用 Powershell 从多个域的活动目录组中提取所有用户?
Extract all users from active directory groups from multiple domains using Powershell?
我在 Active Directory 或 Powershell 方面没有太多专业知识,我需要提取所有用户以及属于 1000 多个安全组的详细信息。
我尝试了几种不同的 PS 在线可用脚本,但由于数据量很大,脚本需要很长时间才能完成(我在保持脚本 运行 后停止了脚本3 天)
我还尝试使用 SSIS 一次分解组列表和 运行 100 个组,但无济于事。
我正在使用以下第一个脚本来提取群组成员,使用第二个脚本来提取其余的用户详细信息
P.S。组和用户是来自多个子域的组合。
脚本 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
}
}
所以我不知道这是多少答案,但它超出了评论所能容纳的范围。所以我要做的是创建一个空哈希表,查询一个组的成员,并为哈希表中的每个用户创建一个条目。然后对于每个额外的组,我都会得到成员,我会检查哈希表以查看我是否已经拥有用户信息,如果没有,我会查询该用户并将其添加到哈希表中。嗯,甚至可以有两个哈希表,一个用于组,每个组将组名作为键,用户列表作为值,然后你可以交叉引用用户的哈希表,你可以输出所有这样的信息类型。
$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 文件,其中将包含组中每个人的用户详细信息。
请注意,none 这是递归的,因此您不会获得嵌套组的成员(如果有的话),但您的原始脚本不是递归的,所以我没有深入探讨.
运行 这是针对一个拥有 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
我在 Active Directory 或 Powershell 方面没有太多专业知识,我需要提取所有用户以及属于 1000 多个安全组的详细信息。
我尝试了几种不同的 PS 在线可用脚本,但由于数据量很大,脚本需要很长时间才能完成(我在保持脚本 运行 后停止了脚本3 天)
我还尝试使用 SSIS 一次分解组列表和 运行 100 个组,但无济于事。
我正在使用以下第一个脚本来提取群组成员,使用第二个脚本来提取其余的用户详细信息
P.S。组和用户是来自多个子域的组合。
脚本 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
}
}
所以我不知道这是多少答案,但它超出了评论所能容纳的范围。所以我要做的是创建一个空哈希表,查询一个组的成员,并为哈希表中的每个用户创建一个条目。然后对于每个额外的组,我都会得到成员,我会检查哈希表以查看我是否已经拥有用户信息,如果没有,我会查询该用户并将其添加到哈希表中。嗯,甚至可以有两个哈希表,一个用于组,每个组将组名作为键,用户列表作为值,然后你可以交叉引用用户的哈希表,你可以输出所有这样的信息类型。
$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 文件,其中将包含组中每个人的用户详细信息。
请注意,none 这是递归的,因此您不会获得嵌套组的成员(如果有的话),但您的原始脚本不是递归的,所以我没有深入探讨.
运行 这是针对一个拥有 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