Introduction
Avec Exchange 2010, pour certains besoins bien spécifiques, il se peut que les cmdlets Powershell soit limitées. Cependant, il existe aussi les Exchanges Web Services. Bien entendu, quand on parle des Exchange Web Services, on pense au C# et à un développement complexe. Cependant, on n'oublie souvent que Powershell permet d'exécuter du C#.
Il sera donc question d'accéder aux EWS via Powershell. Il s'agit surtout d'une introduction car les possibilités de scripting sont infinies. L'exemple mis en œuvre dans cet article montrera comment accéder à un dossier bien spécifique pour le purger suivant les dates de réception des emails. Cela permettra entre autres de voir le langage AQS permettant la recherche d'objets dans une boîte aux lettres Exchange.
Prérequis
Avant toute chose, pour manipuler l'API Exchange Web Services, il est nécessaire d'installer le package correspondant sur le poste qui exécutera le script. Il est trouvable en suivant ce lien : http://www.microsoft.com/en-us/download/details.aspx?id=28952
Attention si vous utilisez, Exchange 2013, il faut prendre cette version :
http://www.microsoft.com/en-us/download/details.aspx?id=35371
Il sera ensuite nécessaire d'ajouter dans chacun des scripts qui sera réalisé la dll permettant d'interagir avec les Web Services. Pour rappel, cela se réalise via la commande Powershell Add-Type :
001 002 003
| Add-Type -path "C:\Program Files\Microsoft\Exchange\Web Services\1.2\Microsoft.Exchange.WebServices.dll"
|
AQS ou Advanced Query Syntax:
Le langage AQS permet de réaliser des recherches dans les objets d'une boîte aux lettres Exchange. Il est très simple à prendre en main.
Pour comprendre toutes les possibilités de ce langage voici le lien MSDN dédié :
http://msdn.microsoft.com/en-us/library/ee693615.aspx
Grâce à ce langage il va être possible de rechercher des éléments :
- par type (emails, réunions, notes, contacts, ...)
- par date (réception ou envoi)
- par propriété d'un email (champ from, to, cc, subject, body, ...)
L'exemple suivant permet de rechercher des emails ayant été reçu le 3 Septembre 2013 :
"Kind:email AND Received:03/09/2013"
On remarque l'opérateur AND qui permet de prendre en compte 2 propositions. Il en existe d'autres comme le OU (l'une ou l'autre des propositions) et le NOT (l'inverse d'une proposition).
Script commenté
Il s'agit ici d'un script où l'utilisateur se connecte à une boîte aux lettres sur laquelle il possède des droits et dont les messages du dossier nommé Personnel seront supprimées s'ils datent de plus de 30 jours. Aussi, pour chaque dossier, il affiche la taille de celui-ci en Ko. Cette dernière opération est aussi faisable via la commande EMS Get-MailboxFolderStatistics mais avec cette exemple nous n'aurons pas besoin d'installer ces outils mais seulement l'API EWS beaucoup plus légère.
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050 051 052 053 054 055 056 057 058 059 060 061 062 063 064 065 066 067 068 069 070 071 072
| #Mailbox à traiter $MailboxName = 'j.dupont@myenterprise.fr' # A installer avant : www.microsoft.com/en-us/download/details.aspx?id=28952 try{ Add-Type -path "C:\Program Files\Microsoft\Exchange\Web Services\1.2\Microsoft.Exchange.WebServices.dll" }catch{ } #On spécifie la version des web services $Version = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP2 $Service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService($version) #On utilise les credentials avec lesquels on est connecté $Service.UseDefaultCredentials = $true #On récupère la configuration Autodiscover pour se connecter à la BAL $Service.AutodiscoverUrl($MailboxName,{$true}) #On récupère l'ID du dossier $RootFolderID = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Root,$MailboxName) #On se connecte au dossier via la connexion que l'on a initialisé $RootFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($Service,$RootFolderID) #On limite le nombre de dossier à analyser à 1000 (sinon problème de throttling) $FolderView = New-Object Microsoft.Exchange.WebServices.Data.FolderView(1000) #On définit un ensemble de propriété à récupérer en même temps que nos dossiers $PropertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties) #On crée une propriété de type taille de dossier $SizeObject = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(3592,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Long) #On l'ajouter à notre vue de dossier afin que la taille soit aussi récupérée. $PropertySet.Add($SizeObject); $FolderView.PropertySet = $PropertySet; #On spécifie qu'on analyse l'intégralité de la hiérarchie $FolderView.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep #On calcule la date d'il y a 30 jours et on la met au format dd/MM/yyyy $DateOld = ((Get-Date).AddDays(-30)).ToString("dd/MM/yyyy") #On récupère tous les dossiers $Response = $RootFolder.FindFolders($FolderView) #Pour chaque dossier ForEach ($Folder in $Response.Folders) { $FolderSize = $null #Si la taille est disponible alors on l'export dans la variable $FolderSize if($Folder.TryGetProperty($SizeObject,[ref] $FolderSize)){ $FolderSizeValue = ([Int64]$FolderSize)/1000 #On affiche la taille du dossier $Message = "Le dossier " + $Folder.DisplayName + " a une taille de $FolderSizeValue Ko" Write-Host $Message }else{ $Message = "Taille du dossier " + $Folder.DisplayName +" introuvable." Write-host $Message } #On compare le display name avec la valeur recherchée if($Folder.DisplayName -eq "Personnel"){ #Si le dossier est bien Personnel alors on récupère tous les mails selon les critères de date définies $Items = $Folder.FindItems("Kind:email AND Received:<$DateOld",$ItemView) #Pour chaque email trouvée ForEach($Item in $Items){ #On le supprime définitivement (à décommenter pour que ce soit effectif) #$Item.Delete([Microsoft.Exchange.WebServices.Data.DeleteMode]::HardDelete) } } }
|
On remarque l’opérateur “<” (inférieur à) dans la requête AQS qui permet de spécifier tout ce qui se trouve avant cette date.
On peut accéder aux dossiers publics, modifier, supprimer, créer, tout type d'objet y compris des dossiers. Il est aussi possible de récupérer différentes informations comme la taille d'un dossier. Il est aussi possible d'analyser les pièces jointes pour supprimer celle dont l'extension est d'un certain type. Il est donc possible d'imaginer plein de scripts comme des tâches planifiées effectuant des traitement sur des boîtes aux lettres.