lunedì 3 settembre 2018

Invio di file excel personalizzato e protetto da password via mail ad un elenco di destinatari CSV

Ciao a tutti di nuovo.

Eccoci qui di nuovo a scrivere un articolo per cercare di automatizzare le cose noiose e tediose della "vita da sysadmin" quotidiana.... :-)

Nel precedente articolo ("Creare molti utenti di dominio in una volta sola da un elenco CSV / Excel") ho spiegato come sia possibile creare molte utenze partendo da un file comma-separated values (facilmente ottenibile da Excel).

Ovviamente queste credenziali vanno poi condivise in forma SICURA con l'utente... a maggior ragione se l'utente è delegato ad amministrare qualche aspetto della nostra rete (un server, un servizio/programma, un apparato, etc...)

Ma spesso non è "comodo" aspettare di vedersi fisicamente e bloccare le attività fino a quel giorno....

Nowadays (oggigiorno) le attività ICT vengono svolte sempre di più remotamente (es. via VPN) ed è quindi essenziale trovare un modo "quasi istantaneo" di condividere le credenziali in maniera sicura.

Un metodo largamente usato è quello di inviare un file crittografato con una password complessa, che viene poi dettata al telefono una volta sola (o magari scritta nella chat di una conference call).

  • Ciascun utente ottiene un file specifico con le proprie credenziali (something you own)
  • Tutti gli utenti di una determinata azienda (faccio l'esempio di consulenti) possono avere la stessa password di apertura del file crittografato (something you know)

Ovviamente, dovendo io creare 15 utenze, non avevo assolutamente voglia di creare 15 file crittografati a mano e nemmeno di dettare 15 password diverse a 15 persone in 15 telefonate...

Quindi ho creato uno script Powershell che, partendo dagli stessi files del precedente articolo:

  1. Apre un file excel "modello" (vedi la spiegazione in basso per uno screenshot su come è fatto)
  2. Scrive le credenziali (username e password) prese dai files usati per generare le utenze.
  3. Salva impostando una password sicura (quindi di fatto crittografando il file)
  4. Invia una mail a ciascun utente, usando il mio account di dominio, di cui mi chiede prontamente le credenziali in maniera sicura, allegando il suo file.



NOTA DI SICUREZZA: La crittografia di excel non è sempre sicura. Microsoft Stessa ci avvisa nel suo articolo: https://support.office.com/en-us/article/protect-an-excel-file-7359d4ae-7213-4ac2-b058-f75e9311b599 
In questo caso è comunque sicuro condividere le password poichè devono essere sostituite quanto prima. Di conseguenza, anche se qualcuno riuscisse a "craccare" il file, dopo aver avuto illecito accesso al messaggio.. probabilmente non riuscirebbe a farsene un granchè perché, nel tempo usato per craccare la password, il vero destinatario l'avrà già cambiata.
Fate le vostre considerazioni in base anche alle informazioni che dovete condividere.


Ecco cosa impareremo in questo articolo:

  1. Aprire e modificare un file excel con Powershell 
  2. Salvare un file excel con Powershell con password (crittografato)
  3. Inviare una mail con Powershell con autenticazione SMTP
  4. Inviare una mail con Powershell con allegato
  5. Ciclare su più file elenco CSV e far corrispondere (match) le informazioni, con Powershell 





Ecco lo script completo, da leggere considerando i CSV creati per l'articolo collegato


# definisce il percorso cartella del file di modello (e dove verranno salvate le copie)
$Model_path="C:\Users\DiegoC\Desktop\TMP\Private\SCRIPTOMANE\2018-08-27_ArticoloScriptomane_inviare_excel_personalizzati_con_password_via_mail\"
#definisce il nome del file excel da prendere come modello.
$model_fname="Modello_Consegna.xlsx"
#definisce il server da usare come server di posta in invio
$smtpSrv=""
#definisce la password con cui verranno cifrati i files excel.
$xlPwd="passwordCompl1c4t1551m4!"
# definisce il formato di salvataggio (standard di excel)
$xlFixedFormat = [Microsoft.Office.Interop.Excel.XlFileFormat]::xlWorkbookDefault
#becco le credenziali del mio utente per poter spedire. verranno usate per autenticarsi con il server mail
$mycredentials = Get-Credential

#importo i nomi e cognomi e le pw
$a = import-csv ($Model_path+"elencoUt.txt") -Delimiter ";" #cognome;nome;nomeSAM;descrizione
$b = import-csv ($Model_path+"elencoPW.txt") -Delimiter ";" #nomeSAM;password


# $a | select -first 1 | foreach { # si può usare questo per fare un test solo con il primo utente...
$a | foreach {
    $usrN=$_.nomeSAM
    $uPwd=($b | Where { $_.nomeSAM -eq $usrN }).password
   
    # write-host ($usrN+": "+$uPwd) # 2018-08-27 test OK

    $excel = New-Object -comobject Excel.Application
    $excel.visible = $false
    $excel.DisplayAlerts = $false
    $objWorkbook = $excel.Workbooks.Open($Model_path+$model_fname)
    $objWorksheet = $objWorkbook.Worksheets(1)
    $objWorksheet.Cells(10, 2).Value = $usrN
    $objWorksheet.Cells(10, 3).Value = $uPwd
    $Istafname=($Model_path+$_.Nome+"."+$_.Cognome+".xlsx")
    # $objWorkbook.SaveAs($Istafname,$null,$xlPwd) # errore... il secondo parametro con $null non va bene.
    $objWorkbook.SaveAs($Istafname,$xlFixedFormat,$xlPwd) # FUNZIONA!!
    $excel.Quit()
   
start-sleep -Seconds 1
    Send-MailMessage -smtpServer $smtpSrv -credential $mycredentials -from '' -to ($_.Nome+"."+$_.Cognome+"@") -subject 'Invio Credenziali i rete' -attachment $Istafname `
    -Body ("Buondi "+$_.Nome+", `ti invio le credenziali di rete.`n Per la password di apertura del file, ti prego di voler far riferimento a XXXXXX (a cui l'ho gia' detta) o di contattarmi via SMS al numero +39XXXXX, indicandomi il nome e cognome. Rispondero' con la Password via SMS.`n`nGrazie e buona giornata.`nDiego.")

}





Ed ecco le spiegazioni per ogni sezione dello script:

# definisce il percorso cartella del file di modello (e dove verranno salvate le copie)
$Model_path="C:\Users\DiegoC\Desktop\TMP\Private\SCRIPTOMANE\2018-08-27_ArticoloScriptomane_inviare_excel_personalizzati_con_password_via_mail\"
#definisce il nome del file excel da prendere come modello.
$model_fname="Modello_Consegna.xlsx"
#definisce il server da usare come server di posta in invio
$smtpSrv=""
#definisce la password con cui verranno cifrati i files excel.
$xlPwd="passwordCompl1c4t1551m4!"
# definisce il formato di salvataggio (standard di excel)
$xlFixedFormat = [Microsoft.Office.Interop.Excel.XlFileFormat]::xlWorkbookDefault
#becco le credenziali del mio utente per poter spedire. verranno usate per autenticarsi con il server mail
$mycredentials = Get-Credential

Qui abbiamo per ora solo definito:
  • il percorso del file di modello (e dei file crittografati che verranno salvati, ciascuno con il nome dell'utente)
  • il nome del modello Excel da aprire (e poi salvare con nome crittografato con password)
  • il nome host o IP del server smtp
  • la password che sarà usata per crittografare l'excel
  • il formato dell'excel (costante standard, serve per dopo)
  • le credenziali per l'accesso al server SMTP, ottenute mediante un prompt sicuro di immissione, di cui faccio uno screenshot qui:


#importo i nomi e cognomi e le pw
$a = import-csv ($Model_path+"elencoUt.txt") -Delimiter ";" #cognome;nome;nomeSAM;descrizione
$b = import-csv ($Model_path+"elencoPW.txt") -Delimiter ";" #nomeSAM;password

Qui importiamo l'elenco utenti con l'altro elenco collegato delle password



# $a | select -first 1 | foreach { # si può usare questo per fare un test solo con il primo utente...
$a | foreach {
    $usrN=$_.nomeSAM
    $uPwd=($b | Where { $_.nomeSAM -eq $usrN }).password
   
    # write-host ($usrN+": "+$uPwd) # 2018-08-27 test OK

    $excel = New-Object -comobject Excel.Application
    $excel.visible = $false
    $excel.DisplayAlerts = $false
    $objWorkbook = $excel.Workbooks.Open($Model_path+$model_fname)
    $objWorksheet = $objWorkbook.Worksheets(1)
    $objWorksheet.Cells(10, 2).Value = $usrN
    $objWorksheet.Cells(10, 3).Value = $uPwd
    $Istafname=($Model_path+$_.Nome+"."+$_.Cognome+".xlsx")
    # $objWorkbook.SaveAs($Istafname,$null,$xlPwd) # errore... il secondo parametro con $null non va bene.
    $objWorkbook.SaveAs($Istafname,$xlFixedFormat,$xlPwd) # FUNZIONA!!
    $excel.Quit()


Qui, per ogni utenza in $a:
  1. recupera username e password dai due elenchi (facendo corrispondere lo username con quello in $b)
  2. apri il modello excel in modalità invisibile e posizionati sul primo foglio (...Worksheets(1))
  3. imposta i valori delle celle con username e password (nel mio caso il modello ha i campi username e password compilati nelle celle B10 e C10, che sono rappresentati da Cells(10,2) e Cells (10,3) perchè le coordinate sono in formato riga,colonna)
  4. componi il nome file che avrà questo file specifico con il nome e cognome della persona che deve riceverlo
  5. salva il file con il nome creato e utilizzando la password definita in precedenza.


   
start-sleep -Seconds 1
    Send-MailMessage -smtpServer $smtpSrv -credential $mycredentials -from '' -to ($_.Nome+"."+$_.Cognome+"@") -subject 'Invio Credenziali i rete' -attachment $Istafname `
    -Body ("Buondi "+$_.Nome+", `ti invio le credenziali di rete.`n Per la password di apertura del file, ti prego di voler far riferimento a XXXXXX (a cui l'ho gia' detta) o di contattarmi via SMS al numero +39XXXXX, indicandomi il nome e cognome. Rispondero' con la Password via SMS.`n`nGrazie e buona giornata.`nDiego.")

}
  • aspetta 1 secondo (necessario perchè altrimenti il send-mailmessage potrebbe trovare il file ancora aperto)
  • invia la mail con 
    • i parametri specificati all'inizio dello script
    • le credenziali fornite in modo sicuro allo start dello script (con get-credential)
    • email del destinatario composta da nome.cognome@dominio (presi dagli elenchi)
    • l'allegato excel crittografato contenente le credenziali.

Nessun commento:

Posta un commento

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

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