Exchange-taken automatiseren met cmdlet extenstion agents

Door ralpje op maandag 7 oktober 2013 09:30 - Reacties (2)
Categorieën: Exchange, Powershell, Scripting, Windows, Views: 3.987

Er zijn dagen dat ik medelijden heb met mijn collega's. Niet omdat het werk vervelend is of omdat de koffie op kantoor slecht is, maar omdat ze mij als collega hebben. En dan met name omdat ik bij elke vraag om assistentie vraag: "heb je powershell al geopend?" ;)
In Server 2012 en Exchange 2013 blijkt eens te meer dat Powershell the way to go is. De grafische beheersmogelijkheden worden steeds verder uitgekleed en zijn, zeker in Exchange, al een tijdje niet meer dan een grafische schil om Powershell heen.
Toch zijn er zaken die in zowel Powershell als de EMC niet direct voor zich spreken. Eén van die dingen kwam ik afgelopen week weer tegen: Exchange retention policies en hoe deze op nieuwe mailboxen toegepast kunnen worden.

Een klant gebruikt Exchange server (in dit geval Exchange 2010 SP3) in combinatie met een softwarebased anti-spam pakket. Van oudsher is de organisatie gewend aan een 'spam'- of 'junk'mail folder in Outlook, waar de anti-spam software de verdachte mails in neerzet. De gebruiker kan vervolgens zelf beoordelen of de mail inderdaad spam is, of dat er een legitieme email per abuis als spam gemarkeerd is. Er is één nadeel: mensen checken de folder, lezen of verplaatsen de mail die ze nodig hebben en negeren de rest. De spamfolder wordt daarmee een vergaarbak van slechte emails die onnodig storage en backup consumeren maar natuurlijk eigenlijk gewoon verwijderd moeten worden.

De oplossing is relatief simpel: retention policies. Maak een retention tag voor de 'junk'folder, stel hem in op 'delete after 30 days' en maak vervolgens een retention policy die je op alle mailboxen kunt gaan toepassen.

Het daadwerkelijk toepassen op de mailboxen is in Powershell zo gepiept:

PowerShell:
1
get-mailbox -resultsize unlimited | foreach {set-mailbox $_.identity -retentionpolicy policy}



Zo simpel is het.... Maar de policy is nu alleen van toepassing op de bestaande mailboxen. Mailboxen die nieuw worden aangemaakt krijgen niet automatisch deze policy mee. Ook is het niet mogelijk om een default policy voor je Exchange-omgeving of mailboxdatabase in te stellen.
Ongeacht of je de EMC of Powershell gebruikt zal je dus bij het aanmaken van een mailbox expliciet moeten aangeven dat je deze policy wilt gebruiken.

En dát is dus waar de exchange cmdlet extension agents om de hoek komen kijken; in dit geval de scripting agent.
Exchange heeft een aantal 'extension agents', bijvoorbeeld voor management van het Offline Address Book. De scripting agent is één van deze in totaal zeven agents en is de enige die standaard nog niet is ingeschakeld.

De werking van deze agent is redelijk eenvoudig, maar toch is het vaak een onbekend of, wellicht beter, onderbelicht deel van Exchange. Na het activeren van de scripting agent wordt die agent elke keer aangeroepen als er een een cmdlet op de server uitgevoerd wordt. Dat gebeurt niet alleen bij cmdlets die direct van Powershell worden uitgevoerd, maar ook als ze worden uitgevoerd door de Exchange Management Console, Exchange services of Exchange Control Panel.
Als de agent wordt aangeroepen wordt er gecontroleerd of er scripts geconfigureerd zijn voor dat betreffende cmdlet. Dat is dus wat we gaan doen om te zorgen dat onze retention policy netjes op alle nieuwe mailboxen wordt toegepast.

Als eerste moeten we zorgen dat de scripting agent geactiveerd wordt. Dit is redelijk eenvoudig: in de <installation path>\V14\Bin\CmdletExtensionAgents folder staat een ScriptingAgentConfig.xml.sample. Door deze te hernoemen naar ScriptingAgentConfig.xml hebben we een config file voor de scripting agent. De agent zelf activeren we vervolgens vanuit Powershell:

PowerShell:
1
Enable-CmdletExtensionAgent "Scripting Agent"



Nu nog zorgen dat we het script laten doen wat we willen :) Laten we eerst naar het volledige script kijken, daarna breken we het in stukken om te zien wat het doet:

XML:
1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="utf-8" ?>
<Configuration version="1.0">
<Feature Name="Mailboxes" Cmdlets="New-Mailbox,Enable-Mailbox">
<ApiCall Name="OnComplete">
if($succeeded) {
$Name= $provisioningHandler.UserSpecifiedParameters["Alias"]
Set-Mailbox $Name -RetentionPolicy "Retention Policy"
}
</ApiCall>
</Feature>
</Configuration>



Het eerste dat opvalt is dat het eigenlijk geen script maar XML is. In de XML-file wordt gespecificeerd welke script in welke situatie moet worden uitgevoerd. Door deze opzet is het ook eenvoudig om meerdere zaken in één config-file op te nemen.

De eerste échte regels na het 'openen' van de XML-file geven aan dat deze actie moet worden uitgevoerd bij het aanmaken van nieuwe mailboxen of het mail-enablen van bestaande users.

XML:
1
2
<Feature Name="Mailboxes" Cmdlets="New-Mailbox,Enable-Mailbox">
<ApiCall Name="OnComplete">


Met andere woorden: bij het gebruik van new-mailbox of enable-mailbox moet iets gestart worden, en wel nadat de actie compleet uitgevoerd is. De 'feature name' tag mag je zelf invullen en is puur voor de overzichtelijkheid van je XML-file. Je kunt bijvoorbeeld blokken met zaken voor provisioning scheiden van scripts die je wilt starten als je een mailbox verwijdert.

In de volgende regels geven we aan wanneer er iets moet worden uitgevoerd en wat dat dan is:

XML:
1
2
3
4
if($succeeded) {
$Name= $provisioningHandler.UserSpecifiedParameters["Alias"]
Set-Mailbox $Name -RetentionPolicy "Retention Policy"
}



De variabele $name wordt eerst ingesteld, door de aangeroepen API, met de naam van de zojuist aangemaakt mailbox.
Vervolgens wordt een set-mailbox aangeroepen op de $name mailbox om de retention policy in te stellen.
In de script block, die wordt aangeven met de { en } symbolen, kun je reguliere powershell-code opnemen. Je kunt er echter ook voor kiezen om een externe .ps1-file met Powershell-scripts aan te roepen. Zeker als je veel gebruik gaat maken van de scripting agent en wat meer complexe code gaat gebruiken is dat bevorderlijk voor leesbaarheid van de config-file.

Aan het eind wordt het XML-document uiteraard weer netjes afgesloten.

De handeling die door de scripting agent wordt uitgevoerd zie je niet terug in (bijvoorbeeld) de Powershell-code die de EMC laat zien bij het aanmaken van de mailbox. Wel krijg je feedback in de wizard als de API call rondom de scripting agent niet goed kan worden uitgevoerd en een error geeft. In dat geval wordt de mailbox wel probleemloos aangemaakt, maar worden de extra acties vanuit de scripting agent niet doorgevoerd op de mailbox.
Als de scripting agent wel gewoon zonder problemen zijn werk kan doen, zal je direct na het aanmaken van de mailbox in de eigenschappen van de mailbox zien dat de retention policy actief is.

Je begrijpt dat je op deze manier veel zaken in Exchange kunt automatiseren. Het leukste is om hier in je testomgeving eens mee aan de slag te gaan, zodat je kunt zien wat er allemaal mogelijk is.

Voor de verbeelding nog een ander mooi voorbeeld van het gebruik van de agent:

XML:
1
2
3
4
5
6
7
8
<Feature Name="MailboxProvisioning" Cmdlets="remove-mailbox">
<ApiCall Name="validate">
if($succeeded)    {
$removedmailbox = $provisioningHandler.UserSpecifiedParameters["Name"]
New-MailboxExportRequest -Mailbox $removedmailbox -FilePath \\filserver\PSTFiles
}
</ApiCall>
</Feature>


In dit geval wordt de ApiCall 'validate' gebruikt. Bij het uitvoeren van een cmdlet checkt Exchange altijd eerst of het cmdlet valide is en of er genoeg informatie is om het cmdlet te starten. Als dit het geval is, wordt de scripting agent getriggerd. Dit gebeurt dan dus nog vóór het cmdlet daadwerkelijk wordt uitgevoerd. Wat het bovenstaande stuk code doet laat zich dus raden ;)

Laatste tip voordat je hiermee aan de slag gaat: in een multiserver omgeving moet je de scripting agent op elke exchange-server activeren en ook de xml-file op elke server beschikbaar hebben. Het makkelijkste is dan natuurlijk om die file simpelweg te kopiëren van de ene naar de andere server.

Meer informatie over de scripting agent vindt je (uiteraard) op Technet: http://technet.microsoft.com/en-us/library/dd297951.aspx

Volgende: Nieuw in Office 365: Multifactor Authentication 02-'14 Nieuw in Office 365: Multifactor Authentication
Volgende: Vind de nerds in je Exchange-omgeving 09-'13 Vind de nerds in je Exchange-omgeving

Reacties


Door Tweakers user MAX3400, maandag 7 oktober 2013 09:55

Kan je stukje Junk-afhandeling dit niet veel simpeler realiseren met MRM en Retention Tagging?

Oh, en dan even een vraagje over je laatste stukje XML; ondanks de vernieuwingen in recente Office-versies, doe je geen check op PST-size?

Door Tweakers user ralpje, maandag 7 oktober 2013 10:07

MAX3400 schreef op maandag 07 oktober 2013 @ 09:55:
Kan je stukje Junk-afhandeling dit niet veel simpeler realiseren met MRM en Retention Tagging?
Dit ís MRM en retention tagging ;) Het enige nadeel daarvan is dat je dus niet een standaard kunt opleggen voor je hele organisatie, je moet bij het aanmaken van de database expliciet opgeven welke retention policy je wilt gebruiken. Om te voorkomen dat dat vergeten wordt heb ik het op deze manier gescript.
Oh, en dan even een vraagje over je laatste stukje XML; ondanks de vernieuwingen in recente Office-versies, doe je geen check op PST-size?
Dat is natuurlijk afhankelijk van de maximale mailboxgrootte in je organisatie; als je dat enigszins op orde hebt hoef je die check niet extra te doen. Als dat niet zo is kun je die check uiteraard in je script verwerken.

Reageren is niet meer mogelijk