Home > OS >  Powershell: Why can't I add aliases in functions?
Powershell: Why can't I add aliases in functions?

Time:01-29

I tried adding several aliases in my powershell profile script. For organization reasons I wanted to keep those in a function which I would call at the end of said profile. I discovered that, while the function can be called from inside or outside the script without any problems, the aliases don't apply to my current powershell session. Only when I add them one at a time in the profile script, they would be usable.

This is my script as it is right now

function Populate-Aliases() {
  New-Alias grep Select-String
  New-Alias touch New-Item
  New-Alias lsa dir -Force
}

Populate-Aliases

I'm also certain the script is executed when I create a new ps session, as is proven by inserting any output in the function. It's just the aliases that don't apply to my session.

I tried creating the aliases via function in the profile script, which didn't work. I also tried declaring a function from within the terminal as such:

function al(){New-Alias lsa dir -Force}
al
lsa

This did also not work which leads me to believe that I'm making some kind of mistake or creating aliases in functions is not supported (which I could not quite understand why that would be the case).

Creating an alias via New-Alias in the cli works without any problem. Also just adding the New-Alias statement to the profile script works, when it is not enclosed in a function.

CodePudding user response:

-Scope
Specifies the scope in which this alias is valid. The default value is Local. For more information, see about_Scopes.

This means that, by default, the concerned alias is only available in the scope of the function:

function Test {
    New-Alias Show Write-Host
    Show 'This works'
}
Test
Show 'but this does not work'

Unless you will set the -scope to global:

function Test {
    New-Alias -Scope Global Show Write-Host
    Show 'This works'
}
Test
Show 'And this works too'

CodePudding user response:

To complement iRon's helpful answer:

While a function name such as Populate-Aliases - or perhaps better, using an approved verb, Add-CustomAliases - does suggest modification of the caller's state, it is generally better to let the caller make the choice to have its state modified, by using . , the dot-sourcing operator, which executes the specified function or script directly in the caller's scope rather than in a child scope (as is the default and as happens when you use &, the call operator).

Thus, you could leave your function as-is and simply invoke it in your $PROFILE file as follows:

# Dot-source the function call, so that it runs directly in the current scope
# (which inside $PROFILE is the *global* scope), causing the aliases to
# become globally defined.
. Populate-Aliases

Note that this technique also allows you to out-source the alias definitions to a script file; say you place them in an CustomAliases.ps1 file alongside your $PROFILE file, you can then define them globally as follows:

# Ditto, via an external .ps1 file.
. $PSScriptRoot/CustomAliases.ps1

The only challenge is that not using . for invocation then becomes effectively a quiet no-op. The function's / script's comment-based help could make that clear, but you can also implement a runtime check to enforce dot-sourced invocation:

function Add-CustomAliases {

  # Ensure that the function was invoked with dot-sourcing.
  if ($MyInvocation.InvocationName -ne '.') { 
    throw "Please invoke this function dot-sourced."
  }

  New-Alias grep Select-String
  New-Alias touch New-Item
  New-Alias lsa dir -Force
}

. Add-CustomAliases # OK

Add-CustomAliases # Throws an error, due to using dot-sourcing.

Note: With the script-file implementation, an extended check is necessary for robustness (see this answer).

# Content of CustomAliases.ps1

# Ensure that the script was invoked with dot-sourcing.
if (-not ($MyInvocation.InvocationName -eq '.' -or $MyInvocation.Line -eq '')) {
  throw "Please invoke this script dot-sourced."
}

New-Alias grep Select-String
New-Alias touch New-Item
New-Alias lsa dir -Force
  • Related