PowerShell Wget: Scarica file con facilità

Hai bisogno di scaricare file dal web ma odii cliccare ripetutamente sui link? Se il tuo lavoro prevede il download regolare di file dal web, probabilmente vorrai automatizzare il compito. Perché non usare PowerShell per scaricare file in modo simile a wget?

Windows PowerShell e PowerShell dispongono di funzionalità di download di file. Utilizzare PowerShell per scaricare file è una questione di conoscere quali cmdlet e classi .NET utilizzare e come utilizzarli.

In questo articolo, imparerai i vari modi per utilizzare PowerShell per scaricare file dal web.

Prerequisiti

Siccome questo è un articolo di “imparare facendo”, ci sono alcuni prerequisiti da rispettare per poter seguire gli esempi. Di seguito sono elencati i requisiti di base.

  • A computer that is running on Windows 10 or higher. This computer is where you will run the scripts/commands featured in this article.
  • Windows PowerShell 5.1 o PowerShell 7.1 (consigliato).
    • Windows 10 include già Windows PowerShell 5.1.
  • A web site that hosts the files to download.
    • Per il download di file non autenticati, considera l’utilizzo del sito Tele2 Speedtest, che è gratuito.
    • Se vuoi testare il download di file con autorizzazione, potresti dover creare il tuo server file HTTP. Un esempio di server file HTTP gratuito è HFS di Rejetto.

Utilizzo di PowerShell per scaricare file da URL: quattro modi

Esistono quattro metodi per utilizzare PowerShell per scaricare file che non dipendono da strumenti di terze parti. Questi sono:

  • Invoke-WebRequest
  • Invoke-RestMethod
  • Start-BitsTransfer
  • Classe .NET WebClient.

Qualunque metodo tu utilizzi tra questi quattro, la logica e i componenti per farli funzionare sono gli stessi. È necessario avere un URL di origine che punti alla posizione del file e il percorso di destinazione per salvare i file scaricati. Se richiesto dal server web, è anche necessario inserire le credenziali.

Le sezioni successive mostrano ognuno di questi quattro metodi. Alla fine, spetta a te decidere quale metodo adattare quando si utilizza PowerShell per scaricare file.

Utilizzare Invoke-WebRequest come alternativa a wget in PowerShell

Il primo metodo in PowerShell per scaricare file è utilizzare il cmdlet Invoke-WebRequest. Forse il cmdlet più utilizzato in questo articolo, Invoke-WebRequest può scaricare collegamenti HTTP, HTTPS e FTP.

Indipendentemente dal fatto che la posizione di origine richieda agli utenti di effettuare l’accesso, il cmdlet Invoke-WebRequest può gestire richieste con credenziali.

Per scaricare un file, la sintassi di seguito mostra i parametri minimi richiesti per ottenere il risultato desiderato.

Invoke-WebRequest -Uri <source> -OutFile <destination>

Ad esempio, il codice seguente scarica un file con il nome 10MB.zip da un sito web. Quindi salva il file scaricato in C:\dload\10MB.zip. Puoi copiare il codice qui sotto e incollarlo nella tua sessione PowerShell per testarlo.

# Posizione del file di origine
$source = 'http://speedtest.tele2.net/10MB.zip'
# Destinazione per salvare il file
$destination = 'c:\dload\10MB.zip'
# Scarica il file
Invoke-WebRequest -Uri $source -OutFile $destination

La dimostrazione qui sotto mostra il risultato atteso dopo l’esecuzione del codice sopra in PowerShell. Come puoi vedere, il download del file è stato eseguito con successo.

PowerShell wget : Downloading a file using Invoke-WebRequest

E se la sorgente richiede l’autenticazione prima di consentire l’accesso? Ad esempio, il codice qui sotto scarica un file da un sito web privato in cui gli utenti devono effettuare l’accesso.

$source = 'https://mirror.lzex.ml/100MB.zip'
$destination = 'c:\dload\100MB.zip'
Invoke-WebRequest -Uri $source -OutFile $destination

Tuttavia, il download è fallito a causa dell’accesso non autorizzato.

Downloading failed due to unauthorized access

Se è richiesta l’autenticazione, è necessario aggiungere una credenziale alla richiesta utilizzando il parametro -Credential. La prima riga del codice qui sotto ti chiede di inserire la credenziale (nome utente e password) e la memorizza nella variabile $credential.

$credential = Get-Credential
$source = 'https://mirror.lzex.ml/100MB.zip'
$destination = 'c:\dload\100MB.zip'
Invoke-WebRequest -Uri $source -OutFile $destination -Credential $credential

