PowerShell Wget: Baixe arquivos com facilidade

Você precisa baixar arquivos da web, mas odeia clicar repetidamente em links? Se o seu trabalho envolve baixar arquivos da web regularmente, você provavelmente vai querer automatizar a tarefa. Por que não usar o PowerShell para baixar arquivos de forma semelhante ao wget do PowerShell?

O Windows PowerShell e o PowerShell vêm com capacidades de download de arquivos. Usar o PowerShell para baixar arquivos é uma questão de saber quais cmdlets e classes .NET usar e como usá-los.

Neste artigo, você aprenderá as várias maneiras de usar o PowerShell para baixar arquivos da web.

Pré-requisitos

Como este é um artigo de aprendizado prático, existem alguns pré-requisitos para garantir que você possa seguir os exemplos. Abaixo estão os requisitos básicos.

  • 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 ou PowerShell 7.1 (recomendado).
    • O Windows 10 já inclui o Windows PowerShell 5.1.
  • A web site that hosts the files to download.
    • Para downloads de arquivos não autenticados, considere usar o site Tele2 Speedtest, que é gratuito.
    • Se você quiser testar downloads de arquivos com autorização, talvez tenha que criar seu próprio servidor de arquivos HTTP. Um exemplo de um servidor de arquivos HTTP gratuito é HFS by Rejetto.

Usando o PowerShell para Baixar Arquivos de URLs: Quatro Maneiras

Há quatro métodos para usar o PowerShell para baixar arquivos que não dependem de ferramentas de terceiros. Estes são:

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

Independentemente do método que você escolher usar entre esses quatro, a lógica e os componentes para fazê-los funcionar são os mesmos. Deve haver uma URL de origem apontando para a localização do arquivo e o caminho de destino para salvar os arquivos baixados. Se necessário pelo servidor web, você também precisará inserir as credenciais.

As próximas seções mostram cada um desses quatro métodos. No final, cabe a você decidir qual caminho adaptar ao usar o PowerShell para baixar arquivos.

Usando Invoke-WebRequest como Alternativa do PowerShell para wget

O primeiro método no PowerShell para baixar arquivos é usando o cmdlet Invoke-WebRequest. Talvez o cmdlet mais utilizado neste artigo, Invoke-WebRequest, pode baixar links HTTP, HTTPS e FTP.

Independentemente de a localização da origem exigir que os usuários façam login, o cmdlet Invoke-WebRequest pode lidar com solicitações com credenciais também.

Para baixar um arquivo, a sintaxe abaixo mostra os parâmetros mínimos necessários para alcançar o resultado desejado.

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

Por exemplo, o código abaixo baixa um arquivo com o nome 10MB.zip de um site. Em seguida, ele salva o arquivo baixado em C:\dload\10MB.zip. Você pode copiar o código abaixo e colá-lo em sua sessão do PowerShell para testar.

# Localização do arquivo de origem
$source = 'http://speedtest.tele2.net/10MB.zip'
# Destino para salvar o arquivo
$destination = 'c:\dload\10MB.zip'
# Baixar o arquivo
Invoke-WebRequest -Uri $source -OutFile $destination

A demonstração abaixo mostra o resultado esperado após executar o código acima no PowerShell. Como você pode ver, o download do arquivo foi bem-sucedido.

PowerShell wget : Downloading a file using Invoke-WebRequest

E se a origem exigir autenticação antes de permitir o acesso? Por exemplo, o código abaixo baixa um arquivo de um site privado onde os usuários precisam fazer login.

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

No entanto, o download falhou devido ao acesso não autorizado.

Downloading failed due to unauthorized access

Se a autenticação for necessária, você deve adicionar uma credencial à solicitação usando o parâmetro -Credential. A primeira linha no código abaixo solicita que você insira a credencial (nome de usuário e senha) e a armazena na variável $credential.

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

