Bashir Momen
Bashir Momen

Reputation: 1681

How to compare a location with Home folder in PowerShell

I have tried to run a script in a specific location but I could not and I realize that is related to the following code which I assumed should return True but it actually returns False if you are in the home folder in windows 10.

$loc=Get-Location 
$loc -eq $HOME  =>> Should return True but it is not.

So any comment or answer is appreciated.

Upvotes: 2

Views: 463

Answers (3)

mklement0
mklement0

Reputation: 438018

Mathias R. Jessen's helpful answer shows that Get-Location returns a System.Management.Automation.PathInfo instance rather than a string and how to account for that.

There is a small caveat, however:

While probably rare in practice, a test based on the returned object's .Path property and the equivalent implicit stringification of the whole object via "..." may still fail, namely if the current location is based on a custom PowerShell drive:

.Path then reports the PowerShell-specific path, whereas $HOME is always expressed as a file-system-native path, so even if the two paths ultimately refer to the same file-system location, -eq will not detect that.

To account for that, use the .ProviderPath property instead, which - just like $HOME - expresses the directory as a file-system-native path:

(Get-Location).ProviderPath -replace '[\\/]$' -eq $HOME
  • Note: The unfortunate need for removing a trailing path separator, if present, via -replace '[\\/]$' stems from the fact that PowerShell, as of v7.0, doesn't normalize what .ProviderPath reports: if the current, PS-drive-based path is the root of that PS drive, .ProviderPath unexpectedly retains the trailing \ (or / on Unix-like platforms) in the native path that is returned.
    This problematic behavior is the subject of this GitHub issue.

To give a complete example:

# Define a custom H: drive whose root is $HOME.
$null = New-PSDrive H FileSystem $HOME

# Change to the root of the new drive, which is effectively the 
# same as $HOME, though from PowerShell's perspective the path is H:\
Set-Location H:\

# !! -> $false, because .Path reports 'H:\'
(Get-Location).Path -eq $HOME

# OK -> $true - .ProviderPath reports the true, file-system-native path.
# Note: 
#   If GitHub issue #12971 gets fixed (see above),
#   the -replace '[\\/]$' part will no longer be needed.
(Get-Location).ProviderPath -replace '[\\/]$' -eq $HOME

Additionally, if there's a chance that the current location is based on a symbolic link / reparse point, you'll have to do additional work to determine path equality.

Upvotes: 3

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174505

Get-Location returns a location object, whereas $home is just a string. Either convert $loc to a string, or compare $home to its Path property:

$loc.Path -eq $home
# or 
"$loc" -eq $home

Since PowerShell's -eq operator behaves according to the type of the left-hand side operand, you could also flip the two operands and it'll work as well:

$home -eq $loc

Upvotes: 5

stackprotector
stackprotector

Reputation: 13451

Get-Location returns an object. You have to compare $HOME to the correct property of that object:

(Get-Location).Path -eq $HOME

Upvotes: 2

Related Questions