PowerShell Wget: Загрузка файлов с легкостью

Вы нуждаетесь в загрузке файлов из Интернета, но ненавидите постоянные клики по ссылкам? Если ваша работа часто связана с загрузкой файлов из Интернета, вы, вероятно, захотите автоматизировать эту задачу. Почему бы не использовать PowerShell для загрузки файлов, подобно альтернативному варианту wget в PowerShell?

Windows PowerShell и PowerShell обладают возможностями загрузки файлов. Использование PowerShell для загрузки файлов – это вопрос знания, какие cmdlet’ы и классы .NET использовать и как их применять.

В этой статье вы узнаете различные способы использования PowerShell для загрузки файлов из Интернета.

Предварительные требования

Поскольку это статья “обучение через практику”, есть несколько предварительных требований, чтобы вы могли следовать примерам. Вот базовые требования.

  • 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 или PowerShell 7.1 (рекомендуется).
    • Windows 10 уже включает Windows PowerShell 5.1.
  • A web site that hosts the files to download.
    • Для неаутентифицированных загрузок файлов рассмотрите возможность использования сайта Tele2 Speedtest, который бесплатен.
    • Если вы хотите проверить загрузку файлов с авторизацией, вам может потребоваться создать свой HTTP-файловый сервер. Примером бесплатного HTTP-файлового сервера является HFS от Rejetto.

Использование PowerShell для загрузки файлов из URL: Четыре способа

Существует четыре метода использования PowerShell для загрузки файлов, которые не зависят от сторонних инструментов. Это:

  • Invoke-WebRequest
  • Invoke-RestMethod
  • Start-BitsTransfer
  • Класс .NET WebClient.

Какой из этих четырех методов вы используете, логика и компоненты для их работы одинаковы. Должен быть исходный URL, указывающий на местоположение файла, и путь назначения для сохранения загруженных файлов. Если это требуется веб-сервером, вам также нужно ввести учетные данные.

В следующих разделах показаны все четыре метода. В конце концов, решение о том, какой способ адаптировать при использовании PowerShell для загрузки файлов, остается за вами.

Использование Invoke-WebRequest в качестве альтернативы PowerShell для загрузки файлов

Первый метод в PowerShell для загрузки файлов – использование cmdlet Invoke-WebRequest. Возможно, самый используемый cmdlet в этой статье, Invoke-WebRequest, может загружать ссылки HTTP, HTTPS и FTP.

Независимо от того, требуется ли вход в систему на местоположении источника, cmdlet Invoke-WebRequest может обрабатывать запросы с учетными данными.

Для загрузки файла синтаксис ниже показывает минимальные параметры, необходимые для достижения желаемого результата.

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

Например, приведенный ниже код загружает файл с именем 10MB.zip с веб-сайта. Затем он сохраняет загруженный файл по пути C:\dload\10MB.zip. Вы можете скопировать приведенный ниже код и вставить его в вашу сессию PowerShell для тестирования.

# Местоположение исходного файла
$source = 'http://speedtest.tele2.net/10MB.zip'
# Место для сохранения файла
$destination = 'c:\dload\10MB.zip'
# Скачать файл
Invoke-WebRequest -Uri $source -OutFile $destination

Ниже приведено демонстрация ожидаемого результата после запуска приведенного выше кода в PowerShell. Как видите, загрузка файла прошла успешно.

PowerShell wget : Downloading a file using Invoke-WebRequest

Что, если для доступа требуется аутентификация? Например, приведенный ниже код загружает файл с частного веб-сайта, где пользователи должны войти в систему.

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

Однако загрузка не удалась из-за отсутствия авторизации.

Downloading failed due to unauthorized access

Если требуется аутентификация, вы должны добавить учетные данные к запросу, используя параметр -Credential. Первая строка в приведенном ниже коде приглашает вас ввести учетные данные (имя пользователя и пароль) и сохраняет их в переменной $credential.

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