A demonstração abaixo mostra o que você esperaria ver ao executar o código acima no PowerShell. Como você pode ver, o cmdlet Get-Credential solicitou uma solicitação de credencial do PowerShell. Desta vez, usando a credencial com Invoke-WebRequest, resultou em um download bem-sucedido.

Downloading a file with authentication

Relacionado: Usando o cmdlet Get-Credential do PowerShell e todas as coisas relacionadas a credenciais

Atenção aos erros de análise ao usar 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.

Você terá que reemitir seu comando, mas desta vez, inclua a opção -UseBasicParsing.

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

No Windows PowerShell, você pode receber uma mensagem de erro: O conteúdo da resposta não pode ser analisado porque o mecanismo do Internet Explorer não está disponível ou a configuração de primeira inicialização do Internet Explorer não está completa. Especifique o parâmetro UseBasicParsing e tente novamente.

Começando com o PowerShell Core 6.0, o cmdlet Invoke-WebRequest usa apenas análise básica. Como tal, o parâmetro -UseBasicParsing não é mais necessário.

Usando Invoke-RestMethod

O cmdlet Invoke-RestMethod é mais voltado para o envio de uma solicitação HTTP ou HTTPS para um serviço web RESTful. Este cmdlet é mais adequado para solicitações que interagem com APIs REST como a Graph API da Microsoft.

Quando se trata de baixar arquivos diretamente da web, Invoke-RestMethod é uma excelente opção. Não se deixe enganar pensando o contrário. Não há muita diferença entre usar Invoke-RestMethod e Invoke-WebRequest quando usados para baixar arquivos de um link web direto.

Baixando um arquivo usando Invoke-RestMethod

Para baixar um arquivo usando Invoke-RestMethod, use a sintaxe abaixo. Você notará que o comando utiliza os mesmos parâmetros que Invoke-WebRequest.

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

No código de exemplo abaixo, o arquivo é baixado do valor da URL na variável $source. Em seguida, salvo no caminho definido na variável $destination.

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

Se a fonte exigir autenticação, você pode passar as credenciais usando o parâmetro -Credential. O exemplo abaixo solicita as credenciais e as armazena na variável $credential. O valor da variável $credential é então passado para o parâmetro -Credential.

Também, como o link do arquivo é uma fonte HTTP e não HTTPS, significa que você está enviando uma autenticação não criptografada. Normalmente, você deve evitar o uso de fontes HTTP por questões de segurança. Mas se for necessário usar uma fonte HTTP, você precisa adicionar o interruptor -AllowUnencryptedAuthentication ao seu 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

Usando Start-BitsTransfer

Start-BitsTransfer é projetado especificamente para transferir arquivos entre computadores cliente e servidor. Este cmdlet do PowerShell depende do Serviço de Transferência Inteligente em Segundo Plano (BITS) que é nativo do sistema operacional Windows.

Porque Start-BitsTransfer requer o BITS para funcionar, significa que este cmdlet não está disponível em computadores não-Windows. Por outro lado, Start-BitsTransfer desfruta dos benefícios do BITS em si. Alguns desses benefícios são:

  • Sensibilidade à largura de banda e uso da rede.
  • Manuseio de interrupções (continuar, auto-continuar, pausar, etc.)
  • Download de vários arquivos como trabalhos em segundo plano.
  • Capacidade de definir prioridades para trabalhos de download.

Download de um Arquivo

A maneira fundamental de usar Start-BitsTransfer no PowerShell para baixar um arquivo é especificar uma origem e um destino. Ao usar o script abaixo, você só precisa alterar os valores de $source e $destination de acordo com seus requisitos.

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

Conforme demonstrado abaixo, o arquivo é baixado para o caminho c:\dload\100MB.zip.

Downloading a file using Start-BitsTransfer

Supondo que o destino não seja especificado, Start-BitsTransfer baixa e salva o arquivo no diretório de trabalho atual. Por exemplo, se você executar Start-BitsTransfer a partir de C:\dload, o arquivo será baixado para o mesmo diretório.

