![Powershell: Uma variável dentro de uma variável; percepção variável](https://rvso.com/image/1449093/Powershell%3A%20Uma%20vari%C3%A1vel%20dentro%20de%20uma%20vari%C3%A1vel%3B%20percep%C3%A7%C3%A3o%20vari%C3%A1vel.png)
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:
- Aspas simples versus aspas duplas no PowerShell: qual é a diferença?
- Referenciando variáveis e valores de variáveis
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 $config1
ser expandidas antes que o valor seja passado para Invoke-Expression
. Esse valor precisa incluir aspas duplas para que $selhost
possa 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 $config1
foram 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.