Ниже приведена демонстрация того, что вы увидите при запуске вышеуказанного кода в PowerShell. Как видите, команда Get-Credential запросила учетные данные в PowerShell. На этот раз использование учетных данных с Invoke-WebRequest привело к успешной загрузке.

Downloading a file with authentication

Связано: Использование командлета PowerShell Get-Credential и все, что касается учетных данных

Проверка на наличие ошибок при разборе при использовании 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.

Вам придется повторить вашу команду, но на этот раз включите переключатель -UseBasicParsing.

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

В Windows PowerShell вы можете получить сообщение об ошибке: Содержимое ответа не может быть обработано, потому что движок Internet Explorer недоступен или не завершена первоначальная настройка Internet Explorer. Укажите параметр UseBasicParsing и попробуйте снова.

Начиная с PowerShell Core 6.0, cmdlet Invoke-WebRequest использует только базовый анализ. Следовательно, параметр -UseBasicParsing больше не требуется.

Использование Invoke-RestMethod

Cmdlet Invoke-RestMethod более предназначен для отправки HTTP- или HTTPS-запроса к веб-службе RESTful. Этот cmdlet более подходит для запросов, взаимодействующих с REST API, такими как Graph API Microsoft.

Когда речь идет о загрузке файлов прямо из Интернета, Invoke-RestMethod отличный вариант. Не дайте себя обмануть, полагая иначе. Между использованием Invoke-RestMethod и Invoke-WebRequest при загрузке файлов по прямой веб-ссылке нет большой разницы.

Загрузка файла с использованием Invoke-RestMethod

Чтобы загрузить файл с помощью Invoke-RestMethod, используйте синтаксис ниже. Обратите внимание, что команда использует те же параметры, что и Invoke-WebRequest.

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

В приведенном ниже коде файл загружается с URL-адреса, указанного в переменной $source. Затем он сохраняется по пути, определенному в переменной $destination.

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

Если для доступа к источнику требуется аутентификация, вы можете передать учетные данные, используя параметр -Credential. В приведенном ниже примере запрашиваются учетные данные и сохраняются в переменную $credential. Значение переменной $credential затем передается параметру -Credential.

Также, поскольку ссылка на файл является источником HTTP, а не HTTPS, это означает, что вы отправляете незашифрованную аутентификацию. Обычно следует избегать использования источников HTTP из соображений безопасности. Но если вам действительно необходимо использовать источник HTTP, вам нужно добавить переключатель -AllowUnencryptedAuthentication к вашей команде.

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

Использование Start-BitsTransfer

Start-BitsTransfer предназначен специально для передачи файлов между клиентскими и серверными компьютерами. Эта команда PowerShell зависит от Службы передачи фонового интеллектуального переноса (BITS), которая является встроенной в операционную систему Windows.

Поскольку Start-BitsTransfer требует BITS для работы, это означает, что эта команда недоступна на компьютерах с другими операционными системами, кроме Windows. С другой стороны, Start-BitsTransfer наследует преимущества самого BITS. Некоторые из этих преимуществ включают:

  • Осведомленность о пропускной способности и использовании сети.
  • Обработка прерываний (возобновление, автоматическое возобновление, пауза и т. д.)
  • Загрузка нескольких файлов в качестве фоновых заданий.
  • Возможность установки приоритетов загрузки файлов.

Загрузка файла

Основной способ использования Start-BitsTransfer в PowerShell для загрузки файла заключается в указании источника и места назначения. Используя скрипт ниже, вам нужно только изменить значения $source и $destination в соответствии с вашими требованиями.

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

Как видно из демонстрации ниже, файл загружается по пути c:\dload\100MB.zip.

Downloading a file using Start-BitsTransfer

Предположим, что место назначения не указано, Start-BitsTransfer загружает и сохраняет файл в текущем рабочем каталоге. Например, если вы запустите Start-BitsTransfer из C:\dload, файл будет загружен в тот же каталог.

