Liturgist Liturgist - 3 months ago 26
PowerShell Question

Using variable as parameter works, using source of variable fails

I found a way to get the current working directory into $dp0.

PS C:\src\powershell> Get-Content .\curdir2.ps1
$dp0 = [System.IO.Path]::GetDirectoryName($myInvocation.MyCommand.Definition)

Set-Location -Path $dp0
Write-Host "location is set"

Set-Location -Path [System.IO.Path]::GetDirectoryName($myInvocation.MyCommand.Definition)

Write-Host (Get-Location).Path


Why is it that when I try to use the same way as a parameter to
Set-Location
it is an error? I think this may be something fundamental about the objects in Powershell. What do I need to know?

Set-Location : A positional parameter cannot be found that accepts argument 'C:\src\powershell\curdir2.ps1'.
At C:\src\powershell\curdir2.ps1:6 char:1
+ Set-Location -Path [System.IO.Path]::GetDirectoryName($myInvocation.MyCommand.De ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Set-Location], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.SetLocationCommand

Answer

Use parentheses.
As you can see in PS ISE that entire parameter is interpreted as a literal string otherwise.
And always use -LiteralPath instead of -Path to correctly handle directories with [] brackets.

Set-Location -LiteralPath ([IO.Path]::GetDirectoryName($myInvocation.MyCommand.Definition))

PS3.0+: cd -LiteralPath $PSScriptRoot