Category: active directory

Csak dinamikusan

Felteszem, sokan használunk dinamikusan frissített DNS zónákat. Valószínűleg legalább annyian dühöngünk is miatta, mert az istenért sem működik a döglött rekordok eltávolítása.

Ahhoz, hogy megértsük, miért nem, célszerű megismerkedni részletesebben is a folyamattal.

DHCP oldalon:
Itt tudjuk beállítani, hogy mindazon host, amely DHCP kliens, milyen időszakonként frissítse meg az IP cím bérleti idejét.

DNS oldalon:

  • Stale record: Döglött rekord. Eredeti gazdája már régen nem létezik vagy már más IP címet birtokol – de a bejegyzés még nem tűnt el.
  • Scavenging process: Magyarul dögevés. Ennek a folyamatnak során tűnnek el a döglött rekordok a zónafájlokból.
    A folyamat beállítási lehetőségei elég gyérek: gyakorlatilag nulla a beavatkozási lehetőségünk. Hét naponta fut le, nem tudjuk befolyásoni, hogy a nap melyik órájában induljon el.
  • Aging: Annak eldöntése, hogy egy rekord döglött-e vagy sem. Két fontos paramétert kell hozzá beállítani:
    – No-refresh interval
    – Refresh interval

Ez utóbbi folyamat külön megér egy misét. Nézzük csak, mi van a beállítópanelra írva:

No-refresh interval: The time between the most recent refresh of a record timestamp and the moment when the timestamp may be refreshed again.
Refresh interval: The time between the earliest moment when a record timestamp can be refreshed and the earliest moment when the record can be scavenged.

Bevallom őszintén, nagyon sokáig nem értettem, mit jelentenek ezek a mondatok. Nem is mertem hozzányúlni, hagytam mindkettőt a default 7 napos értéken. Nemrégiben viszont piszkálgatnom kellett, és így most már sokkal világosabb a helyzet:

  • No-refresh interval: Az az időszak, amikor a DNS szerver nem foglalkozik a rekorddal. Tekintve, hogy a takarítás erőforrásigényes folyamat, nem mindegy, mennyi rekordot kell folyamatosan csekkelni.
  • Refresh interval: Az az időszak, amelyen belül a DHCP szervernek meg kell újítani a bejegyzést. Amennyiben ezt nem teszi meg, akkor lesz a rekord stale.

Nézzünk végig egy folyamatot:

  1. Beóvakodik a hálózatba egy kliens, a DHCP IP címet ad neki.
  2. A DHCP beregisztrálja a kliens nevét, IP címét a megfelelő AD integrált zónába.
  3. Amíg le nem telik a No-refresh érték, addig a DNS szerver nem bántja a rekordot. Célszerű ezt ugyanannyira választani, mint amennyi a DHCP-ben a bérlet lejáratának ideje.
  4. Letelt a No-refresh idő, mostantól már figyel rá a DNS szerver.
  5. Amennyiben a Refresh időtartam alatt nem történik meg a rekord frissítése a DHCP által, akkor a rekord stale lesz.
  6. Hét naponta megjelenik a Scavenging és elviszi a stale rekordokat.

Így már nem is bonyolult.
Most nézzük, meg, miért nem működik?

Leginkább azért, mert ez a dögevő meglehetősen szégyenlős. Tudja, hogy a munka, melyet végez erőforrásigényes, így amikor kidugja az orrát a barlangból és azt látja, hogy a DNS szerver éppen nagyon dolgozik, vissza is bújik. Majd legközelebb.
Ebben ugye az a különösen szép, hogy nem tudjuk beállítani, mikor dugja ki az orrát. Hiába tudjuk, hogy éjfélkor már alszik a széken a kabát, szunnyadozik a szakadás – nem adhatjuk meg neki ezt aktiválódási időpontnak.

Kétféleképpen kerülhetjük meg:

  • Elindítjuk manuálisan, grafikus felületről. Jobbklatty a szerver nevén, ‘Scavenge Stale Resource Records’.
  • Elindítjuk manuálisan, parancssorból. A Support Tools része a dnscmd segédprogram, ehhez kell hozzácsapni a /startscavenging paramétert.

Az utóbbi különösen azért figyelemre méltó, mert parancssor lévén ütemezhető is – azaz megkerültük a Scavenge bizonytalan indulásának problematikáját. Innentől kezdve gyakorlatilag nincs is rá szükségünk, bátran kapcsoljuk ki. (Az ‘Aging’ panelen vegyük ki az ikszet a ‘Scavenge Stale Resource Record’ checkbox-ból.) Figyelem, minden DNS szerveren ki kell kapcsolni, melyen az illető zóna megtalálható.

Ez utóbbi gondolatot érdemes egy kicsit továbbvinni. Ez az egész dinamikus regisztrációs folyamat csak AD integrált DNS zónákon működik – ezek ‘zónafájljai’ viszont a tartomány mindegyik tartományvezérlőjén megtalálhatók. (Ez mondjuk nem teljesen igaz, itt nézhetsz utána részletesebben.) Na most, teljesen felesleges mindegyik DC-n beindítani ezt az erőforrásigényes takarítási folyamatot, amikor a jelölgetések, törlések úgyis replikálódnak: vagy beállítod egy DC-n, a többin pedig letiltod, vagy leállítod mindegyiken és enyhébb forgalmú időszakra beállítva beidőzíted a fenti parancsot valamelyik DC-n.

Végül egy jópofa trükk: hogyan takarítsuk ki gyorsan a zónánkat?
Például úgy, hogy a DHCP lejárati idejéhez képest vegyük jóval alacsonyabbra a No-refresh/Refresh értékeket. Ezt annál is könnyebb megtenni, mert a paraméterek igen messze találhatók egymástól a grafikus felületen.
Menjünk végig a korábban részletezett folyamaton. A DHCP 2 naponta frissít, a frissítési értékek legyenek mondjuk 2 óra.

  1. Beóvakodik a hálózatba egy kliens, a DHCP IP címet ad neki.
  2. A DHCP beregisztrálja a kliens nevét, IP címét a megfelelő AD integrált zónába.
  3. A No-refresh érték viszonylag hamar letelik, két óra múlva a DNS már figyeli a rekordot.
  4. Eltelik újabb két óra, a DHCP természetesen nem regisztrál újra, mivel ő csak kétnaponta újítja meg a bérletet. A rekord stale állapotú lesz.
  5. Hét naponta megjelenik a Scavenging és elviszi a stale rekordokat – azaz a jelen esetben a zóna nagy részét. (Nyilván maradnak kivételek, akik még éppen nem váltak döglötté. Ne felejtsük el, a döglött rekord is újra aktivizálódhat, ha a DHCP ugyanazt az IP címet adja vissza a kliensnek két nap múlva.)
[Update]
Kollégám hívta fel a figyelmemet, hogy Windows2003 tartományban már lehet szabályozni a Scavenge periodicitását is. A DNS konzolon belül kijelöljük a szervert, properties, advanced, ablak alja, csodálkoz.

Szabályozott megfertőzés

Korábban már pedzegettem, most ki is fejtem, mire gondoltam.

Gondolom, vagyunk többen is, akik már módosították valamilyen Active Directory sémáját. Nem egy nagy ügy, a megfelelő jogosultsággal be kell lépni a megfelelő gépen és a parancssorból le kell futtatni egy programot, melynek valamilyen *prep-re végződik a neve. (Na jó, van amikor egy kapcsoló végződik prep-re.) Tudom, mindenki tudja, de legyen kerek az írás: a megfelelő jogosultság enterprise admin/lokális admin/schema admin jogosultságból áll, a megfelelő gép pedig az erdő Schema Master FSMO szerepkörével bíró tartományvezérlője. A többi DC-n a séma csak olvasható.

Szóval ennyi. Természetesen van egyszerűbb címtár és van bonyolultabb. Habár elég kicsi az esélye, hogy egy Microsoft termék okozta címtárbővítés gondot okozna, de még ebben az esetben is jobb óvatosnak lenni, különösen az összetettebb címtárak esetén. Saját sémabővítésnél meg aztán végképp.
Tehát a szokott rutinnal csinálunk egy System State mentést a DC-ről, ellenőrizzük, hogy megvan-e valahol az Active Directory Restore módhoz szükséges jelszó – és mehet is a preparálás.
Többféle végeredmény is elképzelhető. A legtöbbször nincs semmi probléma, a módosítás lefut, elterjed. De ha baj van, akkor nagy a baj: ugyanis ekkor derül ki, hogy a System State mentésből a sémát autoritatív módon nem tudjuk visszaállítani. Adtunk egy pofont a fekáliának.

Valami más stratégiát kell kiötölnünk, ha biztonságosan szeretnénk sémát módosítani.
Mielőtt persze stratégián gondolkodnánk, analizálni is illene a helyzetet. Hol merülhetnek fel problémák?
Alapvetően két helyen.

  • Rosszul módosul a séma a Schema Master gépen.
  • A replikáció során sérül meg valamelyik DC lokálisan tárolt példánya.

