Заметки о Windows и других программных продуктах Microsoft...

Копирование файлов на удаленный компьютер с помощью PowerShell

Копирование файлов на удаленный компьютер с помощью PowerShell

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

К примеру, нам необходимо скопировать файлы из локальной папки C:\Scripts на удаленный сервер DC02 в папку C:\Temp. Для начала попробуем такую команду:

Copy-Item -Path C:\Scripts -Destination \\DC02\Temp

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

Copy-Item -Path C:\Scripts -Destination \\DC02\C$\Temp

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

ошибка доступа к шаре

 

Для ввода альтернативных учетных данных у командлета Copy-Item имеется специальный ключ Credential, поэтому попробуем так:

Copy-Item -Path C:\Scripts -Destination \\DC02\C$\Temp -Credential $(Get-Credentials)

Однако и тут не все гладко. Оказывается Copy-Item не поддерживает ввод учетных данных для файловой системы.

ошибка при вводе учетных данных

 

Обойти это ограничение можно несколькими путями. Например командлет New-PSDrive позволяет указывать учетные данные, поэтому можно подмонтировать папку на удаленном компьютере как сетевой диск:

New-PSDrive -Name X -PSProvider FileSystem -Root ″\\dc02\C$\Temp″ -Credential $(Get-Credential)

Скопировать файлы с помощью Copy-Item:

Copy-Item -Path C:\Scripts -Destination ″X:″ -Recurse -Force

И удалить диск:

Remove-PSDrive -Name X -Force

монтирование сетевого диска

 

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

$session = New-CimSession -ComputerName dc02 -Credential $(Get-Credential)

Затем расшарим папку и выдадим к ней доступ:

New-SMBShare -Name ″Temp″ -Path ″C:\Temp″ -CimSession $session -Fullaccess ″Everyone″

На созданную шару скопируем нужные файлы:

Copy-Item -Path C:\Scripts -Destination \\DC02\Temp -Recurse -Force

И заметем следы:)

Remove-SMBShare -Name ″Temp″ -CimSession $session -Force
Remove-CimSession $session

создание шары на удаленном компьютере

 

И еще один вариант. В пятой версии PowerShell у командлета Copy-Item появились ключи ToSession и FromSession, дающие возможность копировать файлы прямо в удаленную сессию или из нее. Для примера создадим сессию на dc02:

$credentials = Get-Credential
$session = New-PSSession -ComputerName dc02 -Credential $credentials

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

Copy-Item -Path C:\Scripts -Destination C:\Temp -Recurse -ToSession $session

и обратно:

Copy-Item -Path C:\Temp -Destination C:\Temp -Recurse -Force -FromSession $session

копирование файлов с помощью ps remoting

 

Это самый удобный и, что немаловажно, безопасный способ. Но, к сожалению, он доступен только в PowerShell 5.0.

 
 
Комментарии

Есть еще один способ. Запускаете powershell от пользователя у которого есть права на сервер, и выполняете командлет copy-item с указанием административной шары.

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

Сергей

Еще один вариант — использовать BITS. Очень удобно для больших файлов — есть и докачка, и низкий приоритет можно задать, что бы не мешать работе других пользователей. Модуль BitsTransfer есть уже в PowerShell 2.0.

Запустить копирование:
Start-BitsTransfer -Source C:\Script\ -Destination \\DC02\C$\Temp -Priority high -Asynchronous

Посмотреть прогресс:
Get-BitsTransfer | % {$_.BytesTransferred / $_.BytesTotal * 100 }

Завершить копирование:
Get-BitsTransfer | Complete-BitsTransfer

Василь

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

Насколько помню, у PS тоже есть ограничение на длину пути. Robocopy нормальное решение, но если очень нужно именно PS, то можно включить поддержку длинных путей через реестр или GPO. Подробней здесь

Алекссей

есть задача для пользователя копировать на 3 сервера файл с обновленными отчетами, работает пользователь на 4м отдельном сервере для разработчиков, и сейчас разбираюсь с методом копирования файлов на эти три сервера, в Вашем предложении
$credentials = Get-Credential
$session = New-PSSession -ComputerName dc02 -Credential $credentials
я так понимаю будут запрашиваться права пользователя имеющего административный доступ.
как обходится это требование?
PS файл с отчетами относительно тяжелый более 100 мегабайт.

Вот здесь https://windowsnotes.ru/powershell-2/soxranenie-uchetnyx-dannyx-v-powershell/ я описывал, как сохранять учетные данные.

Подскажите пожалуйста, уже пару дней ищу пример в инете, не могу найти.
Мне нужно из винды закачать файл на линукс (в Hyper-V) через PS. Я уже это делал, но потерял эту команду, помню только, что она была очень длинная и начиналась на Copy-Item. Ни один пример из документации не сработал. Я подключаюсь по 22 (никакие ключи не генерю, в смысле не обмениваюсь, просто ввожу логин\пароль и в команде их также прописывал). На Линуксе PS не запускаю.

Copy-VMFile — вот чем пользовался! А вот если не на ВМ нужно закачать?
Где найти пример на invoke=webrequest = iwr, wget, curl ?

Если через PoSH, то есть PowerShell Remoting Over SSH: https://docs.microsoft.com/en-us/powershell/scripting/learn/remoting/ssh-remoting-in-powershell-core?view=powershell-6
Но я бы сделал проще, поднял бы NFS или SMB шару на линухе и подцепил ее к винде.

Leave a Reply to Алекссей