Recentemente sono stato da un cliente che aveva l’esigenza di poter cancellare una cartella (con lo stesso nome su tutte le caselle) e il suo contenuto, in maniera programmatica su tutti gli utenti della sua infrastruttura....

Mi chiedeva se era possibile fare ciò con Powershell, mi è subito venuto in mente il comando (export-mailbox) , ma purtroppo con questo comando riusciamo a cancellare tutti gli Item all’interno di una cartella, ma non la cartella stessa.

Ho ripensato ai tempi di Exchange 2003, ricordandomi che operazioni di questo tipo erano possibili sfruttando CDOEX e WebDav, e allora mi sono detto: “perchè non provare a capire come fare questo con i nuovi Exchange Web Services introdotti da Exchange 2007? ... ma cosa sono gli Exchange Web Services?

Gli Exchange Web Services (da ora EWS), sono stati introdotti in Exchange 2007 e non sono nient’altro che dei Soap-Based XML web services e che possono essere acceduti remotamente da qualsiasi sistema operativo e qualsiasi linguaggio che possa inviare richieste HTTPS. Gli EWS quindi combinano (e in Exchange 2010 sostituiscono...) tutte le funzionalità di CDOEX e WebDav (accesso a caselle, calendari, creazioni di workflow etc..etc...) e vengono infatti sfruttati da Outlook 2007 per recuperare alcune informazioni riguardanti il calendario (free/busy) e l’OOF, informazioni che le versioni vecchie di Outlook recuperavano dalle Public Folder.

Purtroppo per chi come me nasce come sistemista, interrogare gli EWS non è sicuramente intuitivo e semplice... ma ecco che in nostro aiuto arriva la Microsoft Exchange Web Services (EWS) Managed API!

L’EWS Managed API fornisce una interfaccia .NET all’EWS, facile da usare e soprattutto, come ogni libreria .NET, può essere utilizzata con Powershell. Questa sì che è un ottima notizia!!!

Vediamo quindi come sfruttare questa potente libreria per effettuare operazioni sul nostro Exchange.

Innanzitutto scaricate ed installate l’EWS Managed API (download). Ricordatevi che come prerequistito è necessaria la presenza di .NET Framework 3.5.

Ora Passiamo al codice. La prima cosa da fare è caricare la dll

$dllpath = "C:\Program Files\Microsoft\Exchange\Web Services\1.0\Microsoft.Exchange.WebServices.dll"
[void][Reflection.Assembly]::LoadFile($dllpath)

A questo punto creiamo un ExchangeService object, necessario per la connessione al nostro environment. Dobbiamo esplicitare la versione di Exchange alla quale ci stiamo collegando (nel mio caso Exchange 2007)

$service = new-object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2007_SP1)

Ora facciamo puntare il nostro oggetto all’ EWS


$uri=[system.URI] https://casservername/ews/exchange.asmx

$service.Url = $uri

Eventualmente potremo pensare di sfruttare l’Autodiscover per ricavarci direttamente l’url dell’EWS

$service.AutodiscoverUrl("<Indirizzo e-mail mailbox>")

Torniamo al nostro problema: vogliamo fare una ricerca di una folder all’interno di una mailbox per poi cancellarla.

Per prima cosa creamo un oggetto della seguente  classe

Microsoft.Exchange.WebServices.Data.FolderId 

che conterrà l’id della root folder della nostra mailbox

$folderid = new-object  Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$emailaddress)

Dove $emailaddress identifica la nostra mailbox.

Ci colleghiamo alla root folder

$FolderRoot = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid);

Impostiamo I dati necessari per la ricerca, creando un oggetto di tipo FolderView

$folderview = New-Object Microsoft.Exchange.WebServices.Data.FolderView(10000);

$folderview.Traversal = "Deep";

A questo punto sfruttando il metodo FindFolders, della seguente classe

Microsoft.Exchange.WebServices.Data.ExchangeService

$foldercoll = $service.FindFolders($folderid,$folderview)

La variabile $foldercoll conterrà tutte le folder della nostra mailbox, ora possiamo fare una ricerca per la folder da cancellare e la cancelliamo, sfruttando il metodo Delete della seguente classe di oggetti

Microsoft.Exchange.WebServices.Data.Folder

$foldercoll | foreach      {

        $iterfolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$_.id);

        If ($iterfolder.DisplayName -ceq “<NomeFolderDaCancellare>”                                 

                                   {

                                     $iterfolder.delete('harddelete')

                         }

Per maggiori informazioni Exchange Developer Forums, Exchange Developer Center, and Exchange Developer Blog .

Alla prossima.

Claudio