Powershell: Uma variável dentro de uma variável; percepção variável

Powershell: Uma variável dentro de uma variável; percepção variável

Portanto, a maneira mais fácil de explicar meu problema é mostrar esta versão simplificada do que estou tentando fazer:

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

Agora o que eu realmente quero é que a invocação de $b retorne 'olá mundo!' mas aparentemente não consigo chamar uma variáveldentro deoutra variável como esta. Alguém tem alguma sugestão ou solução alternativa? Sinto que estou perdendo algo óbvio aqui.

Editar: uma versão mais precisa do que estou tentando fazer:

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!

Então, estou retirando a primeira linha de hosts.txt e configurando-a como $selhost, que é apenas 'spr-it-minion'. Em seguida, retiro a segunda linha do config.txt, que é apenas a string '$selhost está offline!' na esperança de que quando eu ligar para $a eu receba 'spr-it-minion is offline!' e não tenho certeza do que fazer.

Edit II: o conteúdo de hosts.txt e config.txt respectivamente.

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]

Edição III: OPastebinao meu roteiro real, se algum de vocês estiver interessado.

Linha 15: configurei $alertSubject para a string "$selhost está offline!" sem aspas nem nada.

Linha 82: Eu uso $alertSubject como linha de assunto de um alerta de e-mail, esperando que a variável que ele contém tenha seu valor representado como: "spr-it-minion está offline!" mas quando recebo o e-mail ou tento escrever-host $alertSubject em qualquer lugar do script, ele apenas diz "$selhost está offline!"

Responder1

Ao definir variáveis ​​no PowerShell, aspas simples ( ') significam que você deseja a versão literal da string. Use aspas duplas ( ") se quiser permitir a expansão de variáveis:

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

Mais informações:

Editar após comentários:

Para o seu exemplo, onde você está extraindo a linha de um arquivo, isso é um pouco mais complicado, pois está extraindo a linha como uma string literal.

A maneira mais fácil (IMO) seria usar oSubstituirmétodo; algo como:

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

Responder2

Ao ler uma string que contém um nome de variável de um arquivo para uma variável, você precisará de algo diferente de aspas duplas para causar a expansão da string. Existe uma ferramenta que é relevante aqui. Chama-se ExpandString. Dê uma olhada neste código de exemplo:

$selhost = 'spr-it-minion'

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

$c

O que está acontecendo aqui é que primeiro forneci valores literais $selhost e $b, semelhantes aos que você leria nos arquivos que está usando. Claro, $b não está certo, porque a referência a $selhost não foi resolvida, conforme descrito na resposta aceita. Mas $c obtém o valor produzido pela expansão de $selhost, que você pode usar em sua saída.

Deixarei de aplicar isso ao seu caso como um exercício de codificação.

Responder3

O que você está tentando fazer aqui é o Powershell dinâmico, ou seja, criar uma string que contenha um comando do Powershell e fazer com que o Powershell execute esse comando. Você pode fazer isso com Invoke-Expression, por exemplo:

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

Embora, para manutenção, você possa querer dividi-lo em algo como:

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

Os crases existem porque o comando que você realmente deseja executar é:

"$selhost is offline!"

As aspas externas permitem $config1ser expandidas antes que o valor seja passado para Invoke-Expression. Esse valor precisa incluir aspas duplas para que $selhostpossa ser expandido quando o comando for invocado.

Alternativamente, você pode colocar aspas duplas no arquivo de configuração:

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

e então é só ter

$alertSubject = Invoke-Expression -Command $config1

Nesse padrão, as aspas duplas externas $config1foram eliminadas porque são redundantes.

Responder4

O método replace funciona bem para variáveis ​​dentro da substituição de variáveis, mesmo ao chamar o PowerShell do 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

Observe o uso de aspas simples para procurar a variável interna a ser substituída pelo conteúdo da variável externa

O resultado é:

file1.doc
file2.doc
etc.

informação relacionada