Reputation: 1547
This seems like it should be a trivial thing.
I am using Powershell v5.1 and I am trying to build a UNC path from 2 strings that represent a server and a share. Given that $Server hold "Distribution" and $Share holds "Publish"...
$Path = "\\" + $Server + "\" + $Share
The output I am getting for $Path is..
\\Distribution Publish\
I tried changing it to...
$Path = "//" + $Server + "/" + $Share
...as a test thinking the special character "\" was causing a problem, but then I still get the odd sequence where there is a space between server and share and the 2nd slash is at the end.
//Distribution Publish/
What am I missing?
Upvotes: 2
Views: 4227
Reputation: 440182
As mentioned in the comments, your symptoms cannot be explained if your $Server
and $Share
variables truly contain just Distribution
and Publish
, respectively, with no hidden control characters.
Here's a contrived example of variable values that do produce your symptom:
> $Server = 'Distribution', 'Publish'; $Share = "`r"; "\\" + $Server + "\" + $Share
\\Distribution Publish\
As James C. points out, a more concise alternative for building the string is: "\\$Server\$Share"
.
As TheIncorrigible1 points out, it is better to build paths using Join-Path
.
'Distribution', 'Publish'
is an array of strings, whose elements PowerShell concatenates with a space (by default) when converting it to a string, which in this case results in Distribution Publish
.
"`r"
creates control character CR (0xD
), which, when printing to the console, resets the cursor position to the first column and prints the remainder of the string there (which in this case is empty).
Note, however, that the CR is still a part of the string, albeit an invisible one.
If you want an easy way to inspect a given string for hidden control characters, see this answer of mine.
Update:
The OP reports that it turned out to be how the $Server
and $Share
variables were bound via parameters, through mistaken use of (C#) method-invocation syntax:
# Correct invocation: $Server binds to 1st parameter, $Share to 2nd.
./script $Server $Share
# INCORRECT: Binds *both* values to the *first* parameter, as an *array*
# and assigns nothing to the second.
# In PowerShell, "," constructs an array.
./script($Server, $Share)
The tricky thing is that ./script($Server, $Share)
happens to be valid PowerShell syntax too, only with different semantics: $Server, $Share
constructs a 2-element array whose elements are the values of $Server
and $Share
, respectively.
To avoid this pitfall, PowerShell offers strict-mode setting Set-StrictMode -Version 2
, which reports an error when method-style invocation is attempted. Note, however, that this setting invariably enables other checks as well, notably causing an error when referencing non-existent properties - see Get-Help Set-StrictMode
.
Upvotes: 4
Reputation: 19694
Avoid string addition like you're doing when working with paths; there are cmdlets that handle that.
$Server = '\\This.server.name'
$File = 'something.exe'
$UNC = Join-Path $Server $File
Additionally, do string validation if you're running into weird errors.
If (!$Server) { "Stuff"; Return } # Checks empty string
If (!$File) { "Stuff"; Return }
If (!(Test-Path $UNC)) { "Stuff"; Return } # error checking for the file
Upvotes: 2