Powershell: Переменная внутри переменной; Variableception

Powershell: Переменная внутри переменной; Variableception

Поэтому самый простой способ объяснить мою проблему — показать вам упрощенную версию того, что я пытаюсь сделать:

PS C:\> $a = 'hello'
PS C:\> $a
hello
PS C:\> $b = '$a world!'
PS C:\> $b
$a world!

Теперь я действительно хочу, чтобы вызов $b возвращал «Привет, мир!», но я, по-видимому, не могу вызвать переменнуюв пределахanther переменная вроде этой. Есть ли у кого-нибудь предложения или обходные пути? Мне кажется, я просто упускаю что-то очевидное.

Редактировать: более точная версия того, что я пытаюсь сделать:

PS C:\> $selHost = (get-content c:\scripts\hosts.txt)[0]
PS C:\> $selhost
spr-it-minion
PS C:\> $a = (get-content c:\scripts\config.txt)[1]
PS C:\> $a
$selhost Is Offline!
PS C:\> $b = "$a"
PS C:\> $b
$selhost Is Offline!

Итак, я вытаскиваю первую строку из hosts.txt и устанавливаю ее в $selhost, что просто 'spr-it-minion'. Затем я вытаскиваю вторую строку из config.txt, которая просто строка '$selhost is offline!' в надежде, что когда я вызову $a, я получу 'spr-it-minion is offline!', и я не уверен, что делать.

Редактирование II: содержимое hosts.txt и config.txt соответственно.

hosts.txt:

spr-it-minion
spr-saflok
spr-crosby
spr-vmhost01
spr-vmhost02
spr-vmhost03

config.txt:

172.31.1.124
$selhost Is Offline!
$selhost Is Offline!
[email protected]
[email protected]

Редактировать III:Pastebinк моему настоящему сценарию, если кому-то из вас интересно.

Строка 15: Я устанавливаю $alertSubject на строку «$selhost is offline!» без кавычек или чего-либо еще.

Строка 82: Я использую $alertSubject в качестве темы оповещения по электронной почте, надеясь, что содержащаяся в ней переменная будет иметь свое значение, представленное следующим образом: «spr-it-minion is offline!» Но когда я получаю электронное письмо или пытаюсь написать $alertSubject-host в любом месте скрипта, он просто сообщает: «$selhost is offline!»

решение1

При определении переменных в PowerShell одинарные кавычки ( ') означают, что вам нужна буквальная версия строки. Используйте двойные кавычки ( "), если вы хотите разрешить расширение переменной:

PS C:\> $a = "hello"
PS C:\> $a
hello
PS C:\> $b = "$a world!"
PS C:\> $b
hello world!

Больше информации:

Редактировать после комментариев:

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

Самый простой способ (ИМХО) — использоватьЗаменятьметод; что-то вроде:

$selHost = (get-content c:\scripts\hosts.txt)[0]
$a = ((get-content c:\scripts\config.txt)[1]).replace('$selhost', $selHost)

решение2

Когда вы считываете строку, содержащую имя переменной, из файла в переменную, вам понадобится что-то другое, чем двойные кавычки, чтобы вызвать расширение строки. Есть инструмент, который здесь уместен. Он называется ExpandString. Взгляните на этот пример кода:

$selhost = 'spr-it-minion'

$b = '$selhost is offline!'
$c = $ExecutionContext.InvokeCommand.ExpandString($b)

$c

Здесь происходит следующее: сначала я задал $selhost и $b литеральные значения, похожие на те, которые вы бы считывали из используемых вами файлов. Конечно, $b не подходит, потому что ссылка на $selhost не разрешена, как указано в принятом ответе. Но $c получает значение, полученное путем расширения $selhost, которое вы можете использовать в своем выводе.

Я оставлю применение этого к вашему случаю в качестве упражнения по кодированию.

решение3

То, что вы пытаетесь сделать здесь, это динамический Powershell, т.е. создать строку, которая содержит команду Powershell, а затем заставить Powershell выполнить эту команду. Вы можете сделать это с помощью Invoke-Expression, например:

$alertSubject = Invoke-Expression -Command "`"$((Get-Content '.\config.txt')[1])`""

Хотя для удобства поддержки вы можете разбить его на что-то вроде:

$config1 = (Get-Content '.\config.txt')[1]
$alertSubject = Invoke-Expression -Command "`"$config1`""

Обратные кавычки нужны, потому что команда, которую вы на самом деле хотите выполнить, выглядит так:

"$selhost is offline!"

Внешние кавычки позволяют $config1расширить значение до того, как оно будет передано в Invoke-Expression. Это значение должно включать двойные кавычки, чтобы его $selhostможно было расширить при вызове команды.

В качестве альтернативы вы можете поместить двойные кавычки в файл конфигурации:

172.31.1.124
"$selhost Is Offline!"
"$selhost Is Offline!"
[email protected]
[email protected]

а затем просто иметь

$alertSubject = Invoke-Expression -Command $config1

В этом шаблоне внешние двойные кавычки $config1опущены, поскольку они излишни.

решение4

Метод replace хорошо работает для подстановки переменных внутри переменных, даже при вызове powershell из Autohotkey:

uri = file$k.doc

psScript2 =
(
param($param1)
for($k=1; $k -le 6; $k++){
$uri = $param1.replace('$k',"$k")
echo $uri
}
)

Run PowerShell.exe -noexit -Command &{%psScript2%} '%uri%',, show
return

Обратите внимание на использование одинарных кавычек для поиска внутренней переменной, которая должна быть заменена содержимым внешней переменной.

Результат:

file1.doc
file2.doc
etc.

Связанный контент