Как загрузить файл через powershell

Обновлено: 07.07.2024

В данной статье описано, как записать и получить данные из файла при работе с PowerShell.

Операторы перенаправления.

Рассмотрим ещё один пример:

Get-ChildItem : Не удается найти путь "C:\temp\skdjfsdlj" , так как он не существует . + CategoryInfo : ObjectNotFound : ( C : \ temp \ skdjfsdlj : String ) [ Get-ChildItem ] , ItemNotFoundException + FullyQualifiedErrorId : PathNotFound , Microsoft . PowerShell . Commands . GetChildItemCommand Get-ChildItem : Не удается найти путь "C:\temp\skdjfsdlj" , так как он не существует . + CategoryInfo : ObjectNotFound : ( C : \ temp \ skdjfsdlj : String ) [ Get-ChildItem ] , ItemNotFoundException + FullyQualifiedErrorId : PathNotFound , Microsoft . PowerShell . Commands . GetChildItemCommand

После выполнения команды в файле будет записан как и результат выполнения команды, так и ошибки:

Get-ChildItem : Не удается найти путь "C:\temp\asdfsadf" , так как он не существует . + CategoryInfo : ObjectNotFound : ( C : \ temp \ asdfsadf : String ) [ Get-ChildItem ] , ItemNotFoundException + FullyQualifiedErrorId : PathNotFound , Microsoft . PowerShell . Commands . GetChildItemCommand

В этом примере мы перенаправили второй поток вывода в первый, а первый поток записали в файл.

В PowerShell существуют следующие потоки:

Set-Content, Add-Content

Так же для записи в файл можно использовать командлеты Set-Content и Add-Content. Эти командлеты заменяет все данные в файле на указанные. Перед записью они преобразовывают объекты в строки и не всегда удобны. Зато они могут использоваться для массового изменения файлов. Простейшая их запись выглядит так:

При работе с файловой системой командлеты могут применять следующие параметры:

В этом параметре нужно указывать новое содержимое элементов.

PS C : \ Temp > Add-content -Path 1 . txt -value "Hello1" , "Hello2"

Название параметра можно опустить, тогда предыдущие примеры будет выглядеть так:

Данный параметр, так же можно передавать по контейнеру.

Но в файл попадут не данные как на консоли, а преобразованные в текстовые строки объекты.

Тоже самое произойдёт, если в параметр -value передать переменную:

PS C : \ temp > Set-content -literalPath 1 . txt , 2 . txt "Hello"

или можно добавить данные:

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

-Force

+ CategoryInfo : NotSpecified : ( : ) [ Set-Content ] , UnauthorizedAccessException + FullyQualifiedErrorId : System . UnauthorizedAccessException , Microsoft . PowerShell . Commands . SetContentCommand PS C : \ temp > Set-content -Path "C:\temp\1.txt" -value "33" -force

Тоже самое и для Add-Content:

+ CategoryInfo : NotSpecified : ( : ) [ Set-Content ] , UnauthorizedAccessException + FullyQualifiedErrorId : System . UnauthorizedAccessException , Microsoft . PowerShell . Commands . SetContentCommand PS C : \ temp > Add-Content -Path "C:\temp\1.txt" -value "33" -force

В этом параметре можно указать шаблон имени файла.

PS C : \ temp > Set-content -Path "C:\temp\*" , "C:\temp2\*" -Filter "*.txt" -value "Hello2" PS C : \ temp > Set-content -Path "C:\temp\*" , "C:\temp2\*" -Include "*.doc" , "*.txt" -value "33" -Exclude "1.txt"

или добавить содержимое:

PS C : \ temp > Add-Content -Path "C:\temp\*" , "C:\temp2\*" -Include "*.doc" , "*.txt" -value "33" -Exclude "1.txt" PS C : \ temp > Set-content -Path * . txt -Exclude ? . txt "22"

Так же и для Add-Content:

PS C : \ temp > Add-Content -Path * . txt -Exclude ? . txt "22"

-PassThru

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

