Reputation: 372
I have a declarative pipeline that should execute a powershell step for mounting a path.
The path is provided as a parameter:
parameters {
string(name: 'UNC', defaultValue: '\\\\server01.lab.local\\shared_data', description: 'Shared location to build-data')
}
When I use this value in a simple print, it is working as expected:
...
powershell('''
write-host "test: "${env:UNC}""
''')
...
So the next step was actually to mount it. However, it is not working as expected:
...
powershell('''
New-PSDrive -Name "k" -PSProvider "FileSystem" -Root "\"${env:UNC}\"\"
''')
...
The error that I'm getting here is: powershell.exe : New-PSDrive : A positional parameter cannot be found that accepts argument '\\server01.lab.local\shared_data'. New-PSDrive -Name "k" -PSProvider "FileSystem" -Root ""${ ...
This is when I understand that quoting is the issue. The Powershell command that does work is:
New-PSDrive -Name "k" -PSProvider "FileSystem" -Root "\\server01.labl.local\shared_data"
So what am I missing here in terms of escaping the quotes in the UNC path?
Thanks
Upvotes: 0
Views: 1736
Reputation: 437208
Do not try to quote ${env:UNC}
at all:
powershell('''
New-PSDrive -Name "k" -PSProvider "FileSystem" -Root ${env:UNC}
''')
In cases where you do need to escape "
inside "..."
, use `"
not \"
; e.g.,
"Nat `"King`" Cole"
yields verbatim Nat "King" Cole
- read on for more information.
Inside PowerShell, \
has no special meaning and instead it is `
(the so-called backtick) that serves as the escape character, namely in these contexts:
Inside double-quoted strings ("..."
)
"..."
only, you can use ""
as an alternative to `"
for escaping embedded "
chars (but the other two characters that require escaping inside "..."
, $
and `
itself, can only be escaped as `$
and ``
, respectively).In unquoted command arguments (not often seen); e.g.:
Get-Item C:\Program` Files # Note the escaped space char.
Note that `
isn't just used to signal that the next character is to be used verbatim, but also as the start of escape sequences representing control characters and, in PowerShell (Core) 6+ only, Unicode characters; e.g., "`t"
expands to a tab character, and "`u{fc}"
to ü
. See the conceptual about_Special_Characters topic.
Double-quoting variable references (or expression results) used as command arguments is never necessary in PowerShell (unless you explicitly need to convert to a string first).
E.g., the following works just fine:
$dir = 'C:\Program Files'
Get-Item $dir # NO need to double-quote $dir
If you really need to pass verbatim "
chars. as part of an argument's actual value:
Write-Output "Nat `"King`" Cole"
Note: Even when calling external executables double-quoting around variable references / expression isn't needed, because PowerShell then automatically applies double-quoting behind the scenes, as needed, based on whether a value contains spaces or not.
"
characters to external programs is still broken as of PowerShell 7.1, though a fix is finally being considered - see this answer.As for what you tried:
\
is not special in PowerShell (though it is needed to escape verbatim "
chars. in arguments to the PowerShell CLI[1]).
Therefore, "\"${env:UNC}\"\"
is parsed as follows:
"\"
is a double-quoted string with verbatim content \
. Since a quoted string at the start of a compound token (i.e. if directly followed by another quoted or unquoted token) is always considered an argument by itself, this value becomes its own argument. This notable pitfall is discussed in this answer.${env:UNC}\
expands to the value of environment variable UNC
followed by verbatim \
"\"
is again a double-quoted string with verbatim content \
; because it directly follows the unquoted token ${env:UNC}\
, it is considered part of the same argument.The following example, which outputs the arguments received enclosed in <...>
, each on its own line, demonstrates this:
PS> $env:UNC='foo bar';
& { foreach ($arg in $args) { "<$arg>" } } "\"${env:UNC}\"\"
<\>
<foo bar\\>
[1] This applies to powershell.exe
, the Windows PowerShell CLI; pwsh
, the PowerShell (Core) v6+ CLI, alternatively accepts ""
- see this answer for more information.
Upvotes: 3