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