2

我正在开发用于访问 REST Web 服务的自定义 Powershell Cmdlet。
网络服务要求我进行身份验证,当我这样做时,它会返回一个身份验证令牌,之后我必须将其包含在每个请求中。

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

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

Office 365 Cmdlet

$Credentials = Get-Credential
Connect-MSOLService -Credential $Credentials
Get-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/模块中的每个命令上使用它“幕后”?

感谢您的时间。

4

3 回答 3

2

您必须小心将令牌存储在进程范围的变量中,因为可能有多个 PowerShell 运行空间在同一进程中运行。但是,您可以做的是创建对字典的静态引用,该字典为运行 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];
}
于 2013-08-21T02:44:26.283 回答
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 令牌,并在它过期或会话关闭之前重复使用它。

于 2017-07-31T04:58:50.867 回答
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 模块中执行所有操作,这种方式将有效。

于 2013-08-20T18:41:51.263 回答