Reputation: 2457
I want to create a set of aliases in a file that I can update, then invoke an alias aa
so that the file executes and I am provided with the new aliases in the current session. Ultimately I wanted these aliases available automatically on PS startup so I am using C:\Users\Administrator\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
to put them in. Right now it looks like:
$psdir="C:\Users\Administrator\Documents\WindowsPowerShell"
function Reload-Profile{
# . ${profile} DOES NOT WORK
# Write-Host ${profile}
# Write-Host $profile
# powershell $profile DOES NOT WORK
# Get-ChildItem "${psdir}\*.ps1" | %{.$_} DOES NOT WORK
Write-Host "Custom PowerShell Environment Loaded"
}
function Edit-Profile
{
powershell_ise.exe $profile
}
Set-Alias show Get-ChildItem
Set-Alias show2 Get-ChildItem
Set-Alias aa Reload-Profile
Set-Alias ep Edit-Profile
How can I do this so that the aliases are loaded on startup, yet I can also update them with an aa
alias and have them brought into the current session?
Upvotes: 2
Views: 903
Reputation: 22132
The problem with your code is, that Reload-Profile
is a function and when you invoke it, it will create new scope for itself. When you then invoke . $profile
, it will not create new scope for profile, but it still be invoked inside Reload-Profile
scope. Thus, when Reload-Profile
ends, the scope will be discarded. So, you need to invoke Reload-Profile
with dot invoke operator as well: . Reload-Profile
or . aa
, if you use alias.
I assume, your real question is "How to make aa
command in a way, which does not require to use dot invoke operator?"
The answer will be to use compiled cmdlet instead of PowerShell function, because PowerShell does not create new scope for cmdlet invocation. That cmdlet can then invoke . $profile
in current scope.
Add-Type @‘
using System.Management.Automation;
using System.Management.Automation.Runspaces;
[Cmdlet("Reload", "Profile")]
public class ReloadProfileCmdlet : PSCmdlet {
protected override void EndProcessing() {
InvokeCommand.InvokeScript(
". $profile",
false,
PipelineResultTypes.Output | PipelineResultTypes.Error,
null
);
}
}
’@ -PassThru | Select -First 1 -ExpandProperty Assembly | Import-Module
Set-Alias aa Reload-Profile
P.S.
I recommend you to use different verb instead of Reload
, because Reload
is not included in a list of recommended verbs, thus Import-Module
will issue warning, when you import Reload-Profile
into your session.
Upvotes: 1
Reputation: 1255
If the original author of the comment that contained the following code decides to post it as an answer, just add a comment to this answer and I will remove it. As it has been two days I don't really expect him to. Meanwhile this should give people a better idea of what is actually happening.
# https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.utility/add-type
# Create a new cmdlet Reload-Profile using C# code and import it
Add-Type '
using System.Management.Automation;
using System.Management.Automation.Runspaces;
// https://msdn.microsoft.com/en-us/library/dd878294(v=vs.85).aspx
[Cmdlet("Reload", "Profile")]
public class ReloadProfileCmdlet : PSCmdlet {
protected override void EndProcessing()
{
// https://msdn.microsoft.com/en-us/library/ms568378(v=vs.85).aspx
// Runs $profile without parameters in the current context and displays the output and error
InvokeCommand.InvokeScript(". $profile", false, PipelineResultTypes.Output | PipelineResultTypes.Error, null);
}
}' -PassThru | Select -First 1 -ExpandProperty Assembly | Import-Module;
# Setup an alias for the new cmdlet
Set-Alias aa Reload-Profile
For better readability/highlighting the C# code standalone:
using System.Management.Automation;
using System.Management.Automation.Runspaces;
// https://msdn.microsoft.com/en-us/library/dd878294(v=vs.85).aspx
[Cmdlet("Reload", "Profile")]
public class ReloadProfileCmdlet : PSCmdlet {
protected override void EndProcessing()
{
// https://msdn.microsoft.com/en-us/library/ms568378(v=vs.85).aspx
// Runs $profile without parameters in the current context and displays the output and error
InvokeCommand.InvokeScript(". $profile", false, PipelineResultTypes.Output | PipelineResultTypes.Error, null);
}
}
Upvotes: 2