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.
¡Gran pregunta! Solo necesitaba descubrir cómo hacer lo mismo. – Noldorin
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