PS C : \ temp > Get-ChildItem | Set-Content 1 . txt -PassThru | gm Address Method System . Object & , mscorlib , Version =2 . 0 . 0 . 0 , Culture = neutral , PublicKeyToken = b77a5c561934 . . . CopyTo Method System . Void CopyTo ( array array , int index ) , System . Void CopyTo ( array array , long index )

-Confirm

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

Выполнение операции "Установка содержимого" над целевым объектом "Путь: C:\temp\1.txt" . [ Y ] Да - Y [ A ] Да для всех - A [ N ] Нет - N [ L ] Нет для всех - L [ S ] Приостановить - S [ ? ] Справка

Данные командлеты позволяют писать в файл только строки, для записи в файл объектов используются следующие командлеты:

Out-File

В простейшем варианте этот командлет выглядит так:

Out-File может принимать следующие параметры:

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

Имя данного параметра можно опустить, как мы и сделали в предыдущем примере.

Полная запись будет выглядеть так:

-Append

При указании данного параметра данные будут дописываться, а не затираться.

Тоесть если мы запустим команду:

-NoClobber

Данный параметр предотвращает перезапись существующих данных.

Если запусnить команду :

При уже имеющемся файле 2.txt

То получится ошибка:

+ get - childitem | Out - File < < < < - FilePath 2.txt - NoClobber + CategoryInfo : ResourceExists : ( C : \ temp \ 2.txt : String ) [ Out - File ] , IOException + FullyQualifiedErrorId : NoClobber , Microsoft . PowerShell . Commands . OutFileCommand

Однако с параметром -Append

get-childitem | Out-File -FilePath 2 . txt -NoClobber -Append

Сохранности данных ничего не угрожает и данные благополучно допишутся в конец файла.

-Confirm

Параметр указывает, что перед выполнением команды у пользователя будет запрошено подтвержение.

При выполнении данной команды:

Выполнение операции "Вывод в файл" над целевым объектом "2.txt" . [ Y ] Да - Y [ A ] Да для всех - A [ N ] Нет - N [ L ] Нет для всех - L [ S ] Приостановить - S [ ? ] Справка

-Force

То есть команда:

PowershellAndFiles3

При этом после записи в этот файл, галка не уберётся.

get-childitem 234234f 2 > &1 | Out-file 2 . txt -Encoding "ASCII"

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

Например создадим вложенный массив :

Посмотрим на массив:

В данном примере и в файле и в консоле будет одно и тоже:

Запишем объект массива в файл, через параметр -InputObject:

Теперь в консоли будет выводиться :

Указывает максимальное кол-во символов в строке, при превышении данного значения, строка обрезается.

Получился вот такой файл:

Данный инструмент намного функциональней, чем просто перенаправление в файл, но он как и перенаправление имеет один не достаток, эти способы могут быть только в конце контейнера. И после данных выводов в файл объекты дальше не передаются. Это позволяет избежать следующий командлет:

Tee-Object

Этот командлет сохраняет отображаемые объекты и передаёт их дальше по контейнеру.

-FilePath

Так же с помощью свойства

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

Get-ChildItem * . txt | Tee-Object -Variable listfile | Get-Content

После выполнения этой команды в переменной $listfile будет содержаться объект типа System.IO.FileInfo

Так же как и в Out-File в Tee-Object можно передать переменную на командлет:

Только в PoverShell 3.0 Tee-Object научился дописывать в файл с помощью параметра

-Append

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

Get-ChildItem * . txt | Tee-Object 3 . txt -Append | Get-Content

После выполнения данной командой данные допишутся в конец файла 3.txt, а не будут перезаписывать файл.

Get-Content

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

У него есть ряд параметров, которые работают так же как и в Set-Content:

Задает путь к элементу. В отличие от значения параметра Path, значение параметра LiteralPath используется точно в том виде, в котором оно введено. Никакие символы не интерпретируются как подстановочные знаки. Если путь включает escape-символы, его нужно заключить в одиночные кавычки. Одиночные кавычки указывают оболочке Windows PowerShell, что никакие символы не следует интерпретировать как escape-символы.

