Home > Mobile >  Is there a way to override `~` (tilde) location in powershell
Is there a way to override `~` (tilde) location in powershell

Time:05-17

The problem

I am trying to change the expanded path of the ~ character in PowerShell without changing the $Env:USERPROFILE variable.

What I've tried

My initial approach was to create an alias to a function that references a differen environment variable, but it doesn't seem to work.

My code:

function Get-HomeDirectory { 
  # This is a custom function, it works as I have tested it
  # It should be self-explanatory
  Get-EnvironmentVariable -Key $HOME_DIR_KEY -User
}
Set-Alias -Name ~ -Value Get-HomeDirectory

Result

If I use Get-Help it works as expected:

PS> Get-Help ~                                                                                                                                                                            

NAME
    Get-HomeDirectory

SYNOPSIS
    Returns the home directory of the current user.


SYNTAX
    Get-HomeDirectory [<CommonParameters>]


DESCRIPTION
    Retrieves the value set for the `$Env:USER_HOME_DIR` environment variable.


RELATED LINKS
    Set-HomeDirectory

REMARKS
    To see the examples, type: "Get-Help Get-HomeDirectory -Examples"
    For more information, type: "Get-Help Get-HomeDirectory -Detailed"
    For technical information, type: "Get-Help Get-HomeDirectory -Full"
    For online help, type: "Get-Help Get-HomeDirectory -Online"

But if I try to use it I get:

PS> cd ~
PS> pwd
C:\Users\myuser

What works properly

Nevertheless, I can make it work if I pass it with a pipe (as it should), but that's not a very convenient way of using it:

PS> ~ | cd
PS> pwd

Path
----
B:\

CodePudding user response:

Using a function (via an alias) to redefine ~ in arguments cannot work (except if the function call is enclosed in (...)), for the reasons explained in Jeroen Mostert's comment on your question.

There is a solution, though note that it redefines the meaning of an initial ~ - a placeholder for a provider's home location that is interpreted as such only by provider cmdlets - in file-system provider paths session-globally.

# Make the file-system provider use the value of
# env. var. USER_HOME_DIR as its home location.
(Get-PSProvider FileSystem).Home = $Env:USER_HOME_DIR

Note:

  • The change takes effect for the current session only; to make it persistent, you'd have to add it to your $PROFILE file - but note that loading of profiles can be bypassed via the CLI's -NoProfile parameter.

  • Every provider has its own - potentially undefined - home location. Thus, in the - atypical - event that the provider underlying the current location is not the file-system provider, ~ refers to that provider's home location; a contrived example:

    # !! Fails, because the function provider has no home location defined. 
    Set-Location Function:; Get-Item ~
    
  • Related