![Powershell: Переменная внутри переменной; Variableception](https://rvso.com/image/1449093/Powershell%3A%20%D0%9F%D0%B5%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F%20%D0%B2%D0%BD%D1%83%D1%82%D1%80%D0%B8%20%D0%BF%D0%B5%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D0%BE%D0%B9%3B%20Variableception.png)
Поэтому самый простой способ объяснить мою проблему — показать вам упрощенную версию того, что я пытаюсь сделать:
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.