Code Buckets

Buckets of code

PowerShell

PowerShell Join-Path with multiple parameters

In my day to day job I use a fair amount of PowerShell. Some might say the deployment process is mountains of PowerShell glued together by Team Foundation Server. Cruel but accurate. I don’t make any claims to be a PowerShell expert (I really don’t) so I post this not to show my PS brilliance but rather as a way for me to practice and learn. I appreciate this has been written about elsewhere but as I say it’s just practice and I wrote this without peeking at anybody else’s solution (promise)

Standard Call

Within the mountains of PowerShell I use Join-Path quite a bit. It’s fine for two parameters

Join-Path "C:\TestPath1" "TestPath2"

Output

C:\TestPath1\TestPath2

But I’m always mildly surprised it can’t cope with more parameters

Join-Path "C:\TestPath1" "TestPath2" "TestPath3"

Output

Join-Path : A positional parameter cannot be found that accepts argument 'TestPath3'.

At line:1 char:1

+ Join-Path "C:\TestPath1" "TestPath2" "TestPath3"

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : InvalidArgument: (:) [Join-Path], ParameterBindingException

    + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.JoinPathCommand

Boom – unhappy code, unhappy coder.

Piped Call

The most straightforward solution is to pipe the output of one call to a send call and so on. So

Join-Path "C:\TestPath1" "TestPath2" | Join-Path "TestPath3"

Sadly doesn’t work

Join-Path : The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its

properties do not match any of the parameters that take pipeline input.

At line:1 char:40

+ Join-Path "C:\TestPath1" "TestPath2" | Join-Path "TestPath3"

+                                        ~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : InvalidArgument: (C:\TestPath1\TestPath2:PSObject) [Join-Path], ParameterBindingException

    + FullyQualifiedErrorId : InputObjectNotBound,Microsoft.PowerShell.Commands.JoinPathCommand

In order to get this to work the second parameter needs to be explicitly named

Join-Path "C:\TestPath1" "TestPath2" | Join-Path -ChildPath "TestPath3" | Join-Path -ChildPath "TestPath4"

Which then works perfectly well

C:\TestPath1\TestPath2\TestPath3\TestPath4

Using parameter array

It feels as if it should/must/ought to be possible to do this without piping – by passing in an array of parameters. Indeed it is. This function will do the trick

function Join-ArrayPath
{
   param([parameter(Mandatory=$true)]
   [string[]]$PathElements) 

   if ($PathElements.Length -eq "0")
   {
     $CombinedPath = ""
   }
   else
   {
     $CombinedPath = $PathElements[0]
     for($i=1; $i -lt $PathElements.Length; $i++)
     {
       $CombinedPath = Join-Path $CombinedPath $PathElements[$i]
     }
  }
  return $CombinedPath
}

To call it it needs to be imported into the shell, There are a number of ways to do this but the easiest is by using the dot operator (dot-sourcing) i.e.

. "C:\PowerShellLib\Join-ArrayPath.ps1"

The function is then available to be called

Join-ArrayPath "c:\TestPath1","TestPath2","TestPath3","TestPath3"

And again works perfectly well

C:\TestPath1\TestPath2\TestPath3\TestPath4

So there you have it, both original and insightful.  Sadly the original is not insightful and the insightful is not original. But I enjoyed writing it!

Note on script permissions

When importing the script about you may see this

File C:\PowerShellLib\Join-ArrayPath.ps1 cannot be loaded because running

scripts is disabled on this system. As part of Microsoft Trustworthy Computing initiative PowerShell is secure by default won’t allow scripts to be run. To bypass this run

Set-ExecutionPolicy Unrestricted

This is just for demo purposes though. For production or anything other than quick demos then consider signing scripts (see links below).

Useful Links

Adding functions to Powershell sessions
http://mikepfeiffer.net/2010/06/how-to-add-functions-to-your-powershell-session/

Execution Policies
https://technet.microsoft.com/library/hh847748.aspx

Better ways to work with the PowerShell execution policy
https://technet.microsoft.com/en-us/magazine/2b6812f2-e6e5-41ad-a1c4-6b9e01977cc7

3 COMMENTS

LEAVE A RESPONSE

Your email address will not be published. Required fields are marked *