La dimostrazione qui sotto mostra cosa ti aspetti di vedere quando esegui il codice sopra in PowerShell. Come puoi vedere, il cmdlet Get-Credential richiede una richiesta di credenziali PowerShell. Questa volta, utilizzando la credenziale con Invoke-WebRequest, il download è riuscito.

Downloading a file with authentication

Correlato: Utilizzo del cmdlet PowerShell Get-Credential e tutto ciò che riguarda le credenziali

Attenzione agli errori di parsing quando si utilizza Invoke-WebRequest

A crucial thing to remember when using Invoke-WebRequest in Windows PowerShell is that, by default, this cmdlet uses the Internet Explorer engine to parse data. The error below may happen when using Invoke-WebRequest on computers without the Internet Explorer in it.

Dovrai ripetere il comando, ma questa volta includi lo switch -UseBasicParsing.

Invoke-WebRequest -Uri <source> -OutFile <destination> -UseBasicParsing

In Windows PowerShell, potresti ricevere un messaggio di errore: Il contenuto della risposta non può essere analizzato perché il motore di Internet Explorer non è disponibile, o la configurazione di primo avvio di Internet Explorer non è completa. Specifica il parametro UseBasicParsing e riprova.

A partire da PowerShell Core 6.0, il cmdlet Invoke-WebRequest utilizza solo l’analisi di base. Pertanto, il parametro -UseBasicParsing non è più necessario.

Utilizzando Invoke-RestMethod

Il cmdlet Invoke-RestMethod è più orientato all’invio di una richiesta HTTP o HTTPS a un servizio web RESTful. Questo cmdlet è più adatto per le richieste che interagiscono con API REST come Microsoft Graph API.

Quando si tratta di scaricare file direttamente da Internet, Invoke-RestMethod è un’ottima opzione. Non lasciarti ingannare a pensare diversamente. Non c’è molta differenza nell’utilizzo di Invoke-RestMethod e Invoke-WebRequest quando vengono utilizzati per scaricare file da un link web diretto.

Scaricare un file usando Invoke-RestMethod

Per scaricare un file usando Invoke-RestMethod, utilizza la sintassi seguente. Noterai che il comando utilizza gli stessi parametri di Invoke-WebRequest.

Invoke-RestMethod -Uri <source> -OutFile <destination>

Nel codice di esempio qui sotto, il file viene scaricato dall’URL indicato nella variabile $source. Poi, viene salvato nel percorso definito nella variabile $destination.

$source = 'http://speedtest.tele2.net/10MB.zip'
$destination = 'c:\dload\10MB.zip'
Invoke-RestMethod -Uri $source -OutFile $destination

Se la fonte richiede l’autenticazione, è possibile passare le credenziali utilizzando il parametro -Credential. L’esempio di seguito richiede le credenziali e le memorizza nella variabile $credential. Il valore della variabile $credential viene quindi passato al parametro -Credential.

Inoltre, poiché il collegamento al file è una fonte HTTP e non HTTPS, significa che si sta inviando un’autenticazione non crittografata. In genere, è consigliabile evitare di utilizzare fonti HTTP per motivi di sicurezza. Ma se è necessario utilizzare una fonte HTTP, è necessario aggiungere lo switch -AllowUnencryptedAuthentication al comando.

$credential = Get-Credential
$source = 'http://speedtest.tele2.net/10MB.zip'
$destination = 'c:\dload\10MB.zip'
Invoke-RestMethod -Uri $source -OutFile $destination -Credential $credential -AllowUnencryptedAuthentication

Utilizzo di Start-BitsTransfer

Start-BitsTransfer è progettato specificamente per il trasferimento di file tra computer client e server. Questo cmdlet di PowerShell dipende dal Background Intelligent Transfer Service (BITS) che è nativo del sistema operativo Windows.

Poiché Start-BitsTransfer richiede BITS per funzionare, significa che questo cmdlet non è disponibile su computer non Windows. D’altra parte, Start-BitsTransfer gode dei vantaggi di BITS stesso. Alcuni di questi vantaggi sono:

  • Consapevolezza della larghezza di banda e dell’utilizzo di rete.
  • Gestione delle interruzioni (ripristino, ripresa automatica, pausa, ecc.)
  • Download di più file come lavori in background.
  • Capacità di impostare le priorità dei lavori di download.

Scaricare un file

Il modo fondamentale per utilizzare Start-BitsTransfer in PowerShell per scaricare un file è specificare una sorgente e una destinazione. Utilizzando lo script di seguito, è sufficiente modificare i valori di $source e $destination in base alle proprie esigenze.

