PowerShell Wget: Baixar arquivos com facilidade

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

O Windows PowerShell e o PowerShell possuem recursos 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á 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ê deseja testar o download de arquivos com autorização, talvez precise criar seu próprio servidor de arquivos HTTP. Um exemplo de servidor de arquivos HTTP gratuito é o HFS do Rejetto.

Usando o PowerShell para baixar arquivos de URLs: quatro maneiras

Existem quatro métodos para usar o PowerShell para baixar arquivos que não dependem de ferramentas de terceiros. São eles:

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

Independentemente do método escolhido 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 precisa inserir as credenciais.

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

Usando o Invoke-WebRequest como uma alternativa ao wget no PowerShell

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

Se a localização de 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 obter 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 pode ver, o download do arquivo foi bem-sucedido.

PowerShell wget : Downloading a file using Invoke-WebRequest

E se a fonte 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 a 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ê espera ver ao executar o código acima no PowerShell. Como 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 o sinalizador -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 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 sobre 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 o Microsoft Graph API.

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 usado 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 usa os mesmos parâmetros que Invoke-WebRequest.

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

No código de exemplo abaixo, o arquivo é baixado do valor de 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. Tipicamente, você deve evitar o uso de fontes HTTP por questões de segurança. Mas se você precisar usar uma fonte HTTP, é necessário adicionar o switch -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 PowerShell depende do Serviço de Transferência Inteligente em Segundo Plano (BITS) que é nativo do sistema operacional Windows.

Porque Start-BitsTransfer requer 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 próprio BITS. Alguns desses benefícios são:

  • Consciência de largura de banda e uso de rede.
  • Tratamento de interrupções (resumir, auto-resumir, pausar, etc.)
  • Download de vários arquivos como trabalhos em segundo plano.
  • Capacidade de definir prioridades de trabalho de download.

Downloading a File

A maneira fundamental de usar Start-BitsTransfer no PowerShell para baixar um arquivo é especificar uma origem e um destino. Usando 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

Como você pode ver na demonstração 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 de C:\dload, o arquivo será baixado para o mesmo diretório.

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

Baixando 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 para a origem, enquanto a segunda coluna deve conter o caminho de destino. O conteúdo do arquivo seria como o 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

Uma vez 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ê pode observar 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 interruptor -Asynchronous ao 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 cada trabalho de 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 Transferido.

Viewing the file download job status

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

O PowerShell é baseado no .NET, e sua natureza o torna capaz de aproveitar o poder do .NET em si. Existem duas classes .NET que você pode usar no PowerShell para baixar arquivos; WebClient e HttpClient.

Se deseja saber mais sobre essas duas classes .NET de uma forma mais desenvolvimentista 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.

Baixando 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-se o download do arquivo da fonte.

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

Por favor, copie o código abaixo e execute-o em sua sessão do PowerShell para testar. Note 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()
# Baixe o arquivo
$webClient.DownloadFile($source, $destination)

Se o recurso exigir 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 o uso da 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.

Baixando 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á em execução, 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()

Nas 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 de 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 você 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 contém apenas o arquivo de script. Há um prompt para inserir o nome de usuário e a senha. Em seguida, o script continua a baixar o arquivo. Após o download, você pode ver que o novo arquivo agora está 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 no PowerShell! Seja para baixar de fontes protegidas por senha, um único arquivo ou vários arquivos – há uma maneira PowerShell disponível para você.

Os métodos de download de arquivos 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 a sistemas não Windows, com a exclusão do Start-BitsTransfer.

E como o PowerShell vai além de um prompt de comando, você pode traduzir o que aprendeu para scripts. Isso significa uma oportunidade de automação para você. Sem mais copiar URLs, clicar em links e esperar por downloads manualmente.

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