Su ogni computer Windows recente è presente PowerShell, una shell pensata per l'amministrazione ma utilissima anche per le piccole manutenzioni d'ufficio: svuotare la cartella dei download dei file vecchi, archiviare le fatture dell'anno precedente, raccogliere tutti i PDF sparsi in una struttura di sottocartelle. Non richiede installazioni e, a differenza del vecchio prompt dei comandi, lavora con oggetti invece che con semplice testo.
Il concetto chiave: la pipeline di oggetti
Quando si elencano i file con Get-ChildItem, PowerShell non restituisce righe di testo ma oggetti con proprietà: Name, Extension, Length (la dimensione in byte), LastWriteTime e così via. Questi oggetti passano attraverso la pipeline, il simbolo |, al comando successivo, che può filtrarli o agire su di essi.
Get-ChildItem C:\Lavoro\Download -File |
Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-60) } |
Select-Object Name, Length, LastWriteTime
La riga elenca i file più vecchi di 60 giorni con nome, dimensione e data. $_ rappresenta l'oggetto corrente nella pipeline. Gli operatori di confronto si scrivono come parole: -lt (minore), -gt (maggiore), -eq (uguale), -like (corrispondenza con caratteri jolly).
La rete di sicurezza: -WhatIf
Prima di spostare o cancellare qualsiasi cosa, i comandi che modificano il sistema accettano il parametro -WhatIf. Con questo parametro il comando descrive cosa farebbe, senza farlo.
Get-ChildItem C:\Lavoro\Download -File -Filter *.tmp |
Remove-Item -WhatIf
L'output mostrerà, per ogni file, una riga che inizia con «WhatIf:» e descrive l'operazione prevista. Solo dopo aver controllato l'elenco si toglie il parametro. È la stessa filosofia della prova a vuoto negli script Python, ed è un'abitudine da non abbandonare mai. In alternativa -Confirm chiede conferma file per file.
Esempio 1: smistare i file per estensione
Una cartella in cui finisce di tutto può essere ordinata creando una sottocartella per tipo di file:
$origine = "C:\Lavoro\Da smistare"
Get-ChildItem $origine -File | ForEach-Object {
$tipo = $_.Extension.TrimStart(".").ToLower()
if (-not $tipo) { $tipo = "senza_estensione" }
$destinazione = Join-Path $origine $tipo
New-Item -ItemType Directory -Path $destinazione -Force | Out-Null
Move-Item $_.FullName -Destination $destinazione -WhatIf
}
New-Item -Force crea la cartella solo se non esiste, senza generare errori. Join-Path compone i percorsi in modo corretto, evitando di dimenticare o duplicare la barra rovesciata.
Esempio 2: archiviare per anno e mese
Le fatture vecchie possono essere raggruppate in cartelle 2024-01, 2024-02 in base alla data di modifica:
Get-ChildItem C:\Archivio\Fatture -File -Filter *.pdf |
Group-Object { $_.LastWriteTime.ToString("yyyy-MM") } |
ForEach-Object {
$cartella = "C:\Archivio\Fatture\$($_.Name)"
New-Item -ItemType Directory -Path $cartella -Force | Out-Null
$_.Group | Move-Item -Destination $cartella -WhatIf
}
Group-Object raccoglie i file con la stessa chiave; ogni gruppo ha un Name (la chiave, cioè anno e mese) e un Group (i file). Il formato yyyy-MM mantiene l'ordinamento alfabetico coerente con quello cronologico.
Esempio 3: comprimere un archivio
Per spedire o conservare un insieme di file, Compress-Archive crea un file ZIP:
Compress-Archive -Path C:\Archivio\Fatture\2024-* -DestinationPath C:\Backup\fatture_2024.zip
Il comando opposto è Expand-Archive. Per archivi molto grandi esistono strumenti più efficienti, ma per l'uso quotidiano d'ufficio questo è sufficiente.
Trovare i file più ingombranti
Quando il disco condiviso è pieno, la prima domanda è: che cosa occupa spazio?
Get-ChildItem \\server\condivisa -File -Recurse -ErrorAction SilentlyContinue |
Sort-Object Length -Descending |
Select-Object -First 20 FullName, @{n="MB"; e={[math]::Round($_.Length / 1MB, 1)}}
La proprietà calcolata @{n=...; e=...} aggiunge una colonna con la dimensione in megabyte, molto più leggibile dei byte. -ErrorAction SilentlyContinue evita che le cartelle senza permessi di lettura riempiano lo schermo di errori.
Salvare e lanciare uno script
I comandi si possono salvare in un file .ps1. Per motivi di sicurezza, però, Windows può impedirne l'esecuzione. Il criterio di esecuzione si consulta con Get-ExecutionPolicy; per consentire gli script locali al solo utente corrente si usa:
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
Con RemoteSigned gli script scritti sul proprio computer vengono eseguiti, mentre quelli scaricati da Internet devono essere firmati. Nelle aziende questa impostazione può essere gestita centralmente dall'amministratore. Nel mio lavoro preferisco salvare ogni script con un commento iniziale che spiega scopo, cartelle coinvolte e data dell'ultima modifica.
| Comando | Funzione |
|---|---|
Get-ChildItem |
Elenca file e cartelle |
Where-Object |
Filtra per condizione |
Move-Item / Copy-Item |
Sposta o copia |
Remove-Item |
Elimina |
Group-Object |
Raggruppa per chiave |
Compress-Archive |
Crea file ZIP |
In sintesi
- PowerShell lavora con oggetti: dimensione e data dei file sono proprietà da filtrare.
- Usate sempre
-WhatIfprima di spostare o eliminare. Group-Objecte il formatoyyyy-MMpermettono archiviazioni per periodo.Compress-Archivecrea ZIP senza programmi aggiuntivi.- Impostate il criterio
RemoteSignedper l'utente corrente e documentate ogni script.