PS C : \ Temp > Get-content -LiteralPath C : \ temp \ 1 . txt , C : \ temp \ 1 . txt , C : \ temp \ 1 . txt PS C : \ Temp > Get-content -LiteralPath C : \ temp \ 1 . txt , C : \ temp \ 1 . txt , C : \ temp \ 1 . txt | set-content 4 . txt PS C : \ Temp > Get-content -Path C : \ temp \ * . txt | set-content 5 . txt

Задает фильтр с использованием формата или языка поставщика. Значение этого параметра определяет значение параметра Path. Синтаксис фильтра, в том числе использование подстановочных знаков, зависит от поставщика. Фильтры эффективнее других параметров, потому что поставщик применяет их при извлечении объектов (вместо использования Windows PowerShell для фильтрации извлеченных объектов).

PS C : \ Temp > Get-content -Path C : \ temp \ * , C : \ temp2 \ * -filter * . csv | set-content 5 . csv Get-Content : Объект для указанного пути C : \ temp \ * не существует или отфильтрован с помощью параметра -Include или -Exc + Get-content < < < < -Path C : \ temp \ * , C : \ temp2 \ * -filter * . csv | set-content 5 . csv + CategoryInfo : ObjectNotFound : ( System . String [ ] : String [ ] ) [ Get-Content ] , Exception + FullyQualifiedErrorId : ItemNotFound , Microsoft . PowerShell . Commands . GetContentCommand PS C : \ Temp > Get-content -Path C : \ temp \ * -Include * . csv , * . txt | set-content 6 . txt Get-content -Path C : \ temp \ * -Exclude * . txt , * . csv | set-content 6 . doc

-Force

И два особенных параметра:

Данный параметр задает количество извлекаемых строк содержимого. По умолчанию используется значение -1 (все строки).

Данная команда вывела ровно 5 строк из файла 1.txt

Задаёт количество строк передаваемых по конвееру.

PS C : \ temp > Get-Content 1 . txt -ReadCount 5 | foreach < $_ + "-------" >

На примере видно, что строки передаются по 5 штук.

Если вывод происходит на консоль, то большое число в данном параметре может существенно увеличить скорость выдачи информации, но увеличит время ожидания до выдачи первых строк.

Данные команды конечно расширяют возможности работы с данными в файлах Powershell, но полученные данные с помощью операторов перенаправления или командлетами Out-File и Tee-Object больше подходят для логирования процессов, нежели для анализа данных. К тому же использовать полученные данные в дальнейших скриптах не тривиальная задача. Для решения этих проблем в PowerShell есть командлеты Import-CSV,Export-CSV, Export-Clixml, Import-Clixml. Рассмотрим их по отдельности:

Export-CSV

Раз я веду разговор о записи в файл, именно этот командлет мне нужен. Но стоит упоменуть о командлете ConvertTo-CSV. Так как Export-CSV выполняет все действия ConvertTo-CSV, а после записывает в файл. Поэтому если вам не хватает функционала работы с файлами командлета Export-CSV то вы можете конвертировать объекты PowerShell с помощью ConvertTo-CSV, а помом записать полученный результат удобным вам способом.

Рассмотрим свойства данного командлета:

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

Как работать с Powershell BITS

Если вы хотите узнать какая у вас версия сначала нужно выполнить импорт модуля:

Затем получить данные по командлетам:

BitsTransfer

Навигация по посту

Можно так же увидеть работающий сервис:

Из доступных методов аутентификации есть для прокси (ключ -ProxyAuthentication) и для конечного сервера (ключ -Authentication):

Скачивание файлов через Powershell BITS

Для начала скачивания нужно выполнить командлет:

Где:
-Source - откуда скачиваем
-Destination - куда

Режим по умолчанию синхронный. Об этом так же говорит подобная картинка:

BITS синхронный режим

Если при синхронной работе у нас или источника будут проблемы с каналом, выключится компьютер например, то процесс прервется без возможности восстановления. Так же будет если мы нажмем Ctr+C.

Для того что бы выполнить асинхронное скачивание нужно добавить ключ -Asynchronous:

