2009-11-03 15 views
25

Tengo un archivo template.txt que contiene lo siguiente:variables de expansión en el contenido del archivo

Hello ${something} 

me gustaría crear un script de PowerShell que lee el archivo y amplía las variables en la plantilla, es decir

$something = "World" 
$template = Get-Content template.txt 
# replace $something in template file with current value 
# of variable in script -> get Hello World 

¿Cómo podría hacer esto?

+0

¡Gran pregunta! Solo necesitaba descubrir cómo hacer lo mismo. – Noldorin

+1

Solo para reiterar un comentario sobre una respuesta a continuación, no sé de una forma de hacerlo (expansión variable) que no permita que se ejecuten expresiones arbitrarias. Dejé de usar variables de PowerShell y usé variables de entorno con '[System.Environment] :: ExpandEnvironmentVariables()' en su lugar. ¡Cualquier solución ** segura ** que use variables de powershell sería muy interesante! – Tao

Respuesta

26

Otra opción es utilizar ExpandString() ej .:

$expanded = $ExecutionContext.InvokeCommand.ExpandString($template) 

Invoke-Expresión también funcionará. Sin embargo, ten cuidado Ambas opciones son capaces de ejecutar código arbitrario por ejemplo:

# Contents of file template.txt 
"EvilString";$(remove-item -whatif c:\ -r -force -confirm:$false -ea 0) 

$template = gc template.txt 
iex $template # could result in a bad day 

Si usted quiere tener una eval cadena "seguro" y sin la posibilidad de ejecutar accidentalmente código a continuación, se pueden combinar los trabajos de PowerShell y espacios de ejecución para hacer precisamente eso restringida por ejemplo:

PS> $InitSB = {$ExecutionContext.SessionState.Applications.Clear(); $ExecutionContext.SessionState.Scripts.Clear(); Get-Command | %{$_.Visibility = 'Private'}} 
PS> $SafeStringEvalSB = {param($str) $str} 
PS> $job = Start-Job -Init $InitSB -ScriptBlock $SafeStringEvalSB -ArgumentList '$foo (Notepad.exe) bar' 
PS> Wait-Job $job > $null 
PS> Receive-Job $job 
$foo (Notepad.exe) bar 

Ahora bien, si se intenta utilizar una expresión en la cadena que utiliza un cmdlet, esto no va a ejecutar el comando:

PS> $job = Start-Job -Init $InitSB -ScriptBlock $SafeStringEvalSB -ArgumentList '$foo $(Start-Process Notepad.exe) bar' 
PS> Wait-Job $job > $null 
PS> Receive-Job $job 
$foo $(Start-Process Notepad.exe) bar 

Si wo A uld le gusta ver una falla si se intenta un comando, luego use $ ExecutionContext.InvokeCommand.ExpandString para expandir el parámetro $ str.

+0

¡Eso es perfecto, gracias! –

+0

Lo siento si estoy malinterpretando algo, pero hasta donde puedo decir, 'ExpandString() 'no es más seguro ... Sigue expandiendo la expresión, lo que significa que en su ejemplo, específicamente, todo en C: \ sigue borrado! ¿Quiso indicar que incluso con 'ExpandString()' código arbitrario ** también ** se ejecutará? – Tao

+0

(en el ejemplo anterior, '$ ExecutionContext.InvokeCommand.ExpandString ($ template)' resulta en un día igualmente malo!) – Tao

5

he encontrado esta solución:

$something = "World" 
$template = Get-Content template.txt 
$expanded = Invoke-Expression "`"$template`"" 
$expanded 
+2

Podría meterlo en problemas si hubiera código en el archivo. –

Cuestiones relacionadas