Извлечь всех пользователей из групп активного каталога из нескольких доменов с помощью Powershell?

У меня нет большого опыта в Active Directory или Powershell, мне нужно вытащить всех пользователей и там детали, принадлежащие более чем 1000 группам безопасности.

Я пробовал несколько разных сценариев PS, доступных в Интернете, но из-за большого количества данных сценарий занимает очень много времени (я остановил сценарий после того, как он продолжал работать в течение 3 дней)

Я также попытался разбить список групп и запустить 100 групп одновременно с использованием SSIS, но безрезультатно.

Я использую следующий 1-й скрипт для извлечения членов групп и 2-й скрипт для извлечения остальной информации о пользователе.

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
    }
}

person Inder Rana    schedule 28.10.2015    source источник
comment
Где вы запускаете свой код? Если вы запускаете его с удаленного компьютера, попробуйте запустить его на своем DC.   -  person kekimian    schedule 28.10.2015
comment
@Cavalli - у меня нет доступа к серверу DC, я запускаю его на рабочей станции под управлением Windows Enterprise (не Windows Server).   -  person Inder Rana    schedule 28.10.2015
comment
У меня была точно такая же проблема, я решил ее, запустив свой скрипт локально на моем DC. Вы контролировали производительность своей рабочей станции при запуске сценария (использование процессора, память ...)?   -  person kekimian    schedule 28.10.2015
comment
Если вы знакомы с рабочими процессами PowerShell, это может быть хорошим кандидатом для этого. Если нет, вы можете попробовать запустить это как задание для извлечения членов группы, чтобы вы могли запрашивать сразу несколько групп. Кроме того, вы обязательно удалите повторяющиеся пользовательские ссылки? Допустим, пользователь входит в 8 из ваших 1000 групп. Вы пытаетесь получить информацию о пользователе 8 раз или только один раз?   -  person TheMadTechnician    schedule 28.10.2015
comment
Кроме того, сценарий 1 перезаписывает один и тот же файл снова и снова для каждой группы, поэтому вы получите результат только для последней группы в списке.   -  person TheMadTechnician    schedule 28.10.2015


Ответы (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
person Chris Hayes    schedule 26.05.2016

Так что я не знаю, насколько это ответ, но это больше, чем может вместить комментарий. Поэтому я бы сделал пустую хеш-таблицу, запросил членов группы и создал запись для каждого пользователя в хеш-таблице. Затем для каждой дополнительной группы я получал участников и проверял хэш-таблицу, чтобы узнать, есть ли у меня информация о пользователе, а если нет, я бы запросил этого пользователя и добавил его в хеш-таблицу. Хм, может быть, даже есть две хэш-таблицы, одна для групп, и каждая группа будет иметь имя группы в качестве ключа и список пользователей в качестве значения, а затем вы можете перекрестно ссылаться на хеш-таблицу пользователей, и вы можете вывести все виды информации таким образом.

$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
}

Это сделает файл CSV для каждой группы в папке C: \ Temp, и он будет содержать данные пользователя для всех в группе.

Имейте в виду, что все это не рекурсивно, поэтому вы не получаете членов вложенных групп, если они есть, но ваши исходные сценарии не были рекурсивными, поэтому я не вдавался в это.

person TheMadTechnician    schedule 28.10.2015