В асинхронном режиме у нас появляется информация только о начатой задаче:

Start-BitsTransfer асинхронное скачивание

В предыдущей команде я добавил ключ -DisplayName, который дает имя задаче иначе оно будет по умолчанию. С помощью этой команды мне будет легче идентифицировать процесс и его статус:

Get-BitsTransfer информация о ходе процесса скачивания

Можно увидеть поля BytesTotal(сколько весит документ) и BytesTransferred (сколько скачено). Если у нас прервется соединение, то в асинхронном режиме никаких уведомлений не будет (в отличие от синхронного). Для того что бы увидеть проблему нужно еще раз запустить этот командлет:

Ошибка скачивания через BITS

Восстановление процесса произойдет либо через 10 минут (по умолчанию) либо в ручную. При этом, всегда когда мы работаем с существующим процессом BITS мы должны передавать объект либо через конвейер (как на примере ниже) либо через переменную. Если не указать имя для процесса, то Resume произойдет для всех:

При этом ключ -Asynchronous нужно указывать обязательно если не желаете синхронную.

Если мы передумали, то возможно выполнить Remove:

Если хотим приостановить процесс (подходит и для синхронной загрузке) можно использовать:

После окончания, в случае асинхронной работы, нам нужно завершить процесс командой:

Только после этого файл преобразуется из tmp.

Из неописанного есть ключ -UseStoredCredential , который проверит учетные данные в Windows Credential Manager или другие учетки с ключом -Credential.

Установка приоритета загрузки в Powershell BITS

У нас доступны 4 вида приоритетов загрузки

  • Foreground - задачи самого приоритетного плана с конкуренцией за канал. Стоит по умолчанию.
  • High - Используется только свободная часть канала, но приоритет среди других задач будет выше.
  • Normal - Только свободная часть канала, но приоритет ниже чем у High
  • Low - Самый низкий приоритет, только свободный канал.

Мы можем использовать этот приоритет во время начала закачивания:

Где:
-Priority - режим приоритета

Указываем приоритет загрузки уже у созданного, рабочего процесса:

Как и у Start, так и Set есть ключи для интервала возобновления загрузки:

Где:
-RetryInterval - То, сколько времени должно пройти для повторной попытки скачивания, в секундах. Минимально 60 секунд. По умолчанию 600 секунд (10 минут).
-RetryTimeout - В течении какого времени эти попытки будут происходить. По умолчанию в течение 14 дней. Если установить 0, то никаких попыток не будет.

Мы так же можем установить скорость для BITS, но это делается в политиках. Политики находятся:

Computer Configuration -> Administrative Templates -> Network -> Background Intelligent Transfer Service (BITS)

Загрузка через Powershell BITS

Для закачивания есть два значения, которые указываются в ключе -TranferType. Всего значения три:
-Download - по умолчанию.
-Upload
-UploadReply - загружает файл и получает копию.

Причем мы не сможем делать Upload для того что бы скачать одновременно скачивать файл и передавать на другой компьютер, а вот с Download можем.

Скачивание и загрузка множества файлов

Скачивать мы можем папками с помощью wildcard * :

Мы можем скачать только определенный тип, добавив расширение:

Если мы используем асинхронное скачивание - не забываем завершить процесс:

Завершение загрузки BITS

Или использовать командлет Add-BitsFile, который позволяет добавлять файлы во время скачивания:

Загружать можно только файл. Вариант прогнать через цикл, но в таком случае будет множество процессов:

В документации Microsoft есть вариант использования CSV файлов через конвейер с Add-BitsFile, но у меня так и не сработало. Возможно или неверная документация.

date

04.12.2018

directory

PowerShell

comments

комментариев 36 Совет. Командлет Invoke-WebRequest доступен в Windows PowerShell 3.0, поэтому перед началом работы убедитесь, что у вас используется эта или более свежая версия. Если на компьютере установлено несколько версий Posh, переключиться между ними можно так.

Использование командлета Invoke-WebRequest

Попробуем выполнить следующую команду:

Invoke-WebRequest -Uri "http://winitpro.ru"

Invoke-WebRequest обработка html страниц в powershell