Akármelyik eset ellen is szeretnénk védekezni, mindenképpen látszik, hogy csak a replikációba történő beavatkozással érhetünk célt. Az első esetben például úgy, hogy lehetőség szerint elszigeteljük a Schema Master-t – és csak akkor oldjuk fel a blokádot, ha a módosítás rendben megtörtént. A második esetben pedig úgy járunk el, hogy a sémát apró lépésekben eresszük rá a címtárra.
Hol lehet belenyúlni a replikációba? Például a site határokon: a site-site konnektoron beállítjuk, hogy a Schema Master gépet tartalmazó site elszigetelődjön. Mielőtt ez megtörténne, még beteszünk egy harmadik DC-t a site-ba (remélem, kettő azért van site-onként), beléptetjük, megvárjuk, míg erdő szinten lemegy a replikáció – majd lekapcsoljuk a gépet. Jön az elszigetelés, séma update. Ha jó, akkor jó. Ha rossz, akkor lekapcsoljuk mindkét DC-t, a tartalék gépet visszakapcsoljuk, majd seize az összes FSMO-ra, amely a korábbi két DC-n volt. Ezeket pedig visszaállítjuk valahogy: vagy újratelepítjük és úgy tesszük vissza a System State mentésből a lényeget, vagy mentésből rakjuk vissza az egész gépet – ez eszköz és rákészülés függvénye. Arra kell csak nagyon vigyáznunk, hogy amíg rossz állapotban van a két DC, nehogy összetalálkozzanak az ideiglenesen berakottal. Nem egészséges, ha több gép is azt hiszi magáról, hogy ő a FSMO.
A séma terjedését ugyanezzel a trükkel lehetett terelgetni. Mindig csak egy elszigetelt site-ra engedjük rá, aztán ha rendben lement, akkor mehetünk tovább.
Figyelem: a fentebb írott szöveg nem konkrét recept, inkább csak elv. A valóságban ritka az olyan tiszta helyzet, mint amelyet példának választottam: lehet több DC is a site-on, tartományok is átnyúlhatnak más site-ra, az sem mindegy, milyen FSMO szerepek vannak a konkrét site-on. Minden konkrét esetben az adott címtárra vonatkozó stratégiát kell kidolgozni.

No, tehát nagyjából ez volt régebben a helyzet. A régebben kifejezés alatt azt értem, hogy azelőtt, mielőtt megismertem volna a repadmin segédprogram +DISABLE_OUTBOUND_REPL kapcsolóját. Ez ugyanis azt tudja, hogy a konkrét gépen, melyen begépelem, leállítja a kifelé menő replikációt. (A – jellel meg újraengedélyezi.)
Gondoljuk végig. Eddig site szinten izoláltunk – mostantól tudunk DC szinten is. Első lépésben bőven elég elkülöníteni a Schema Master gépet. Ha nem sikerül a művelet, akkor lekapcsoljuk a gépet, valamelyik lábon álló DC magához ragadja a kidőlt masina FSMO szerepeit, majd visszaállítjuk az eredeti Schema Mastert és lehet újra próbálkozni. Telephelyenként is megtehetjük, hogy először a bridgehead szervereket frissítjük, majd utána a többit – azaz mindig lesz élő DC, aki képviseli a tartományt.
Remek.

Nem. Kávét főzni sajnos nem tud.
Meg egyébként is, az a netsh dolga.

Hol a rekord?

Szerverüzemeltető kollégám furcsa jelenséggel fordult hozzám: képtelen kitörölni egy reverz DNS bejegyzést. Kitörli, de az visszamászik. Nézzek már rá.

Első blikkre nem villanyozott fel túlzottan az eset. Lehet mögötte replikációs probléma, lehet valami DHCP félrekonfigurálás – még az se kizárt, hogy a kliensen bolondult meg valami.

Leteszteltem. Kitöröltem a kérdéses rekordot, majd egyből nyomtam egy F5-öt. A rekord visszajött. Egyből. Ejha. Az összes prekoncepció ment a kukába: ilyen gyorsan egyik sem hozza vissza a törölt rekordot. Átmentem egy másik tartományvezérlőre, azon is nyomtam egy törlést, F5 – a rekord megint ott volt. (Ha esetleg az eddigiekből nem lenne egyértelmű, a zóna AD integrált volt.)

Rögtön felcsillant a szemem – ez nem egy szokványos feladat.
Okoskodjunk.
Mivel a zóna AD integrált, így tulajdonképpen arról van szó, hogy valamiért sikertelen lesz egy törlési művelet a címtárból. Legalábbis ha GUI-n keresztül próbálom végrehajtatni. De pontosan mit is akarok törölni?

Itt jött egy hosszú sóhaj. A magam részéről még erősen emlékszem arra az időkre, amikor a zónafájlok könnyen átlátható szöveges fájlok voltak, olvasásuk, szerkesztésük teljesen egyszerű volt. Most viszont törhettem a fejem, hol is vannak egyáltalán az adatok.

Tényleg, hol? Tudjuk, hogy elméletileg a zóna és a tartomány még csak köszönő viszonyban sincsennek egymással. Úgy értem, egy DNS szerverre tetszőleges számú AD integrált zónát is felvehetek, miközben a konkrét tartományhoz tartozó zóna csak egy a sok közül és nem is feltétlenül kell jelen lennie minden DNS szerveren. Ergo a zóna adatai akár a konfigurációs, akár a tartományi névtérben is lehetnek. (A sémában azért csak nem.;)
Lehetne ugyan guglizni, de jelen esetben érdemesebb inkább becsavarogni a névtereket. ADSIEdit a jóbarátunk, nézzük meg először a konfigurációs névteret, úgyis az a kisebb. Itt bizony nincs. Marad a tartományi – és ott is van: system/microsoftdns/ folder alatt jámborul vigyorognak ránk a zónák.

Így néz ki egy AD integrált reverz DNS zóna

Kitérő:
Attól függően, hogy W2k vagy W2k3 címtárunk van, nagyon eltérő képet kapunk a fenti folderben. W2k címtár esetén mind a reverz, mind a forward zónák ott figyelnek a Domain névtér megfelelő folderében. Ezzel szemben W2k3 címtár esetén a forward dns zónák önálló névteret kaptak a Domain névtér alatt, méghozzá rögtön kettőt: DomainDNS, illetve ForestDNS névvel. A reverz zónák maradtak a régi helyen.
Most szerencsénk van, mert éppen a reverz zónát akarjuk piszkálni. De mi van akkor, ha valamelyik forward zónát szeretnénk direktben kibelezni? Az ADSIEdit csak a klasszikus névtereket adja fel kapcsolódásra és itt nem látszanak az alá rejtett névterek. Igaz, van egy olyan opciója, ahol tetszőleges DN-t is megadhatok kapcsolódásként. Már csak azt kellene megtudni, mi is a DomainDNS partíció DN neve… de ezt meg a konfigurációs névtérből tudjuk kinyerni, itt ugyanis van egy Partition bejegyzés, ahonnan kiolvashatók az egyes partícók adatai. (Az ldp érdekes módon nem vacakol ennyit, egyből mutatja a Domain névtér alatt a DNS névtereket is.)
Huh.

A képen már a sikeres kapcsolódást láthatjuk.

Innentől már miénk a terep. Szépen megkeressük a minket érintő objektumot és… hoppá. Melyik a módosítandó tulajdonság? Ilyenkor segít az ldp. Ugye tudjuk (tudjuk, mert már írtam róla), az ldp mutatja meg egy objektum összes értékkel bíró tulajdonságát. Innentől már nem nagy ügy kispekulálni, hogy minket bizony a dnsrecord tulajdonság érdekel.

A kisebbik baj, hogy a tulajdonság értéke hexadecimális kódolású karakterlánc. A közepes baj az, hogy nem csak a ptr rekordhoz tartozó karakterlánc van ebben a tulajdonságban, hanem egyéb adatok is. A legnagyobb baj viszont az, hogy ha visszamegyünk az ADSIEdit-hez és lekérjük ezt a tulajdonságot, akkor csak az első néhány bájtot látjuk. A legeslegnagyobb baj pedig az, hogy nincs a felületen modify gomb – így csak törölni vagy hozzáadni tudunk, de természetesen egy ilyen bonyolult formátumú tulajdonságnál semmi esélyünk sincs, hogy majd begépeljük a frankót. Az ldp-vel nagyjából ugyanez a helyzet, bár ott is tudnánk módosítani a tulajdonság értékét, de nincs olyan lehetőség, hogy a jelenlegi érték jelenjen meg egy textboxban, én meg majd editálom és utána visszaírom.

Kitérő:
A konkrét esetben tényleg így jártam, tekintve, hogy az még W2k címtár volt. Kíváncsiságból megnéztem a tesztelésre használt W2k3 címtárban és voilá, ott már volt modify gomb az ADSIEditben. Persze itt sem egyértelmű elsőre, hogy mit kell módosítani, de az ldp segítségével megfejthető, lásd alábbi ábrák.

Ilyenkor gördül végig egy könnycsepp a rendszergazda arcán és elérzékenyülve gondol vissza a Quick Editorral karbantartott zónákra.

Az mindenesetre már látszott a konkrét feladatnál, hogy finom műtétre nincs lehetőségem. (Az eredeti feladat tkp. az lett volna, hogy módosítsuk a ptr rekord értékét.) Ha szikével nem megy, vegyük elő a baltát: töröljük a francba az egész objektumot. Végülis, bármennyire bonyolultan néz is ki, csak egy ptr rekordról van szó.
És ez már meghatotta. Amint a törlés ténye szétreplikálódott, az a bizonyos ptr rekord végképp megszűnt létezni – kicsiny lelke jelenleg a semmi szélén üldögél és József Attilát olvasgat.