Для загрузки файлов, требующих аутентификации, у Start-BitsTransfer есть параметр -Credential, который принимает объект PSCredential.

Загрузка нескольких файлов

Чтобы продемонстрировать загрузку нескольких файлов, вам нужно создать файл CSV с двумя столбцами. Назовите файл filelist.txt. Первый столбец должен содержать ссылку на источник, а второй столбец должен содержать путь назначения. Содержание файла должно выглядеть следующим образом.

# источник,назначение
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

Связано: Управление CSV-файлами в PowerShell с помощью Import-Csv

Как только файл CSV будет готов, используйте следующую команду для начала загрузки файла. Эта команда импортирует файл CSV с помощью Import-Csv и передает его содержимое в Start-BitsTransfer.

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

Обратитесь к демонстрации ниже, чтобы увидеть, как работает приведенный выше код. Как видите, загрузка начинается, и вы видите прогресс загрузки. При этом приглашение PowerShell недоступно во время процесса загрузки.

Starting a synchronous multiple file download

Предположим, вы хотите начать процесс загрузки в виде фоновой задачи. Для этого вам нужно всего лишь добавить переключатель -Asynchronous в конце команды Start-BitsTransfer.

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

Изначально состояние каждой задачи будет показано как connecting. На скриншоте ниже показан идентификатор каждой задачи загрузки файла.

Starting file download as background jobs

Теперь, когда вы начали процесс загрузки, вам захочется проверить, завершилась ли загрузка. Чтобы проверить состояние задачи загрузки, используйте командлет Get-BitsTransfer. Как видите ниже, состояние задач загрузки изменилось на Transferred.

Viewing the file download job status

Использование класса WebClient и класса HttpClient (.NET Framework)

PowerShell основан на .NET, и его природа позволяет использовать мощь самого .NET. В PowerShell вы можете использовать два класса .NET для загрузки файлов: WebClient и HttpClient.

Если вы хотите узнать больше о двух классах .NET в разработке и техническом плане, вы можете начать с → Когда использовать WebClient против HttpClient против HttpWebRequest. В следующем разделе вы узнаете, как использовать WebClient и HttpClient в PowerShell для загрузки файлов из Интернета.

Загрузка файла с помощью класса System.Net.WebClient

Для использования класса WebClient вам необходимо создать объект типа System.Net.WebClient. В приведенном ниже примере $webClient – это новый объект System.Net.WebClient. Затем с помощью метода DownloadFile() начинается загрузка файла из источника.

Связано: Использование ускорителей типов данных в PowerShell для ускорения кодирования

Скопируйте приведенный ниже код и запустите его в сеансе PowerShell для тестирования. Обратите внимание, что на экране не будет отображаться никакого прогресса или вывода, пока не произойдет ошибка. Однако командная строка PowerShell будет заблокирована до завершения загрузки.

# Определите исходную ссылку и путь назначения
$source = 'http://speedtest.tele2.net/10MB.zip'
$destination = 'c:\dload\10MB.zip'
# Создайте новый WebClient
$webClient = [System.Net.WebClient]::new()
# Загрузите файл
$webClient.DownloadFile($source, $destination)

Если для загрузки файла требуется аутентификация, вы можете использовать следующий код. Первая строка запрашивает учетные данные и сохраняет их в переменной $credentials. Значение $credential затем включается в запрос на загрузку файла.

# Запрос имени пользователя и пароля
$credentials = Get-Credential
$source = 'http://speedtest.tele2.net/10MB.zip'
$destination = 'c:\dload\10MB.zip'
# Создание нового WebClient
$webClient = [System.Net.WebClient]::new()
# Добавление учетных данных
$webClient.Credentials = $credentials
# Загрузка файла
$webClient.DownloadFile($source, $destination)

Согласно этому документу Microsoft: “Мы не рекомендуем использовать класс WebClient для новой разработки. Вместо этого используйте класс System.Net.Http.HttpClient.”

