Skip Ribbon Commands
Skip to main content

Ondrej Sevecek's Blog

:

Engineering and troubleshooting by Directory Master!
Ondrej Sevecek's Blog > Posts > ADLAB: Vyhledání všech členů nějaké AD skupiny
srpen 23
ADLAB: Vyhledání všech členů nějaké AD skupiny

Zrovna jsem v rámci jednoho projektíku dokončil PowerShell funkci na vyhledání všech členů nějaké doménové skupiny. Už se na to chystám dlouho, tak se mi teď hodilo, že mě to donutilo to dokončit. Možná se to může zdát jednoduché, projet rekurzivně member atribut, ale ve skutečnosti není.

Musíte počítat s tím, že členem skupiny může být jiná skupina (group) z jiné domény, může to být počítač (computer) nejen uživatel (user), může to být taky servisní účet (msDS-ManagedServiceAccount, nebo msDS-GroupManagedServiceAccount). Skupiny mohou být navíc distribuční (distribution), nebo i aplikační, což nechcete dále procházet více do hloubky (i když i tyto skupiny mají SID) ani přidávat do výsledku. Existují i speciální typy objektů, jako je trust (ve skutečnosti je to normální účet typu user), nebo inetOrgPerson, což je to stejné jako uživatel.

Nesmíte zapomenout, že můžete mít více domén ve forestu a stejně tak můžete mít i trusty (externí a forestové) a tím pádem musíte řešit foreign security principal (foreignSecurityPrincipal), u kterého nejsou skoro žádné informace kromě SIDu, takže nevíte, jestli je to další skupina, nebo jen uživatel z jiného forestu.

Je to balík kódu, takže je potřeba stáhnout část mojí ADLAB knihovničky (pouhých 5100 řádečků :-)). Ne že by to bylo všechno potřeba, ale mám to prostě jako jednu z funkcí ve své větší knihovně. Nemusíte se bát, soubor lib-common.ps1 neobsahuje žádné zapisující, nebo měnící, ani destrukční funkce. Schválně. Ty mám v jiném souboru, který ke čtení informací z AD vůbec nepotřebujete.

Takže stáhnout lib-common.ps1, nebo lib-common.ps1.txt pokud vám nejde stáhnout rovnou PS1. Potom už stačí jen to vyzkoušet například takto:

.\lib-common.ps1 noConfig
Get-GroupMembershipt 'cn=Zamestnanci,OU=Skupiny,DC=gopas,DC=virtual'

nebo

.\lib-common.ps1 noConfig
Get-GroupMembershipt 'cn=Zamestnanci,OU=Skupiny,DC=gopas,DC=virtual' | ft *

Musíte tam jenom nahradit distinguishedName té skupiny. A nezapomeňte nahrávat tu knihovnu s parametrem noConfig, ať to nevytváří zbytečně log soubor (byl by v tempu). Jo a musíte to pustit pod účtem, který může všude číst, jinak to neprohledá komplet do hloubky.

Pokud to někdo vyzkoušíte, budu jen rád za každou odezvu :-) ano, je to pomalé, ale je to přece skript. Pokud by byly nějaké problémy, poznáte to ve výpisu v barvě červené nebo modré. Ostatní výpis je jen ladící.

Comments

LDAP_MATCHING_RULE_IN_CHAIN

Z hlediska výkonu by se možná dala použít  funkce v LDAPu -"LDAP_MATCHING_RULE_IN_CHAIN". A až na výsledné kolekci  provádět další selekci. A taky nevím, jestli to funguje v prostředí s více doménami.

function Get-GroupMembers ([string] $groupDN)
{
[String] $filter = "(&(objectCategory=person)(objectClass=user)(memberof:1.2.840.113556.1.4.1941:=" + $groupDN + "))"
[DirectoryServices.DirectorySearcher] $searcher = New-Object DirectoryServices.DirectorySearcher($filter)
[System.DirectoryServices.SearchResultCollection] $results = $searcher.findAll()
return ,$results
}
[System.DirectoryServices.DirectoryEntry] $de = New-Object System.DirectoryServices.DirectoryEntry
$r = Get-GroupMembers ("CN=Administrators,CN=Builtin," + $de.distinguishedName.value)
$r
Martin Jirků on 23.8.2013 14:58

Re: Vyhledání všech členů nějaké AD skupiny

jasně, to jsem taky zvažoval. ale ono to vyžaduje až 2003 SP1, nevím jak to právě funguje ve více doménách v jednom forestu, například pokud zrovna aktuální řadič domény není GC a už vůbec nejspíš ne mezi foresty.

další problém je, že to stejně nepomůže v případě, že členství uživatele je uděláno pomocí primaryGroupID, to se stejně musí vyhledat separátně.

takže použití tohohle by mi ušetřilo vlastní rekurzi v případě member atributu, ale už nic dalšího, nejspíš.
ondass on 23.8.2013 15:03

Re: Vyhledání všech členů nějaké AD skupiny

jo, jen pro informace, nemusíte zbytečně vypisovat [System.DirectoryServices.DirectoryEntry], stačí "type accelerator" [ADSI], který je taky k dispozici pro [DirectoryServices.DirectorySearcher] jako [ADSISearcher]
ondass on 23.8.2013 15:42

Re: Vyhledání všech členů nějaké AD skupiny

paráda, děkuji, tohle jsem přesně potřeboval!
martin lukáš on 23.8.2013 15:56

Add Comment

Sorry comments are disable due to the constant load of spam *


Omlouvám se, ale příval spamu nelze kontrolovat, takže mi prosím pošlete email, pokud máte nějaký dotaz, nebo připomínku.

Title


Pole Title nemusíte vyplňovat, doplní se to samo na stejnou hodnotu jako je nadpis článku.

Author *


Pole Author nesmí být stejné jako pole Title! Mám to tu jako ochranu proti spamu. Roboti to nevyplní dobře :-)

Body *


Email


Emailová adresa, pokud na ni chcete ode mě dostat odpověď. Nikdo jiný než já vaši emailovou adresu neuvidí.

Attachments