Как загрузить файл через 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
То есть команда:
При этом после записи в этот файл, галка не уберётся.
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, а помом записать полученный результат удобным вам способом.
Рассмотрим свойства данного командлета:
Данный параметр обязательный и задаёт имя файла, в который будут записываться данные.
Если вы хотите узнать какая у вас версия сначала нужно выполнить импорт модуля:
Затем получить данные по командлетам:
Навигация по посту
Можно так же увидеть работающий сервис:
Из доступных методов аутентификации есть для прокси (ключ -ProxyAuthentication) и для конечного сервера (ключ -Authentication):
Скачивание файлов через Powershell BITS
Для начала скачивания нужно выполнить командлет:
Где:
-Source - откуда скачиваем
-Destination - куда
Режим по умолчанию синхронный. Об этом так же говорит подобная картинка:
Если при синхронной работе у нас или источника будут проблемы с каналом, выключится компьютер например, то процесс прервется без возможности восстановления. Так же будет если мы нажмем Ctr+C.
Для того что бы выполнить асинхронное скачивание нужно добавить ключ -Asynchronous:
В асинхронном режиме у нас появляется информация только о начатой задаче:
В предыдущей команде я добавил ключ -DisplayName, который дает имя задаче иначе оно будет по умолчанию. С помощью этой команды мне будет легче идентифицировать процесс и его статус:
Можно увидеть поля BytesTotal(сколько весит документ) и BytesTransferred (сколько скачено). Если у нас прервется соединение, то в асинхронном режиме никаких уведомлений не будет (в отличие от синхронного). Для того что бы увидеть проблему нужно еще раз запустить этот командлет:
Восстановление процесса произойдет либо через 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 * :
Мы можем скачать только определенный тип, добавив расширение:
Если мы используем асинхронное скачивание - не забываем завершить процесс:
Или использовать командлет Add-BitsFile, который позволяет добавлять файлы во время скачивания:
Загружать можно только файл. Вариант прогнать через цикл, но в таком случае будет множество процессов:
В документации Microsoft есть вариант использования CSV файлов через конвейер с Add-BitsFile, но у меня так и не сработало. Возможно или неверная документация.
Использование командлета Invoke-WebRequest
Попробуем выполнить следующую команду:
Invoke-WebRequest -Uri "http://winitpro.ru"
Как вы видите, возвращенный ответ представляет собой не простой HTML код страницы. Вы видите различные свойства web-документа. Командлет Invoke-WebRequest, как и большинство других командлетов PowerShell оперирует объектами. Invoke-WebRequest возвращает объект типа HtmlWebResponseObject. Посмотрим все свойства данного объекта:
$WebResponseObj = Invoke-WebRequest -Uri "http://winitpro.ru"
$WebResponseObj| Get-Member
Чтобы получить сырой HTML код веб страницы, который содержится в данном объекте, выполните:
Как вы видите, веб сервер вернул ответ 200, т.е. запрос выполнен успешно и веб сервер доступен и работает корректно.
Получаем список всех HTML ссылок на странице
Чтобы получить и сам текст ссылки (содержится в элементе InnerText), можно воспользоваться такой конструкцией:
Можно выбрать только ссылки с определенным CSS классом:
Или определенным текстом в url:
Парсинг 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\:
В качестве интересного примера использования командлета Invoke-WebRequest можно привести способ узнать внешнего IP адреса компьютера из PowerShell.
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
С помощью следующей конструкции сохраним информацию о куках (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 не удаляется.
При необходимости отменить задачу, сделать это можно следующим образом:
Возможные ошибки
При первом запуске скрипта может возникнуть ошибка вида:
Для устранения ошибки необходимо разрешить выполнение сценариев, сменив политику выполнения:
Файл для загрузки
В загружаемом файле приложена чуть более доработанная версия скрипта, с интерактивными диалоговыми окнами выбора файла-источника и каталога-назначения, а также возможностью выбора нескольких файлов.
Читайте также: