To complement Mathias R. Jessen's helpful answer with background information:
PowerShell's
Set-Location $env:HOMEDRIVE
is equivalent to cmd.exe
's:
cd /d %HOMEDRIVE%
That is, the reference to environment variable HOMEDRIVE
is replaced with its value (expanded) - typically C:
- and that drive is changed to. Note how PowerShell does not require an analog to the /d
switch to make the drive change take effect.
However, in both shells, changing to a drive spec. only - without a path component - changes to whatever the shell considers the current directory on that drive, which may or may not be the root directory.
- In order to change to a specific directory - such as the root directory - its path must be specified too.
While Set-Location (Join-Path $env:HOMEDRIVE '\')
is a robust and generic way to construct and pass the path to the root directory of the drive spec. stored in environment variable HOMEDRIVE
, PowerShell offers a more concise alternative:
Set-Location $env:HOMEDRIVE\ # or, with variable name disambiguated: ${env:HOMEDRIVE}\
The above works, because, simply put, PowerShell parses string arguments implicitly as if they were expandable strings (double-quoted strings with embedded variable references or even commands).
That is, the above is equivalent to all of the following:
Set-Location "$env:HOMEDRIVE\" # expandable string
Set-Location "${env:HOMEDRIVE}\" # ditto, variable name disambiguated
Set-Location "$(${env:HOMEDRIVE})\" # $(...) embeds full commands (not necessary here)
In addition to Join-Path
being a more robust way to join path components, there are pitfalls associated with the unquoted-argument approach, such as subtle differences between unquoted and double-quoted arguments (interior whitespace requires double-quoting, as do certain characters that are shell metacharacters); when in doubt, pass the argument to Write-Output
to see what it expands to; for details, see this answer of mine.