Para downloads que requerem autenticação, Start-BitsTransfer possui um parâmetro -Credential que aceita um objeto PSCredential.

Download de Múltiplos Arquivos

Para demonstrar o download de vários arquivos, você precisará criar um arquivo CSV com duas colunas. Nomeie o arquivo filelist.txt. A primeira coluna deve conter o link da origem, enquanto a segunda coluna deve conter o caminho de destino. O conteúdo do arquivo seria semelhante ao abaixo.

# source,destination
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

Relacionado: Gerenciando Arquivos CSV no PowerShell com Import-Csv

Assim que o arquivo CSV estiver pronto, utilize o comando abaixo para iniciar o download do arquivo. O comando importa o arquivo CSV usando Import-Csv e passa o conteúdo para Start-BitsTransfer.

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

Consulte a demonstração abaixo para ver como o código acima funciona. Como você pode ver, o download é iniciado e você acompanha o progresso do download. O prompt do PowerShell não está disponível durante o processo de download.

Starting a synchronous multiple file download

Suponha que você queira iniciar o processo de download como um trabalho em segundo plano. Para fazer isso, você só precisa adicionar o -Asynchronous switch no final do comando Start-BitsTransfer.

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

Inicialmente, o estado de cada trabalho mostrará conectando. A captura de tela abaixo mostra o ID de trabalho de cada download de arquivo.

Starting file download as background jobs

Agora que você iniciou o processo de download, você vai querer verificar se o download foi concluído. Para verificar o status do trabalho de download, use o cmdlet Get-BitsTransfer. Como você pode ver abaixo, o status dos trabalhos de download mudou para Transferred.

Viewing the file download job status

Usando a Classe WebClient e a Classe HttpClient (.NET Framework)

O PowerShell é baseado em .NET, e sua natureza permite que ele aproveite o poder do próprio .NET. Existem duas classes .NET que você pode usar no PowerShell para baixar arquivos; WebClient e HttpClient.

Se você deseja obter mais informações sobre essas duas classes .NET de maneira mais desenvolvida e técnica, você pode começar com → Quando usar WebClient vs. HttpClient vs. HttpWebRequest. Na próxima seção, você aprenderá como usar WebClient e HttpClient no PowerShell para baixar arquivos da web.

Download de um arquivo usando System.Net.WebClient

Para usar a classe WebClient, você precisa iniciar um objeto como um **tipo System.Net.WebClient**. No exemplo abaixo, o $webClient é o novo objeto System.Net.WebClient. Em seguida, usando o método DownloadFile(), inicia o download do arquivo da origem.

Relacionado: Usando Aceleradores de Tipos de Dados do PowerShell para Agilizar a Codificação

Por favor, copie o código abaixo e execute-o em sua sessão do PowerShell para testar. Observe que você não verá nenhum progresso ou saída na tela, a menos que haja um erro. No entanto, o prompt do PowerShell ficará bloqueado até que o download seja concluído.

# Defina o link de origem e o caminho de destino
$source = 'http://speedtest.tele2.net/10MB.zip'
$destination = 'c:\dload\10MB.zip'
# Crie o novo WebClient
$webClient = [System.Net.WebClient]::new()
# Faça o download do arquivo
$webClient.DownloadFile($source, $destination)

Se a fonte requer autenticação para permitir o download do arquivo, você pode usar o código abaixo. A primeira linha solicita as credenciais e as armazena na variável $credentials. O valor de $credential é então incluído na solicitação de download do arquivo.

# Solicitar nome de usuário e senha
$credentials = Get-Credential
$source = 'http://speedtest.tele2.net/10MB.zip'
$destination = 'c:\dload\10MB.zip'
# Criar o novo WebClient
$webClient = [System.Net.WebClient]::new()
# Adicionar a credencial
$webClient.Credentials = $credentials
# Baixar o arquivo
$webClient.DownloadFile($source, $destination)

De acordo com este documento da Microsoft: “Não recomendamos que você use a classe WebClient para novos desenvolvimentos. Em vez disso, use a classe System.Net.Http.HttpClient.”

