How to handle file paths with special characters?

前端 未结 2 1121
青春惊慌失措
青春惊慌失措 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.

    0 讨论(0)
  • 2021-01-15 05:41

    So, I was able to figure out a solution that works as long as the brackets aren't empty [].

    Here's what I've got:

    Start-Process Powershell -Verb runas -ArgumentList "-ExecutionPolicy","Bypass","-File","`"$(Get-Item -LiteralPath $PSScriptRoot\elevated.ps1)`""
    

    Using this as the test path:

    C:\Users\Administrator\Desktop\Test Folder\badname-!@#$%^_+-=.,{}`~[&]()
    

    A path with empty brackets [] still doesn't work, but doesn't return an error. I'm assuming this means that it wasn't able to find a file in the expected path while interpreting the brackets as a wildcard still. Not sure if there's really anything that will fix that except maybe checking the path before running and throwing an error.

    0 讨论(0)
提交回复
热议问题