Home > Enterprise >  In Powershell, get join-path to work with $null and empty string
In Powershell, get join-path to work with $null and empty string

Time:11-03

Powershell 5 says "no way Jose", can't join path with null or empty string. I say why not? Is there a way to get join-path to be more "Flexible" without adding more if-else blocks?

    $its_in_the_path = $true
    #$its_in_the_path = $false

    if ($its_in_the_path) {
        $mydir = ""
    }
    else {
        $mydir "C:\tool\path  
    }

    $tool = join-path $mydir "runit.exe"
Cannot bind argument to parameter 'Path' because it is an empty string.
daskljdhgfaklsuhfalhfluwherfluqwhrluq2345214723452345h2kjrwefqy345
At   ~~~~~~~~~~~~~~~~~~~~~~
      CategoryInfo          : InvalidData: (:) [frunsim], ParameterBindingValidationException
      FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,frunsim

CodePudding user response:

Join-Path will not allow $null values or [string]::Empty. You can use Path.Combine Method for that:

PS \> [System.IO.Path]::Combine($null, "runit.exe")
runit.exe

PS \> [System.IO.Path]::Combine('C:\', 'Documents', "runit.exe")
C:\Documents\runit.exe

CodePudding user response:

Santiago Squarzon's helpful answer shows you how to work around the inability to pass $null or '' to Join-Path.

However, since your use case seems to be about invoking executables, and since PowerShell requires prefix .\ (or a full path) in order to invoke an executable located in the current directory, it is better to default to .

Therefore, the immediate solution is:

$its_in_the_path = $true
#$its_in_the_path = $false

if ($its_in_the_path) {
    $mydir = '.'
}
else {
    $mydir 'C:\tool\path'
}

$tool = Join-Path $mydir "runit.exe"

However, you can simplify this approach:

$tool = Join-Path ('.', $mydir)[[bool] $mydir] "runit.exe"

In PowerShell (Core) 7 you can express this intent more directly, using ?:, the ternary conditional operator, relying on the fact that both $null and '' (the empty string) convert to $false` in a Boolean context:

$tool = Join-Path ($mydir ? $mydir : '.') "runit.exe"

Alternatively, also in PowerShell (Core) 7 , if $mydir is only every $null / undefined (and not also ''), you can further simplify with ??, the null-coalescing operator

$tool = Join-Path ($mydir ?? '.') "runit.exe"
  • Related