Text Log

Conto2.3 – Loggare con PowerShell

Come detto in fase di design [1], le logiche di ET andranno implementate in PowerShell script. Per chi non ha idea di che cosa si tratti niente paura: è semplicemente un linguaggio di scripting disponibile anzitutto su sistemi Microsoft (che lo ha sviluppato) ma installabile anche su Linux (non credo che abbia senso ma nel caso trovate qualche info qui [2]). L’idea è quella di avere un linguaggio un po’ più elaborato della semplice linea di comando mantenendo l’agilità e l’austerità della stessa.

Per cominciare a codificare in PowerShell vi serve davvero poco, praticamente solo un editor di testo. Io vi consiglio ad ogni modo di utilizzare Visual Studio Code [3] che è un editor gratuito, leggero e che supporta molti linguaggi di programmazione e dunque è in grado di supportarvi in maniera efficiente e anche di fornirvi una modalità debug che vi aiuta nel troubleshooting.

Tornando al nostro obbiettivo: è fondamentale definire una modalità per loggare, sia a schermo che su file le azioni effettuate. Per farlo creeremo una funzione ad-hoc chiamata WriteLog che avrà il doppio compito di scrivere su file ed a schermo le info che verranno passate.

  • La scrittura a schermo sarà effettuata tramite il comando Write-Host “stringa da scrivere”
  • La scrittura su file avverrà attraverso Add-content File -value “stringa da scrivere”

Inoltre nella scrittura su file aggiungiamo anche un timestamp che dica quando quel log è stato scritto.

function WriteLog
{
    Param (
       [Parameter(Mandatory)]    
       [string]$LogString
    )

    $Stamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss")
    $LogMessage = "$Stamp - $LogString"
    Add-content $LogFile -value $LogMessage
    Write-Host $LogString -ForegroundColor White
}

Attenzione alla prima riga dove c’è la scritta Param: questo indica che tra parentesi si trovano i parametri che si possono passare alla funzione. Nel nostro caso è la stringa da loggare che, come vedete ha una dicitura Mandatory perché non avrebbe senso chiamare un log senza un messaggio da loggare.

Proviamo dunque ad invocare la funzione con un valore di test

WriteLog "Text to write"

Eseguendo lo script da linea di comando (oppure in debug dall’IDE di Visual Studio Code) ci troveremo a schermo esattamente la scritta che volevamo.

Esempio di WriteLog

Questo però non è sufficiente a scrivere su file perché in effetti dobbiamo in qualche modo definire qual’è il file da scrivere. Per farlo definiamolo come variabile il nome di un file generico da collocare nella stessa cartella del file Powershell.

$myDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$Logfile = "$myDir\log_$($env:computername)_$((Get-Date).toString("yyyyMMdd_HHmmss")).log"

La prima riga memorizza in $myDir il path relativo della cartella corrente. La seconda invece definisce il path del file di log aggiungendo il nome della macchina fisica aggiungendo un timestamp per evitare problemi di sovrascrittura generando di fatto un nuovo file di log ad ogni run. Se ora rilanciamo lo script troveremo un file di log nella cartella con questo contenuto

File di log generato
Contenuto del file di log

Una cosa molto interessante di PowerShell è come sia semplice comporre delle stringhe sfruttando i valori delle variabili: $LogMessage = “$Stamp – $LogString” semplicemente introduce i valori delle variabili nel testo senza altri comandi. Davvero veloce e pratico.

Ricapitolando: abbiamo creato una prima versione del nostro PowerShell script che in questo momento logga su file ed a schermo un testo. Il dettaglio dello script lo trovate sotto. Per maggior facilità di lettura la funzione WriteLog è dichiarata nella prima parte dello script mentre verrà richiamata nella seconda parte dello script. Non è una necessità, lo script funziona uguale anche se la funzione è dichiarata a valle, è semplicemente una convenzione mia.

#begin FUNCTIONS
function WriteLog
{
    Param (
        [Parameter(Mandatory)]    
        [string]$LogString
    )
    $Stamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss")
    $LogMessage = "$Stamp - $LogString"
    Add-content $LogFile -value $LogMessage
    Write-Host $LogString -ForegroundColor White
}

#end FUNCTIONS

# Get the current Directory
$myDir = Split-Path -Parent $MyInvocation.MyCommand.Path
#Set the file log name
$Logfile = "$myDir\log_$($env:computername)_$((Get-Date).toString("yyyyMMdd_HHmmss")).log"

WriteLog "Text to write"

Trovate qui [4] lo zip con il file per provare a vostra volta.

[1] https://www.beren.it/2021/12/30/conto2-3-il-design/

[2] https://docs.microsoft.com/it-it/powershell/scripting/install/installing-powershell-on-linux?view=powershell-7.2

[3] https://code.visualstudio.com/download

[4] https://www.beren.it/wp-content/uploads/2022/01/CONTO2.3-01.zip