为 创建电源外壳别名.$profile



我想在文件中创建一组可以更新的别名,然后调用别名aa以便文件执行并在当前会话中为我提供新别名。最终,我希望这些别名在PS启动时自动可用,因此我使用C:UsersAdministratorDocumentsWindowsPowerShellMicrosoft.PowerShell_profile.ps1将它们放入。现在它看起来像:

$psdir="C:UsersAdministratorDocumentsWindowsPowerShell"  
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

如何执行此操作,以便在启动时加载别名,同时还可以使用aa别名更新它们并将它们引入当前会话?

如果包含以下代码的评论的原始作者决定将其作为答案发布,只需在此答案中添加注释,我就会将其删除。因为已经两天了,我真的不希望他这样做。同时,这应该让人们更好地了解实际发生的事情。

# 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

为了更好的可读性/突出显示 C# 代码独立:

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);
    }
}

代码的问题在于,Reload-Profile是一个函数,当你调用它时,它会为自己创建新的作用域。然后调用 . $profile 时,它不会为 profile 创建新的作用域,但仍会在Reload-Profile作用域内调用。因此,当Reload-Profile结束时,范围将被丢弃。因此,如果您使用别名,您还需要使用点调用运算符调用Reload-Profile. Reload-Profile. aa

我假设,您的真正问题是"如何以一种不需要使用点调用运算符的方式制作aa命令?

答案是使用已编译的 cmdlet 而不是 PowerShell 函数,因为 PowerShell 不会为 cmdlet 调用创建新的范围。然后,该 cmdlet 可以在当前范围内调用. $profile

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


附言我建议您使用不同的动词而不是Reload,因为Reload不包括在推荐的动词列表中,因此当您将Reload-Profile导入会话时,Import-Module会发出警告。

最新更新