我可能以错误的方式执行此操作,并且应该以某种方式使用WSManConnectionInfo,但我发现很多示例都指向这种在C#app中使用不同凭据创建新PowerShell会话作为有效方法的方法。
我遇到了调用New-PSSession的部分,因为它没有返回会话对象(返回一个空集合),我可以在下一组命令中使用它。我的目标是创建一个C#函数,该函数接收PowerShell脚本块并使用管理员凭据运行它。
( UPDATE )以下代码现在可以使用了。请务必检查客户端计算机名称的“Enable-WSManCredSSP”参数,否则在创建新PSSession时将无法委派凭据。我更改了代码以使用客户端的本地计算机名称而不是域名中的*,我相信使用*是一种糟糕的安全措施。
public static IEnumerable<PSObject> RunScriptBlock(string block)
{
var nc = Domains.Default.GetNetworkCredential();
var creds = new PSCredential(nc.Domain + "\\" + nc.UserName, nc.SecurePassword);
using (Runspace rs = RunspaceFactory.CreateRunspace())
{
rs.Open();
using (var psh = PowerShell.Create())
{
psh.Runspace = rs;
PSSession session = null;
try
{
psh.AddCommand("Enable-WSManCredSSP");
psh.AddParameter("Role", "Client");
psh.AddParameter("DelegateComputer", Environment.MachineName + ".mydomain.com");
psh.AddParameter("Force", true);
psh.Invoke();
psh.Commands.Clear();
psh.AddCommand("Enable-WSManCredSSP");
psh.AddParameter("Role", "Server");
psh.AddParameter("Force", true);
psh.Invoke();
psh.Commands.Clear();
psh.AddCommand("New-PSSession");
psh.AddParameter("Credential", creds);
psh.AddParameter("Authentication", "Credssp");
session = psh.Invoke()[0].BaseObject as PSSession;
psh.Commands.Clear();
psh.Runspace.SessionStateProxy.SetVariable("", "");
psh.AddCommand("Invoke-Command");
psh.AddParameter("Session", session);
ScriptBlock sb = new RunspaceInvoke().Invoke("{ " + block + " }")[0].BaseObject as ScriptBlock;
psh.AddParameter("ScriptBlock", sb);
var results = psh.Invoke();
//if (results.HasErrors)
//{
//}
return results;
}
catch (Exception)
{
return null;
}
finally
{
psh.Commands.Clear();
psh.AddCommand("Remove-PSSession");
psh.AddParameter("Session", session);
psh.Invoke();
rs.Close();
}
}
}
}