Category: szkript

Mint a régész

Valamiért ez a cikk a privát blogba került bele, pedig simán illik ide is, méghozzá a szívás kategóriába. Sőt, a nagyon nagy szívás kategória sem lenne túlzás.
Csak hogy összezavarjam az ellenfelet, a történet végét itt írom meg.

Miután az éles szervert többször is betérdeltettem pusztán csak azzal, hogy belenéztem néhány public folderbe, kitaláltuk, hogy bevirtualizáljuk(1) az egész cuccot, atombiztosan elszeparáljuk az éles környezettől és azt már piszkálgathatom. Hogy mennyire ment könnyen a virtualizálás? Sajnos a kolléga nem ír blogot, pedig nagyban tudná vele javítani a közhangulatot. Amekkorát szopott vele, ahhoz képest egy átlag IT jómunkásember élete hawaii pihenés.

(1) A virtualizálás rendszeresen behalt, végül disaster recovery alapon backupból állt fel a rendszer.

Oké, röpke 2-3 hét alatt elkészült a tesztrendszer, odáig, hogy már futott az Information Store szolgáltatás az Exchange szerveren. Csak hogy tisztázzuk a játékteret: Windows 2003 STD, Exchange 2003 STD, külön gépen Windows 2003 STD domain controller.
Ezt a rendszert már sokkal bátrabban tanulmányozhattam. Mit mondjak, egyik döbbenetből a másikba estem. Először találtam néhány public foldert, ahol 100000 fölött volt az elemszám. Aztán találtam egyet, ahol 200000 fölött volt. Aztán beléptem az admin nevében és a postafiókjában, az elküldött elemeknél – írdd és mondd – 2000000 fölött. Ha esetleg gondot okoznának a nullák, akkor leírom betűkkel is: kétmillió feletti elemszám. Standard 32 bites Windows szerveren, melynek nem lehet 3 GB-nél több memóriát adni.

Párbeszéd.
– Az Exchange alapvetően a memóriában dolgozik – jelentettem ki.
– Csak nem a miénk – vont vállat a helyi ember – A miénk kizárólag diszkre.

Kitérő.
Egyszer valamikor egy nagyobb cég rendszereit tekergettem, mint szerver adminisztrátor. Szintén Exchange 2003. A szerver nem muzsikált túl jól, ezért kihívtunk egy Microsoft rapid mérnököt, vizsgálja át és mondjon róla véleményt. A csajszi szó szerint ledobta a haját, amikor megtudta, hogy néhány felhasználónál vannak olyan folderek, melyekben 60000 feletti az elemszám. Erre a számra mondta azt, hogy borzalmasan sok, csoda, hogy egyáltalán működik a szerver.
Kitérő vége.

Nos, mint ahogy korábban is írtam, ez a cég az Exchange platformra tette a… a mindent. Gyakorlatilag ezen megy a teljes céges workflow. Ezt kellett feltérképeznem.

Kitérő.
Az Exchange 2000-ben jelentek meg az event sinkek. Rögtön kétfajta is lett belőlük: store sinkek és transport sinkek. Az előbbi az adatbázismotorra figyelt, az utóbbi az smtp motorra. Sinket úgy lehetett létrehozni, hogy a fejlesztőember megírta a kódot, akár vbscriptben, akár vb-ben, de úgy emlékszem, írhatta C#-ban is. Ebből aztán gyártott egy COM objektumot és beregisztrálta a Windows-ba. Nem mennék bele a részletekbe, de a kétfajta sinknek más volt a beépülési technikája. A store sinkek látszódtak a Component Services konzolban, a transzport sinkek viszont nem, ezeket csak egy spéci szkript segítségével lehetett kezelni. A sinkek úgy működtek, hogy rákapcsolódtak egy eseményfigyelőre (ezeket kezelte az Event Service) és ha az bekövetkezett, akkor elindult a hozzájuk rendelt kód. Aztán a Microsoft látta, hogy ez így nem igazán jó. 2005-ben ezt az egészet – beleértve a webstore-hoz kapcsolódó matyizást is – kitette egy külön termékbe, ez lett a Sharepoint. Az Exchange 2007-ből eltűntek a transport sinkek, helyettük bejöttek a transport agent-ek. Az Exchange 2010-ből pedig eltűntek a store sinkek is.
Kitérő vége.

Az én vizsgálódásomnak az volt a célja, hogy a workflow milyen komponenseket használ. Ha például van benne transport sink, akkor megette a fene, mert ekkor már a 2007-es Exchange-re sem tudunk áttérni. Nem kicsit nehezítette a feladatot, hogy az egész roppant bonyolult rendszerről semmilyen dokumentáció nem volt, és akik készítették, mára elérhetetlenek. A rendszer csak úgy ketyeg magában.

Az első eredmények biztatóak voltak. Az smtpreg.vbs szerint transport sink nincs. Store sinkből csak a CDO for Workflow (CDOWF) volt beregisztrálva. (Innovation never stops.) Ez gáz, mert ez a CDO a 2007-ben megszűnt, de ha nem használják, akkor simán mehetünk tovább, akár a 2010-es verzióig is. Honnan tudjuk, hogy használják-e vagy sem? Ki kell nyerni a rendszerből az összes kódot és át kell vizsgálni. Bagatell.

Hol lehet kód? Custom sink nincs, tehát egyedi COM objektum sincs. Lehetnek még speciális formok, melyek mögött ott figyelhet egy-egy szkript. Nos, ilyenből rengeteg volt. Külön nehezíti a helyzetet, hogy a custom formok is több helyen lehetnek: létezik egy központi form tároló a public folder hierarchiában, külön el lehet helyezni formokat az egyes public folderek tulajdonságai között, emellett lehetnek formok a felhasználók postafiókjaiban is. Csak hogy érezzük a nagyságrendet: a központi tárolóban volt tíz egyedi form, emellett volt több tízezer public folder, melyeket – dokumentáció híján – egyenként kellene végignézni, hogy publikáltak-e a folder adatlapjába egyedi formot, plusz ott volt valami ezer kliens, akiknek a cachelt profiljába töltődtek le különböző formok. Ja, és a céges IT folyamatok között szerepelt egy olyan lépés, hogy az Outlook 2003 telepítésekor fel kellett telepíteni egy setup.exe segítségével két darab saját fejlesztésű dll-t, melyekről persze senkinek nem volt semmilyen infója. Az egész cucc csak max. Outlook2003-mal(2) működött és max. 32 bites XP-n. (Ez persze elég rendesen bebetonozta a céget a kőkorszakba.)

