Chiunque lavori tutti i giorni in PowerShell prima o poi ha bisogno di recuperare un comando digitato in precedenza: una stringa di connessione o un parametro complesso. PowerShell tiene traccia di questi comandi in due modi distinti e complementari, che è utile conoscere entrambi perché rispondono a esigenze diverse.
Get-History: la cronologia della sessione corrente
Il primo strumento è il cmdlet Get-History (alias h o history), che restituisce l’elenco dei comandi eseguiti nella sessione di PowerShell attualmente aperta
Get-HistoryOgni voce include un Id progressivo e il testo del comando. Questo Id è utile perché permette di rieseguire un comando specifico senza doverlo riscrivere:
Invoke-History -Id 12Il limite di questa cronologia è che vive solo in memoria e all’interno del processo PowerShell corrente: chiudendo la finestra, l’elenco restituito da Get-History viene perso. Per impostazione predefinita PowerShell conserva fino a 4096 voci per sessione, un valore configurabile tramite la variabile $MaximumHistoryCount.
Il file persistente di PSReadLine
Dalla versione 5.0 di PowerShell in poi, il modulo PSReadLine (caricato di default) mantiene una cronologia persistente su disco, condivisa tra tutte le sessioni e che sopravvive alla chiusura del terminale. È quella che permette, ad esempio, di premere la freccia su in una finestra appena aperta e ritrovare comandi digitati giorni prima. Il percorso esatto del file dipende dalla configurazione corrente e si ottiene con
(Get-PSReadLineOption).HistorySavePath
# Output su Windows
%APPDATA%\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt
# Output su Linux
~/.local/share/powershell/PSReadLine/ConsoleHost_history.txtPoiché si tratta di un semplice file di testo, uno dei modi più immediati per consultarlo è leggerlo direttamente con Get-Content, magari filtrando il risultato
Get-Content (Get-PSReadLineOption).HistorySavePathPer cercare un comando specifico tra centinaia di righe è comodo combinarlo con Select-String
Get-Content (Get-PSReadLineOption).HistorySavePath | Select-String "docker"oppure, per vedere solo le ultime voci
Get-Content (Get-PSReadLineOption).HistorySavePath -Tail 20Cambiare il percorso del file di cronologia
Il percorso restituito da (Get-PSReadLineOption).HistorySavePath non è fisso: può essere modificato con Set-PSReadLineOption, ad esempio per spostare la cronologia su un altro disco.
Set-PSReadLineOption -HistorySavePath "D:\PSHistory\ConsoleHost_history.txt"Alcuni aspetti da tenere presenti
- La modifica vale solo per la sessione corrente. Per renderla permanente va inserita nel profilo di PowerShell ($PROFILE), altrimenti al riavvio del terminale il percorso torna a quello di default
- La cartella di destinazione deve esistere già perché PSReadLine non la crea automaticamente. Va quindi predisposta in anticipo
- Il file esistente non viene spostato automaticamente: cambiando percorso, PSReadLine inizia semplicemente a leggere e scrivere dal nuovo file. Per non perdere la cronologia già accumulata bisogna copiare manualmente il vecchio .txt nella nuova posizione prima di eseguire il comando
Rendere la modifica permanente con il profilo
$PROFILE è una variabile che punta a uno script eseguito automaticamente ad ogni avvio di PowerShell: è il posto giusto dove inserire il comando visto in precedenza per non doverlo ripetere ogni volta. Il file indicato da $PROFILE di solito non esiste ancora, e va creato la prima volta
Test-Path $PROFILE
New-Item -ItemType File -Path $PROFILE -ForceA quel punto si apre con un editor qualsiasi (notepad $PROFILE) e si aggiunge la riga con il percorso desiderato
Set-PSReadLineOption -HistorySavePath "D:\PSHistory\ConsoleHost_history.txt"Le modifiche diventano effettive riaprendo PowerShell, oppure subito eseguendo
. $PROFILEper ricaricare il profilo nella sessione corrente.
Perché due cronologie diverse
Get-History e il file di PSReadLine non sono la stessa cosa e possono differire nel contenuto. Get-History registra solo i comandi eseguiti nella sessione attiva, comprensivi di dettagli come stato ed esito, mentre il file di PSReadLine registra ogni riga inviata al prompt, indipendentemente dalla sessione, ed è quello che alimenta la ricerca interattiva della cronologia mentre si digita.
Questa ricerca interattiva è probabilmente la funzionalità più usata in pratica: digitando l’inizio di un comando e premendo il tasto F8 (o le frecce su/giù), PSReadLine scorre tra le voci del file che iniziano con quel testo. In alternativa, la combinazione Ctrl+R attiva una ricerca incrementale simile a quella della shell Bash, dove digitando un frammento qualsiasi vengono proposti i comandi che lo contengono.
Per svuotare la cronologia della sola sessione corrente
Clear-HistoryQuesto comando però non tocca il file su disco, i comandi restano comunque salvati da PSReadLine e riappariranno alla riapertura del terminale. Per rimuoverli definitivamente è necessario intervenire sul file stesso, ad esempio cancellandolo o svuotandolo
Remove-Item (Get-PSReadLineOption).HistorySavePathAttenzione ai dati sensibili
Poiché il file di PSReadLine salva ogni comando digitato in chiaro, può capitare che vi finiscano informazioni sensibili: password passate come parametro, token di accesso, stringhe di connessione con credenziali incluse. PSReadLine prova a mitigare parzialmente il problema riconoscendo automaticamente alcuni pattern comuni (come -Password o -Token seguiti da un valore) ed escludendoli dal salvataggio, ma questo filtro non è infallibile e non copre tutti i casi.
Se si vuole disattivare del tutto il salvataggio persistente, ad esempio su una macchina condivisa o durante un’operazione con credenziali particolarmente delicate, è possibile impostare temporaneamente
Set-PSReadLineOption -HistorySaveStyle SaveNothingQuesta impostazione vale solo per la sessione corrente; per renderla permanente va inserita nel profilo di PowerShell ($PROFILE), con lo stesso procedimento visto sopra.
Da quel momento, ogni nuova sessione di PowerShell parte con il salvataggio su disco disattivato. I comandi restano comunque disponibili tramite Get-History finché la sessione è aperta, ma non vengono più scritti nel file ConsoleHost_history.txt, né quelli della sessione corrente né quelli di sessioni future.