自定义Powershell Cmdlet - 创建隐藏的可访问变量

时间:2013-08-20 18:36:06

标签: c# powershell cmdlet

我正在开发一个用于访问REST Web服务的自定义Powershell Cmdlet web服务要求我进行身份验证,当我这样做时,会返回一个authenticaton-token,我必须在之后的每个请求中包含该权限。

我面临的问题是我无法以期望的方式存储令牌,因此我可以在身份验证后轻松地使用它。

我想它是否可以像 Connect-MSOLService 一样工作。
对于那些不熟悉Office 365 cmdlet的人,我将举几个例子。

Office 365 Cmdlet

  

$ Credentials = Get-Credential
  Connect-MSOLService -Credential $ Credentials
  得到-MSOLUser

在此示例中,Get-MSOLUser将返回每个Office 365用户,因为事先已调用Connect-MSOLService。

我的Cmdlet

  

$ Credentials = Get-Credential
  $ token = Connect-WebService -Credential $ Credentials
  Get-Server -token $ token
  Get-Client -token $ token

正如您所看到的,我必须返回令牌并将其存储在变量中,并在认证后的每次通话中使用它。

所以这引出了我的问题,我怎样才能将令牌“注入”Powershell会话并在之后的cmdlet /模块中的每个命令上使用它“引擎盖下”?

感谢您的时间。

3 个答案:

答案 0 :(得分:2)

您必须小心将令牌存储在进程范围的变量中,因为可以在同一进程中运行多个PowerShell运行空间。但是,您可以执行的操作是创建对Dictionary的静态引用,该字典会为运行cmdlet的运行空间存储令牌。您可以像这样获取运行空间ID:

Guid runspaceId = Guid.Empty;
using (var ps = PowerShell.Create(RunspaceMode.CurrentRunspace))
{
    runspaceId = ps.Runspace.InstanceId;
}

然后使用静态只读字段创建一个静态类,如下所示:

public static class TokenUtil {
    public static readonly Dictionary<Guid,PSObject> Tokens = new Dictionary<Guid,PSObject>();
}

检查此运行空间的现有令牌,如下所示:

PSObject token = null;
if (TokenUtil.Tokens.ContainsKey(runspaceId))
{
    token = TokenUtil.Tokens[runspaceId];
}

答案 1 :(得分:1)

如果使用PowerShell 5.0程序集,您可以继承PSCmdlet并使用SessionState来存储变量。

private string const variableName = "MyVar";
private Token token = new Token("your token");
SessionState.PSVariable.Set(new PSVariable(variableName, token, ScopedItemOptions.Private));

然后使用GetValue()检索它。

Token storedToken = (Token)SessionState.PSVariable.GetValue(variableName);

此变量可供PowerShell会话使用,但会在cmdlet调用之间保持不变。我用它来存储第一个查询的API令牌,并在它到期或会话关闭之前重复使用它。

答案 2 :(得分:0)

我不知道微软是如何做到这一点的,但我认为一种方法就是这样:

function Connect-WebService {
   param($credential)

   #Do all of the connection here


   #Set the global variable so it will be available outside of this function
   $script:token = ...
}

function Get-Server {
   param(
      $token = $script:token # By default use the globally set $token variable
  )
}

如果您在PowerShell模块中执行所有操作,这种方式将起作用。