Avere un profilo PowerShell consente di snellire l'uso della shell e costruirsi il proprio "coltellino svizzero" di funzioni e comandi (o meglio, "cmdlet" come si chiamano nel gergo di Powershell), rendendo l'uso del terminale più rapido e "accogliente" per le proprie esigenze. Useremo PowerShell 5.1, comunemente presente nei recenti sistemi Windows, ma la procedura è facilmente adattabile anche a PowerShell Core 7 (per il quale, ad esempio, il percorso del file del profilo è differente: $HOME\Documents\PowerShell).
Il primo passo è controllare se ci sia già un profilo impostato; è sufficiente quindi provare ad individuare se esiste nel suo percorso, ossia quello della variabile di sistema $Profile. Se l'esito del comando "Test-Path $PROFILE"
è "False" significa che non c'è alcun profilo:
Per creare il file che costituisce il profilo, è necessario avere i privilegi di amministratore e il comando è "New-Item -Type File -Path $PROFILE -Force
":
L'indirizzo di default è nella cartella Documenti, sottocartella WindowsPowerShell, dove viene creato il file Microsoft.Powershell_profile.ps1 che verrà letto ed eseguito ad ogni avvio del terminale PowerShell. Inizialmente il profilo è un file di testo vuoto, ma cliccandoci con il tasto destro e scegliendo "Modifica", potremo scrivere al suo interno le nostre personalizzazioni, usando PowerShell ISE (consigliato) o anche semplicemente il Blocco Note.
Per impostare una policy che ci consenta di usare localmente il file .ps1, è consigliabile settarla su RemoteSigned, eseguendo nella shell il comando "Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
". In questo modo ogni script (o file .ps1) che proviene da un altro PC non verrà eseguito se non è digitalmente firmato, mentre i file prodotti dall'utente, come quello del profilo, non saranno bloccati.
Vediamo ora alcune modifiche di esempio gestibili dal file del profilo, tenendo ben presente che, affinché ogni modifica abbia effetto, è necessario salvare il file .ps1 e rilanciare la shell, così che possa ricaricare il profilo; non è invece necessario chiudere PowerShell ISE o il Blocco Note.
RITOCCHI GRAFICI
Alcune impostazioni grafiche della shell possono essere regolate anche senza il profilo: con la combinazione "ALT + SPAZIO
" si apre il menu della shell e in "Proprietà" abbiamo diverse opzioni di "tuning", fra cui anche quelle dei colori:
Il profilo può tuttavia esserci utile se vogliamo cambiare ulteriori combinazioni di colori come, ad esempio, l'aggressivo rosso su nero dell'infausto messaggio di errore
magari smorzandolo un po' rendendolo un bianco su nero:
Per ottenere questa modifica è sufficiente scrivere nel file del profilo:
$colors = $host.privatedata
$colors.ErrorForegroundColor = "White"
$colors.ErrorBackgroundColor = "Black"
Nell'immagine che segue stiamo usando PowerShell ISE ma, come detto, va bene anche il semplice Blocco Note:
Per conoscere l'elenco dei colori disponibili, si può digitare il comando "Write-Host -ForegroundColor
", premere "SPAZIO
" e poi "TAB
" per scorrere le varie possibilità cromatiche. Un modo decisamente più professionale, ma forse anche più difficile da ricordare, è usare il comando "[Enum]::GetValues([ConsoleColor])
".
IMPOSTAZIONI DELL'AVVIO
Passiamo a qualcosa di meno "superficiale": per impostare il percorso di default da cui si avvia la shell, basta scriverlo nel file del profilo con il comando "Set-Location [percorso]
". In questo caso lo abbiamo impostato, a titolo di esempio, su "C:\Users" (essendo admin):
Come avrete notato, i comandi PowerShell non sono "case sensitive", quindi l'uso delle maiuscole nelle cmdlet non è obbligatorio. Proseguendo con le modifiche: è possibile anche impostare all'avvio della shell l'apertura in esergo di un testo predefinito o del contenuto di un determinato file; può essere una citazione motivazionale che ci ispira oppure una sorta di post-it con informazioni utili sulla rete o gli host. Per avere un testo uguale ad ogni avvio di shell, è sufficiente scriverlo in questo modo:
Il comando "Write-Host
" specifica fra virgolette il testo che deve comparire e il "`n" finale è facoltativo: serve ad avere una riga vuota di spazio prima dell'inizio della shell (da notare che il segno prima della "n" è il cosiddetto backtick, digitabile con la combinazione "alt
+ 96
").
In questo altro esempio attingiamo dal contenuto del file "notes.txt" con il comando "Write-Host (Get-Content [percorso]\notes.txt) -ForegroundColor White -BackgroundColor DarkCyan "`n"
":
Le opzioni "-ForegroundColor White -BackgroundColor DarkCyan" servono ad impostare i colori usati da "Write-Host
" e quelli disponibili sono gli stessi visti in precedenza per modificare l'irruenza del messaggio di errore in rosso. Se invece vogliamo richiamare righe casuali da un file di frasi simpatiche oppure cheatcode da un elenco, la riga di comando da aggiungere al profilo è invece "Write-Host (Get-Random -InputObject (Get-Content [percorso-file])) "`n"
".
COMANDI PERSONALIZZATI E FUNZIONI
Notoriamente PowerShell consente di impostare degli alias dei comandi (tramite la cmdlet "Set-Alias
"), tuttavia tali alias hanno validità circoscritta alla sessione corrente e in caso di comandi in pipe è necessario prima impostarli in una funzione e poi assegnare l'alias. Come ottenere comandi e funzioni persistenti, fruibili in ogni sessione, anche quelle senza diritti di admin? Come avrete già intuito, il file del profilo ci consente anche questo.
Chiaramente si possono impostare funzioni più o meno complesse; quanto segue è solo una esemplificazione con un paio di funzioni a scopo illustrativo; non vengono usati i moduli, potrebbero esserci imperfezioni e sicuramente gli script proposti non sono fra i più "eleganti", ma ciascuno saprà poi scrivere il proprio codice secondo le sue competenze.
Ricordiamo ancora che per modificare il file del profilo occorre essere amministratori, ma i cambiamenti avranno effetto anche quando verrà usato PowerShell come utente standard. Un primo esempio potrebbe essere voler tenere a portata di mano un comando unico per visualizzare in una finestra con tabella gli ultimi 20 eventi nel log di sistema, per sapere se ci sono stati aggiornamenti Windows, se qualche dispositivo si è connesso, eventuali mancate risoluzioni DNS, etc. Il comando per farlo è "Get-EventLog -LogName System -Newest 20 | Select-Object -Property * | Out-GridView
", non esattamente impossibile da ricordare, ma è certamente più rapido digitare una parola che indica la funzione corrispondente.
Nella sintassi tipica di PowerShell, "verbo-oggetto", potremmo proporre qualcosa come "get-news" (dopo esserci accertati che non esista già), ma siccome questa è una funzione per uso personale, possiamo anche chiamare la funzione semplicemente "novità" (per quanto le lettere accentate possano creare problemi di codifica per alcuni parametri delle funzioni, quindi in generale è meglio non tentare la sorte). In generale, la sintassi più "minimale" per impostare una funzione personalizzata è questa:
function [nome funzione] {
[comando o serie comandi]
}
Di solito è bene provare i comandi singolarmente e fuori dalla funzione, prima di assemblare la funzione. Non resta quindi che scrivere tre righe nel file del profilo, salvarlo, aprire la shell e richiamare la funzione digitando il suo nome e premere "INVIO":
Un secondo esempio, con un codice decisamente più strutturato, potrebbe essere quello di una funzione che ci consente di spostare in una cartella predefinita tutti i file creati da più "x" mesi, che non hanno avuto un accesso negli ultimi "y" mesi e che sono più grandi di "z" MB.
Non è una funzione che passerà alla storia per la sua utilità, ma come detto la usiamo solo come esempio di serie di comandi difficili da ricordare, o quantomeno piuttosto lunghi da scrivere, che possono essere richiamati ed eseguiti digitando una sola parola a nostra scelta.
Il vantaggio di una funzione scritta in modo più accurato della precedente è che può contenere anche una "guida all'uso", grazie al comando "Get-Help
", che ci ricorda cosa fa tale funzione, quali sono i parametri obbligatori e quali facoltativi, e in cui possiamo salvare anche qualche esempio.
Procediamo per gradi e partiamo dalla funzione da scrivere (incollare nel vostro caso) nel file del profilo: per comodità, la trovate in allegato all'articolo ("pws_funzione_accantona.zip", SHA1: 520BACEAF85B367AC46D4E9C44C6AC60057E1FEA).
Incollando il testo su PowerShell ISE, il testo verrà colorato automaticamente in base alle funzioni delle parole; ad esempio, le righe di commento sono in verde e solitamente possono essere cancellate senza compromettere la funzionalità del codice. Da considerare tuttavia che in questo script il commento iniziale incluso fra "<#" e "#>" è quello da cui il comando "Get-Help"
attinge le sue informazioni, quindi cancellarlo potrebbe non essere una buona idea. Ecco come si presenta una parte del codice con PowerShell ISE:
Una volta compresi il senso e la sintassi del codice, è possibile cambiare sia il nome della funzione ("accantona"), sia il percorso o il nome della cartella di destinazione, così come si possono aggiungere altri parametri. Salvato dunque il profilo ed aperta la shell, con il comando "Get-Help accantona
" o più semplicemente "accantona -?
" potremo leggere il manuale della nostra funzione; tenendo presente che, come sempre, per visualizzare gli esempi è necessario usare il comando "Get-Help accantona -examples
", mentre la versione più completa (esempi inclusi) si ottiene con "Get-Help accantona -full
". Il comando "Get-Help accantona -online
" aprirà il sito indicato in "Related links" che in questo caso è quello del presente articolo.
Leggendo il paragrafo "DESCRIPTION" veniamo a sapere che ci sono due parametri obbligatori, quello della cartella a cui applicare la funzione (-cartella) e quello dell'età massima consentita per i file (-creazione), superata la quale i file verranno considerati ammessi allo spostamento. Il comando di base è dunque "accantona -cartella [percorso] -creazione [mesi]
" (ricordarsi di scrivere il percorso fra virgolette se sono presenti spazi nei nomi delle cartelle o dei file) con la possibilità di non scrivere esplicitamente il nome dei due parametri obbligatori, ma semplicemente "accantona [percorso] [mesi]
", come spiegato in "Get-Help -Examples
".
Da segnalare che la funzione è in grado di comunicarci con differenti messaggi i principali scenari in cui non viene spostato alcun file, ossia: se non c'è nessun file con i criteri scelti, se la cartella non contiene nessun file al primo sotto-livello (perché è vuota o contiene altre cartelle), oppure se la cartella data in input non esiste.
In questo caso, al posto dell'intero percorso, abbiamo usato ".\" come "prefisso" o come percorso relativo, ad indicare la posizione attuale della shell ("C:\Users\User\Downloads"). Per l'output in cui vengono trovati e spostati dei file nella cartella preimpostata ("$HOME\Documents\ACCANTONAMENTO") è stata scelta una differente combinazione di colori, anch'essa personalizzabile modificando lo script a proprio piacimento:
Una funzionalità molto utile ci è data dall'aver implementato nello script anche lo switch "-whatif" (ad es. "accantona [percorso] -creazione 3 -whatif
"): PowerShell ci anticiperà cosa farebbe se la funzione venisse eseguita, ma di fatto non accadrà nulla, avremo solo una previsione del cambiamento effettuato (in questo caso, quali sono i file che verrebbero spostati altrove).
La prima riga del "WhatIf" ci ricorda che verrà creata anzitutto la cartella "ACCANTONAMENTO", la seconda dichiara quale file verrà spostato e dove. Chiaramente nelle esecuzioni successive otterremo solo l'anticipazione di quali file verranno spostati, essendo la cartella "ACCANTONAMENTO" già stata creata, ma va considerato comunque che la funzione controlla ad ogni esecuzione l'esistenza della cartella di destinazione, quindi se, fra un'esecuzione e l'altra venisse cancellata, ci verrebbe ricordata nuovamente la sua necessaria creazione. Per inciso, se volete sapere quali cmdlet implementano il parametro "-whatif", non vi resta che usare il comando "Get-Command -ParameterName whatif
".
Nella funzione "accantona" è stata inoltre impostata la possibilità di poter avere un ripensamento, utilizzando lo switch "-confirm" (ad es. "accantona [percorso] -creazione 3 -confirm
") che, come avrete intuito, ci chiederà (doppia) conferma prima di eseguire il codice, che come al solito inizia (alla prima esecuzione) chiedendo se si vuole creare la cartella "ACCANTONAMENTO" e in seguito chiede duplice conferma di voler spostare i file individuati:
Per sapere quali cmdlet implementano il parametro "-confirm", potete usare il comando "Get-Command -ParameterName confirm
".
Come per tutte le cmdlet native, dopo aver digitato il nome, l'evocazione dei parametri e degli switch può essere fatta semplicemente digitando il trattino "-" e poi scorrendo i parametri disponibili con il tasto "TAB
" (o "SHIFT
+ TAB
" per scorrere all'indietro); per confermarli è sufficiente premere "spazio". Se preferiamo un'interfaccia grafica, proprio come per molte altre cmdlet di PowerShell, anche per "accantona" possiamo usare il comando "Show-Command accantona
", compilare i campi e poi cliccare su "Run" (che nonostante il nome, scriverà il comando nella shell, ma non lo eseguirà):
In caso abbiate bisogno di riportare la shell alle sue impostazioni di default, la soluzione più semplice e al contempo radicale è rinominare o cancellare il file del profilo Microsoft.Powershell_profile.ps1.
Le potenzialità del poter impostare funzioni personalizzate che si comportano come normali cmdlet sono innumerevoli, e sono l'ideale per soddisfare la propria voglia o necessità di ottimizzare i tempi e la digitazione. Nondimeno, è doveroso sottolineare che un "effetto collaterale" dell'abituarsi ad usare PowerShell con il proprio profilo personalizzato è che, quando ci si trova ad operare con un altro dispositivo, si sente inevitabilmente la mancanza delle "scorciatoie" a cui si è ormai assuefatti.