How to handle file paths with special characters?

前端 未结 2 1120
青春惊慌失措
青春惊慌失措 2021-01-15 04:52

I\'ve got a PowerShell script that needs to be able to call another PS script from within the same directory with elevated credentials. Because the scripts need to be porta

2条回答
  •  野的像风
    2021-01-15 05:37

    As an aside: In PSv3+ you can use $PSScriptRoot to refer to the directory in which the script is located.
    If you can modify the target script, you can place Set-Location -LiteralPath $PSScriptRoot at the top to change to that folder.


    To avoid quoting/escaping problems, pass arguments individually, as distinct elements of an array to -ArgumentList (-Args):

    Start-Process powershell -Verb runas -ArgumentList '-ExecutionPolicy', 'Bypass', 
      '-File', "`"$dir\elevated.ps1`"", "`"$dir`""
    

    Unfortunately, that alone is not enough:

    • When you use -File, even though the arguments are passed individually, the script file path and the directory path still require embedded "..." quoting in order to pass values with embedded spaces correctly: "`"..."`" passes a value with embedded double-quoting (` is PowerShell's escape character, so `" escapes a double quote).Tip of the hat to Ansgar Wiechers.
      This bug has been reported on GitHub.

      • In case you ever need to pass an argument with embedded " characters (which filesystem paths by definition never contain), use something like:
        ('"{0}"' -f ($value -replace '"', '\"'))
    • Sadly, even that is not enough if your path contains [ characters that aren't each part of a syntactically valid wildcard-pattern range (e.g., [ab], [0-9]), because PowerShell - as of Windows PowerShell v5.1 / PowerShell Core v6.0.0-beta.6 - mistakenly interprets the path as a wildcard pattern and fails if it finds it malformed - see this GitHub issue.

      • In other words: your invocation may or may not work, depending on how [ and possibly ] are used in your path; e.g. foo[1] works, but foo[] doesn't.
      • There is currently no workaround that works in all cases.

    Alternative with -Command:

    -Commmand allows you to pass a piece of PowerShell code - a mini-script, if you will - which you can use to pass a single, quoted string that is parsed by PowerShell rules by the new instance:

    Start-Process powershell -Verb runas -ArgumentList '-ExecutionPolicy', 'Bypass', 
      '-Command', "& `"$dir\elevated.ps1`" `"$dir`""
    

    Note the need to use & to invoke the script, because it is given as a quoted string, and that the expansion of $dir is performed by the current session.

    Unfortunately, the problem with filenames that happen to look like malformed wildcard patterns (discussed above) applies to this invocation scenario too.

提交回复
热议问题