Gondoljuk végig, mi is történt. Törölni akartunk egy ptr rekordot. A kezelői felületről nem ment. Bele akartunk nyúlni az adatbázisba – és itt kezdett el izgalmas lenni a játék: rendszerezni kellett a tudásunkat, hogy ebben a nem is túl egyszerű környezetben kisilabizáljuk, hol is lehet a minket érintő adat. És amikor meglett, kiderült, hogy gyakorlatilag nem editálható, tehát csak és kizárólag a del billentyűvel avatkozhatunk be hatásosan. (Ez a billentyű egyébként a legtöbbször tényleg nagyon hatásos.)
De végül sikerült. És lassan már a címtár felépítését is kezdjük érteni.

AD gyötrések II.

Nem bírunk nyugton ülni a fenekünkön, még mindig felhasználói adatokat akarunk módosítani az Active Directoryban. Csakhogy mostanra begörcsölt a jobb csuklónk, így szomorúan lökjük félre az egeret. Innentől csak a billentyűzetre fogunk támaszkodni.
Lássuk a parancssoros AD editáló segédprogramokat.

5. DS parancsok
A Windows szerverek esetén maga az operációs rendszer is tartalmaz egy csomó címtárpiszkálgatásra alkalmas segédprogramot. Ilyenek például a Windows2003 szerverben megtalálható DS* kezdetű parancsok.

  • DSAdd
    Segítségével különböző típusú objektumokat (computer, contact, group, ou, user, quota) adhatunk a címtárhoz.
    Részletes ismertetése megtalálható itt.

    Példa:
    Új felhasználó hozzáadása a címtárhoz:
    dsadd user „cn=Vaszilij Kubaszov, cn=users, dc=test, dc=net”

  • DSGet
    Segítségével különböző típusú objektumok (computer, contact, group, ou, user, quota, server, subnet, site, partition) egyes tulajdonságait tudjuk lekérdezni.
    Részletes ismertetése megtalálható itt.
    Elég sűrűn szokták a DSQuery parancs kiegészítéseként használni. (Lásd később.)

    Példa:
    Egy felhasználó csoporttagságainak kilistázása, beleértve az egymásbaágyazott csoportokat is:
    dsget user „CN=Magyari Béla,CN=Users,DC=test,DC=net” -memberof -expand

  • DSMod
    Segítségével különböző típusú objektumok (computer, contact, group, ou, server, user, quota, partition) egyes tulajdonságait tudjuk módosítani.
    Részletes ismertetése megtalálható itt.

    Példa:
    Felhasználó jelszavának megváltoztatása, belépéskor jelszóváltás kikényszerítése.
    dsmod user „CN=Farkas Bertalan,CN=Users,DC=test,DC=net” -pwd ujjelszo -mustchpwd yes

  • DSMove
    Egy objektum átmozgatására, illetve átnevezésére szolgál.
    Részletes ismertetése megtalálható itt.

    Példa:
    Felhasználó átrakása egy másik OU-ba.
    dsmove „CN=Valerij Kubaszov,CN=Users,DC=test,DC=net” -newparent OU=CCCP,CN=Users,DC=test,DC=net

  • DSQuery
    A megadott feltételek segítségével lekérdezi a címtárat. Lehet szűkíteni egyes objektumokra (computer, contact, group, ou, site, server, user, quota, partition), de lehet szűkítés nélkül (dsquery *) is használni.
    Részletes ismertetése megtalálható itt.

    Példa:
    Lekérjük az összes olyan felhasználót, akinek az előneve a ‘Farkas’ szóval kezdődik, plusz lekérdezzük hozzá a felhasználó néhány adatát (dn, description) is.
    dsquery user -name Farkas* | dsget user -dn -desc

  • DSRm
    Objektum törlése a címtárból.
    Részletes ismertetése megtalálható itt.

    Példa:
    Egy OU és összes elemének törlése.
    dsrm -subtree -noprompt -c OU=CCCP,CN=Users,DC=test,DC=net

Link szekció:

6. ADFind, ADMod

Joe Richards mindig reszelget valamit a műhelyében. Joe – aki egyébként Directory MVP – nem csak a neve miatt szimpatikus, hanem azért is, mert a segédprogramjait ingyen bocsátja a nagyérdemű részére. Mindegyik program kizárólag csak parancssori verzióban létezik. Joe szemmel láthatóan nem kedveli a GUI-kat.

A sok közül kettőt emelnék most ki. Ennek a kettőnek története van. Korábban Joe elég sokat macerálta az Active Directoryt, hol ldapsearch-csel, hol egy bizonyos search.vbs szkripttel, illetve ha ezekkel megakadt, akkor nekiállt saját visual basic szkripteket írni. Tudjuk, hogy vbsciptben nem lehet minden AD műveletet végrehajtani, vannak olyan értékek, főleg a binárisok, melyek elég nehezen adják meg magukat. Aztán amikor már teljesen elege lett ebből a kínlódásból, Joe megírta az ADFind segédprogramot. C++-ban.
Nem sokkal később a Microsoft is kijött a DS* családdal, de Joe állítja, hogy az ő programjai sokkal flexibilisek, léteznek hozzá add-on-ok (pl. egy perl szkript, mely a végeredményt csv formátumba konvertálja) – és nem utolsó sorban, működnek Windows 2000 szervereken is.

  • ADFind
    Ez egy query segédprogram, az AD-n belül hajt végre megadott lekérdezéseket. Ahogy Joe fogalmazott: ez egyfajta speciális keveréke az ldapsearch, search.vbs, ldp, dsquery, dsget programoknak, egyéb dögös opciókkal feltupírozva.
    A program részletes leírása itt található, maga a program is innen tölthető le.

    Példák:
    Egy felhasználó objektum összes értékkel bíró tulajdonságának és azok értékeinek kilistázása, úgy, hogy az idő jellegű adatok emberi módon jelennek meg:
    adfind -b dc=test,dc=net -f name=”Farkas Bertalan” -tdc

    Kitiltott felhasználók kilistázása az egész AD erdőből:
    adfind -gc -b -bit -f „&(objectcategory=person)(samaccountname=*)(useraccountcontrol:AND:=2)” -dn

    Séma dump:
    adfind -sc sdump

  • ADMod
    Ez a program már egyértelműen a DS* programok megjelenése után íródott. Joe-nak ugyanis azokból is elege lett: a dsmod, dsmove, dsrm programok nem igazán akartak úgy működni, ahogy ő szerette volna, pontosabban nem igazán akartak úgy működni, ahogy az expert adminok szerették volna – ezért írt egy olyan segédprogramot, mely az ő ízlése szerint viselkedik. Elméletileg ugyanazokat a dolgokat tudja, mint a fenti hármas, csak máshogy – kiegészítve azzal, hogy van benne undelete funkció, igaz ez csak Windows 2003 szerveren működik. (Az összes többi funkció elérhető Windows 2000 szervereken is.)
    A program részletes leírása itt található, maga a program is innen tölthető le.

    Példák:
    Egy felhasználói tulajdonság értékének módosítása:
    admod -b „CN=Valerij Kubaszov,OU=CCCP,CN=User,DC=test,DC=net” „ipPhone::bal3″

    Felhasználó létrehozása:
    admod -b ou=CCCP,cn=users,dc=test,dc=net objectclass::user samaccountname::leonyidb -add

    Módosítja az összes beépített adminisztrátor leírás mezőjének az értékét. (Nagyon szép összecsövezése az adfind és admod programoknak.)
    adfind -gc -b -f „&(objectcategory=person)(objectclass=user)(name=administrator)” -dsq |admod „description::Rendszergarázda”

Link szekció:

7. Ldifde, csvde
A Windows szerverekben megtalálható másik kupac címtárkezelő parancs a *DE végű parancsokból áll. (DE: Directory Export) Ezek a programok azon filozófia mentén működnek, hogy képesek fájlba exportálni a címtár részeit, illetve képesek fájlból adatokat importálni a címtárba. (A DS* parancsoktól eltérően mindkettő létezik már Windows2000 szerveren is.)
A csvde inkább nagytömegű módosításokra alkalmas, az ldifde viszont a fifikásabb változtatások lezongorázására.

  • CSVDE Mint a nevéből is kikövetkeztethető, az átmeneti tárolóként használt fájl jelen esetben csv típusú – azaz akár szövegszerkesztőből, akár Excelből remekül szerkeszthető.
    Tipikus menet, hogy a címtár egy részét kiexportáljuk, akármilyen módszerrel módosítjuk a csv fájlt, majd a fájlt tartalmát visszaimportáljuk. Szintén tipikus, hogy ez elsőre nem szokott sikerülni. A full export során ugyanis a bináris értékek (SID, GUID és egyéb blobok) is kikerülnek a fájlokba, ezeket viszont nem lehet importálni. Persze a világ nem dől össze, exportálás során egyszerűen meg kell adni a -m -n kapcsolókat és ekkor binárisék békén maradnak.
    A parancs részletes leírása itt található.
  • LDIFDE
    Ennek a nevéből már közvetlenül nem következik a fájl típusa. Márcsak azért sem, mivel ez egy kevert fájlból dolgozik. Kevert, mert a fájlban – szabvány szerinti szintaxisban (LDIF) – egyaránt megtalálhatók az adatok és a parancsok is. Értelemszerűen használatához ismerni kell ezt a szintaxist – és emellett magát az LDAP protokollt is. Nem egyszerű, de megéri elmélyedni benne. Aki Active Directory hegesztésekkel foglalkozik, annak meg úgyis kötelező, mivel a szintaxis elemei vissza-visszaköszönnek a mindennapi munka területein. (Az LDIF egyáltalán nem mellesleg az AD replikáció nyelve.)
    Apró nehezítés, hogy magának a parancsnak is van néhány kapcsolója. A részletes leírást itt találhatjuk. Röviden az LDIF fájl felépítéséről:

    dn: ldap útvonal
    changetype: parancs
    adatok
    >üres sor<
    dn: ldap útvonal
    changetype: parancs
    adatok
    >üres sor<
    … stb …

    A changetype után a következő parancsok állhatnak: add, delete, modify [, modrdn, moddn]. (A kapcsos zárójelben szereplő parancsok – rdn/dn módosítása – részei az LDIF RFC-nek, de tudtommal a Windows LDIFDE nem ismeri ezeket. Kipróbálni még nem próbáltam.)
    Amennyiben az adatok több adatblokkot is tartalmaznak, a blokkokat a ‘-’ karakterrel választjuk el.

    Példák.
    A szöveges fájl beimportálása mindegyik esetben így fog kinézni: ldifde -i -f puffer.txt

    OU létrehozása
    puffer.txt tartalma:
    dn: ou=CCCP,cn=Users,DC=test,DC=net
    changetype: add
    objectclass: organizationalUnit
    ou: CCCP

    Adminisztrátor leírás mezőjének módosítása
    puffer.txt tartalma:
    dn: cn=Administrator,cn=Users,DC=test,DC=net
    changetype: modify
    replace: description
    description: Rendszergarázda

    Ámokfutás – módosítjuk egy felhasználó leírás mezőjét, értéket adunk az IP telefon tulajdonságának és töröljük a munkahelyi azonosítóját.
    puffer.txt tartalma:
    dn: cn=Valerij Kubaszov,ou=CCCP,cn=Users,DC=test,DC=net
    changetype: modify
    replace: description
    description: Beépített ember

    add: ipPhone
    ipPhone: bal3

    delete: employeeID

Link szekció:

8. Excel

Végére hagytam a kedvencemet. Én gyakorlatilag csak ezt használom a tömeges AD módosítások lezongorázására.
Nem, nem zakkantam meg. Legalábbis nem teljesen.
Tudjuk, hogy az Active Directory-t ADSI-n keresztül különböző módokon érhetjük el: .net/vbs/jscript… és egyebek. Az Excel makrók pedig akárhogy is nézzük, teljesen szabályos vbscript-ből állnak, kiegészítve Excel specifikus parancsokkal, változókkal.
Ideális.
Eleinte mondjuk kicsit macerás, de ahogy elkészülnek a tipikus részfeladatok építőkövei, onnan már csak sima falazás az egész. (Építőkockákat a netről is letölthetünk, sőt…)
Első pillantásra jogos lehet a kérdés, hogy miben különbözik ez a módszer a CSVDE használatától. Mindkettőben ki lehet exportálni bizonyos tulajdonságokat egy Excel kompatibilis táblázatba, lehet kézzel módosítani, majd vissza lehet tölteni azokat a címtárba.
A nagy különbség az on-fly vbscript használati lehetőség. Ha valaki látta már, hogyan néz CSVDE esetében a proxaddresses multivalue változó, akkor sejtheti, hogy miről beszélek. Ember legyen a talpán, aki ezt – akár Excelben is – könnyedén szerkesztgeti. Ellenben a makró futása során már a szépen szétválogatott címek kerülnek ki táblázat mezőibe. Ha nem is egyszerűen, de lehetőségünk van lekezelni a bináris mezőket.
Ugyanez a röptében feldolgozás teszi lehetővé, hogy bizonyos feltételektől függően formázhassam a kiírást (szöveg kövérítés, szöveg/háttérszín változtatás), kontrollértékek kiírásával nyomon követhessem a folyamatot. Nem elhanyagolható például, hogy egyszerre több worksheet-et tudok kezelni (mondjuk egyikben tárolva a folyamatban érintett OU-k nevét; így csak azok az OU-k kerülnek feldolgozásra, amelyekkel foglalkozni akarok) – és természetesen rendelkezésre állnak az Excel függvényei a különböző feldolgozásokhoz.

A nagy ujjongásban meg kell említenem a módszer legnagyobb hátrányát is: csak akkor működik, ha van a közelben Excel. Ez a szerverszobákban, a szervereken nem igazán szokott lenni. Akkor értelemszerűen marad a többi megoldás – de ha kényelmesen, usermódban is ráérünk megoldani egy feladatot, akkor a munkaállomásunkról már simán használhatjuk az Excel makrókat.

Végül két építőkocka:

Felhasználó információk legyűjtése:

Sub Macro1()
Attribute Macro1.VB_Description = „Macro recorded 2006.09.03 by JoeP”
Attribute Macro1.VB_ProcData.VB_Invoke_Func = „a\n14″

‘ Macro1 Macro
‘ Macro recorded 2006.09.03 by JoeP

‘ Keyboard Shortcut: Ctrl+a

‘ Adatok lekérdezése a címtárból

‘——————————————————————–
‘ Deklarációk

Dim oActUsers
Dim child, sor
‘——————————————–
‘ Inicializálás

On Error Resume Next

Worksheets(”Munka”).Activate
Cells.Select
Selection.Clear
Range(”A1″).Select

Cells(1, 1).Value = „Username”
Cells(1, 2).Value = „Employee ID”
Cells(1, 3).Value = „Display name”
Cells(1, 4).Value = „Description”
Cells(1, 5).Value = „Phone”
Cells(1, 6).Value = „Mobile”
Cells(1, 7).Value = „Office”
Cells(1, 8).Value = „Title”
Cells(1, 9).Value = „Department”
Cells(1, 10).Value = „Object”
sor = 3
‘——————————————–
‘ Bind