Parece que a classe WebClient está obsoleta, e a nova classe que a Microsoft está endossando é a classe HttpClient. Mas não se preocupe. A próxima seção fala sobre como usar a classe HttpClient no PowerShell para baixar arquivos da web.

Download de um Arquivo usando System.Net.Http.HttpClient

Assim como a classe WebClient, você precisa primeiro criar o System.Net.Http.HttpClient. Usando o código abaixo, você pode baixar o arquivo da $source para o $destination. Consulte os comentários acima de cada linha para saber o que cada linha de código faz.

O código abaixo está ativo, e você pode testá-lo executando-o em sua sessão do PowerShell.

# Defina a origem e o destino
$source = 'http://speedtest.tele2.net/10MB.zip'
$destination = 'c:\dload\10MB.zip'
 
# Crie a solicitação de download do cliente HTTP
$httpClient = New-Object System.Net.Http.HttpClient
$response = $httpClient.GetAsync($source)
$response.Wait()
 
# Crie um fluxo de arquivo apontando para o destino do arquivo de saída
$outputFileStream = [System.IO.FileStream]::new($destination, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write)
 
# Transmita o download para o fluxo de arquivo de destino
$downloadTask = $response.Result.Content.CopyToAsync($outputFileStream)
$downloadTask.Wait()
 
# Feche o fluxo de arquivo
$outputFileStream.Close()

Em situações em que o download de um arquivo requer autenticação, você precisa adicionar as credenciais ao objeto HttpClient. Para incluir uma credencial na solicitação de download do arquivo, crie um novo objeto System.Net.Http.HttpClientHandler para armazenar as credenciais.

Você pode copiar o código abaixo e executá-lo no PowerShell para testar. Ou também pode executá-lo como um script do PowerShell. Neste exemplo, o código é salvo como download-file.ps1.

# Defina a origem e o destino
$source = 'http://speedtest.tele2.net/10MB.zip'
$destination = 'c:\dload\10MB.zip'
 
# Solicite credenciais
$credentials = Get-Credential

# Crie a solicitação de download do cliente HTTP com credenciais
$handler = New-Object System.Net.Http.HttpClientHandler
$handler.Credentials = $credentials
$httpClient = New-Object System.Net.Http.HttpClient($handler)
$response = $httpClient.GetAsync($source)
$response.Wait()
 
# Crie um fluxo de arquivo apontando para o destino do arquivo de saída
$outputFileStream = [System.IO.FileStream]::new($destination, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write)
 
# Transmita o download para o fluxo de arquivo de destino
$downloadTask = $response.Result.Content.CopyToAsync($outputFileStream)
$downloadTask.Wait()
 
# Feche o fluxo de arquivo
$outputFileStream.Close()

A demonstração abaixo mostra o resultado ao executar o script do PowerShell para baixar o arquivo.

No início, o diretório possui apenas o arquivo de script nele. Há um prompt para inserir o nome de usuário e senha. Em seguida, o script prossegue para baixar o arquivo. Após o download do arquivo, você pode ver que o novo arquivo está agora dentro do diretório de destino.

Downloading a file using the .NET HttpClient class

Conclusão

O Windows PowerShell e o PowerShell Core vêm com capacidades integradas para baixar arquivos, atuando como uma alternativa ao wget do PowerShell! Seja baixando fontes protegidas por senha, arquivos únicos ou múltiplos – um caminho do PowerShell está disponível para você.

Os métodos de download de arquivo abordados neste artigo funcionam tanto no Windows PowerShell quanto no PowerShell Core. Isso significa que esses métodos se aplicam tanto a sistemas Windows quanto não-Windows, com a exclusão do Start-BitsTransfer.

E como o PowerShell é mais do que um prompt de comando, você pode traduzir o que aprendeu em scripts. Para você, isso significaria uma oportunidade de automação. Não mais copiar URLs, clicar em links e esperar por downloads manualmente.

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