$source = 'http://speedtest.tele2.net/100MB.zip'
$destination = 'c:\dload\100MB.zip'
Start-BitsTransfer -Source $source -Destination $destination

Come puoi vedere dal demo sottostante, il file viene scaricato nel percorso c:\dload\100MB.zip.

Downloading a file using Start-BitsTransfer

Se non viene specificata la destinazione, Start-BitsTransfer scarica e salva il file nella directory di lavoro corrente. Ad esempio, se esegui Start-BitsTransfer da C:\dload, il file viene scaricato nella stessa directory.

Per i download che richiedono l’autenticazione, Start-BitsTransfer dispone di un parametro -Credential che accetta un oggetto PSCredential.

Download di file multipli

Per dimostrare il download di file multipli, è necessario creare un file CSV con due colonne. Chiamare il file filelist.txt. La prima colonna dovrebbe contenere il collegamento alla sorgente, mentre la seconda colonna deve contenere il percorso di destinazione. Il contenuto del file sarebbe come quello riportato di seguito.

# sorgente,destinazione
http://speedtest.tele2.net/1MB.zip,c:\dload\1MB.zip
http://speedtest.tele2.net/10MB.zip,c:\dload\10MB.zip
http://speedtest.tele2.net/100MB.zip,c:\dload\100MB.zip

Correlato: Gestione dei file CSV in PowerShell con Import-Csv

Una volta che il file CSV è pronto, utilizzare il comando di seguito per avviare il download del file. Il comando importa il file CSV utilizzando Import-Csv e passa i contenuti a Start-BitsTransfer.

Import-Csv .\filelist.csv | Start-BitsTransfer

Fare riferimento al demo di seguito per vedere come funziona il codice sopra. Come si può vedere, il download inizia e si può visualizzare il progresso del download. Il prompt di PowerShell non è disponibile durante il processo di download.

Starting a synchronous multiple file download

Supponiamo che si voglia avviare il processo di download come un lavoro in background. Per farlo, è sufficiente aggiungere l’interruttore -Asynchronous alla fine del comando Start-BitsTransfer.

Import-Csv .\filelist.csv | Start-BitsTransfer -Asynchronous

Inizialmente, lo stato di ogni lavoro mostrerà “connecting”. Lo screenshot di seguito mostra l’id di ogni download dei file.

Starting file download as background jobs

Ora che hai avviato il processo di download, vorrai verificare se il download è stato completato. Per verificare lo stato del lavoro di download, utilizzare il cmdlet Get-BitsTransfer. Come si può vedere di seguito, lo stato dei lavori di download è cambiato in “Transferred”.

Viewing the file download job status

Utilizzando la classe WebClient e la classe HttpClient (.NET Framework)

PowerShell si basa su .NET e la sua natura gli permette di sfruttare la potenza di .NET stesso. Ci sono due classi .NET che è possibile utilizzare in PowerShell per scaricare file; WebClient e HttpClient.

Se desideri saperne di più su queste due classi .NET in modo più sviluppato e tecnico, puoi iniziare con → Quando utilizzare WebClient vs. HttpClient vs. HttpWebRequest. Nella sezione successiva, imparerai come utilizzare WebClient e HttpClient in PowerShell per scaricare file da Internet.

Scaricare un file utilizzando System.Net.WebClient

Per utilizzare la classe WebClient, è necessario inizializzare un oggetto come tipo System.Net.WebClient. Nell’esempio di seguito, $webClient è il nuovo oggetto System.Net.WebClient. Successivamente, utilizzando il metodo DownloadFile(), viene avviato il download del file dalla fonte.

Correlato: Utilizzo degli acceleratori di tipi di dati di PowerShell per velocizzare la codifica

Copia il codice di seguito ed eseguilo nella sessione di PowerShell per testare. Tieni presente che non vedrai alcun progresso o output sullo schermo a meno che non si verifichi un errore. Tuttavia, il prompt di PowerShell sarà bloccato fino al completamento del download.

# Definisci il link di origine e il percorso di destinazione
$source = 'http://speedtest.tele2.net/10MB.zip'
$destination = 'c:\dload\10MB.zip'
# Crea il nuovo WebClient
$webClient = [System.Net.WebClient]::new()
# Scarica il file
$webClient.DownloadFile($source, $destination)

Se la sorgente richiede l’autenticazione per consentire il download del file, è possibile utilizzare il codice di seguito. La prima riga richiede le credenziali e le memorizza nella variabile $credentials. Il valore di $credential viene quindi incluso nella richiesta di download del file.