Set oActUsers = GetObject(”LDAP://cn=users, dc=test, dc=net”)
oActUsers.Filter = Array(”user”)
‘——————————————-
‘ Legyüjtés indul

For Each child In oActUsers
Cells(sor, 1).Value = child.samaccountname
Cells(sor, 2).Value = child.employeeid
Cells(sor, 3).Value = child.displayname
Cells(sor, 4).Value = child.Description
Cells(sor, 5).Value = child.telephonenumber
Cells(sor, 6).Value = child.mobile
Cells(sor, 7).Value = child.physicaldeliveryofficename
Cells(sor, 8).Value = child.Title
Cells(sor, 9).Value = child.department
Cells(sor, 10).Value = child.distinguishedname
sor = sor + 1
Next
‘———————————–
‘ Dekoráció
‘ Itt lehet cifrázni a táblázatot

Range(”C1″).Select

End Sub

——————————————————————————

Módosított információk visszaírása:

Sub Macro2()
Attribute Macro2.VB_Description = „Macro recorded 2006.09.03 by JoeP”
Attribute Macro2.VB_ProcData.VB_Invoke_Func = „b\n14″

‘ Macro2 Macro
‘ Macro recorded 2006.09.03 by JoeP

‘ Keyboard Shortcut: Ctrl+b

‘ Adatok visszaírása a címtárba

Dim sor, eszterlanc, oActUser

On Error Resume Next

sor = 3

Do While Cells(sor, 1).Value <> „”
eszterlanc = „LDAP://” & Trim(Cells(sor, 10).Value)
Set oActUser = GetObject(eszterlanc)

If Not IsEmpty(Cells(sor, 2).Value) Then
oActUser.putex 2, „employeeid”, Array(Trim(CStr(Cells(sor, 2).Value)))
Else
oActUser.putex 1, „employeeid”, „”
End If
oActUser.setinfo
Err.Clear

If Not IsEmpty(Cells(sor, 3).Value) Then
oActUser.putex 2, „displayname”, Array(Trim(CStr(Cells(sor, 3).Value)))
Else
oActUser.putex 1, „displayname”, „”
End If
oActUser.setinfo
Err.Clear

If Not IsEmpty(Cells(sor, 4).Value) Then
oActUser.putex 2, „description”, Array(Trim(CStr(Cells(sor, 4).Value)))
Else
oActUser.putex 1, „description”, „”
End If
oActUser.setinfo
Err.Clear

If Not IsEmpty(Cells(sor, 5).Value) Then
oActUser.putex 2, „telephonenumber”, Array(Trim(CStr(Cells(sor, 5).Value)))
Else
oActUser.putex 1, „telephonenumber”, „”
End If
oActUser.setinfo
Err.Clear

If Not IsEmpty(Cells(sor, 6).Value) Then
oActUser.putex 2, „mobile”, Array(Trim(CStr(Cells(sor, 6).Value)))
Else
oActUser.putex 1, „mobile”, „”
End If
oActUser.setinfo
Err.Clear

If Not IsEmpty(Cells(sor, 7).Value) Then
oActUser.putex 2, „physicaldeliveryofficename”, Array(Trim(CStr(Cells(sor, 7).Value)))
Else
oActUser.putex 1, „physicaldeliveryofficename”, „”
End If
oActUser.setinfo
Err.Clear

If Not IsEmpty(Cells(sor, 8).Value) Then
oActUser.putex 2, „title”, Array(Trim(CStr(Cells(sor, 8).Value)))
Else
oActUser.putex 1, „title”, „”
End If
oActUser.setinfo
Err.Clear

Set oActUser = GetObject(eszterlanc)
If Not IsEmpty(Cells(sor, 9).Value) Then
oActUser.putex 2, „department”, Array(Trim(CStr(Cells(sor, 9).Value)))
Else
oActUser.putex 2, „department”, „n/a”
End If
oActUser.setinfo
Err.Clear

sor = sor + 1
Loop

End Sub

AD gyötrések I.

Módosítani kellene felhasználói adatokat az Active Directoryban. Ez még nem nagy ügy, előkapjuk az Active Directory Users & Computers snap-int és átírjuk, amit akarunk.
Csakhogy ez nem mindig elegendő. Illetve, van, amikor elegendő, de kényelmetlen. Azután van, amikor elegendő ugyan, de nem szeretnénk annyit dolgozni.
Szerencsére rengeteg segédprogram létezik erre a feladatra. Jelen cikkben a grafikus felülettel rendelkezők kerülnek bemutatásra, a következőben pedig a parancssorosak lépnek porondra.

1. ADModify.net

Nagyon hasznos kis program. Valamikor az Exchange csapat írta saját használatára, de annyira jó lett, hogy felturbózták és most általános címtármódosító program lett belőle. Egyik előnye, hogy nagy tételben (bulk) lehet segítségével a címtár adatait módosítani. A másik, hogy bármely adat értékét módosíthatjuk vele – feltéve, hogy megvannak hozzá a jogosultságaink.

Már rögtön az induló képernyőn felvillant valamit az erejéből:

Nagyítás

  • 1.1 Modify AttributesItt léphetünk be az adatmódosító menübe. Persze nem egyből, először ki kell jelölnünk a módosítandó adatok körét. Ez lehet egy felhasználó, több felhasználó (lsd a képen), illetve extrém esetben a konfigurációs névtér egy eleme. Amikor több felhasználóról van szó, kijelölhetjük őket egyesével, de használhatunk saját magunk által összerakott LDAP lekérdezést is.

    Nagyítás

    A lényeg, hogy a jobb oldali oszlopban legyen valamilyen objektum – ekkor mehetünk tovább.
    A következő képernyőn egy százfülű ablakot találunk, mely első ránézésre meglehetősen hasonlít az ADUC felhasználói adatokat módosító ablakára. De csak első ránézésre.
    Az ördög ugye szokás szerint megint a részletekben…

    Például nézzük meg alaposan a fenti ablakot. Látható, hogy az előzőleg kijelölt felhasználói csokor számára egységesen tudunk új smtp címet generálni, sőt, akár elsődlegessé is tehetjük azt. Ha belegondolunk, hogy ugyanez Recipient Policy segítségével mennyire körülményes (LDAP szűrő, Recipient Update Service rugdosása…), akkor hamar megszerethetjük ezt a fület – pedig a legérdekesebb opcióról nem is beszéltem. Gondolom, nem árulok el újdonságot, ha megemlítem, hogy a Recipient Policy segítségével kiszórt emailcímek a policy törlése után nem törlődnek maguktól. Annál azért jobban kapaszkodnak. Egyfelől ezeket el lehet távolítani úgy, hogy felbérelünk tizenegy norvég hálóstoppoló öregasszonyt akik egyenként kitörlik a megfelelő címeket – másfelől megcsinálhatjuk azt, hogy a megszűnt házirend LDAP-szűrő ablakából kimásoljuk az LDAP feltételt, azzal berontunk az ADModify.net segédprogramba, majd miután lejött az érintett felhasználók listája, mindegyiket kijelöljük és a fenti képen látható ‘Remove email address’ opcióval eltávolítjuk a feleslegessé vált címeket.
    Végülis, ízlés kérdése.
    (Megjegyzem, azért ez a lehetőség nem helyettesíti teljeskörűen a Recipient Policy-t – a felhasználók létrehozását, mozgatását kísérő automatizmus hiányzik belőle.)

    Csemegézzünk még a fülek között. Van egy másik remek tab, úgy hívják, hogy custom. Amennyiben ismerjük a módosítandó tulajdonság nevét, akkor itt simán átírhatjuk az értékét.
    Konkrét példa. Nagyon sok helyen létezik a felhasználóknak egy, a HR által generált azonosítója. A címtárban létezik az employeeID nevű tulajdonság, direkt erre a feladatra felingerelve. Nagyon fontos egy tulajdonság lenne, hiszen ezáltal lenne összeköthető a HR adatbázis és az Active Directory. Mégse használja senki, mert az ADUC-ban nincs kivezetve a felületre az értéke. Amennyiben használják, akkor vagy megvásárolják a Hyena segédprogramot, vagy az adminnak kell összedobnia egy webfelületű szkriptet a tulajdonság kezelése céljából – vagy egy másik tulajdonságot oroznak el erre a célra.
    Nos, az ADModify.net ebben is segít. Az alábbi képen éppen Farkas Berci munkahelyi azonosítókódját módosítom. (Sajnálatosan a probléma ettől teljesen nem oldódik meg, a kód értékét kiolvasni ebből a programból sem tudjuk. Erre lesznek jók a később bemutatott parancssoros segédprogramok.)

    Itt kell megemlíteni még egy lehetőséget. Amikor kijelöljük, kiknek az adatait akarjuk piszkálni, kiválaszthatjuk a konfigurációs névteret is, illetve ezen belül tetszőleges objektumot. Az más kérdés, hogy elég furán fog kinézni utána a felhasználói adatok módosítására kitalált képernyő – mondjuk egy Exchange Store objektumnál. De még így sem értelmetlen a módszer, ugyanis a custom fül alatt módosíthatunk olyan tulajdonságot, amely ennél a – nem egészen idevaló – objektumnál található. (Szvsz. ez persze igazából csak agytorna, az ilyen tulajdonságok kezelésére ezerszer jobb segédprogram az ADSIEdit.)

  • 1.2 Undo ChangesMinden módosításról log készül xml formátumban, tehát simán vissza is tudjuk vonni az eddigieket.
    Magát a logot az alábbi ábra mutatja, az alatta lévő pedig a visszatöltő ablakot.
    Nem egy pilótavizsgás funkció, de roppant hasznos.

  • 1.3 Import Mailbox rightsExchange postafiókok jogosultságait importálhatjuk be xml fájlból.
    Maga a fájl az első menüpontban állítható elő, mint az ábrán is látható.

    Mielőtt továbbrohannánk, időzzünk el egy kicsit az ablaknál. Ugye mindenkinek feltűnt, hogy a program segítségével felhasználók egy tetszőleges csoportjánál tehetünk rá valakit megfelelő jogosultággal az illetők postafiókjára, illetve pont fordítva, vehetünk el jogosultságokat a postafiókoktól?
    Ha igen, akkor tényleg mehetünk tovább.
    A jogosultság export után egy xml fájl keletkezik.

    Nagyítás

    Szép. És ami fájl, az természetesen módosítható is. Más kérdés, hogy értelme nem sok van – jogosultság visszatöltést célszerűen backup/restore céllal érdemes használni, ugyanis jelen menüpontban nincs undo. Ha módosítani akarunk, akkor használjuk csak a korábbi ‘Mailbox Rights’ fület.

    És akkor a visszatöltés nem túl szofisztikált ablaka:

    Itt azt kell észrevenni, hogy a jogosultságok lehetnek additívak, illetve agyonvágóak.

A programcsomaggal nemcsak GUI jön, létezik a program parancssoros változatban is. A szintaxist és a kapcsolókat most nem elemzgetném, az ‘admodcmd -? > admodcmdhlp.txt’ parancsot ajánlom mindenki szíves figyelmébe, illetve a keletkező fájl kinyomtatását. Nagyon sok oldal lesz, de ebből lehet majd kibogarászgatni, hogy bármit, amit a grafikus felületen meg lehetett csinálni, hogyan lehet parancssorból is véghezvinni. Példák természetesen vannak.

Az írás végére még néhány link:

2. GALMod

A program becsületes neve: Global Address List Modify tool.
Nem egy mai gyerekről van szó, anno az Exchange5.5-höz készült – ennek ellenére remekül elboldogul az újabb Exchange verziókkal is, hiszen a szerverek szó nélkül tovább passzolják a címtárnak a módosítási igényeket. A program először az Exchange 5.5 Resource Kit-nek volt része, majd rákerült a későbbi verziókhoz tartozó RK cédékre is.
A használata egyszerű, mint a faék. Első induláskor legyárt egy MAPI profilt (ha addig nem volt), majd feljön egy háromfülű ablak, amelyikben a profilhoz tartozó postafiók azon adatait lehet módosítani, melyek a címlistákban is megjelennek.

Nagyítás
2.1 MAPI profil kiválasztása

Nagyítás
2.2 Első fül

Nagyítás
2.3 Második fül

Hogy annyira azért ne legyen egyszerű az élet, szerveroldalon Windows2003 szerver kell hozzá, futó ASP.NET szolgáltatással. (A régebbi verziók esetén szükség lesz egy kis hegesztésre is, ezekről részletesen itt vagy itt lehet olvasni.)

A képeken látható, hogy bizonyos mezők szürkék – ezek nem módosíthatók. A többi viszont igen.

Link szekció:

3. Directory Update
Jim McBee egyébként is egy jónevű fickó. Directory MVP, aki egész érdekes írásokat szokott publikálni a blogján. Régebben használta néha a GALMOD programot és érzékelte annak hiányosságait. Szerencsére nem csak érzékelte, hanem írt is egy másikat, melyet Directory Update-nek nevezett. (Nem, nem Norbi.)

Miben is különbözik ez a GALMOD-tól?
Sok mindenben:

  • Semmit nem kell kliensoldalon telepíteni.
  • Egyenként lehet szabályozni, hogy a GAL-ban szereplő tulajdonságok közül melyek látszódjanak és ezek közül melyek legyenek módosíthatók.
  • Bővebb a módosítható tulajdonságok köre.
  • Minden tulajdonsághoz szabadon konfigurálható drop-down lista rendelhető.
  • A képernyő testreszabható.
  • A kommunikáció egyszerűen titkosítható.

Ennyi plusz funkció láttán Jim úgy döntött, hogy ez nem ingyenes program lesz, inkább megpróbálja eladni azt. Jelenleg 250$/domain áron forgalmazza. Nem kevés… de ha belegondolunk, hogy mivel a felhasználók saját böngészőjükből képesek módosítani az adataikat, így az eredmény egy mindig aktuális címtár lesz, … lehet, hogy mégis megéri. (Természetesen ahol szigorú előírások, ISOxxxx és change management szabályozza a változtatásokat, ott a program számára nem sok babér terem. De kisebb/közepes cégeknél el lehet rajta gondolkodni.)
A webről 10 napos próbaverziót lehet letölteni.

Pár szó a működésről.
Ahhoz, hogy egyáltalán telepíteni lehessen, egy Windows2003 DC vagy member szerverre lesz szükség, melyen fut az IIS és az ASP.NET szolgáltatás. Maga a telepítés nem különösebben bonyolult, majdhogynem next-next-finish. A végén létrejön egy DirectoryUpdate virtuális könyvtár. Opcionálisan erre lehet rávarázsolni az SSL elérést.

Első lépésben a szerveroldal kész is. Kliens oldalon be kell írni a böngészőbe, hogy ‘http://webszerver/DirectoryUpdate/default.aspx’ – és máris Bob a bácsikánk.

A sikeres bejelentkezés után kapjuk meg az adatmódosító ablakot.
Már ez sem rossz, de testreszabás nélkül ez az ablak egy félkarú óriás. (Gyönyörű:)
A virtuális könyvtár alatt találni fogunk két xml és egy css fájlt. Ezeken keresztül lehet majd az alkalmazást konfigurálgatni. A css fájl értelemszerűen a kinézet – betűk, színek – állítgatására jó, az xml fájlok közül az egyik az alapbeállítások biztonsági tartaléka. A másik, az appsettings.xml tartalmazza a program működését befolyásoló paramétereket. A felépítése értelmes, logikus, nem hiszem, hogy túlságosan el kellene mélyülnöm a magyarázatában.
Minden értékhez tartozik egy type, egy editable és egy visible változó. Az utóbbi kettő yes/no értékkel bírhat, a type pedig lehet text v. dropdown. Ezekkel lehet beállítani, hogy egy tulajdonság egyáltalán látható legyen-e, ha igen, akkor az értéke szerkeszthető legyen-e és ha igen, akkor szabadon lehessen módosítani vagy csak egy legördülő listáról. Magukat a listaelemeket value tag-ek közé kell beírni.

Először töltsük fel a listaelemeket.

Nagyítás

Majd tiltsuk le az IP telefon értékének a módosítását.

Nagyítás

És itt is a kívánt végeredmény.

Nagyítás

Végül a link szekció:

4. ADSIEdit, LDP
Segédprogramok nem csak lelkes emberek műhelyeiben teremnek, akadnak az operációs rendszerben is rendesen. A Windows server telepítő cédé Support Tools csomagjában (telepíteni kötelező!) található többek között a címsorban található két segédprogram. Mindkettő grafikus felületű – és mindkettőről elmondható, hogy mindent, hangsúlyozom, mindent módosíthatunk segítségükkel a címtárban. (Feltéve, hogy van hozzá jogosultságunk.) Emiatt kéretik igen óvatosan bánni velük.
Az ADSIEdit egy MMC snap-in, célszerű felvenni a mindennapos custom MMC konzolunkra.

Nagyítás

A használata igen egyszerű. (A W2K és a W2K3 alatti verziók eltérnek egy cseppet, de nem vészesen. A cikkben a W2K3 verziót használtam.)
Kikeressük a megfelelő tulajdonságot (ehhez persze ismerni kell az AD névtereit és azokon belül a struktúrákat), majd nemes egyszerűséggel átírjuk azt. A lenti példában például törlöm Farkas Berci egyik emailcímét.

Nagyítás

Az LDP programnak kicsit más a filozófiája. Elsősorban gyors nézegetéshez ajánlott, a tulajdonság értékek átírása kicsit körülményes benne. Nagy előny, hogy az egyes objektumokra kattintva csak az értékkel rendelkező tulajdonságokat listázza ki, így gyorsan áttekinthetjük egy objektum összes létező értékét. (Tudjuk ugye, hogy ha egy tulajdonságnak nincs értéke, akkor az nem létezik.)
A lenti képernyőkép szerintem magáért beszél.

Nagyítás

Ahhoz, hogy idáig eljussunk, három lépést kell megtennünk.

– Connection/Connect

Nagyítás

– Connection/Bind

Nagyítás

– View/Tree

Nagyítás

Értéket módosítani pedig az alábbi módon lehet.

Nagyítás

Link szekció:

Egyszerű kiolvasás

Abszolút egyszerű feladatot kaptam. Csináljak egy listát, a következő oszlopokkal: felhasználói név, GUID. Az első oszloppal nem volt semmi gond és úgy véltem, a másikkal sem lesz. Kétperces munka. Egy perc volt, amíg megnéztem adsiedit-tel, hogyan is hívják a tulajdonságot: objectguid. A következő perc pedig azzal telt, hogy az előregyártott lekérdezőszkriptemben átírtam a lekérdezést a kívánt formára.
Majd az elkövetkező pár órában azzal foglalkoztam, hogy rájöjjek, miért is nem működik ez a módszer. A szkript ugyanis üres oszlopot hozott le.
Rutinosan kikapcsoltam a szofisztikált hibafigyelést (on error resume next), így meg is kaptam a várt runtime error-t.
Nézzük, ldp-ből mit látok. Semmit. Nincs ilyen tulajdonság. Visszamentem az adsiedit-hez, hátha az előbb káprázott a szemem, de nem – a tulajdonság ott volt, sőt, módosítani is tudtam. (Ezzel azért óvatosan.) Azaz jogosultsági probléma sem lehet.
Jöjjön a gugli power. Hosszas keresgélés után találtam olyan linkeket, miszerint felejtsem el, a feladat vbscript segítségével nem oldható meg. Ugyanis az objectguid az egy binárisokat tartalmazó tömb, a vbscipt viszont kizárólag a variant típusú tömböket tudja kezelni.
Szerencsére a lendület továbbvitt és kipróbáltam még néhány keresőszót. És meg is lett az eredménye, rátaláltam egy írásra Eric Lippert blogján.
A szokásos szöveggel indít. Hogy miért nem lehet megoldani a feladatot. Aztán megmutatja, milyen trükközéssel lehet mégis.
Először bedobja a cstr() függvényt. Ez egy olyan függvény, amely képes kigondolkozni a dobozból. Mindent, még az általa értelmezhetetlen adatokat is átkonvertálja sztringgé. Bízik benne, hogy a programoló csak tud kezdeni valamit a karakterkukaccal. És Eric tud. Nekiáll sztringet szeletelni, karaktereket konvertálni, nullából duplanullát csinálni – míg végül a boszorkánykonyhájából kipottyan a friss, ropogós GUID.

Egyszerű kiolvasás. Ja.

Itt sincs, ott sincs

Megőrjít.
Van egy kliens gépem. Ezen akarok futtatni egy szkriptet, mely távoli AD szájtok felhasználóinál módosítana display nevet. (Vbscript + ADSI.) Az adatok Excel táblában vannak.
Lefuttattam az egyik szájtra, a nevek átíródtak. Megnéztem ADUC-ból, tényleg.
Lefuttattam ugyanazt a szkriptet a másikra, nevek látszólag átíródtak. ADUC – mégsem íródtak át. Átfutottam az összes DC-t, sehol sem íródtak át. Picit átírtam a szkriptet, hogy most csak lekérdezze az értékeket – és tényleg nem íródtak át. Beleraktam még vagy ötször a setinfo-t, biztos, ami kurvafix – és kiegészítettem azzal, hogy írás után olvassa is vissza ADSI-n keresztül az értékeket és írja ki fájlba. Szkript lefutott, és a megváltozott értékeket írta ki. Gyorsan ADUC – sehol sem volt változás. Site-site replikáció megrángatása, újból körbenézés, semmi. Lefuttattam a szkriptet csak olvasó módban – a régi értékek jöttek vissza.
Hihetetlen.
A kliens gépről egy gyors próba, ldp-vel megváltoztattam a távoli szájt felhasználójának az adatát – és így működött, tehát se jogosultsági, se tűzfal probléma nincs. Ha ugyanezt egy nyomorult háromsoros vbscript-ből csináltam, akkor bezzeg nem ment.
Bele fogok dilizni. Ez az egy lépés van hátra abból a holland projektből, melynek már a nevétől is feláll a szőr a hátamon. És itt, az utolsó lépésnél jön be egy ilyen X akta, amikor már nem vágyom másra, mint hogy lezárjam ezt a szutykot.

Miután jól kisírtam magam, nekiálltam gondolkozni. Mi lenne például, ha kitörölném a bűvös ‘on error resume next’ sort?
Hoppá. Rögtön az elején befigyelt egy hiba:

Run-time error ‘-2147016693 (8007200b)
Automation Error
The attribute syntax specified to the directory service is invalid

Na, vajon mi lehet ez? Erős a gyanú, hogy adathiba, hiszen a szkript más szájtra lefutott. Kezdjünk játszani. Első körben csak a displayname értékét írtam ki – nem volt hiba. Jött a keresztnév, nem volt hiba. Jött a vezetéknév – és vele együtt a hiba. Hmm… ennyire kényes lenne az az sn attribútum?
Ránéztem az excel táblára – és letéptem az első sor csempét. Az adott szájton nem mi adminisztrálunk és a fiúk nem vacakoltak, a teljes nevet a keresztnévhez írták – azaz az sn attribútumba üres mezőt kellett volna betölteni. Ettől borult meg a szkript futás közben – de az onerrorresumenext továbblökte, mintha mi sem történt volna. Nem is történt semmi. Kiírás sem.
Oké. Akkor tegyünk bele egy vizsgálatot és ha üres a mező, akkor a kérdéses mezővel ne történjen semmi, de a sor többi mezőjét írja ki. Jó lesz ez? Nem biztos. Lehet, hogy az ügyfél törölt egy értéket és szeretné, ha az el is tűnne az AD-ból. Jó, akkor írjunk ki egy “”-t.
Nos, aki azt hiszi, hogy az oChild.attributum = “” lesz a jó megoldás, az még menjen vissza egy kicsit a homokozóba. Ugyanis pont ez a forma adta a fenti runtime error-t.
Igenám, de akkor hogyan lehet törölni egy attribútum értékét? Gugli.
És végül itt van a megoldás. Annyira szép, hogy alig hiszem el.
Tudni kell, hogy az AD-ba lehet cseppeként is írni. Ilyenkor csak a megváltozott attribútum értéke utazik a dróton, azaz spóroltunk egy csomó sávszélességet. Cserébe kicsit bonyolultabb a szintakszis.
Ilyen: oChild.putex X, “attributum”, valtozo,
ahol az X a helyzet kulcsa. Ugyanis ha X=2, akkor kiírás következik, ha X=1, akkor törlés.
Tehát a kérdéses kódrészlet:

If Trim(Cstr(Cells(sor,1).value)) = “” then
oChild.putex 1, “displayname”, “”
else
oChild.putex 2, “displayname”, Trim(Cstr(Cells(sor,1).value))
EndIf

Dögi. Futtassuk meg.
Megint ugyanazt a runtime error-t kapjuk. WTF?
Nos, ismét jött egy kis Gugli – majd megint lekerült a falról egy sor csempe.
A putex-es verzió ugyanis tömböt kér paraméternek. Miért? Csak. Akkor, amikor törlök, akkor nem is igazán kell neki érték, a “” bőven megteszi. De akkor, amikor módosítok, akkor bizony tömbbe kell rakni a változót.
Így fog kinézni a sor:
oChild.putex 2, “displayname”, Array(Trim(Cstr(Cells(sor,1).value)))
És ez már tényleg működik.

Illetve…
Boldogan engedtem rá a felturbózott szkriptet a böszme nagy excel táblára – és pár perc múlva megint runtime error-t kaptam. Egy kicsit megrugdostam az asztallábat majd nekiálltam nyomozni. Hiába. Minden teljesen rendben volt. Kínomban kimásoltam a táblázatból a dn értéket, benyomtam az ldp-be – és megfeküdt az is tőle. Nocsak. Nézzünk be az ADUC-ba.
Basszus. Amíg szarakodtam a szkripttel, addig törölték a felhasználót.
‘On error resume next’ visszakapcsol. Anyátok.

A GC sem mindenható?

Őszintén szólva, még mindig tátva van a szám. Ettől a cikktől maradt úgy… pontosabban egy új, a GC-kre vonatkozó információtól.
A cikk egyébként több okból is nagyon jó. Meg lehet pl. tanulni belőle, hogyan tudom gyorsan megállapítani, mely GC-ket lát az Exchange szerver. (Pontosabban a DSACCESS szolgáltatása, mely a GC-XCH kapcsolatért felel.) Élvezetes a gondolatmenet, ahogy Jasper felgöngyölte a problémát. És megtudhatjuk, hogy megint a Public Folderek a bűnösek. És hogy a GC-k sem tudnak mindent.
Számomra ez utóbbi volt az igazán megdöbbentő:

It turns out that Exchange does not always use the local GCs. For certain specific security related user attributes like tokenGroups and tokengroupsGlobalandUniversal (used to determine what security groups a user is a member of and therefore what permissions s/he has to secure resources such as public folders). Exchange MUST query a DC that is authoritative for the user’s home domain, which will likely be an out-of-site DC—in this case it happened to be a DC in Australia. This behavior was introduced around the Exchange 2000 SP2 time frame to address an issue where users from remote domains (sibling or parent) were denied access to public folders even when the security groups they were in should have allowed them access. Pre-SP2 we had made the false assumption (in the product) that a local GC can service ALL queries that Exchange issues. A local GC can (and should) service MOST queries in a well designed multi-site AD environment.

Eltekintve attól, hogy erősen hiányzik egy ige a második mondatból, kihámozható, hogy Jasper szerint a GC adatbázisok nem tartalmazzák azokat az információkat, hogy a felhasználók mely biztonsági csoportoknak a tagjai. Ez alapjaiban rendítette meg az elképzelésemet a GC-k működéséről. De tényleg. Hiszen pont azért találták ki, hogy gyorsan, mindenféle DC abuzálás nélkül el lehessen dönteni, hogy Géza hozzáfér-e egy erőforráshoz, vagy sem?
A többi már csak hab a tortán; hogy Exchange SP2 előtt ilyenkor meghalt a PF elérés, SP2 után viszont megpróbálja a világ másik végén lévő helyi GC-t használni. Aztán van amikor ezzel több kárt okoz, mint hasznot.

Ezt ne próbáljátok ki otthon

Essünk túl rögtön a nehezén: farok voltam. Nem is kicsit. De megint mákom volt, nem ez okozta a szopást.
Mint írtam korábban, egy nagyobb lélegzetű projekt részeként fel kellett húznom egy távoli tartományban, egy távoli szájtban egy tartományvezérlőt. Anélkül, hogy túl sokat gondolkodtam volna, felhúztam rá egy w2k3 szervert. Aztán amikor jött a dcpromo, kerregett egy kicsit, majd indignáltan közölte, hogy “legalább egy adprep kellene, fiú“. Basszus – csaptam a fejemre – ez még csak natív w2k tartomány. Oké, tudomásul vettem, hogy nem történt meg az előléptetés – a biztonság kedvéért átnéztem az AD-t, de sehol semmi nyoma nem volt, hogy keletkezett volna egy DC.
Újrahúztam a gépet, immáron w2k-val, megint dcpromo, remekül sikerült. Elég késő este volt, gondoltam reggelre lemegy minden replikációs szutyok.
Hát, nem. Semmi replikáció nem történt, semmi srv rekord nem jött létre – a DC bizony elég döglöttnek tűnt. Egy kollégával nekifogtunk a feltámasztásnak, de nem bírtuk kirángatni a klinikai halál állapotából. A hibaüzenetek mélyén mindig beleütköztünk egy gyanús objektumba, mely egy guid névre hallgatott. Úgy tűnt, hogy ez a bazi hosszú karaktersorozat akadt keresztbe az AD torkán.
Ha nem, hát nem. Dcpromo vissza. Azt mondta, hogy nem lehet, mert nem működik a replikáció. Itt kezdett el jojózni a szemem – hát pont azért akarom demotálni, mert nem működik a replikáció! Aznapra elég is volt ennyi.
Hétvégén egyrészt aludtam egyet-kettőt, másrészt gondolkodtam. Igen, szoktam. Néha.
Találtam is valami magyarázatot. Igaz, légből kapott – ún. identifikált – magyarázat volt, de logikusnak tűnt. Kicsi is, savanyú is, de a miénk. Valószínűleg az első dcpromo már megágyazott a szervernek a konfigurációs névtérben – és csak utána vette észre, hogy nem megfelelő a séma. Persze ezt már nem takaritotta ki. Mocskos Microsoft. Trehány banda.
Jöttem két nap múlva és megpróbáltam létrehozni egy ugyanolyan nevű DC-t. Naná, hogy ennek – legbelül – csak ronda guid-os neve lehetett, hiszen az előző ágy még ott illatozott. Hogy aztán miért okozott helyrehozhatatlan replikációs hibát ez az elnevezés, azt már nem tudom.
A megoldás adta magát: valamilyen módon ki kell takaritani a döglött DC-t, helyét felszántani, sóval bevetni, aztán másik néven kreálni egy újabb tartományvezérlőt. A takarításhoz meg is találtam a megfelelő KB cikkeket (egyik, másik), innentől kezdve már csak a diplomácia maradt hátra. Mennyire lesz ez kockázatos? Ha fejreállítom a regionális vezető szerepre törő ügyfél éles tartományát egy Europe-wide projektben, akkor én az EMEA régióban sem találok új munkahelyet. De az idő is erősen sürget, és bár kicsi a kockázat, de ha megemlítem, akkor beindul a change management, kockázatelemzés, független tesztelés, annyakínja…
Volt min agyalnom.
Végül megoldódott a helyzet. Beavattam a főnökömet, írtam az ügyfélnek, fél napig vártam, nem válaszoltak, hallgatás – beleegyezés. Mehettem dózerolni. Az első döbbenet akkor ért, amikor a dcpromo /forceremoval sem működött. Azt mondta, nem tudja leállítani a netlogont. Nofene.
Itt már azért sejtettem, hogy megint mehetek a jó öreg zajos, szélviharos szerverhelyiségbe.
Egyelőre beléptem az ILO porton, letiltottam az összes hálókártyát, majd nekiálltam megműteni az éles AD szívét. Nem mondom, hogy nem remegett a kezem.
Itt érdemes megemlékezni egy fordítási bakiról.

10. Perform a metadata cleanup for the demoted domain controller on a surviving domain controller in the forest.

10. Végezze el a metaadatok törlését a lefokozott tartományvezérlőn az erdő egy még meglévő tartományvezérlőjéről.

Uraim, ez nem ugyanaz, nagyon nem…
A műtét sikerült, az ügyfél nem vett észre semmit, én meg tekerhettem a Dataplexbe. Ilyen flott telepítésem még nem volt blade-del: 2 óra alatt tiptop fent volt az oprencer, mindenestől. Hát, igen… a rutin.
És jött megint a félelmetes dcpromo. Látszólag minden sikerült. Jó, akkor most menjünk büfébe, mert szégyenlős a kicsi – ha nézik, akkor nem replikál. De ez a büdös dög akkor sem replikált, ha nem nézték. Ugyanaz a jelenség. Semmi replikáció, szájton belül RPC error, szájton kívül semmitmondó ‘majd replikálok, ha ráérek‘ üzenet, az eventlogban meg egy teljesen értelmezhetetlen hibaüzenet: nem tud bejegyezni egy bazinagyguid nevű aliast az msdcs.forestroot dns zónába. Megnéztem és ez egy igen idétlen zóna: tele van ilyen ökörhugyozás bejegyzésekkel és az új DC-nek tényleg nyoma sincs.
Nos, a szituáció megérett egy funkcionális eszkalációra. (ITIL vagyunk, vagy miaf@sz.) Először mozgósítottam a tűzfalas emberünket, majd ezzel egy időben becsörögtem a Microsoft PSS-hez. Tuti örültek nekem, délután fél ötkor, egy ‘A’ kategóriás bejelentéssel. Az első embernek egyből el is romlott a postafiókja, így kénytelen volt rögtön eszkalálni a problémát.
Amíg ők odabent békésen eszkalálgattak, visszahívott az – egyébként igen jónevű – tűzfalas emberünk.
– Hát, van néhány drop, DNS kéréseknél – mondta.
– Mennyi?
– Tulajdonképpen kurva sok.
– Áááááá! – kezdtem el sikoltozni. (Még rögtön az elején nyomatékosan kértem, hogy az új DC és a többi között any-any szabály legyen.)
– Elég érdekes a dolog – folytatta a srác, mintha érezte volna, mi bántja a szívemet – ugyanis protocolfilter fogja meg; azt mondja, hogy valótlan a kérés szintakszisa.
Kezdett összeállni a dolog.
– Nem lehet, hogy ez egy olyan DNS kérés, amelyikben valaki egy kibaszott hosszú nevű aliast akar beregisztrálni? – érdeklődtem.
– De, lehet.
– Nem-e lehetne-e ezt a protokolszűrést kikapcsolni-e?
– De, lehet. (Medve a halállistával.)
Vártam pár percet, újraindítottam a DC-t és… pár perc múlva begerjedt a replikáció. Én így még nem örültem replmon képernyőnek.
Tehát összeállt a kép: a dcpromo lefutott, de egy DNS regisztráció nem történt meg: az új DC GUID-ja nem került be aliasként a forest root tartomány msdcs.forest.root zónájába. És azért nem került bele, mert a bejegyzési kérelmet a tűzfal BOF támadásnak érzékelte.
Oké. De miért vágta ez haza a replikációt?
Ekkor hívtak vissza a Microsofttól. Örömmel közöltem, hogy megoldódott a probléma. Rakjuk össze, amink van – javasolta a srác. Erre elmondtam, mire jöttünk rá – ő pedig elmagyarázta, hogy hogyan is történik igazából a replikáció. Így:

The domain controller initiating the replication (DC1) queries the Active Directory in searching for its configured replication partners. These replication partners are typically defined by the Knowledge Consistency Checker (KCC), but can also be defined manually.
DC1 knows only the name of the domain controller that it wants to replicate with (DC2). It finds a GUID in the Active Directory that matches the target domain controller’s name (DC2). Note that each domain controller in the forest should have its own unique GUID.
Now that DC1 knows DC2’s GUID, it must find DC2’s IP address so that it can connect to it across the network. To do this, DC1 uses DNS. DC1 sends a recursive DNS query to its locally configured DNS server for a CNAME record. The format of this record always matches the following
guid._msdcs.root of Active Directory forest
Where guid is the GUID that DC1 found in the Active Directory, and root of Active Directory forest is the root of the Active Directory forest. For example 91f9b084-4876-4b59-be17-59e74c340221._msdcs.reskit.com where 91f9b084-4876-4b59-be17-59e74c340221 is a GUID and reskit.com is the root of the Active Directory forest.
DC1’s locally configured DNS server should respond to the query for the CNAME with an alias. The alias is another name for the GUID. For example, the GUID 91f9b084-4876-4b59-be17-59e74c340221 is resolved to dc-02.reskit.com.
Now that DC1 knows the alias for the GUID, it must resolve the alias to an IP address so that it can connect to DC2 across the network. DC1 sends a recursive DNS query to its locally configured DNS server for a Host (A) record that matches the name of the alias. The DNS server should respond with the IP address that has been mapped to the alias — for example, 169.254.66.7
Now that DC1 knows DC2’s IP address, it can connect to DC2 over the network and replicate Active Directory data.

Röviden összefoglalva, itt kőkemény névfeloldás folyik. A replikációs partnerek csak egymás nevét ismerik. Ez alapján kikeresik az AD-ból a partner GUID-ját. Most már csak a GUID-hoz tartozó IP cím kellene – ezt tartalmazza az a bizonyos zóna a forest rootban. Ha ebben nincs meg az új DC GUID-IP összerendelése, a replikáció csonkára fut.
Szép, mi? Jól mellétrafáltam az ujjamból szopott magyarázattal. Szó sem volt megágyazásról, beragadásról meg trehány Microsoftról. Minden tiszta, logikus és érthető. Csak az kicsit gáz, hogy ezt az infót a PSS-től kellett megtudnom. Lehet, hogy valahol le van írva… lehet… de én még nem találkoztam vele.

Szóval most működünk.
Milyen fából faragják a jó tűzfalast? Úgy van. Pár perc múlva visszahívott, hogy oké, JoeP, szóljál mikor kapcsolhatom vissza a filtert, mert anélkül szarul érzem magam. Itt kezdtem el másodjára sikoltozni – de aztán rájöttem, hogy nem beszél hülyeségeket. Ha vigyázunk arra a szájbanyomott rekordra, akkor többször nem kell bejegyezni. Kiolvasni meg csak ki tudják. Talán. Holnap teszteljük.
Szeretünk a penge élén.

Keresés az AD-ben e-mail címre

Egy régi problémám volt az, hogy hogyan találjunk meg egy felhsználót az Active Directoryban az e-mail címe alapján. Volt erről egy hosszú thread a technetklub levlistán (http://listmanager.technetklub.hu/read/messages?id=122959 [2008-05-30: Ez a link már nem él. A technetklub levlista kimúlt, béke poraira. Még nem adtam fel, hogy az archívumot egyszer kirakom az internetre publikusan, de sajna nincs időm befejezni a kódot.]) amiből az derült ki, hogy valamelyik proxyAddress alapján nehéz megtalálni a felhasználót, ráadásul lassú is. A probléma alapja, hogy azt gondoltom (gondoltuk többen), hogy a proxyAddresses propertyben nem lehet keresni mert az egy multivalue property. Már tervezgettem, hogy írok valami szolgáltatást a dologra. Egy progi megadott időközönként végigtúrja az AD-t épít belőle egy adatbázist amiben utána én tudok gyorsan keresni.
Ma megint kellet volna ez a dolog így tüzetesebben utánnanéztem a Windows 2000 Scripting Guide-ban (http://www.microsoft.com/technet/scriptcenter/guide/default.mspx). Olvasva az ADSI keresésre vonatkozó részt egy mondatra figyeltem fel (itt: http://www.microsoft.com/technet/scriptcenter/guide/sas_ads_jgtf.mspx):
…use objectCategory rather than objectClass because objectCategory is single-valued and ideal for servicing search requests…
 
Várjunk csak, ezek szerint lehet multivalue propertyben keresni. Kipróbáltam. Íme az eredmény:
var SearchMail = "test@domain.hu"; 
var ADConnect = new ActiveXObject("ADODB.Connection"); 
var ADCommand = new ActiveXObject("ADODB.Command"); 
var rootDSE, ForestRoot, ADRS; 
rootDSE = GetObject("LDAP://rootDSE"); 
ForestRoot = rootDSE.Get("rootDomainNamingContext"); 
ADConnect.Open("Provider=ADsDSOObject;"); 
ADCommand.ActiveConnection = ADConnect; 
ADCommand.CommandText = "<GC://" + ForestRoot + 
    ">;(&(objectCategory=user)(proxyAddresses=smtp:" + 
    SearchMail + "));name;subtree"; 
ADRS = ADCommand.Execute(); 
for(; !ADRS.EOF; ADRS.MoveNext()) 
    WScript.Echo(ADRS.Fields("name").Value); 
ADConnect.Close();