Совет. Если вы подключены к Интернет через прокси-сервер то для корректной работы командлетов PoweShell, воспользуйтесь советами из статьи: Как настроить PowerShell для доступа через прокси-сервер.

Как вы видите, возвращенный ответ представляет собой не простой HTML код страницы. Вы видите различные свойства web-документа. Командлет Invoke-WebRequest, как и большинство других командлетов PowerShell оперирует объектами. Invoke-WebRequest возвращает объект типа HtmlWebResponseObject. Посмотрим все свойства данного объекта:

$WebResponseObj = Invoke-WebRequest -Uri "http://winitpro.ru"
$WebResponseObj| Get-Member

свойства объекта HtmlWebResponseObject

Чтобы получить сырой HTML код веб страницы, который содержится в данном объекте, выполните:

powershell: получить html код страницы и http заголовки

Как вы видите, веб сервер вернул ответ 200, т.е. запрос выполнен успешно и веб сервер доступен и работает корректно.

Получаем список всех HTML ссылок на странице

Invoke-WebRequest вывести список ссылок на html странице

Чтобы получить и сам текст ссылки (содержится в элементе InnerText), можно воспользоваться такой конструкцией:

Можно выбрать только ссылки с определенным CSS классом:

Или определенным текстом в url:

powershell фильтр объектов на html странице

Парсинг HTML страниц с помощью Powershell

Командлет Invoke-WebRequest позволяет довольно быстро и удобно парсить содержимое любых веб-страниц. При обработке HTML страницы из ее содержимого формируются коллекции ссылок (links), веб-форм (forms), изображений (images), скриптов (scripts) и т.д.

С помощью Powershell получим содержимое главной страницы нашего сайта:

$Img = Invoke-WebRequest "https://winitpro.ru/"

Затем выведем список всех изображений на данной странице:

Сформируем коллекцию из полных url путей к используемым изображениям:

$images = $Img.Images | select src

Инициализируем новый экземпляр класса WebClient:

И скачаем все изображения со страницы (с оригинальными именами) в каталог c:\tools\:

Пример парсинга html страницы на powershell

В качестве интересного примера использования командлета Invoke-WebRequest можно привести способ узнать внешнего IP адреса компьютера из PowerShell.

Аналог wget на powershell: как скачать файл по http

Invoke-WebRequest "https://download.mozilla.org/?product=firefox-32.0.3-SSL&os=win&lang=ru" -outfile “c:\tools\firefox setup 32.0.3.exe”

Таким образом вы с легкостью можете на определенной веб-странице найти все ссылки, попадающие под конкретные критерии (класс ссылки, разрешение в имени файла, url адрес), и скачать файлы по полученным ссылкам. Например, имеется некий сайт с кучей ссылок на PDF документы. Ваша задача скачать все эти файлы на ваш компьютер. Костяк PowerShell скрипта для массовой скачки файлов может выглядеть так:

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

В PowerShell 6.1 команделт Invoke-WebRequest поддерживает режим докачки. Таким образом с помощью параметра Invoke-WebRequest -Uri $Uri -OutFile $OutFile –Resume вы можете возобновить загрузку файла в случае падения канала или сервера.

Заполнение и отправка веб-форм на Powershell

powershell аутентификация с помощью веб форм на mailru

С помощью следующей конструкции сохраним информацию о куках (Cookies) подключения в отдельной сессионной переменной:

Следующей командой отобразим список заполняемых полей в HTML форме авторизации (форма называется LoginExternal):

Присвоим нужные значения всем полям:

Чтобы передать заполненную форму на веб сервер, вызовем атрибут HTML-формы action.

$Log = Invoke-WebRequest -method POST -URI ("https://e.mail.ru/login" + $mailru.Forms["LoginExternal"].Action) -Body $mailru.Forms["LoginExternal"].Fields -WebSession $session

Недостатки командлета Invoke-WebRequest

Другая проблема – командлет Invoke-WebRequest тесно связан с Internet Explorer. Например, в редакциях Windows Server Core, в которых IE не установлен, командлет Invoke-WebRequest использовать нельзя.

