Powershell - команда «Копировать-элемент» в блок-скрипте Invoke-Command

Sep 02 2020

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

Что я пробовал: -

Хотя я использую следующие команды PowerShell, он работает нормально (означает, что файл скопирован с одного сервера на другой)

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

На самом деле файл существует по этому пути.

Я уже пытался сослаться на следующий вопрос-ответ о переполнении стека

  • Ошибка с командой PowerShell для копирования файла на удаленный сервер с учетными данными
  • Параметр Session в сценарии PowerShell имеет значение NULL или пусто
  • пульт дистанционного управления powershell
  • Invoke-Command с удаленным сеансом: невозможно проверить аргумент параметра
  • Невозможно скопировать двоичный файл на удаленную виртуальную машину Azure
  • Команда PowerShell для копирования файла на удаленный компьютер

Я также пытался получить помощь, используя

 Get-Help Invoke-Command

Вопрос :-

  1. Как я могу использовать команду «Copy-Item» внутри «Invoke-Command (Scriptblock)» в скрипте (2) для копирования файла?
  2. Есть ли лучший способ добиться этого (имеется в виду передовой опыт)?

Ответы

T-Me Sep 03 2020 at 19:50

Invoke-Commandимеет параметр, который -ArgumentListможно использовать для предоставления значений локальных переменных в удаленном сеансе. Проблема в том, что это просто ЗНАЧЕНИЕ переменной. Нет файла!

Что вы можете сделать:
Используйте Get-Content -Rawдля небольших файлов, чтобы сохранить константу в переменной. В целевой системе создайте New-Itemс помощью -Valueэтого файла. Однако это не очень эффективно.

Пример:

$txt = Get-Content -Raw -Path "C:\test\oldFile.txt" $Session = New-PSSession 127.0.0.1
Invoke-Command -Session $Session -ScriptBlock { Param($Txt) New-Item -Path c:\test\newFile.txt -Value $txt } -ArgumentList $txt 
#Get-PSSession | Remove-PSSession

Результат:

   Verzeichnis: C:\test    # Sry german OS


Mode                LastWriteTime         Length Name                      PSComputerName           
----                -------------         ------ ----                      --------------           
-a----       03.09.2020     12:23         658033 newFile.txt               127.0.0.1  

Что вы должны сделать:
Я думаю , что ваше использование Copy-Item -ToSession $Sessionявляется правильным способом сделать это. Он буквально создан специально для ваших целей. Обратной стороной является то, что целевой каталог должен существовать. Но в любом случае вам понадобится сеанс PSSession для обоих командлетов. Таким образом, вы можете использовать один Invoke-Commandи тот же сеанс PSSession. Сначала создайте сеанс PSSession. Используйте Invoke-Commandдля создания каталога. Затем используйте, Copy-Itemчтобы переместить файл в нужное место. Наконец, вы можете использовать его Invoke-Commandдля завершения некоторых шагов. И не забудьте, Remove-PSSessionкогда закончите:

$DestinationPath = "C:\test"
Invoke-Command -Session $Session -ScriptBlock { Param($Destination) New-Item -Path $Destination -ItemType Directory } -ArgumentList $DestinationPath
Copy-Item -Path "C:\test\oldFile.txt" -ToSession $Session -Destination "c:\test\newFile.txt" Invoke-Command -Session $Session -ScriptBlock { write-host "Do some stuff" }
$Session | Remove-PSSession