martedì 26 luglio 2011

Riorganizzare o rinominare i files immagine e MP3 con i dati EXIF e ID3 (e, ovviamente, leggere i dati EXIF e ID3) - Parte 1 - Lo Scriptomane - livello MEDIO

Qualche giorno fa, mi è stata fatta un'obiezione (peraltro legittima) da un amico: ma che c@#[o mi metti in copia conoscenza dei tuoi post sul blog, che io sono un grafico (per farla breve) ... posso apprezzare, capire il concetto, ma....

Caro Tiz, hai ragione!

Per questo ho deciso di pubblicare qualche script che abbia utilità comune, in modo da interessare anche chi non fa il sistemista di mestiere... .... e siccome ho tanti amici grafici e/o appassionati di fotografia....

Oggi parliamo di come leggere i dati EXIF delle immagini in una cartella e spostarle / rinominarle in base a questi dati.

I dati EXIF sono messi nelle proprietà delle immagini da TUTTE le fotocamere digitali oggi in commercio ed includono dati MOLTO interessanti, come il tempo di posa, l'apertura del diaframma e addirittura possono contenere  la GEOLOCALIZZAZIONE dell'immagine, se la fotocamera o il telefono sono stati correttamente impostati.

Per visualizzarli in windows potete cliccare con il destro su una immagine e scegliere proprietà. Nella scheda Dettagli troverete le informazioni di cui vi ho parlato.

Pubblicherò qui TRE script (nella parte 1, parte 2 e parte 3 di questo multi-articolo succulento): uno che ottiene tutte le info di un file che abbiano qualche dato dalla "info 0" alla "info 500"***, uno che sposta le immagini in cartelle in base alla proprietà "DATA DI ESPOSIZIONE", l'ultimo le rinomina, includendo i dati di "tempo di esposizione" ed "apertura del diaframma". Sentitevi liberi di chiedere per qualsiasi modifica che vi è necessaria per le vostre esigenze....


*** lo script può facilmente essere reiterato per tutti i files di una cartella con un semplice batch con il comando FOR, che includerò qui.

lunedì 18 luglio 2011

VBScript: come tenere traccia dello spazio dischi su Windows Server 2003, 2008 e 2008 R2 - Lo Scriptomane - livello BASE

A volte ci si trova a chiedersi perchè un processo fallisca o a quale punto fallisca (esempio tipico: un piano di manutenzione di SQL server) oppure, per qualsiasi altro motivo, qual'è il momento esatto in cui si riempie un disco.

Altre volte, si vuole semplicemente monitorare la situazione dei dischi, tenendone traccia. Ad esempio quando si vuole calcolare la business growth per la stima della scalabilità del sistema di file server/s.

Per tutte queste ed altre necessità, è sufficiente un piccolo script, schedulato ad intervalli più o meno vicini, che permette di avere un log con data ed ora di ciascuna rilevazione.

In calce trovate lo script completo, basta copiarlo ed incollarlo in file di testo, salvandolo come .vbs



Ma vediamone insieme ciascun pezzo:

Option Explicit
Dim iSpc, strComputer, objWMIService
Dim fso, fsHandle, MyShell,LogFileName, colItems, objItem


DICHIARIAMO LA MODALITA' DI ESECUZIONE "STILE VB6""" " E LE VARIABILI INIZIALI


Set MyShell = CreateObject("Wscript.Shell")

CREIAMO UN OGGETTO SHELL (la tanto amata shell)

Set fso = Wscript.CreateObject("Scripting.FilesystemObject")

CREIAMO UN OGGETTO FILESYSTEM: CI SERVIRA' PER CREARE E SCRIVERE IL FILE DI LOG

LogFileName= MyShell.SpecialFolders("Desktop") & "\FreeSpace.txt"
set fsHandle = fso.OpenTextFile (LogFileName,8,True)

DEFINIAMO IL NOME DEL LOG, CHE VERRA' SALVATO SUL DESKTOP PER COMODITA'

strComputer = "."

IL COMPUTER E' IL LOCALE (.)
 
Set objWMIService = GetObject _
( "winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery _
("Select * From Win32_LogicalDisk Where DriveType = 3")

Creiamo le collections con le query WMI, ottenendo tanti oggetti disco quanti sono i dischi LOCALI (DriveType=3).

For Each objItem in colItems
 
iSpc = cDbl(iSpc) + cDbl(objItem.FreeSpace)
iSpc= iSpc/1024
iSpc= iSpc/1024
iSpc= iSpc/1024
iSpc= FormatNumber(iSpc,1)
fsHandle.Writeline Now & " -- " & objItem.DeviceID & " -- " & iSpc & " GB Spazio Libero"
 
Next

PER CIASCUNA VOCE:
  1. convertiamo il valore della proprietà FreeSpace in una variabile DOUBLE con cDbl
  2. lo dividiamo 3 volte per 1024 (1 GB = 1024 MB, 1 MB = 1024KB, 1KB = 1024 Bytes) perchè il valore fornito è in Bytes.
  3.  Lo formattiamo come intero
  4. lo scriviamo in una nuova linea con il valore della data e ora attuali (Now), la lettera (DeviceID) e lo spazio libero calcolato in GB.



fsHandle.Writeblanklines 1
fsHandle.close
set MyShell = Nothing
set fso = Nothing

Scriviamo una riga bianca, chiudiamo il file ed annulliamo gli oggetti, per liberare la memoria.



Ed eccolo qui, pronto per Voi:

################# INIZIO ####################

Option Explicit
Dim iSpc, strComputer, objWMIService
Dim fso, fsHandle, MyShell,LogFileName, colItems, objItem
Set MyShell = CreateObject("Wscript.Shell")
Set fso = Wscript.CreateObject("Scripting.FilesystemObject")
LogFileName= MyShell.SpecialFolders("Desktop") & "\FreeSpace.txt"
set fsHandle = fso.OpenTextFile (LogFileName,8,True)

strComputer = "."

Set objWMIService = GetObject _
( "winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery _
("Select * From Win32_LogicalDisk Where DriveType = 3")

For Each objItem in colItems
'recupera le info e converti da uint64
iSpc = cDbl(iSpc) + cDbl(objItem.FreeSpace)
iSpc= iSpc/1024
iSpc= iSpc/1024
iSpc= iSpc/1024
iSpc= FormatNumber(iSpc,1)
fsHandle.Writeline Now & " -- " & objItem.DeviceID & " -- " & iSpc & " GB Spazio Libero"
Next

fsHandle.Writeblanklines 1
fsHandle.close
set MyShell = Nothing
set fso = Nothing


############FINE ###############

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!