如何在当前运行空间中获取和设置变量? (基于cmdlet的模块)

时间:2019-06-19 12:24:37

标签: c# powershell

我正在尝试为我们拥有的应用程序编写基于cmdlet的PowerShell模块。初始连接cmdlet之后,我想在用户打开其当前PowerShell窗口时将值存储在某处。其中一个值是我根据用户凭据创建的auth密钥,以后调用时需要使用该密钥,而无需为每个操作提供凭据。

我认为从C#的自定义对象中获取和设置这些对象可能很容易,但是我很难将其应用于当前的运行空间。我承认,我也是C#的新手。

这是我以最小形式进行的最成功尝试的一个示例,即这将被评估为true,但是,它不是同一运行空间。如果我在PowerShell中调用$ item,显然它不知道我在做什么。

using System.Management.Automation.Runspaces;

namespace Test
{
    public class VariableTest
    {
        public bool CreateVariable()
        {
            var runSpace = RunspaceFactory.CreateRunspace();
            runSpace.Open();

            runSpace.SessionStateProxy.SetVariable("item", "FooBar");
            var a = runSpace.SessionStateProxy.PSVariable.GetValue("item");

            if (a.ToString() == "FooBar")
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}

如果我在PowerShell中编写此模块,则可能只是将它们保存在全局变量中。谁能帮助您获取和设置这些值,以便我可以在PowerShell控制台中调用item?还是这是非常错误的,并且已经存在一些原因来说明我错过的C#中的持久性模块范围变量。

2 个答案:

答案 0 :(得分:3)

假设您的Connect-* cmdlet继承了PSCmdlet,则可以通过this.SessionState.PSVariable访问变量:

[Cmdlet("Connect", "SomeSystem")]
public class ConnectCmd : PSCmdlet
{
    protected override void EndProcessing()
    {
        SessionState.PSVariable.Set(new PSVariable("varName", valueGoesHere, ScopedItemOptions.Private));
    }
}

现在,在同一运行空间中运行的任何cmdlet都可以检索和读取变量:

[Cmdlet("Get", "Stuff")]
public class GetCmd : PSCmdlet
{
    protected override void EndProcessing()
    {
        WriteObject(SessionState.PSVariable.Get("varName").Value);
    }
}

请注意,Private选项不是可见性或作用域修饰符,而是确保没有人可以覆盖变量值。

答案 1 :(得分:1)

非常感谢上述Mathias在此方面的指导。这是任何寻求此功能的人的最小示例。

连接cmdlet

using System.Management.Automation;

namespace Test
{
    [Cmdlet(VerbsCommunications.Connect, "TestSystem")]
    public class VariableTest : PSCmdlet
    {
        private string _item;
        public string Item
        {
            get { return _item; }
            set { _item = value; }
        }

        protected override void BeginProcessing()
        {
            base.BeginProcessing();
        }

        protected override void ProcessRecord()
        {
            Item = "FooBar";
        }

        protected override void EndProcessing()
        {
            SessionState.PSVariable.Set(new PSVariable(nameof(Item), Item, ScopedItemOptions.Private));
        }
    }
}

其他cmdlet

using System.Management.Automation;

namespace Test
{
    [Cmdlet(VerbsCommunications.Read, "TestVariable")]
    public class ReadVariable : PSCmdlet
    {
        protected override void BeginProcessing()
        {
            base.BeginProcessing();
        }

        protected override void ProcessRecord()
        {
            var test = SessionState.PSVariable.Get("Item");
            WriteObject(test.Value.ToString());
        }
    }
}

结果

PS C:\> Connect-TestSystem
PS C:\> Read-TestVariable
FooBar