it-swarm.com.de

Das Entkommen von Dollarzeichen in PowerShell-Pfad funktioniert nicht

Warum funktioniert das nicht?


$drvrInstFilePath = "$sharePath\$imageName\ISO`$OEM$`$1\RPKTools\RPKDriverInst.bat"
echo $drvrInstFilePath
$drvrInstContent = Get-Content -LiteralPath "$sharePath\$imageName\ISO`$OEM$`$1\RPKTools\RPKDriverInst.bat"  | Out-String

Das Echo zeigt den richtigen Pfad, der Befehl "Get-Content" erweitert jedoch die Zeichenfolgen "$ oem" und "$ 1" in leere Zeichenfolgen, obwohl sie mit Escapezeichen versehen sind. Warum?

18
Belac

Verwenden Sie anstelle von durchgehenden Dollarzeichen einfache Anführungszeichen ' anstelle von doppelten Anführungszeichen ". Dadurch wird verhindert, dass PowerShell $ in eine Variable erweitert. Wie so

$p = "C:\temp\Share\ISO$OEM$"
# Output
C:\temp\Share\ISO$


$p = 'C:\temp\Share\ISO$OEM$'
# Output
C:\temp\Share\ISO$OEM$

Wenn Sie einen Pfad mithilfe von Variablen erstellen müssen, sollten Sie Join-Path verwenden. Wie so

$s = "share"
join-path "C:\temp\$share" 'Share\ISO$OEM$'
# Output
C:\temp\Share\ISO$OEM$
42
vonPryz

Sie haben doppelte Anführungszeichen mit einem einzigen Backtick verwendet. Dies ist eine falsche Kombination. Tatsächlich bin ich nicht sicher, ob ein einziger Backtick alleine in any case ausreicht. Ihre erfolgreichen Optionen, um dem Dollarzeichen ($) in PowerShell zu entgehen, sind die Verwendung doppelter Anführungszeichen mit einer Backslash-Backtick-Kombination ("\` $ find ") oder die Verwendung einfacher Anführungszeichen mit einem einfachen Backslash ( '\ $ find') . [Beachten Sie jedoch die Ausnahme am Ende der Funktionsaufrufparameter.] Beispiele finden Sie unten.

Für diejenigen, die mit der Unterscheidung nicht vertraut sind, ist es wichtig, das backtick - Zeichen (`) nicht mit dem -Zitat Zeichen (') in diesen Fluchten zu verwechseln.

[ERFOLG] Doppelte Anführungszeichen als Container mit Backslash-Backtick als Escape:

PS C:\Temp> 'What is $old?' | ForEach-Object {$_ -replace "\`$old", "(New)"}
What is (New)?
PS C:\Temp>

[FAIL] Anführungszeichen als Container mit Backslash-Apostroph als Escapezeichen:

PS C:\Temp> 'What is $old?' | ForEach-Object {$_ -replace "\'$old", "(New)"}
What is $old?
PS C:\Temp>

[ERFOLG] Einfache Anführungszeichen als Container mit einfachem Backslash als Escapezeichen:

PS C:\Temp> 'What is $old?' | ForEach-Object {$_ -replace '\$old', "(New)"}
What is (New)?
PS C:\Temp>

[FAIL] Einfache Anführungszeichen als Container mit Backslash-Backtick als Escape:

PS C:\Temp> 'What is $old?' | ForEach-Object {$_ -replace '\`$old', "(New)"}
What is $old?
PS C:\Temp>

Insgesamt kann die einfachste Option die Verwendung von einfachen Anführungszeichen als Container und eines einzelnen Backslash als Escapezeichen sein: '\$old'

Update : Als ob die oben genannten nicht verwirrend genug wären, wenn Sie einen Funktionsaufruf anstelle eines Befehls verwenden, sind einfache Anführungszeichen erforderlich ohne ein Escapezeichen. Wenn Sie versuchen, eine Escape-Anweisung für den Funktionsaufrufparameter zu verwenden, wird nicht work:

[FAIL] Verwenden eines Escape in einem Funktionsparameter:

PS C:\Temp> 'What is $old?' | ForEach-Object {$_.ToString().Replace('\$old', "(New)");}
What is $old?
PS C:\Temp>

[SUCCESS] Verwenden von einfachen Anführungszeichen ohne Escapezeichen in einem Funktionsparameter:

PS C:\Temp> 'What is $old?' | ForEach-Object {$_.ToString().Replace('$old', "(New)");}
What is (New)?
PS C:\Temp>
9
Michael

In meinem Fall musste ich einige der in einer Zeichenfolge verwendeten $-Zeichen entziehen, andere jedoch nicht als Variablen.

Beispielsweise hat mein SSRS-Instanzname ein $-Zeichen:

[ReportServer $ SSRS]

Um dem $ -Zeichen zu entgehen, verwende ich einfache Anführungszeichen. Ansonsten verwende ich die -join-Anweisung, um Variablen mit den Zeichenfolgen zu verketten, die tatsächliche $ -Zeichen enthalten.

 $sql = -join('ALTER DATABASE [ReportServer$', $instanceName,'TempDB]
  SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
  GO

  USE [master]
  RESTORE DATABASE [ReportServer$', $instanceName,'TempDB] FROM  DISK = N''C:\temp\ReportServerTempDB.BAK'' WITH  FILE = 1,
    MOVE N''ReportServerTempDB'' TO N''', $sqlDataDrive + "\data_" + $instanceName, '\ReportServer$', $instanceName,'TempDB.mdf'', 
    MOVE N''ReportServerTempDB_log'' TO N''', $sqlLogDrive + "\log_" + $instanceName, '\ReportServer$', $instanceName,'_TempDBlog.LDF'',  NOUNLOAD,  REPLACE, RECOVERY,  STATS = 5
  GO

  ALTER DATABASE [ReportServer$', $instanceName,'TempDB]
  SET MULTI_USER;
  GO
  ')
0
Jeremy Thompson