Eine weitere Option ist ExpandString() z.B .:
$expanded = $ExecutionContext.InvokeCommand.ExpandString($template)
Invoke-Expression auch arbeiten zu verwenden. Aber sei vorsichtig. Beide Optionen sind in der Lage die Ausführung beliebigen Codes zB:
# 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
Wenn Sie einen „sicheren“ string eval ohne das Potenzial haben wollen, versehentlich Code ausführen, dann können Sie Powershell-Arbeitsplätze und beschränkt Runspaces kombinieren, um genau das zu tun zB:
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
Nun, wenn Sie einen Ausdruck in der Zeichenfolge zu verwenden versuchen, ein Cmdlet verwendet, wird dies den Befehl nicht ausführen:
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
wenn Sie WO Möchten Sie einen Fehler sehen, wenn ein Befehl versucht wird, verwenden Sie $ ExecutionContext.InvokeCommand.ExpandString, um den $ str-Parameter zu erweitern.
Große Frage! Ich musste nur herausfinden, wie ich das Gleiche machen kann. – Noldorin
Nur um einen Kommentar zu einer Antwort unten zu wiederholen, ich kenne keine Möglichkeit, dies zu tun (variable Erweiterung), die nicht erlaubt, dass beliebige Ausdrücke ausgeführt werden. Ich gab Powershell-Variablen auf und verwendete stattdessen Umgebungsvariablen mit '[System.Environment] :: ExpandEnvironmentVariables()'. Jede ** sichere ** Lösung mit Powershell-Variablen wäre sehr interessant! – Tao