При работе на серверах в режиме подключения Remote Desktop Connection (RDP) постоянно возникает необходимость копирования/перемещения файлов между локальной и удаленной машиной. Для этого в подключении настраивается "проброс" дисков и буфера обмена локальной машины. Файлы копируются обычным способом в проводнике удаленной машины или просто через буфер обмена.

Такой "обычный" метод прекрасно работает до тех пор, пока файлы не оказываются сравнительно большими или соединение недостаточно стабильным. А большинство файлов, которые необходимо скопировать, как раз и являются большими: дистрибутивы, конфигурации, выгрузки баз, архивы логов, бэкапы и т.д. Загрузка / выгрузка таких файлов не всегда проходит успешно. Малейшая нестабильность канала приводит к обрыву передачи с ошибкой. Иногда приходится возобновлять передачу вновь и вновь и вновь, что может длиться часами. Особенно, если размер файла составляет несколько Гигабайт.


И если на серверах, которыми владеете Вы или Ваша Компания, возможны другие варианты организации файлообмена, кроме как по RDP-соединению, то к серверам, находящихся в инфраструктуре Заказчика, чаще всего есть только RDP доступ (к тому же, в большинстве случаев, через VPN) и организация альтернативных способов требует согласования со службой информационной безопасности Заказчика.


Однажды, после того как выгрузка нескольких гигабайт архивированных логов ТехЖурнала с продуктивной системы в контуре Заказчика для отправки на контроль в

Целью заметки не является подробное описание данного протокола. В Сети достаточно материала, в том числе и на русском языке. Сосредоточимся лишь на практическом применении в отношении RDP-сессий.

Реализация

При решении задачи я воспользовался реализацией скрипта на PowerShell

Для примера будем загружать с локальной машины на удаленную дистрибутив сервера 1С, т.к. доступа к Интернет с самого сервера нет.

Ниже привожу основную, рабочую часть скрипта. Достаточно указать в параметрах -Source и -Destination свои пути к файлам. Оба пути - с удаленной машины. Один указывает на локальный диск, второй - на "проброшенный" (\\tsclient)

Служба может работать в обе стороны, т.е. как скачивать на удаленную машину с локальной, так и закачивать с удаленной на локальную. Достаточно поменять местами значения параметров -Source и -Destination.

Запускать скрипт нужно на удаленной машине, т.е. в RDP-сессии.

Совет: самый простой способ добавить путь к файлу - найти его в проводнике, выделить, нажать Shift+ПКМ и выбрать "Копировать как путь". Что сделать дальше со строкой в буфере, полагаю и так все знают.

После запуска скрипт демонстрирует прогресс операции в процентах.


Можно в любой момент прервать его выполнение по Ctrl-C или закрыв окно. При следующем запуске через несколько минут можно заметить что процент выполнения будет больше того, на котором был произведен обрыв. Таким же образом будет возобновлена передача файлов после повторного соединения при обрыве связи или отключении сессии. При настройках по умолчанию, следующая попытка после неудачной предпринимается через 10 минут. Чтобы не ожидать автоматического возобновления, можно запустить скрипт повторно.


Если оставить задачу "без присмотра", т.е. без работающего скрипта, то загрузка выполнится, но загружаемые файлы не появятся в целевом каталоге. Вернее, в нём будут временные файлы вида "BIT5F71.tmp". Для того, чтобы в каталоге назначения объявились "правильные" файлы, необходимо выполнить "финализацию", при которой созданные временные файлы будут переименованы и задание службы будет удалено.

Сделать это можно, просто повторно запустив скрипт. Либо выполнить в консоли:


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


Как уже было показано, при завершении скрипта по Ctrl-C или закрытием окна и даже выходом из сессии, задача BITS-transfer не удаляется.

При необходимости отменить задачу, сделать это можно следующим образом:

Возможные ошибки

При первом запуске скрипта может возникнуть ошибка вида:

Для устранения ошибки необходимо разрешить выполнение сценариев, сменив политику выполнения:

Файл для загрузки

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

Читайте также: