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

C# 如何在当前运行空间中获取和设置变量?(基于cmdlet的模块),c#,powershell,C#,Powershell,我正在尝试为现有的应用程序编写基于cmdlet的PowerShell模块。在使用initial connection cmdlet之后,我希望在用户打开其当前PowerShell窗口时将值存储在某个位置。其中一个值是一个身份验证密钥,我从用户的凭据创建它,然后在以后的调用中需要它,而不为每个操作提供凭据 我认为在C#中的自定义对象中获取和设置这些可能很容易,但我正在努力使其应用于当前运行空间。我承认,我对C#也很陌生 这是我最成功的尝试的一个例子,以最小的形式,也就是说,这将评估为真,但是,它不

我正在尝试为现有的应用程序编写基于cmdlet的PowerShell模块。在使用initial connection cmdlet之后,我希望在用户打开其当前PowerShell窗口时将值存储在某个位置。其中一个值是一个身份验证密钥,我从用户的凭据创建它,然后在以后的调用中需要它,而不为每个操作提供凭据

我认为在C#中的自定义对象中获取和设置这些可能很容易,但我正在努力使其应用于当前运行空间。我承认,我对C#也很陌生

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

使用System.Management.Automation.Runspaces;
名称空间测试
{
公共类变量测试
{
公共bool CreateVariable()
{
var runSpace=RunspaceFactory.CreateRunspace();
Open();
SetVariable(“item”、“FooBar”);
var a=runSpace.SessionStateProxy.PSVariable.GetValue(“项”);
如果(a.ToString()=“FooBar”)
{
返回true;
}
其他的
{
返回false;
}
}
}
}

如果我在PowerShell中编写这个模块,我可能会将它们保存在一个全局变量中。是否有人可以帮助获取和设置这些值,以便我可以调用PowerShell控制台中的项?或者这是非常错误的,并且已经存在某种原因来解释我遗漏的C#中的持久性模块范围变量。

假设您的
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
选项不是可见性或范围修饰符,而是确保没有人可以覆盖变量值。

非常感谢Mathias在这方面的指导。这里是一个最小的例子,供其他来找这个的人参考

Connect cmdlet

使用System.Management.Automation;
名称空间测试
{
[Cmdlet(VerbsCommunications.Connect,“TestSystem”)]
公共类VariableTest:PSCmdlet
{
私有字符串_项;
公共字符串项
{
获取{return\u item;}
设置{u item=value;}
}
受保护的覆盖void BeginProcessing()
{
base.BeginProcessing();
}
受保护的覆盖无效ProcessRecord()
{
Item=“FooBar”;
}
受保护的覆盖无效EndProcessing()
{
SessionState.PSVariable.Set(新PSVariable(nameof(Item)、Item、ScopedItemOptions.Private));
}
}
}
其他cmdlet

使用System.Management.Automation;
名称空间测试
{
[Cmdlet(VerbsCommunications.Read,“TestVariable”)]
公共类ReadVariable:PSCmdlet
{
受保护的覆盖void BeginProcessing()
{
base.BeginProcessing();
}
受保护的覆盖无效ProcessRecord()
{
var test=SessionState.PSVariable.Get(“项”);
WriteObject(test.Value.ToString());
}
}
}
结果

PS C:\>连接测试系统
PS C:\>读取测试变量
福巴

这很酷。谢谢如果可以的话,我有几个问题。1) Private选项是否意味着将来的cmdlet无法覆盖该值?2) 我是否能够从未来的cmdlet中类似地调用变量值,即
SessionState.PSVariable.Get(do stuff)
相同运行空间/会话中的任何cmdlet都能够以这种方式读取变量,是(更新的答案)
Private
选项无法防止从其他cmdlet调用SessionState.PSVariable.Set(someOtherPSVariableInstance)谢谢!太好了。我尝试了你的建议,并根据你的答案在下面留下了一个例子。