PI Services

Le blog des collaborateurs de PI Services

Interaction Powershell - Exchange Web Services

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.

EXCHANGE 2013 – Configurer “AutoReseed'” pour un DAG

AutoReseed est une fonction qui permet de restaurer rapidement la redondance des bases de données après une défaillance du disque. En cas de défaillance du disque, les copies de bases de données stockées sur celui-ci sont automatiquement réamorcées sur un disque de rechange sur le même serveur de banque d’information.

La mise en place de cette fonctionnalité repose sur trois points de montage (mount point) ainsi que de disposer de trois disques dur par serveur.

image

 

La structure des points de montage permet au répertoire C:\EXDB\DB01 et au répertoire C:\EXVOLS\Volume de présenter les mêmes données.

En cas de défaillance du disque E, le point de montage C:\EXDB\DB01 sera associé au disque F automatiquement.

clip_image002

La Configuration du D.A.G doit être adaptée.

Les attributs ci-dessous sont à paramétrer:

AutoDagDatabasesRootFolderPath : configure le chemin qui contient les bases à protéger. C:\EXDB dans notre cas.

Set-DatabaseAvailabilityGroup DAG-2013 –AutoDagDatabasesRootFolderPath « C:\EXDB »

AutoDagVolumesRootFolderPath : configure le chemin pour les points de montage des volumes des bases et du volume de « spare ». C:\EXVOLS dans notre cas.

Set-DatabaseAvailabilityGroup DAG-2013 –AutoDagVolumesRootFolderPath « C:\EXVOLS »

AutoDagDatabaseCopiesPerVolume: configure le nombre de copie de base par volume.

Set-DatabaseAvailabilityGroup DAG-2013 –AutoDagDataBaseCopiesPerVolume 1

clip_image004

Dans le répertoire EXVOLS créez deux dossiers

Volume1 sera le point de montage pour la base

Volume2 sera le point de montage pour le disque de « spare »

C:\EXVOLS\Volume1

C:\EXVOLS\Volume2

Ajoutez les points de montage

clip_image006

Cliquez sur Add

clip_image008

clip_image010

Idem pour Volume2 (à réaliser sur le second disque)

Ce qui donne

clip_image012

Mappez le dossier qui contiendra la base de données

C:\EXDB\DB01 au volume1

On peut utiliser MountVol.exe

clip_image014

Faire un point de montage sur le disque qui contient C:\EXVOLS\Volume1

clip_image016

clip_image018

On voit ce résultat

clip_image020

Créez  la structure de la base

clip_image022

ATTENTION : la structure doit être rigoureuse, elle doit respecter le nommage de la base.

Je l’ai subi à mes dépens…..

clip_image024

La création des dossiers dans EXDB\DB01 se reflète sur le point de montage EXVOLS\Volume1.

Créez une base avec une copie passive sur le second serveur du DAG.

Pour vérifier le mécanisme je vais simuler une défaillance du disque dur on le mettant “offline”

clip_image026

Lorsqu’on sélectionne “Volume1” l’accès est en échec.

clip_image028

La vérification de l’état de la base montre un statut “FailedAndSuspended”

clip_image030

Ne vous attentez pas à voir “AutoRessed” à réagir immédiatement comme la bascule qui a été quasiment immédiat du noeud actif vers le noeud passif, il faut attendre que le process MS Exchange Replication ait contrôlé le statut des bases, process qui s’effectue toutes les 15 mn.

clip_image032

On voit donc qu’après ce délai la banque sur le serveur revient en “Healthy”, puis le “ContentIndex” également. La défaillance est donc corrigée.

clip_image034

Regardons les évènements dans « Seeding »

clip_image036

Vous verrez de nombreux évènements liés au « seeding ».

clip_image038

Vérifiez les points de montages :

Pour rappel, avant :

clip_image039

Après le disque « failure »:

clip_image041

On constate que le répertoire C:\EXVOLS\DB01 est maintenant monté sur le disque F

Remplacez le disque défectueux.

Remarque : le répertoire C:\EXVOLS\Volume1 n’existe plus.

clip_image043

Recréez ce dossier

clip_image045

Recréez le point de montage

clip_image047

clip_image049

Vérifions avec MOUNTVOL

clip_image051

Le disque remplacé devient donc le disque de « SPARE »

Volume1 reste vide.

clip_image053

L’avantage de cette technologie est de réduire les couts concernant la mise en œuvre de technologie RAID, et permet également de ne pas déployer un troisième serveurs pour supporter une troisième copies de base, le volume de « spare » jouant ce rôle.

Certes dans cet exemple sachant qu’il faut trois disques et que l’on protège qu’une banque, l’intérêt est limité car on préfèrera sans doute mettre en œuvre du RAID.

L’intérêt économique sera mis en évidence lorsqu’on protègera plusieurs banques.