Script CMD per archiviare file vecchi su Windows

Uno script CMD per archiviare file vecchi su Windows può spostare automaticamente i documenti modificati prima di una data stabilita. Il metodo proposto usa un file .cmd come punto di avvio e PowerShell per gestire in modo affidabile date, percorsi e sottocartelle. Lo script trasferisce i file in una cartella di archivio, mantiene la struttura originale e salva un registro delle operazioni eseguite. La data viene interpretata nel formato AAAA-MM-GG, indipendentemente dalle impostazioni locali di Windows. Prima dell’esecuzione automatica è opportuno provarlo su una copia dei dati, perché lo spostamento modifica realmente la posizione dei file.

Come funziona lo script CMD per archiviare file vecchi

Lo script cerca soltanto i file presenti nella cartella indicata in SOURCE e nelle sue sottocartelle. Un file viene archiviato quando la sua data di ultima modifica è precedente alla data specificata nella variabile CUTOFF.

L’archiviazione utilizzata in questo esempio consiste nello spostamento dei file verso una cartella diversa, non nella creazione di un archivio ZIP. La struttura delle sottocartelle viene mantenuta: un file contenuto in C:DatiProgetti2022report.docx finirà, per esempio, in C:DatiArchivioProgetti2022report.docx.

Il file .cmd richiama PowerShell con -NoProfile, così il comportamento non dipende dai profili personali configurati nell’ambiente PowerShell. Il comando Get-ChildItem individua i file, LastWriteTime confronta la data di modifica e Move-Item completa l’archiviazione.

Lo script offre questi comportamenti:

  • ricerca ricorsiva nelle sottocartelle;
  • selezione dei soli file, senza spostare direttamente le cartelle;
  • mantenimento della struttura relativa delle directory;
  • creazione automatica delle cartelle mancanti nell’archivio;
  • registrazione di data, origine e destinazione in un file di log;
  • uso del formato data AAAA-MM-GG, più sicuro rispetto alle date locali come 01/02/2024.

Per ulteriori dettagli sui comandi PowerShell utilizzati è disponibile la documentazione Microsoft di Get-ChildItem.

Come creare il file .cmd

Passo 1: preparare le cartelle

Creare, se non esistono, una cartella sorgente e una cartella destinazione. Nell’esempio vengono utilizzati:

C:DatiDaArchiviare
C:DatiArchivio

La cartella DaArchiviare contiene i file da analizzare, mentre Archivio riceve quelli più vecchi della data stabilita. La destinazione può trovarsi anche su un altro disco, per esempio E:ArchivioDocumenti, purché l’account che esegue lo script disponga dei permessi necessari.

Passo 2: inserire lo script

Aprire il Blocco note e incollare il codice seguente. Modificare almeno SOURCE, ARCHIVE e CUTOFF prima di salvare il file.

@echo off
setlocal

set "SOURCE=C:DatiDaArchiviare"
set "ARCHIVE=C:DatiArchivio"
set "CUTOFF=2024-01-01"
set "LOG=%~dp0archiviazione.log"

if not exist "%SOURCE%" (
echo Cartella sorgente non trovata: "%SOURCE%"
exit /b 1
)

if not exist "%ARCHIVE%" (
md "%ARCHIVE%"
if errorlevel 1 (
echo Impossibile creare la cartella di archivio.
exit /b 1
)
)

powershell.exe -NoProfile -ExecutionPolicy Bypass -Command ^
"$ErrorActionPreference = 'Stop';" ^
"try {" ^
"  $source = [IO.Path]::GetFullPath($env:SOURCE).TrimEnd('');" ^
"  $archive = [IO.Path]::GetFullPath($env:ARCHIVE).TrimEnd('');" ^
"  $cutoff = [datetime]::ParseExact($env:CUTOFF, 'yyyy-MM-dd', [Globalization.CultureInfo]::InvariantCulture);" ^
"  $items = @(Get-ChildItem -LiteralPath $source -File -Recurse -Force | Where-Object { $_.LastWriteTime -lt $cutoff -and -not $_.FullName.StartsWith($archive + '', [StringComparison]::OrdinalIgnoreCase) });" ^
"  foreach ($item in $items) {" ^
"    $relative = $item.FullName.Substring($source.Length).TrimStart('');" ^
"    $destination = Join-Path $archive $relative;" ^
"    $destinationFolder = Split-Path -Parent $destination;" ^
"    if (-not (Test-Path -LiteralPath $destinationFolder)) { New-Item -ItemType Directory -Path $destinationFolder -Force | Out-Null }" ^
"    if (Test-Path -LiteralPath $destination) {" ^
"      Write-Warning ('Destinazione già esistente, file ignorato: ' + $destination);" ^
"      continue" ^
"    }" ^
"    Move-Item -LiteralPath $item.FullName -Destination $destination;" ^
"    $line = '{0:yyyy-MM-dd HH:mm:ss} | {1} -> {2}' -f (Get-Date), $item.FullName, $destination;" ^
"    Add-Content -LiteralPath $env:LOG -Value $line;" ^
"    Write-Host $line" ^
"  }" ^
"  Write-Host ('File archiviati: ' + $items.Count);" ^
"} catch {" ^
"  Write-Error $_.Exception.Message;" ^
"  exit 1" ^
"}"

