我正在开发一个用于访问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 /模块中的每个命令上使用它“引擎盖下”?
感谢您的时间。
答案 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模块中执行所有操作,这种方式将起作用。