(2) A szkriptekben volt egy verzióvizsgálat. A lehető legbénább módon. Azt vizsgálta, hogy a kliensoldali CDO verzió első 3 karaktere egyenlő-e(!!!) az ‘1.2’ karakterlánccal. Azaz az Outlook2003 CDO verziószáma (1.21) még átment a vizsgálaton, de az Outlook 2007 CDO verziószáma (6.5) már nem. Aztán hogy felülről kompatibilis-e az új CDO, az más kérdés.

Szóval hajrá.

Átnéztem több száz public foldert. (Nyilván egy bizonyos mélység alá már nem mentem le, meg a nevek is beszédesek voltak.) Első körben találtam 37, szkripttel is rendelkező egyedi formot, szanaszét a rendszerben. (Később kiderült, hogy ennél jóval több van, de ekkor már mindegy volt.) Ezeket átbogarásztam és örömmel tapasztaltam, hogy semmi eseményfigyelés sincs bennük, egyszerű vbscript és MAPI.

Csakhogy. Két dolog is nyugtalanított.

  • A helyi emberünk szerint, ha leáll az Event Service, akkor összedől a workflow is. Márpedig ha minden az átnézett formok alapján működik, akkor nem kellene, hogy függjön a szolgáltatástól.
  • A formok alapján rekonstruáltam a folyamatot, majd összevetettem a valós folyamatokkal, mármint azokkal, melyeket a felhasználók tapasztalnak. És volt egy lyuk. Egész egyszerűen voltak olyan lépések, melyek semmelyik formban nem szerepeltek, szabály sem volt rájuk, mégis megtörténtek. Ráadásul ennek a hiányzó folyamatdarabnak erősen eseményvezérelt szaga volt. Csak hát… nem volt custom sink.

Mese nincs, meg kell nézni megint az éles rendszert. Az egyik nap bementem az ügyfélhez, és az egyik informatikus kollégájukkal elkezdtük vizsgálgatni az éles rendszert. Naná, hogy lefagyott. (Fogalmazzunk úgy, hogy nem vagyok túl népszerű ember arrafelé.) De mielőtt kinyírtuk volna, találtam valami teljesen meglepőt. Az ő Outlookjában a Public Folderek tulajdonságlapján volt egy plusz fül, Agents néven. És amögött szkriptek voltak. Rengeteg. Mármint rengeteg foldernél egy-egy szkript.

Legalább annyira zavarban voltam, mint Pinokkió anyák napján. Mi ez???

Utánaolvastam. Aztán a fejemhez kaptam. Dinoszaurusz: event szkript.

Kitérő.
Talán az 5.0, talán az 5.5 Exchange-ben debütált, valamikor 1997-98 környékén az Event Service. (Nem biztos, hogy pontosan emlékszem, cefet régen volt.) Egyértelműen Lotus Notes behatásra: az MS is szerette volna, ha a levelek mozgására lehetne valami folyamatot építeni. A beavatkozási lehetőség szkriptek segítségével történt, ezek voltak az event szkriptek. Egyszerűen megírtuk a szkriptet – figyelve benne egy bizonyos eseményt, pl. új elem érkezését a folderbe, aztán mellétettük a hozzá kapcsolódó akciót – majd ezt a szkriptet a folder Agents fülén beadtuk. Itt még voltak olyan finomságok, hogy magát a szkript futását is lehetett állítgatni. Ez az elképzelés nem jött be, ehelyett vezették be az Exchange 2000-ben a sinkeket, de kompatibilitási okokból a szkripteket is megtartották, egészen a 2003-as verzióig.
Kitérő vége.

Azaz nekem nem 10 évvel ezelőtti technológiát kellett felderítenem, hanem 15 évvel ezelőttit. Ja, hogy a tesztrendszerben miért nem láttam ezt a fület? Mert nem mindig látszik. Csak, ha megfelelő (Atyauristens) jogosultsággal lépünk be és az Outlookban nem cachelt a profilunk.

Oké. Nézzük. Rögtön az első vizsgált szkriptben ott figyelt a Folder_OnMessageCreated() függvény, azaz a custom script megrántotta a Scripting Agent COM objektumot, mely viszont rendszeresen rángatja a CDO-t, illetve azon keresztül az Event Service-t. Melyik CDO-t? Itt már elbizonytalanodtam. Oké, az 5.5 esetében ez nem volt kérdés, akkor az 1.1-es volt. Mivel a 2003 alatt is megy, így valószínűleg elboldogul az 1.2x változattal is. Vagy ott már a CDOWF kell neki? Hiszen mi más miatt lenne az ide feltelepítve? De itt már megint zavarban vagyok, mert mintha a CDOWF-et nem lehetne direktben piszkálni, hanem a benne lévő sinket kellene hivogatni saját alkalmazásból, melynek viszont látszódnia kellene a Component Services-ben is. Talán. Másfelől, ha a sima CDO 1.2-t használja, akkor is gáz van, mert a 2007-ben már az sincs benne. Viszont állítólag fel lehet rá telepíteni. Ilyet láttam már, a T-online szakértője szenvedett véresen hetekig, mert a Onebridge nem tudott együttműködni az Exchange 2007-tel, még azután sem, miután feltettük a szerverre a Onebridge által kötelezően igényelt CDO 1.21-et. Végül a CDO1.2-nek valamilyen korábbi, azóta már nem beszerezhető változatával oldották meg, ha jól emlékszem. De legyen. És akkor mi van? Mennek-e az 1997-es event szkriptek a 2007-es Exchange-en? Amikor már az utódjának tekinthető sink technológia egyik felét is visszavonták? Amikor már a szkriptelés Powershellből megy? A neten semmit sem találtam, egy-két bizonytalan fórumbejegyzéseken kívül. Egyszerűen ez a két fogalom – event script és Exchange 2007 – nem szerepelnek egy lapon.
Szóval tipródtam egy csomót, aztán egyszer csak megtaláltam a választ:

