Как и в исходном вопросе, если все содержимое вашего блока скриптов не является строкой (но вы этого хотите), и вам требуется подстановка переменных внутри блока скриптов, вы можете использовать следующее:
$ExecutionContext.InvokeCommand.ExpandString($b)
Вызов .InvokeCommand.ExpandString($b)
в текущем контексте выполнения будет использовать переменные в текущей области действия для подстановки.
Ниже приведен один из способов создания скриптового блока и извлечения его содержимого:
$a = "world"
$b = [ScriptBlock]::create("write-host hello $a")
$b
write-host hello world
Вы также можете использовать нотацию скриптового блока {}
, чтобы выполнить то же самое, но вам нужно использовать оператор вызова &
:
$a = "world"
$b = {"write-host hello $a"}
& $b
write-host hello world
Особенность использования вышеописанного метода заключается в том, что если вы в любое время измените значение $a
и затем снова вызовете блок скриптов, выходные данные будут обновлены следующим образом:
$a = "world"
$b = {"write-host hello $a"}
& $b
write-host hello world
$a = "hi"
& $b
write-host hello hi
Метод GetNewClosure()
можно использовать для создания клона приведенного выше блока скрипта, чтобы сделать теоретический снимок текущей оценки блока скрипта. Он будет защищен от изменения значения $a
, а затем кода:
$b = {"write-host hello $a"}.GetNewClosure()
& $b
write-host hello world
$a = "new world"
& $b
write-host hello world
Обозначение {}
обозначает объект блока скрипта, как вы, вероятно, уже знаете. Это может быть передано в Invoke-Command
, что открывает другие варианты. Вы также можете создать параметры внутри блока скрипта, которые можно будет передать позже. См. about_Script_Blocks для получения дополнительной информации.