Powershell: una variable dentro de una variable; Concepción variable

Powershell: una variable dentro de una variable; Concepción variable

Entonces, la forma más fácil de explicar mi problema es mostrarles esta versión simplificada de lo que estoy tratando de hacer:

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

Ahora lo que realmente quiero es que la invocación de $b devuelva '¡hola mundo!' pero aparentemente no puedo llamar a una variabledentrootra variable como esta. ¿Alguien tiene alguna sugerencia o solución alternativa? Siento que me estoy perdiendo algo obvio aquí.

Editar: una versión más precisa de lo que estoy intentando hacer:

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!

Así que estoy sacando la primera línea de hosts.txt y configurándola en $selhost, que es simplemente 'spr-it-minion'. Luego saco la segunda línea de config.txt, que es solo la cadena '$selhost is offline!' con la esperanza de que cuando llame a $a aparezca '¡spr-it-minion está desconectado!' y no estoy seguro de qué hacer.

Edición II: el contenido de hosts.txt y config.txt respectivamente.

hosts.txt:

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

configuración.txt:

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

Edición III: ElPastebina mi guión real si alguno de ustedes está interesado.

Línea 15: Configuré $alertSubject en la cadena "¡$selhost está desconectado!" sin comillas ni nada.

Línea 82: uso $alertSubject como línea de asunto de una alerta de correo electrónico con la esperanza de que la variable que contiene tenga su valor representado como: "¡spr-it-minion está desconectado!" pero cuando recibo el correo electrónico o intento escribir-host $alertSubject en cualquier parte del script, simplemente dice "¡$selhost está desconectado!"

Respuesta1

Al definir variables en PowerShell, las comillas simples ( ') significan que desea la versión literal de la cadena. Utilice comillas dobles ( ") si desea permitir la expansión variable:

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

Más información:

Editar después de los comentarios:

Para su ejemplo en el que extrae la línea de un archivo, es un poco más complicado ya que extrae la línea como una cadena literal.

La forma más sencilla (en mi opinión) sería utilizar elReemplazarmétodo; algo como:

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

Respuesta2

Cuando lees una cadena que contiene un nombre de variable de un archivo a una variable, necesitarás algo más que comillas dobles para provocar la expansión de la cadena. Hay una herramienta que es relevante aquí. Se llama ExpandString. Eche un vistazo a este código de muestra:

$selhost = 'spr-it-minion'

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

$c

Lo que está pasando aquí es que primero le he dado valores literales a $selhost y $b, similares a los que leería en los archivos que está utilizando. Por supuesto, $b no es correcto, porque la referencia a $selhost no está resuelta, como se describe en la respuesta aceptada. Pero $c obtiene el valor producido al expandir $selhost, que puede usar en su salida.

Dejaré la aplicación de esto a su caso como ejercicio de codificación.

Respuesta3

Lo que intenta hacer aquí es Powershell dinámico, es decir, crear una cadena que contenga un comando de Powershell y luego hacer que Powershell ejecute ese comando. Puedes hacer esto con Invoke-Expression, por ejemplo:

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

Aunque, por razones de mantenimiento, es posible que desees dividirlo en algo como:

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

Las comillas invertidas están ahí porque el comando que realmente desea ejecutar es:

"$selhost is offline!"

Las comillas externas permiten $config1expandirse antes de pasar el valor Invoke-Expression. Ese valor debe incluir comillas dobles para que $selhostpueda expandirse cuando se invoque el comando.

Alternativamente, puedes poner comillas dobles en el archivo de configuración:

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

y luego solo tener

$alertSubject = Invoke-Expression -Command $config1

En este patrón, las comillas dobles exteriores $config1se han eliminado porque son redundantes.

Respuesta4

El método de reemplazo funciona bien para la sustitución de variables dentro de variables, incluso cuando se llama a PowerShell desde 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

Tenga en cuenta el uso de comillas simples para buscar la variable interna que se sustituirá por el contenido de la variable externa.

El resultado es:

file1.doc
file2.doc
etc.

información relacionada