giovedì 14 luglio 2011

5up3rH4ck3r13n4! - Lo Scriptomane - livello AVANZATO

5up3rH4ck3r13n4!
...
...
Ho Vinto!
Bene signori e signore, ho vinto ancora.

Un po’ di storia:
Microsoft Exchange Server è lo strumento di messaging e collaborazione che rappresenta lo stato dell’ arte per quanto riguarda posta elettronica, calendario, documentazione, to-do e contatti .
In azienda siamo i fortunati possessori di un’edizione 2003 standard SP2. Edizione che fu molto fortunata per Microsoft, sia per Exchange che per Windows Server. Infatti introduceva una vasta serie di nuove possibilità diminuendo la complessità del management e presentando console molto più unificate.

Il Caso:
Mi è stato richiesto di creare un sistema automatizzato per la prenotazione delle sale riunione….
Detto fatto! Creo degli utenti – risorsa, con i nomi delle sale riunione, e li configuro come da documentazione Microsoft in merito.
Quando un utente deve prenotare una sala riunione, non deve fare altro che “invitarla”, ma non come partecipante, come “risorsa” appunto.
L’account delle sale riunione accetterà automaticamente appuntamenti che non siano in conflitto con altri, diversamente li rifiuterà.
Inoltre è possibile vedere la disponibilità della sala in modalità pianificazione



senza per questo dover avere accesso ai dettagli degli eventi altrui. Se non si è partecipanti invitati od organizzatori di un evento, si vedrà soltanto la “barretta” che indica che sarà in corso una riunione, in quel luogo ed in quel momento.
Caratteristica eccezionale di Exchange, vero? Ma….

Il Problema:
dopo pochissimi giorni dalla loro creazione le sale riunione hanno smesso di aggiornare le informazioni di disponibilità (free/busy informations), che in exchange 2003 vengono stoccate in una public folder (una cartella condivisa) sotto forma di “messaggio speciale”.
Quindi le persone non potevano verificare la disponibilità della sala prima della pianificazione ed inoltre la sala accettava RICHIESTE IN CONFLITTO!

Il tutto veniva visualizzato come in figura:

Come potete notare, la sala riunione convocata NON MOSTRA le informazioni di disponibilità. Quando la sala si trova in questo stato, è possibile anche che riunioni vengano prenotate contemporaneamente da più persone nella stessa sala... Con risultato catastrofico...

Dopo varie indagini (e grazie anche alle risposte sul forum di Microsoft), sono giunto alla seguente conclusione:  non vengono aggiornate perché l’utente della sala riunione non effettua modifiche DI PERSONA al calendario.
Voi direte: ma come?!?!?! Ma se è appositamente previsto che sia un utente NON usato da nessuno!
Ebbene è così.


La paventata soluzione:
Microsoft ha rilasciato una "mezza soluzione" a questo link:
http://support.microsoft.com/kb/294282/en-us

Secondo me è una "mezza soluzione" perchè richiedono l'apertura di una chiamata a pagamento (partono da 300 euro circa) per inviare le utility....

Queste utility, come dice anche la descrizione che trovate nella KB di Microsoft (link sopra), non fanno altro che accedere al calendario dell'utente ed inserire degli appuntamenti fittizi.
Una volta capito di cosa si trattava ho deciso di farmelo da me. (chi fa da se fa per tre).



La vera soluzione: 
REQUISITI:

Vi basta avere un PC o un server sempre accesi, durante l'orario di lavoro, con un utente che abbia accesso completo alle cassette delle sale riunioni ed abbia una qualsiasi versione di outlook dal 2003 al 2010...
Impostate diversi profili per l'accesso alle diverse cassette postali (anche se il profilo di default può restare immutato, quindi questi risultano "nascosti") et voilà.
Nel mio caso poteva andare bene il PC di un responsabile del personale o della segreteria generale, ma ho outlook anche su un server, quindi...
Eccolo qui, il mio script, nudo e libero, per tutti voi:

########### file freeBusyUpdate.vbs ###############
Sub CreaAppto(strProfileName)
 Dim objOL
 Dim objAppt
 Const olAppointmentItem = 1
 Const olMeeting = 1
 Const olFree = 0

Set objOL = CreateObject("Outlook.Application")
Set objNamespace = objOL.GetNamespace("MAPI")
    objNamespace.Logon strProfileName,, False, True
 Set objAppt = objOL.CreateItem(olAppointmentItem)