endlocal

Salvare il file con un nome come archivia-file-vecchi.cmd. Nella finestra di salvataggio del Blocco note selezionare Tutti i file nel campo “Salva come” e verificare che il nome non termini con .txt.

Passo 3: impostare la data corretta

La variabile CUTOFF stabilisce il limite temporale. Con CUTOFF=2024-01-01, lo script sposta i file con data di modifica precedente alla mezzanotte del primo gennaio 2024; i file modificati il primo gennaio 2024 non vengono quindi selezionati.

Per archiviare i file modificati prima del primo luglio 2023, usare:

set "CUTOFF=2023-07-01"

La data deve contenere sempre quattro cifre per l’anno, due per il mese e due per il giorno. Un valore come 01/07/2023 può generare un errore o essere interpretato diversamente in base alle impostazioni regionali.

Come testare lo script senza rischiare i file originali

Prima di eseguire il comando sui dati reali, impostare SOURCE su una cartella di prova contenente copie dei file. È importante controllare anche la destinazione, perché Move-Item rimuove il file dalla posizione originale dopo averlo trasferito nell’archivio.

Per una simulazione, sostituire temporaneamente questa riga:

"    Move-Item -LiteralPath $item.FullName -Destination $destination;" ^

con una riga che visualizza soltanto l’operazione prevista:

"    Write-Host ('SIMULAZIONE: ' + $item.FullName + ' -> ' + $destination);" ^

In questo modo lo script elenca i file che rispetterebbero il filtro, ma non li sposta. Dopo il test è necessario ripristinare Move-Item.

Il file archiviazione.log viene creato nella stessa cartella dello script, perché %~dp0 indica il percorso del file .cmd. Il registro contiene una riga per ogni spostamento completato e consente di ricostruire l’origine dei file archiviati.

I file già presenti nella destinazione vengono ignorati per evitare sovrascritture accidentali. Se due file con lo stesso percorso relativo esistono già nell’archivio, lo script mostra un avviso e lascia invariato il file sorgente.

Come eseguire automaticamente l’archiviazione

Per avviare manualmente lo script, fare doppio clic sul file .cmd oppure eseguirlo da Prompt dei comandi. Un account standard potrebbe non avere accesso a tutte le cartelle: in quel caso occorre usare directory per cui l’utente dispone di autorizzazioni di lettura, scrittura e spostamento.

L’esecuzione pianificata si configura con Utilità di pianificazione di Windows:

Passo 1: creare l’attività

Aprire il menu Start, cercare Utilità di pianificazione e scegliere Crea attività. Nella scheda Generale assegnare un nome riconoscibile, come Archiviazione file vecchi.

Passo 2: scegliere la frequenza

Nella scheda Trigger creare una nuova pianificazione giornaliera, settimanale o mensile. Una frequenza settimanale è spesso sufficiente per documenti che cambiano raramente, mentre i flussi di lavoro quotidiani possono richiedere un controllo giornaliero.

Passo 3: indicare il file da eseguire

Nella scheda Azioni creare una nuova azione con tipo Avvio programma. Nel campo del programma inserire il percorso completo del file .cmd, per esempio:

C:Scriptarchivia-file-vecchi.cmd

Se l’attività deve funzionare anche senza una sessione interattiva, configurare correttamente l’account Windows e verificare i permessi sulle cartelle sorgente e destinazione. Dopo aver salvato l’attività, usare Esegui per effettuare un primo test controllato.

Uno script CMD per archiviare file vecchi Windows diventa affidabile quando data, percorsi, permessi e log vengono verificati prima della pianificazione automatica.

Per approfondire, consulta la documentazione ufficiale.

Potrebbe interessarti anche:

FAQ

No. Il filtro usa LastWriteTime, cioè la data dell’ultima modifica. La data di creazione non viene considerata.

Sì. I percorsi assegnati alle variabili SOURCE e ARCHIVE sono racchiusi tra virgolette e possono contenere spazi, come C:Documenti aziendaliArchivio.

No. Il codice sposta i file mantenendo la struttura delle cartelle. Per creare ZIP servirebbe aggiungere una fase specifica di compressione.

Il file viene ignorato e non viene sovrascritto. Lo script mostra un avviso per segnalare il conflitto.

Sì, se il percorso di rete è raggiungibile e l’account usato dallo script dispone dei permessi necessari. Con Utilità di pianificazione è preferibile usare percorsi UNC, come ServerCondivisaDati.

Altri articoli di questa serie:

PDF Strumenti PDF gratis Nel browser, senza upload Apri gli strumenti