我正在尝试为我们拥有的应用程序编写基于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#中的持久性模块范围变量。
答案 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