Event service
No longer available. Retain a computer that is running Exchange 2000/2003 in the Exchange 2007 organization if you need this functionality.

Na, ezzel a megoldással csak adnánk egy pofont a szarnak. Mixelt 2003/2007 rendszer üzemeltetése önmagában is nehézkes, de egy ilyen egyedi, átláthatatlan workflow-val együtt kezelhetetlen rémálom lenne, miközben semmit sem vinne előre, mert a leginkább erőforrásigényes, leginkább sérülékeny folyamat továbbra is a meglévő, harmatgyenge 2003-as szerveren futna.
Verdikt: a szerver kurvára nem upgradelhető.

Ez már nem is történelem, hanem mitológia.

ps.
Hangulati aláfestésként egy Dilbert rajz.

AntiSpam Update

Van egy dolog, ami már jó ideje bosszant.

Az Exchange 2007/2010 lehetőséget biztosít arra, hogy a Hub Transport szerveren feltelepísük a Microsoft AntiSpam agent-jeit. Ezzel kapunk egy jól működő, nagy tudású spam szűrő infrastruktúrát.

Ez ugyan nem annyira hatékony, mint a ForeFront for Exchange, továbbá nincs benne vírusirtó, viszont ingyen van.

Amikor ez a lehetőség először megjelent az Exchange 2007-ben, akkor lehetőségünk volt arra, hogy a hozzá tartozó definíciós fájlokat automatikusan frissítsük (Ez a ForeFront nélkül 3 hetente történt). Ez a lehetőség egy adott ponton megszűnt. Pontosabban, ha nincs ForeFrontunk akkor az Exchange maga nem frissít, hanem ezt a Windows Update teszi meg helyette.

Ezzel viszont gond van. Én magam részéről szerveren sosem kapcsolom be a frissítések automatikus telepítését (csak az automatikus letöltést), mert a folyamatos üzem miatt az nem elfogadható, hogy a szerver újrainduljon, amikor az update-nek ehhez van kedve, ráadásul bizonyos környezetekben a biztonsági frissítések csak tesztelés után kerülhetnek az éles rendszerbe. Ebből adódóan nem csak a biztonsági frissítések, hanem az AntiSpam definició sem települ automatikusan, aminek pedig kellene.

A fenti állapotot kezelendő írtam egy kis javascriptet ami feltelepíti az AntiSpam definíciós fájlt. És csak azt. Ha ezt a kis scriptet (cscript.exe SpamUpdate.js) berakjuk a Task Scheduler-be akkor a fenti problémát megoldottuk.

A script innen tölthető le.

Egysorosból többsoros

Aki rendszeresen Powershell környezetben tevékenykedik, annak ez az írás nem fog sok újdonságot tartalmazni. Nekem viszont meglepetés volt. Meg örülök is neki, hogy rátaláltam a trükkre.

Van valami, amit meg szeretnél csinálni egy csomó objektummal. A nevük lista formájában megvan egy txt fájlban. Tipikus szkript feladat, kell egy foreach ciklus, ebbe betoljuk valahogy a neveket és kész.
Igenám, de mi van, ha nem lehet egy parancsban megfogalmazni a ciklus magjában lévő tevékenységet? A szintakszis durván úgy szól, hogy foreach { }, ahol a kapcsos zárójelek közé kerül az elvégzendő tevékenység. Nekem viszont két parancsot kellett volna beletennem.
Az első próbálkozásra szószerint kiröhögött a PSH: a szkript blokkba megpróbáltam több szkript blokkot beleágyazni, valami ilyesformán: { {a} {b} }. A második próbálkozásom az volt, hogy megpróbáltam a két parancsot egybegyúrni, a PSH végülis pont erről híres, de sehogyan sem sikerült. Harmadikra nekiugrottam a guglinak, de vagy én felejtettem el, hogyan kell keresni, vagy senkit sem izgatott eddig a probléma.
Kénytelen voltam a saját eszemet használni. (A gugli korában. Szégyen.)

A feladatnak van egy korrekt megoldása, nem parancsot adok ki, hanem beleírom az egészet egy szkriptbe, majd lefuttatom. Ott egyszerűen új sort kell kezdeni minden parancsnak. De ehhez eszembe kellett volna jutnia, hogyan kell szkriptet futtatni. (Ja, nem mondtam, ez nem egy kényelmesen elvégzendő feladat volt, hanem egy hirtelen felmerült igény, tizenvalahány óra szopás munka után.) Annyira emlékeztem, hogy van valami trükközés, de arra már nem, hogy végülis mi. Alternatív megoldás lehetett volna az ISE használata, de abba meg az Exchange plugint kellett volna valahogy belegyógyítanom, és az sem ment fejből. Félretettem az elképzelést B tervnek, én pedig tovább gyötörtem a parancskámat.
Véletlenül jöttem rá a megoldásra. Még csak gépeltem be az egyik próbálkozást, amikor félrenyomtam, backspace helyett entert. És kaptam egy új promptot: >>. Szótlanul nézegettem a képernyőt, majd egy idő után bejelzett a mintafelismerő központom.