objAppt.Subject = "Appuntamento di sistema by Diego"
objAppt.Start = Date + 1 + TimeValue("19:30:00")'domani alle 19:30
 objAppt.Duration = 1
 objAppt.Location = "DoveVuoi"
 objAppt.Body = "Questo appuntamento di un minuto creato alle 19:30, serve per aggiornare automaticamente le informazioni sulla disponibilità dei profili delle sale riunioni..."
 objAppt.ReminderMinutesBeforeStart = 1
 objAppt.BusyStatus = olFree
 objAppt.Save()
 WScript.Sleep 1000 'attendi un secondo
 objAppt.Delete() 'cancellalo
 Set objAppt = Nothing
 Set objOL = Nothing
 End Sub
 CreaAppto("salaRiunione1")
 CreaAppto("salaRiunione2")
 CreaAppto("salaRiunione3")
 CreaAppto("salaRiunione4")

########### FINE file freeBusyUpdate.vbs ###############


Ma commentiamolo insieme…
Sub CreaAppto(strProfileName)
 Dim objOL
 Dim objAppt
 Const olAppointmentItem = 1
 Const olMeeting = 1
 Const olFree = 0
^ qui dichiaro la funzione (Sub) che riceve un parametro stringa “strProfileName” che corrisponde al nome del profilo di outlook configurato con l’utenza della sala riunione corrispondente.

Set objOL = CreateObject("Outlook.Application")
Set objNamespace = objOL.GetNamespace("MAPI")
    objNamespace.Logon strProfileName,, False, True
^qui creo l’oggetto “outlook.Application” (in pratica apro outlook), Imposto la sessione MAPI (protocollo di collegamento tra outlook ed exchange), Mi loggo al profilo selezionato.



Set objAppt = objOL.CreateItem(olAppointmentItem)
objAppt.Subject = "Appuntamento di sistema by Diego"
objAppt.Start = Date + 1 + TimeValue("19:30:00")'domani alle 19:30
 objAppt.Duration = 1
 objAppt.Location = "DoveVuoi"
 objAppt.Body = "Questo appuntamento di un minuto creato alle 19:30, serve per aggiornare automaticamente le informazioni sulla disponibilità dei profili delle sale riunioni..."
 objAppt.ReminderMinutesBeforeStart = 1
 objAppt.BusyStatus = olFree
 objAppt.Save()
^ qui creo l’appuntamento, imposto l’oggetto, lo start time a Date+1 (cioè domani ) alle 19:30, imposto la durata a 1 minuto, metto la location, scrivo del testo nel corpo dell’evento, imposto il reminder ad un minuto prima di iniziare, metto che la sala deve essere vista come disponibile (olFree) durante il periodo e infine salvo l’evento.
WScript.Sleep 1000 'attendi un secondo
 objAppt.Delete() 'cancellalo
 Set objAppt = Nothing
 Set objOL = Nothing
 End Sub
 CreaAppto("salaRiunione1")
 CreaAppto("salaRiunione2")
 CreaAppto("salaRiunione3")
 CreaAppto("salaRiunione4")
^qui attendo un secondo (1000 millisec), cancello l’evento e chiudo le connessioni ed outlook. Poi chiudo la funzione.
Infine richiamo la funzione quattro volte, una per ogni cassetta postale risorsa, indicando il nome di ciascun profilo di outlook a cui ho associato i rispettivi account.


Ed ecco fatto, schedulatelo ogni due ore nell'orario di lavoro e non avrete più problemi!
Implementato da due settimane e non ho più visto l'errore, controllato ogni giorno!

Alla faccia degli script supersegreti del c@#[0. 
Yeah.


P.S. se vi capita di farci dei soldini o di risolvere problemi, magari dite che "avete un amico fikissimo, che scrive un blog fikissimo"...


Ciao!

3 commenti:

  1. Bel post, grazie della condivisione Diego!

    RispondiElimina
  2. Ciao, mi è capitato di testare e verificare questo script e non ho avuto fortuna, documentandomi ho riscontrato che il problema è l'autodiscovery di exchange che con le versione outlook 2013/2016

    RispondiElimina
    Risposte
    1. Ciao! Corretto, in Exchange dalla 2010 in avanti esiste una funzionalità apposita che lavora in modo diverso (e non ha più questi problemi).
      L'autodiscovery non so cosa centri, perchè in realtà nelle versioni successive esistono dei tipi di cassetta postale speciale "risorsa" (Room Mailbox e Equipment Mailbox, nella 2010, ad esempio) che consentono anche la configurazione del "resource booking attendant", una funzionalità che appunto permette l'auto accettazione in base agli impegni del calendario.

      Lo script che ho riportato qui, quindi, deve essere proprio inteso per risolvere quella specifica problematica su Exchange 2003.

      Magari puoi indicarmi il tuo problema, così posso vedere se ha una semplice soluzione... :-)

      Elimina

I commenti sono soggetti a moderazione, prima di essere pubblicati.

Qualsiasi contenuto illecito, immorale o che io ritenga (arbitrariamente) offensivo od inappropriato, verrà cancellato.