EiEiGuy
EiEiGuy

Reputation: 1547

How to concatenate string variables with backslashes to create a UNC path in Powershell

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

Answers (2)

mklement0
mklement0

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

Maximilian Burszley
Maximilian Burszley

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

Related Questions