Don't Miss Out
In this issue:
We have been exploring hidden, or at least often overlooked, PowerShell features and commands. It is always a challenge to resolve "You don't know what you don't know". This is why the PowerShell community is awesome and I encourage you to attend user group meetings and the PowerShell Summit. The community loves to share what they know, as do I, which is why we're here. Let's get to it.
Joining Paths
I have always been a big proponent of the Join-Path cmdlet. I don't think you should be building paths like this:
$file = "C:\work\" + "demo.ps1"
It is very easy to forget the slash. This also isn't a good technique to ensure your code will run cross-platform. This is why Join-Path is the better choice.
PS C:\> $file = Join-Path -Path $Home -ChildPath demo.ps1
PS C:\> Write-Host "Creating script file $file"
Creating script file C:\Users\jeff\demo.ps1
The same code works cross-platform.
PS /home/jeff> $file = Join-Path -Path $Home -ChildPath demo.ps1
PS /home/jeff> Write-Host "Creating script file $file"
Creating script file /home/jeff/demo.ps1
Where things can get tricky is when you have a deeper path to create.
PS C:\> Join-Path -Path ([IO.Path]::GetTempPath()) -ChildPath foo\bar\log.txt
C:\Users\jeff\AppData\Local\Temp\foo\bar\log.txt
Making sure you have the right slashes can be a nuisance. PowerShell 7 includes a new parameter that simplifies the process.
PS C:\> Join-Path -Path ([IO.Path]::GetTempPath()) -ChildPath foo -AdditionalChildPath foo,log.txt
C:\Users\jeff\AppData\Local\Temp\foo\foo\log.txt
If you aren't in the habit of reading help, you may not know about AdditionalChildPath. Enter an array of paths to join, in order, and PowerShell does the rest. This is very handy when writing code that will run cross-platform.
PS /home/jeff> Join-Path -Path ([IO.Path]::GetTempPath()) -ChildPath foo -AdditionalChildPath foo,log.txt
/tmp/foo/foo/log.txt
I should point out that you can also pass an array of strings to ChildPath.
PS C:\> Join-Path -path c:\scripts -ChildPath foo,bar,jeff
c:\scripts\foo\bar\jeff
The help documentation suggests that this won't work. I can verify this with Get-ParameterInfo from the PSScriptTools module.
PS C:\> Get-ParameterInfo Join-Path
ParameterSet: __AllParameterSets
Name Aliases Mandatory Position Type
---- ------- --------- -------- ----
Path PSPath True 0 System.String[]
ChildPath True 1 System.String[]
AdditionalChil… False 2 System.String[]
Credential False Named System.Management.Automation.PSCredential
Resolve False Named System.Management.Automation.SwitchParam...
Whether you use ChildPath or AdditionalChildPaths is up to you and might depend on the context. However, ChildPath is required if you want to use AdditionalChildPaths.
There is no reason to use concatenation to create paths when there is a cmdlet that will simplify the process.