PowerShell — отправить переменную через Invoke-Command

У меня есть 3 сервера Windows 2016 и некоторые рутинные задачи, которые я хочу автоматизировать. Я новичок в PowerShell, поэтому я потратил много времени на поиск ответа в StackOverflow и "погуглил".

Моя задача сделать резервную копию некоторых файлов через 7zip на удаленном сервере.

Есть команда, которая отлично работает:

Invoke-Command -ComputerName 10.10.0.20 -ScriptBlock {start-Process  -wait-FilePath 'C:\Program Files\7-Zip\7z.exe' -ArgumentList 'a','-t7z','C:\BlueCollar_backup\bluecollar_121.zip','C:\Services\BlueCollar' -wait}

Но мне нужно добавить дату к имени архива bluecollar_121.zip, оно должно выглядеть как bluecollar_13.08.2018.zip

Я пробовал огромное количество вариантов, но безуспешно.

[string]$stime = get-date -f 'dd.MM.yyyy
Invoke-Command -ComputerName 10.10.0.20 -ScriptBlock {start-Process -FilePath 'C:\Program Files\7-Zip\7z.exe' -ArgumentsList 'a -t7z C:\BlueCollar_backup\bluecollar_'$stime'.zip C:\Services\BlueCollar' -wait}

Вторая попытка была:

[string]$stime = get-date -f 'dd.MM.yyyy
[string]$tmp1="C:\BlueCollar_backup\bluecollar_$stime.zip"
$command = {start-Process -FilePath 'C:\Program Files\7-Zip\7z.exe' -ArgumentsList 'a -t7z $stime C:\Services\BlueCollar' -wait}

И последняя попытка:

[string]$stime = get-date -f 'dd.MM.yyyy
$arguments = @()
$arguments += "a"
$arguments += "-t7z"
$arguments +=  "$tmp1"
$arguments +=  "C:\Services\BlueCollar"
Invoke-Command -ComputerName 10.10.0.20 -ScriptBlock {start-Process -FilePath 'C:\Program Files\7-Zip\7z.exe' -ArgumentList($arguments) -wait}

Они все не работают. Проблема в переменной $stime. Как поместить переменную $stime в Invoke-Command?

UPD1: Я решил эту проблему!

Invoke-Command -ComputerName '10.10.0.20' -ArgumentList  $stime -ScriptBlock{
$stime = $args[0]
start-Process -FilePath 'C:\Program Files\7-Zip\7z.exe' "a -t7z C:\BlueCollar_backup\bluecollar_$stime.zip C:\Services\BlueCollar" -wait
}

person Newbie21231    schedule 07.09.2018    source источник


Ответы (1)


Проблема в том, что компьютер, с которого вы выполняете команду, знает о переменной $stime, но удаленный компьютер этого не знает. Так что вы должны передать его.

Есть несколько вариантов, один из них — использовать переменную $Using.

[string]$stime = get-date -f 'dd.MM.yyyy
Invoke-Command -ComputerName 10.10.0.20 -ScriptBlock {
    start-Process -FilePath 'C:\Program Files\7-Zip\7z.exe' -ArgumentsList "a -t7z C:\BlueCollar_backup\bluecollar_$($Using:stime).zip C:\Services\BlueCollar" -wait
}

Другой вариант, который, возможно, выглядит немного чище, — сделать ваш ScriptBlock строкой текста, а затем передать его на удаленный компьютер:

$ScriptBlock=[ScriptBlock]::Create("start-Process -FilePath 'C:\Program Files\7-Zip\7z.exe' -ArgumentsList 'a -t7z C:\BlueCollar_backup\bluecollar_$stime.zip C:\Services\BlueCollar'")
Invoke-Command -ComputerName 10.10.0.20 -ScriptBlock $ScriptBlock

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

person ErikW    schedule 07.09.2018
comment
Ни один из вариантов не помог, есть ошибка. Не удается найти параметр, соответствующий имени параметра: ArgumentsList. + CategoryInfo: InvalidArgument: (:) [Start-Process], ParameterBindingException + FullyQualifiedErrorId: NamedParameterNotFound, Microsoft.PowerShell.Commands.StartProcessCommand + PSComputerName: 10.10.0.20 - person Newbie21231; 10.09.2018
comment
Я думаю, что это может быть «Список аргументов» вместо «Список аргументов». - person ErikW; 11.09.2018