“egyik”,”másik” | foreach {
>>

Ez teljesen olyan, mintha szkriptfájlba írnám a parancsot! Próbaképpen beírtam az egyik parancsot, enter, jöhetett az új parancs, enter, zárás, üres enter… és már futott is.

“egyik”,”másik” | foreach {
>> $valtozo=bonyolult művelet
>> new-valami -identiy $_ -alias $valtozo -firlefranc
>>}
>>
_

Ne húzdd a szád, mondtam előre. Aki rengeteget piszkálja a PSH-t, annak ez triviális. Én már elég régóta inkább dizájnnal foglalkozom, mint operációval, nekem ez az interaktív szkript üzemmód újdonság volt. De tetszik.

Viszont, hogy legyen hozzáadott érték is, összeszedtem, mi kellett volna ahhoz, hogy szkriptet futtassak. Egyszerűen a shellből elnavigálok abba a könyvtárba, ahol a szkriptfájl van, majd így futtatom: .\myscript.ps1.

Ha pedig az ISE mellett döntöttem volna, akkor ezeket a parancsokat kellett volna elsőnek kiadnom:

  • Exchange 2007:
    Add-PSSnapin Microsoft.Exchange.Management.PowerShell.Admin
  • Exchange 2010:
    Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010

Powershell ISE

Jó. Van egy zsír új Exchange 2010 szerverünk. Piszkálhatjuk konzolból és piszkálhatjuk shellből. Remek.

Egészen addig, amíg el nem bökjük.

Én ugyanis egy hanyag mozdulattal lehúztam a két shortcut-ot a desktopra: ne kelljen keresgélnem, legyenek mindig kéznél. Csakhogy – a fene tudja, miért – de tönkrement a felhasználóm profilja. Nem gond, adminnal belép, profil töröl, felhasználó újra belép. Igenám… de a gyári shortcut-ok a profillal együtt elvesztek.

Ritka hülye helyzet. Van egy teljesen jól működő Exchange 2010 szervered… csak éppen nem férsz hozzá. Oké, a konzol nem probléma. Egyrészt egy üres MMC konzolba is fel lehet venni, másrészt a bin könyvtárban ott van a gyári konzol is. Viszont a konzol ebben a verzióban leginkább csak dekoráció: az igazán komoly dolgokhoz már a shell kell. Naná.

Hogyan is indul a 2007-es EMS? Elindítjuk a Powershell 1.0-át, úgy, hogy paraméterként megadjuk neki az Exchange Extension plugint. Akkor keressünk rá a neten, hogy 2010-nél mi a helyzet.
Szomorú. Azt írják, hogy ugyan el lehet indítani így is, de nem kapunk teljes értékű shellt.
De akkor hogyan indítsam?

Máshogy. Plugin dugaszolás helyett kapcsolódni kell. Találtam ugyanis egy másik írást arról, hogyan lehet rákapcsolódni egy Exchange 2010 számítógépre másik gépről, úgy, hogy megkapjam a shellt. Vad? Ne mondd már. Jó egy éve azt lehet mindenhol olvasni, hogy a Powershell 2.0 már engedni fogja a távoli hozzáférést. Ami esetleg vad lehet, az az, hogy a lokális gépről próbáljuk távoli eléréssel elérni a helyi powershellt. De ha jobban belegondolsz, ez sem olyan szokatlan, hiszen az előző cikkben láthattad, a gyári shortcut is ezt csinálta.

Tehát:

  • Elindítok egy üres powershell ablakot.
  • Beírom egymás után a következő két sort:
    $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://<FQDN of Exchange 2010 server>/PowerShell/ -Authentication Kerberos
    Import-PSSession $Session

Teszt: get-mailbox | fl name. Működik.
Na, ez már valami.

Csak éppen nehézkes és egyáltalán nem elegáns. Például a két parancsot be lehetne tenni egy szkriptbe és azt a szkriptet paraméterként átadni a powershell-nek. Meg lehet csinálni? Meg.

De létezik egy sokkal szebb és praktikusabb megoldás is. A Windows Server 2008 R2-nek, illetve a Windows 7-nek része az ún. Powershell ISE, azaz az Integrated Scripting Environment. (Úgy tudom, Windows 2003 szerverhez, Vistához és XP-hez meg letölthető.)

Mit is tud ez?

Nagyítás

Nagyjából ezt.

Kaptunk egy programozói környezetet. Van interaktív ablakunk (legalsó rész), ahová be tudunk gépelni parancsokat, melyeknek az eredménye a középső – output – ablakban jelenik meg. A felső blokkban pedig szkripteket írhatunk, méghozzá akár többet is, hiszen szemmel láthatóan a szkriptekhez tabok tartoznak. Emellett felhívnám még a figyelmet a debug menüpontra. (A helyzetérzékeny help-ről nem is beszélve.)

Hogyan lesz ebből Exchange Management Shell indító shortcut-unk? Hát úgy, hogy azt a bizonyos másfél sort kirakjuk egy ps1 fájlba, majd gyártunk egy shortcut-ot a Powershell ISE-nek, paraméterként meghíva a szkriptünket. Így az induláskor egyből be is töltődik, rögtön meg is lehet futtatni az F5-tel.

Feladat megoldva. Még mindig fogalmam sincs, mi rejtőzik valójában a gyári shell shortcut mögött – de már nem is érdekel. Van jobb.

Mielőtt még lezárnánk ezt a témát, egy gondolat erejéig érdemes elmeditálni, mit is csinál ez a másfélsoros szkript. Első sor: definiálunk egy változót. Második sor: nyitunk egy sessiont, melynek paraméterei az előzőleg definiált változóban vannak. Mik is ezek a paraméterek? Egy név, egy URI… de micsoda URI! Leírom, hogy nálam ez konkrétan hogyan nézett ki:
http:\\xch10-xch.xch10.tst\powershell
Azaz léteznie kell az Exchange szerveremen egy powershell nevű webszolgáltatásnak.

Nagyítás

És tényleg. Létezik. Tehát amikor egy sessiont nyitok, akkor ehhez a powershell webszolgáltatáshoz kapcsolódok- mely mögött a WinRM dübörög -, megkérem az Exchange modult, mindezt kerberos autentikációval.

Amellett, hogy szemmel láthatóan ez a felület sokkal praktikusabb, az ISE-nek van még egy óriási előnye. El is hangzott, de ha Windows7-et használsz, meg is győződhetsz róla: menjél be az Accessories/Powershell menübe – ott lesz az ISE. Ha belemásolod a fenti másfélsoros szkriptet – esetleg kipreparálod, hogy induláskor betöltődjön – akkor úgy tudod a munkaállomásodról menedzselni az Exchange 2010 szerveredet, hogy nem kellett hozzá semmiféle admin tools-t telepítened. Akár egy mezei felhasználó gépéről is tudsz adminkodni, ha éppen olyan szorult helyzetbe kerülsz.

Ja, hogy akkor majd tud a mezei felhasználó is? Nem, nem. Arra való az RBAC.

De erről majd legközelebb.

GUI-k, gombamódra

Kaján vigyorral figyelem, hogyan szaporodnak a GUI-k a Powershell körül. Félre ne értsd, a Powershell az egyik legjobb dolog, ami az utóbbi években történt az MS világban… csak azon vigyorgok, ahogy a felhasználói igények – csobogó patakként – megtalálják a rövidítéseket, az alacsonyabb partszakaszokat.

Most például Glenn dobott össze egy apró kis szkriptet. Semmi extra, egyszerűen csak csinált egy GUI-t, mely a spamfilter ügynökök naplójából összevadászgatja azt, hogy mi is történt konkrétan egy-egy levéllel. Nyilván ugyanezt meg lehetne csinálni egy egyszerű szövegszerkesztőből is… csak sokkal fapadosabban, sokkal kényelmetlenebbül.

Beindult az evolúció. Amire van igény, az előbb-utóbb el is fog készülni. Én például határozottan biztos vagyok benne, hogy hamarosan lesz egy olyan szkript, mely a régi message tracking vizuális formájában mutatja meg egy-egy legyűjtés eredményét – a jelenlegi ugyanis borzasztóan kényelmetlen.

Linkek:

A Powershell és a Windows Server 2008 Core

Ez bizony két különböző világ. A Powershell az .Net alapú, márpedig a Server Core alatt nem fut a .Net.

Két dolgot tehetünk:

  • Megvárjuk, amíg a Microsoft valamelyik Feature Pack-ba belerakja.
  • Hekk!

Dimitrij Sotnyikov az utóbbit választotta. Istenem, türelmetlen típus.

Habár le is lehetne fordítani az írását, de mégsem teszem. A lépések annyira egyértelműek, a megértésükhöz sincs szükség semmilyen Rigó utcai certifikációra.

Szóval az írás. Itt.

ps1. Bár Dimitrij bevallja, ő is ‘szerezte’ az ötletet, Alex Kibkalo blogjából. De valamiért mégsem azt az írást linkeltem be.

ps2. Az írás korábban készült, de már erre a blogra terveztem kirakni. Gondoltam, pár napot csak tudok vele várni. Hát, nem. Közben Kurbli is kirakta.

További faragások

Tesztelgettek egy kis Calendar-t, OWÁ-t, Blackberry-t, végül a helyi rendszergazda úgy döntött, hogy átmigrálja az összes postafiókot az új Exchange szerverre. Távolról – egyenesen Barcelonából – szurkoltam neki.
Amikor visszajöttem, alapvetően elégedett embereket találtam. Még működött a rendszer. Az utóbbi időben kicsit visszavettek az igényeikből.

De persze kisebb-nagyobb problémáik voltak.

Az Insource panaszkodott, hogy nem látják senkinek sem a foglaltsági információját. Meg hiába foglalnak le tárgyalókat, nem jelenik meg a foglalásuk. Ellentesztek. Mindenkinek működik. Kérdeztem a rendszergazdát, mi különleges lehet az Insource gépeken. Hosszas fejvakarás. Végül kinyögi, hogy ők külön címtárban vannak, mely össze van trustolva a cég címtárával. B+. Egy preparálatlan címtár. Pár óra vakaródzás nálam is, aztán szép lassan megszületett a megoldás: abban a tartományban nincs SCP objektum a címtárban, így nem érik el az Autodiscovery szolgáltatást. Outlook teszt, kibogarásztam, milyen DNS néven keresi a kliens a szolgáltatást. Rövid nyomozás, milyen DNS szervert is használnak a fiúk, aliasként felvettem benne a CAS-ra az autodiscovery nevet, egyből megjavult minden.

A gyerektartományba nemrég felvett úriember neve viszont nem jelenik meg a globális címlistában. Az istennek sem. Várunk vele, rugdosok mindent, nem és nem. Hazafelé már a fákat és a köveket is rugdosom, hátha az segít. (A mélypont és a lenyugvás.)
Elsőre persze a GAL-ra gyanakodtam. Végigböngésztem, mit is csinál és úgy véltem, túl bonyolult a szűrőfeltétel. Ki kellene cserélni. Szűrőcsere… mint a gépkocsikban. Végülis… elég lenne annyi kritérium, hogy legyen alias értéke az objektumnak. Nosza. Nem lehet. Ha már egyszer sikeresen módosítottad a GAL-t, akkor azt többször nem lehet. Miaf? Ez mekkora kreténség már…?
Beleástam magam a szakirodalomba. Utólag már azt mondom, megérte az a másfél nap kinlódás. Most már sokkal jobban átlátom, mi is zajlik a mélyben. (Olyannyira, hogy lett is belőle egy Technet cikk.) Végigmentem egyenként a láncon, begyorsítottam mindent, amit csak lehetett, végül megtaláltam azt is, hogy a leánytartományi RUS egy olyan GC-hez volt rendelve, melyet menetközben a rendszergazda – velem egyeztetve – megszűntetett, emiatt állt le az aszinkron frissítgetés. Ez is ki lett pipálva.

Aztán belefutottunk egy olyan szopásba, hogy van egy SQL rendszer, mely ékezetes karaktereket tartalmazó ASCII kódolású leveleket küld a leánytartomány Exchange2000 szerverére. Ott még ékezethelyesek a levelek. Aztán amint átjutnak az Exchange 2007 Mailbox szerverre, akkor teljes katyvasz lesz a levelekből. Az első gyanú a locale beállítás. Az Exchange2000 szervereken magyar és angol. Az Exchange2007-ben… default. A get-mailboxserver szerint ugyanis üres az érték. És nem is lehet módosítani, hiába próbáltam akár szöveges formában, akár decimális, akár hexadecimális formátumban beadni a magyar locale-t.
Tudomány elfogy. Bejelentettük az esetet a PSS-nek. Még mindig náluk van… de egyre inkább úgy tűnik, azt fogják mondani, hogy ez by default és RFC kompatibilis és alakítsam át úgy az SQL rendszert, hogy más karakterkészlettel menjen a levél. Az ügyfél baromira fog neki örülni. Eddig egyedül az Exchange2007 OWA jött be nekik, minden másra azt mondta, hogy sok kényelmetlenség semmiért.

Aztán egyszer csak váratlanul vége szakadt az őrületnek.
Menetközben beindult a többtelephelyes gyerektartomány tartományi migrációja, gyakorlatilag nélkülem. Ekkor már amit lehetett, azt helyi emberrel csináltatták meg – a rendszergazda meg már végigcsinált egy tartományi migrációt, látta, hogyan megy. Egyedül a DHCP okozhatott problémákat, erre megigértem, hogy majd utánanézek. Ehhez képest azért meglepődtem, hogy anélkül demotáltak egy DC-t, hogy nem szóltak, azt sem várták meg, utánanéztem-e a DHCP-nek. Aztán az üzemeltetési szempontból kritikus telephelyen egyszer csak megállt a DHCP szolgáltatás. Rövid időn belül mindenki szaladgált össze-vissza, mint pók a falon. Routermágusok vetették be magukat, eredmény nélkül. Már olyan embereket is felhívtak, akik anno a rendszert építették, csak azóta máshová mentek dolgozni. Gondoltam, én is megnézem, mit tehetnék. Rövid keresgélés után belebotlottam, hogy a telephelyi DC-re DHCP Relay lett telepítve, mely a demotált DC-re mutatott. Átállítottam az újra, beindult minden. Aztán kiderült, hogy a DNS áthelyezése sem igazán sikerült – és ekkor még igen finom voltam. Azt is rendbetettem. De már késő volt, ezt a bakit a cég már nem nyelte le. Csúnya veszekedések jöttek, indulatos ordibálások. Aztán az IT vezető írt egy körlevelet, miszerint az egész projekt műszaki tartalmáért én egyszemélyben vagyok a felelős, tehát tessék engem anyázni. Erre bepöccentem, én is írtam egy levelet, hogy a projektnek ebben a formában vége. Le fogok ülni, összeszedem, hogyan állunk, és aprólékosan meg fogom tervezni, hogyan lehet a rendszert egyenesbe tenni. Csak ez a tervezés tartott 3 hétig. Érdekes módon most már nem volt tiltakozás – pedig ekkor már negyedik hónapja(!) ment ez a projekt ilyen eszetlen tempóban.

Tanulság? Már itt is látszik. Az olcsójános technika megbosszulja magát. A durrbele-észnélkül-ügyesekvagytokfiúk_megtudjátokcsinálni mentalitás ekkora átalakításoknál nem működik. Ami több hónapos projekt, azt nem lehet hetekbe sűríteni, különösen úgy nem, hogy a tervezést hagyjuk el belőle. Ráadásul szakmailag ismeretlen terepen… Itt is látszott, még akkor is belefutottunk volna egy-egy nagyobb szopásba, ha mindent alaposan megtervezünk a rendelkezésre álló szakirodalom alapján. Ezért kell ismeretlen terepen külön időt hagyni laborkisérletre is – és az alapján kell írni a tervet. Persze nehéz akkor, ha stratégiai okból a munkát el kell vállalni, az ügyfél IT vezetője viszont nem érzékeli a munka nagyságát, nem tartja fontosnak a tervezést – aztán a végén persze mindent a külső cég nyakába varr. (Amiben persze meglehetősen groteszk módon _formálisan_ igaza van: a helyi rendszergazda és a tűzfalas ember valamikor az Ügyfél alkalmazásában álltak, aztán átkerültek hozzánk, a projekt idején teljes mellszélességgel éppen hozzánk tartoztak, de most, amikor ezt írom, már megint az Ügyfél alkalmazottai.)
Még valami. Nem tudom, ki mennyire figyelmesen olvasta el az írásokat… de talán akad egy-két ember, akiben felhorgadt valamiféle hiányérzet. Igen, sehol sem említettem meg egy nevet: azt, hogy projektmanager. Nem volt. Elfogyott. Gyakorlatilag mindkét cég úgy állt hozzá, hogy ez egy hipp-hopp upgrade, lekeverjük hamar. Én hiába küldözgettem mindkét irányba a jeleket, hogy ez így nem fasza, csak mosolygásokat kaptam: ügyes gyerek vagy, majd megoldod. Hát, nem. Kockafejűként nehéz ilyet beismernem, de egy bizonyos bonyolultság felett már szükség van dedikált PM-re. Ne a technikai embernek kelljen már a (fejben)tervezéssel meg az implemetálással küszködve még az Ügyféllel is harcolni.

Tulajdonképpen a történetnek itt vége is van. A projekt még megy, egész biztosan lesznek még benne izgalmas dolgok, de innentől már sínen vagyunk. Tervezés, döntés, implementálás – és ugyanez annyiszor, míg az átalakítás végére nem érünk. Ebből nem fogok engedni.
Ha már én lettem az egyszemélyi felelős.

Az erő velünk van

Na, ja. Csak nem mindegy, mennyire körülményes kezelni. A végén még a saját kezünket vágjuk le vele.

Nemrég füstölögtem néhány enyhén szürkét arról, hogy mennyire értelmetlennek tartom a Powershell (tudom, Exchange Management Shell, de már annyira rááll a szám) parancsok bemagolásszintű visszakérdezését vizsgán. Úgy látszik, nem csak én, hanem egy fejlesztő társaság is, akik megalkották a PowerGUI-t.

A tudásáról nagyjából képet alkothatunk, rögtön a telepítés elején.

Nagyítás

Jól látható, hogy alapvetően három területre koncentrál: Exchange 2007, Operation Manager 2007 és Network. Ezekhez szép színes grafikus felületet kapunk, ráadásként pedig egy Powershell szkript editort.

Nagyítás

A fenti kép egy kicsit olyan, mint az az állatorvosi ló. Igyekeztem úgy sarokba szorítani a programot, hogy lehetőleg minél többet áruljon el magáról. Éppen ezért direkte olyat kértem tőle, mely kimaradt az Exchange Management Console-ból: kértem egy statisztikát az egyik felhasználóm postafiókjáról. (EMS-ben ez ugye úgy nézne ki, hogy get-mailboxstatistics 25ezer paraméter.) Az akciópanelen látszik, hogy a képernyőkimenetet mindenféle formátumú fájlokba irányíthatjuk. Lenyitottam a Tools menüt, bemutatva, hogy a GUI-ból is meghívhatjuk a szkript editort – és természetesen ez igaz visszafelé is. Végül alul látható, két nyomógomb: ezek közül a ‘Powershell Code’ feliratú az eddigi tevékenységünket naplózza vissza, értelemszerűen PSH kódban.

Még egy érdekesség.

Nagyítás

Az ugye tiszta, hogy bármelyik kattogtatás végeredménye egy Powershell parancs vagy szkript lesz. Ezt a szkriptet az adott menüpont tulajdonságaként kérdezhetjük le. A fenti képen például a Computers, azaz számítógépek listájának szkriptje látható – mely PSH szkriptbe ágyazott ADSI lekérdezésekből áll.

Szóval GUI. De nehogy azt hidd, hogy ellene vagyok a szkript alapú menedzselésnek, isten ments. Határozottan örülök a dolgok ilyetén alakulásának – csak éppen elijeszt a hatalmas paraméterkupac, és a körülményes keresgetés. Ezért is örülök én inkább a csomaggal adott szkript editornak.

Nagyítás

Ehhez a képhez véleményem szerint nem szükséges semmilyen magyarázat.

És hogy mennyibe kerül? A program jelenleg tokkal-vonóval ingyenes (béta), köszönhetően a Quest Software támogatásának. Ami biztos, az az, hogy a szkript editor ingyenes is marad. Azaz… hajrá, irány kipróbálni. Ahogy Dimitrij mondta, ‘Notepad for Powershell’.

ps:
Mondjuk, azért érdekes hintapalinta ez:

  • Először elkészül a Powershell (leánykori nevén Monad).
  • Aztán elkészül az EMS modul, mely tulajdonképpen a Powershellbe beépülő snapin.
  • Utána az Exchange fejlesztőcsapat elkészít egy MMC3 snapin-t, mely gyakorlatilag egy varázslókkal sűrűn telepakolt grafikus felület a leggyakrabban használható EMS/Powershell parancsok végrehajtásához.
  • Végül jön egy csapat, aki elkészít egy grafikus felületet, mely tudja mindazt, melyet az Exchange fejlesztők – ki tudja, miért? – kihagytak az általuk gyártott GUI-ból. Nem mellékesen odatettek egy script editort, melynek segítségével tényleg felszabadíthatjuk agyunk azon területeit, melyet eddig a parancs paraméterek foglaltak le.

Jogos lehet a kérdés: akkor most hogyan is állunk a szkript vs. GUI fronton?

Hátbatámadás

Érdekes hibakeresési módszert olvastam Dave Goldman blogjában. Azt mondja, vannak olyan esetek, amikor a Powershell úgy fut lyukra, hogy semmilyen értelmezhető hibaüzenetet sem ad vissza. Én ugyan még nem találkoztam ilyennel, de hiszek neki.

– Ilyenkor nyúljunk vissza a gyökerekhez – javasolja. (Hogy ehhez mit szólnak a gyökerek, arról nem szól a fáma.) Végülis az egész Powershell .net alatt íródott, így a hibakódot el lehet kapni a System.Exceptions objektumon keresztül.

Nosza, csapjunk bele. Írjuk be a hibát okozó parancsot, regisztráljuk, hogy nem jött értelmezhető hibaüzenet, majd olvassuk ki a hibát:

  • $hiba = $error[0]

Utána pedig nézzük meg, mit mutatnak az egyes tulajdonságok. Pl:

  • $hiba.Exception.StackTrace
  • $hiba.Exception.InnerException
  • $hiba.Exception.InnerException.StackTrace

Majd ha még ez sem elég, akkor a kapott hibakódot betáplálhatjuk az err.exe programba és még több információval leszünk gazdagabbak.

Gondoltam, megnézem, hogy is néz ki ez a gyakorlatban. Mint írtam, én még nem tudtam olyan hibát produkálni, melyről ne kaptam volna vissza hibaüzenetet – de mi lenne, ha leellenőrizném, hogy tényleg jó-e a hibaüzenet? Be is írtam egyből, hogy
get-publicfolder -identity kiskutyafule

A következmények alább láthatóak:

Az err.exe kimenetele pedig itt:

Nálam átment a vizsgán.

Mikor léptél be utoljára?

Aki már egy-két évnél régebben van az IT üzemeltetési szakmában, kilométerekről megérzi, mikor akarja a főnöke felvetni neki, hogy ‘Te, milyen jó lenne, ha egy szkriptben legyűjtenéd, kik azok a felhasználók, akik egy hónapja nem léptek be a rendszerbe.’. Ilyenkor kell pánikszerűen kivenni az éves garantált szabadságot és megvárni, amíg magától kihúny a láng a vezéri koponyában.
Miért is? Hiszen ez tulajdonképpen egy érték a felhasználó objektum egyik tulajdonságán. Ki kell olvasni oszt jól van.
Lelkes padavanok bele is szoktak ebbe a hibába esni. Legyűjtik, boldogan leadják a listát. Aztán jön a pofára esés: a listával szembesített felhasználók egy idő után karóval felfegyverkezve szándékoznak elbeszélgetni a lista készítőjével.
Mi történhetett? Hát, például az, hogy ezt a bizonyos értéket a tartományvezérlők khmm… közösülnek replikálni. Azaz ha pontos értéket szeretnénk tudni, akkor a korrekt módszer az lenne, hogy a lekérdezés során letámadjuk az összes tartományvezérlőt, majd kiválasztjuk a legközelebbi dátumot.

Nos, ezzel már készen is lennénk… de azért jogosan horgad fel a népharag: mi az már, hogy egy objektum tulajdonsága nem replikálódik? Azt mondja erre a Microsoft, hogy ha ezt a tömérdek adatot sűrűn replikálnák, akkor belehalna a hálózat. Lehet… végül is lehet. De akkor is bosszantó, hogy nem bízzák ránk a döntést, hanem azt mondják, így van, és kész.
Tulajdonképpen nem mondják. Nézzük csak meg az alábbi képet:

Van egy tulajdonság a tartomány objektumon. Úgy hívják, hogy msDS-LogonTimeSynchronization. Alapértelmezetten üres, ekkor 14 naponta replikálódik az az érték, hogy egyes felhasználók mikor léptek be utoljára. Ha ide beírjuk, hogy 1, akkor ez az érték lecsökken egy napra.
Nem mondom, hogy innentől naprakészek leszünk – de azért ekkor már sokkal jobban megközelítjük a valóságot.
Sokkal jobban, mint azok a szerencsétlenek, akik Windows2000 tartományban tengetik az életüket. Nézzük csak meg, nekik milyen lehetőségeik vannak:

Ennyi. Semmi msDS-LogonTimeSynchronization. Marad az összes DC nyaggatása adsi szkriptekkel.

21

Annyi otthoni teendőm torlódott fel, hogy szószerint megbénultam az íróasztalom előtt. Ezt is kellene, azt is kellene, ez rohadt sürgős, na az meg aztán végképp… csak néztem a monitoromat, néztem… végül úgy döntöttem, hogy hagyom eluralkodni magamon az ösztöneimet és játszok egy kicsit.
Persze geek módra.
Barnának ma este mutattam egy ízelítőt a logikai folyamatok grafikus ábrázolási módjairól, megemlítve, hogy ilyesmi ábrák jelentik a számítógép programozásának az alapjait is. Aztán – már egyedül, magamban – elgondolkodtam, le tudnám-e skiccelni a huszonegyes kártyajáték modelljét. Persze, vágtam rá. Igazából le se kellett rajzolnom, pár perc alatt fejben összeraktam.
Utána jött az izgalom: félóra alatt le tudnám-e programozni ezt – demonstrációs céllal – akármelyik itthoni számítógépen? Emlékszem-e még ennyire a régi dolgaimból, bennem van-e még készség szinten valami programolás – és van-e még eszközöm ahhoz, hogy csak úgy összedobjak egy programot? (Ugye a C64 esetében nem volt gond. Korai – első 10 év – IT-s időmben mindig volt vagy Pascal, vagy Clipper a gépemen beélesítve, bármikor gyorsan kellett valamit csinálnom, egyből ment.)

Az utóbbi feltétel nem okozott komoly problémát: az eszköz természetesen egy átlagos gépen is adott, Excel ma már mindenhol van – és ahol Office van, ott VBScript is van, nem is rossz GUI-val. A programolással már elvoltam egy kicsit, már csak hiúságból is igyekeztem minél tisztábban, egyszerűbben megoldani a feladatot. Jól elvoltam, na.
A sürgős teendőim meg ennyit igazán várhatnak.

Végül itt van a program. Maga az Excel tábla is letölthető, a vbscript része meg alant olvasható.

Sub Macro1()

‘ Macro1 Macro
‘ Macro recorded 2006.11.06 by The Tiger of Wekerle

‘ Keyboard Shortcut: Ctrl+a

Dim i, lapom

Range(”B2:C24″).Select
Selection.ClearContents

i = 0
lapom = 0

Do While lapom < 16 And lapom < Cells(2, 1)
i = i + 1
lapom = lapom + (Int(10 * Rnd(1)) + 2)
Cells(1 + i, 2).Value = lapom
Loop

If Cells(2, 1) > 21 Then
Cells(1 + i, 3).Value = “Yeah, the smarter has won!”
Else
If Cells(1 + i, 2).Value < Cells(2, 1).Value Or Cells(1 + i, 2).Value > 21 Then
Cells(1 + i, 3).Value = “Your mother wears army boots”
Else
Cells(1 + i, 3).Value = “Yeah, the smarter has won!”
End If
End If

Range(”A2″).Select

End Sub

ps: A sorbehúzásokért elnézést, nem szoktam ilyen csúnyán forráskódot írni, de a WordPress kigyomlálja a space-ket.

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.

Requesting data from the Exchange Server

Valószínűleg több sorstársamnak is keserítette már meg az életét a fenti üzenet. Az Outlook kliens monoton homokórázik, a felhasználó csak ül, és a rendszergazdával karöltve szelíden bámulják a monitort.
Ashley Webb leírt egy történetet, ahol igen trükkösen kerítették be ezt a vadat.

Megjegyzés: a sztori – sajnos – nem egy univerzális módszer a probléma megszüntetésére. Csak érdekes megoldás egy szituációra.

Arról volt tehát szó, hogy a klienseknél teljesen sztochasztikusan bejött ez a hiba, miközben az Exchange szerver összes lényeges teljesítménymutatója teljesen rendben volt. (Innentől speciális a történet; a jelenséget ugyanis általában valamilyen szerveroldali/hálózati szűk keresztmetszet okozza.)
Webb szerette volna, ha a homokórázás alatt le tudja menteni az Information Store és a System Attendant által használt memóriatartalmakat (ADPlus.vbs), de ennek igen komoly akadálya volt a véletlenszerű előfordulás. Egész nap csak nem ülhet ott egy biorobot a szerver előtt, a telefonra koncentrálva…
Viszont rájöttek, hogy van egy mutató (Average RPC Latency), mely felugrik, ha bekövetkezik a hiba. Ez jó, mert a permormance monitorban rátettek egy alertet erre a mutatóra, mely egy küszöb átlépésekor automatikusan elindított egy programot – az ADPlus.vbs-t.
79 példányban. Ugyanis a dump elég hosszú ideig tartott, közben pedig az érték többször is leesett, majd visszaugrott. Itt egy garázsszagú buhera következett, összedobtak egy parancsfájlt, ez úgy indult, hogy megvizsgálta egy bizonyos txt fájl létezését: ha nem létezett, akkor létrehozta, majd futott tovább; ha létezett, akkor a szkript megállt.
És ennyi. Megszerezték a kívánatos memóriatartalmat.
A módszernek volt egy apró mellékhatása: a dump igen erőforrásigényes művelet, rendesen leterhelte az Exchange szervert. Amíg futott, addig nem is volt ideje kiszolgálni a klienseket.
Mit csinált helyette? Úgy van, kiszórta nekik is a címben szereplő üzenetet.:-)

[Update]
Benne volt a levegőben. Ha az Exchange csapat egyik tagja csak mellékesen is megemlít egy ennyire összetett és nehezen kezelhető hibát, biztosra lehet fogadni, hogy rengetegen követelnek majd részletes magyarázatot róla.
Nos, itt van a cikk, Nino Bilic tollából. Ez se rossz.