Похоже, что класс WebClient устарел, и новый класс, который поддерживает Microsoft, – это класс HttpClient. Но не волнуйтесь. В следующем разделе рассказывается о том, как использовать класс HttpClient в PowerShell для загрузки файлов из Интернета.

Загрузка файла с использованием System.Net.Http.HttpClient

Как и с классом WebClient, сначала вам нужно создать System.Net.Http.HttpClient. Используя приведенный ниже код, вы можете загрузить файл с $source в $destination. Обратитесь к комментариям над каждой строкой кода, чтобы узнать, что делает каждая строка.

Ниже приведен код, который можно выполнить в сеансе PowerShell, чтобы протестировать его.

# Установите исходный и целевой пути
$source = 'http://speedtest.tele2.net/10MB.zip'
$destination = 'c:\dload\10MB.zip'
 
# Создайте запрос на загрузку с использованием клиента HTTP
$httpClient = New-Object System.Net.Http.HttpClient
$response = $httpClient.GetAsync($source)
$response.Wait()
 
# Создайте поток файла, указывающий на файл для сохранения
$outputFileStream = [System.IO.FileStream]::new($destination, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write)
 
# Перенаправьте загрузку в поток файла для сохранения
$downloadTask = $response.Result.Content.CopyToAsync($outputFileStream)
$downloadTask.Wait()
 
# Закройте поток файла
$outputFileStream.Close()

В случае, когда загрузка файла требует аутентификации, вам необходимо добавить учетные данные в объект HttpClient. Чтобы добавить учетные данные к запросу на загрузку файла, создайте новый объект System.Net.Http.HttpClientHandler, чтобы сохранить учетные данные.

Вы можете скопировать приведенный ниже код и выполнить его в PowerShell для тестирования. Или вы также можете запустить его как сценарий PowerShell. В этом примере код сохранен в файле download-file.ps1.

# Установите исходный и целевой пути
$source = 'http://speedtest.tele2.net/10MB.zip'
$destination = 'c:\dload\10MB.zip'
 
# Запросите учетные данные
$credentials = Get-Credential

# Создайте запрос на загрузку с использованием клиента HTTP и учетными данными
$handler = New-Object System.Net.Http.HttpClientHandler
$handler.Credentials = $credentials
$httpClient = New-Object System.Net.Http.HttpClient($handler)
$response = $httpClient.GetAsync($source)
$response.Wait()
 
# Создайте поток файла, указывающий на файл для сохранения
$outputFileStream = [System.IO.FileStream]::new($destination, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write)
 
# Перенаправьте загрузку в поток файла для сохранения
$downloadTask = $response.Result.Content.CopyToAsync($outputFileStream)
$downloadTask.Wait()
 
# Закройте поток файла
$outputFileStream.Close()

Демонстрация ниже показывает результат при запуске сценария PowerShell для загрузки файла.

В начале в каталоге есть только файл сценария. Появляется приглашение ввести имя пользователя и пароль. Затем сценарий приступает к загрузке файла. После загрузки файла вы можете видеть, что новый файл теперь находится в целевом каталоге.

Downloading a file using the .NET HttpClient class

Заключение

Windows PowerShell и PowerShell Core имеют встроенные возможности для загрузки файлов, действуя как альтернатива wget в PowerShell! Будь то загрузка защищенных паролем источников, одного или нескольких файлов – у вас есть способ через PowerShell.

Методы загрузки файлов, описанные в этой статье, работают как в Windows PowerShell, так и в PowerShell Core. Это означает, что эти методы применимы как к системам Windows, так и к системам Non-Windows, за исключением Start-BitsTransfer.

И поскольку PowerShell – это не просто командная строка, вы можете перевести то, что узнали, в сценарии. Для вас это означает возможность автоматизации. Больше не нужно копировать URL-адреса, щелкать по ссылкам и ждать загрузки вручную.

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