Tagpowershell

Event Sink -> Transport Agent, vagy mégse

A Technet fórumon volt egy kérdés ami egy Outlook hibára vonatkozott (megosztott postafiókban a jogosult nem látja a privátnak jelölt levelet még akkor sem, ha ezt megengedtük neki). A környezet Exchange 2003. Egy megoldási javaslatként (vagyis inkább a hiba megkerüléseként) feldobtam, hogy írok egy Event Sink-et ami leveszi a megosztott postafiókba beeső levelekről a privát jelzést.

Útközben kiderült, hogy éppen Exchange 2007-re migrálnak. Ó, semmi gond, akkor nem Event Sink-et írunk, hanem Transport Agent-et. Vagy mégsem?

Az Exchange 2007-ben létezik a Transport Rule intézménye. Meg lehet oldani a fenti problémát ezzel?

Próbáljuk meg!

Itt van az a EMS Script ami a megoldást adja:

$DGOU = "test.local/Users"
$NoSensitiveDGName = "No Sensitive Message"
$NoSensitiveDGAccount = "nsdg"
New-DistributionGroup -Name $NoSensitiveDGName -OrganizationalUnit $DGOU -SAMAccountName $NoSensitiveDGAccount -Type "Distribution"
$condition = Get-TransportRulePredicate SentToMemberOf
$condition.Addresses = @(( Get-DistributionGroup $NoSensitiveDGName ))
$action = Get-TransportRuleAction RemoveHeader
$action.MessageHeader = "Sensitivity"
New-TransportRule -Name "RemoveSensitivity" -Conditions @($condition) -Action @($action) -Enabled: $true

Az eredeti feladatnál kicsit tovább mentem. a fenti script létrehoz egy disztribuciós listát. Aki ennek a listának a tagja lesz annak a bejövő leveleiről lekerül a privát jelzés (valamint a Personal és a Confidential is).

A fenti feladat kapcsán eszembe jutott egy régi Event Sink. Karsai Peti írta valamikor a távoli múltban. Ez a Sink képes Exchange 2003 alatt leszedni a levelekről az olvasási értesítőt, ami sokakat zavar.

Kicsit átírtam az előző EMS scriptet, így alkalmas lett olvasási értesítők eltávolítására. Természetesen ez is egy disztribúciós lista tagsággal kontrollálható:

$DGOU = "test.local/Users"
$NoReceiptDGName = "No Read Receipt"
$NoReceiptDGAccount = "nrr"
New-DistributionGroup -Name $NoReceiptDGName -OrganizationalUnit $DGOU -SAMAccountName $NoReceiptDGAccount -Type "Distribution"
$condition = Get-TransportRulePredicate SentToMemberOf
$condition.Addresses = @(( Get-DistributionGroup $NoSensitiveDGName ))
$action1 = Get-TransportRuleAction RemoveHeader
$action1.MessageHeader = "Disposition-Notification-To"
$action2 = Get-TransportRuleAction RemoveHeader
$action2.MessageHeader = "Read-Receipt-To"
New-TransportRule -Name "RemoveReadReceipt1" -Conditions @($condition) -Action @($action1) -Enabled: $true
New-TransportRule -Name "RemoveReadReceipt2" -Conditions @($condition) -Action @($action2) -Enabled: $true

Némi Import-Export

Nemrégiben két esetben is szükségem volt arra, hogy két Exchange között vigyek át AD adatokat. Ezekhez írtam néhány pici scriptet. Ezek nem általánosan használhatóak, szóval, akinek kell, az mindenképp ésszel kezelje őket. Mindkét esetben szeparált tartományokról volt szó, tehát még trust sincs köztük.

Az első páros Exchange 2003-ból visz át felhasználókat Exchange 2007-be:

Export (ezt csak úgy parancssorból):

csvde -u -r “(objectCategory=user)” -l “cn,sAMAccountName,sn,givenName,displayName,mail,proxyAddresses,company,department” -f c:\work\users.csv

Import (PowerShell, vagyhívjam EMS-nek?):

Import-Csv c:\work\users.csv | foreach -process
 {
  New-Mailbox -Name ($_.cn) -OrganizationalUnit $_.ou -UserPrincipalName ($_.cn + ‘@domain.local’) -Alias $_.cn -SamAccountName $_.samAccountName -FirstName $_.givenName -LastName $_.sn -Password (ConvertTo-SecureString -string $_.Password -asPlainText -force) -ResetPasswordOnNextLogon $false  -Database ‘Server\Mailbox Database’
  Set-User -Identity $_.cn -Company $_.Company -Department $_.Department -DisplayName $_.displayName
  Set-CASMailbox -Identity $_.cn -EmailAddresses $_.proxyAddresses
 }

A második csomag jóval egyszerűbb. Kontaktokat visz át két Exchange 2007 között:

Export (EMS):

Get-MailContact | Export-Csv c:\work\contacts.csv –NoTypeInformation –encoding UTF8

Imprt (EMS):

Import-Csv c:\work\contacts.csv | foreach -process { New-MailContact -Name ($_.Name) -ExternalEMailAddress ($_.ExternalEMailAddress) }

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.