# Richiedi nome utente e password
$credentials = Get-Credential
$source = 'http://speedtest.tele2.net/10MB.zip'
$destination = 'c:\dload\10MB.zip'
# Crea il nuovo WebClient
$webClient = [System.Net.WebClient]::new()
# Aggiungi le credenziali
$webClient.Credentials = $credentials
# Scarica il file
$webClient.DownloadFile($source, $destination)

Secondo questo documento di Microsoft: “Non raccomandiamo di utilizzare la classe WebClient per nuovi sviluppi. Invece, utilizza la classe System.Net.Http.HttpClient.”

Sembra che la classe WebClient sia obsoleta e la nuova classe che Microsoft sta promuovendo sia la classe HttpClient. Non preoccuparti, però. La prossima sezione parla dell’utilizzo della classe HttpClient in PowerShell per scaricare file da Internet.

Scaricare un file utilizzando System.Net.Http.HttpClient

Come la classe WebClient, è necessario creare prima l’oggetto System.Net.Http.HttpClient. Utilizzando il codice di seguito, è possibile scaricare il file dalla $source alla $destination. Consulta i commenti sopra ogni riga per sapere cosa fa ogni riga di codice.

Il codice qui sotto è attivo e puoi testarlo eseguendolo nella tua sessione PowerShell.

# Imposta la sorgente e la destinazione
$source = 'http://speedtest.tele2.net/10MB.zip'
$destination = 'c:\dload\10MB.zip'
 
# Crea la richiesta di download del client HTTP
$httpClient = New-Object System.Net.Http.HttpClient
$response = $httpClient.GetAsync($source)
$response.Wait()
 
# Crea uno stream di file che punta alla destinazione del file di output
$outputFileStream = [System.IO.FileStream]::new($destination, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write)
 
# Trasmetti il download allo stream del file di destinazione
$downloadTask = $response.Result.Content.CopyToAsync($outputFileStream)
$downloadTask.Wait()
 
# Chiudi lo stream del file
$outputFileStream.Close()

In situazioni in cui il download di un file richiede l’autenticazione, è necessario aggiungere le credenziali all’oggetto HttpClient. Per includere le credenziali nella richiesta di download del file, crea un nuovo oggetto System.Net.Http.HttpClientHandler per memorizzare le credenziali.

Puoi copiare il codice qui sotto ed eseguirlo in PowerShell per testarlo. Oppure puoi eseguirlo anche come script PowerShell. In questo esempio, il codice è salvato come download-file.ps1.

# Imposta la sorgente e la destinazione
$source = 'http://speedtest.tele2.net/10MB.zip'
$destination = 'c:\dload\10MB.zip'
 
# Richiedi le credenziali
$credentials = Get-Credential

# Crea la richiesta di download del client HTTP con le credenziali
$handler = New-Object System.Net.Http.HttpClientHandler
$handler.Credentials = $credentials
$httpClient = New-Object System.Net.Http.HttpClient($handler)
$response = $httpClient.GetAsync($source)
$response.Wait()
 
# Crea uno stream di file che punta alla destinazione del file di output
$outputFileStream = [System.IO.FileStream]::new($destination, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write)
 
# Trasmetti il download allo stream del file di destinazione
$downloadTask = $response.Result.Content.CopyToAsync($outputFileStream)
$downloadTask.Wait()
 
# Chiudi lo stream del file
$outputFileStream.Close()

La demo qui segue mostra il risultato dell’esecuzione dello script PowerShell per scaricare il file.

All’inizio, la cartella contiene solo il file script. Viene richiesto di inserire il nome utente e la password. Successivamente, lo script procede al download del file. Dopo il download del file, è possibile vedere che il nuovo file si trova all’interno della cartella di destinazione.

Downloading a file using the .NET HttpClient class

Conclusione

Windows PowerShell e PowerShell Core hanno funzionalità integrate per scaricare file, agendo come un’alternativa a PowerShell wget! Sia che si tratti di fonti protette da password, di file singoli o multipli, è disponibile un modo PowerShell.

I metodi di download dei file descritti in questo articolo funzionano sia su Windows PowerShell che su PowerShell Core. Ciò significa che questi metodi si applicano sia a sistemi Windows che non Windows, con l’esclusione di Start-BitsTransfer.

E poiché PowerShell è più di un prompt dei comandi, è possibile tradurre ciò che si è appreso in script. Ciò significa che si ha l’opportunità di automatizzare le operazioni. Non più copiare gli URL, cliccare sui link e attendere i download manualmente.

Source:
https://adamtheautomator.com/powershell-download-file/