gpt4 book ai didi

带 RunspacePool 的 C# PowerShell - 如何导入 Exchange Cmdlet,如 Get-Mailbox?

转载 作者:行者123 更新时间:2023-11-30 16:58:23 25 4
gpt4 key购买 nike

我目前正在构建一个 Windows 服务,它将在收到一些请求时执行 PowerShell 命令。将会有很多请求进来,所以我采用了来自:Using Powershell RunspacePool multithreaded to remote server from C# 的代码。

我没有使用 WSManConnectionInfo,只是使用 New-PSSession。请参阅此问题末尾的代码。

这似乎适用于所有常规命令,但使用 Exhange Cmdlet 并之前执行 Import-PSSession 的命令除外。我不想在每次脚本运行时都导入 Cmdlet,但我没有从 C# 中正确导入。调用 PowerShell ErrorStream 后,还指出术语“Get-Mailbox”是未知的。我不明白为什么导入不起作用以及我需要为此做些什么。

我曾工作过一次,但只使用了一个运行空间。移至 RunspacePool 后,我无法让它再次工作。

如有任何帮助,我们将不胜感激。

代码:

static void Main(string[] args)
{
string connectionUri = "https://.../Powershell";
string userName = @"...\...";
string password = "...";

System.Uri uri = new Uri(connectionUri);
System.Security.SecureString securePassword = String2SecureString(password);

System.Management.Automation.PSCredential creds = new System.Management.Automation.PSCredential(userName, securePassword);

//InitialSessionState iss = InitialSessionState.CreateDefault();
//iss.ImportPSModule(new[] { "Get-Mailbox", "Get-MailboxStatistics" });

RunspacePool runspacePool = RunspaceFactory.CreateRunspacePool();
runspacePool.ThreadOptions = PSThreadOptions.UseNewThread;

PowerShell powershell = PowerShell.Create();
PSCommand command = new PSCommand();
command.AddCommand(string.Format("New-PSSession"));
command.AddParameter("ConfigurationName", "Microsoft.Exchange");
command.AddParameter("ConnectionUri", uri);
command.AddParameter("Credential", creds);
command.AddParameter("Authentication", "Basic");
command.AddParameter("AllowRedirection");

// IS THIS NEEDED?
PSSessionOption sessionOption = new PSSessionOption();
sessionOption.SkipCACheck = true;
sessionOption.SkipCNCheck = true;
sessionOption.SkipRevocationCheck = true;
command.AddParameter("SessionOption", sessionOption);

powershell.Commands = command;

runspacePool.Open();
powershell.RunspacePool = runspacePool;
Collection<PSSession> result = powershell.Invoke<PSSession>();

foreach (ErrorRecord current in powershell.Streams.Error)
{
Console.WriteLine("Exception: " + current.Exception.ToString());
Console.WriteLine("Inner Exception: " + current.Exception.InnerException);
}

// Returns the session
if (result.Count != 1)
throw new Exception("Unexpected number of Remote Runspace connections returned.");

// THATS THE PART NOT WORKING
// First import the cmdlets in the current runspace (using Import-PSSession)
powershell = PowerShell.Create();
command = new PSCommand();
command.AddScript("Import-PSSession $Session -CommandName Get-Mailbox, Get-MailboxStatistics -AllowClobber -WarningAction SilentlyContinue -ErrorAction Stop -DisableNameChecking | Out-Null");
command.AddParameter("Session", result[0]);

// This is also strange... without the RunspaceInvoke I always get a SecurityException...
RunspaceInvoke scriptInvoker = new RunspaceInvoke();
scriptInvoker.Invoke("Set-ExecutionPolicy -Scope Process Unrestricted");

var tasks = new List<Task>();

for (var i = 0; i < 3; i++)
{
var taskID = i;
var ps = PowerShell.Create();
ps.RunspacePool = runspacePool;
PSCommand cmd = new PSCommand();
cmd.AddCommand(@".\PSScript1.ps1");
//cmd.AddScript("Get-Mailbox -ResultSize 5");
cmd.AddParameter("Session", result[0]);
ps.Commands = cmd;
var task = Task<PSDataCollection<PSObject>>.Factory.FromAsync(
ps.BeginInvoke(), r => ps.EndInvoke(r));
System.Diagnostics.Debug.WriteLine(
string.Format("Task {0} created", task.Id));
task.ContinueWith(t => System.Diagnostics.Debug.WriteLine(
string.Format("Task {0} completed", t.Id)),
TaskContinuationOptions.OnlyOnRanToCompletion);
task.ContinueWith(t => System.Diagnostics.Debug.WriteLine(
string.Format("Task {0} faulted ({1} {2})", t.Id,
t.Exception.InnerExceptions.Count,
t.Exception.InnerException.Message)),
TaskContinuationOptions.OnlyOnFaulted);
tasks.Add(task);
}

Task.WaitAll(tasks.ToArray());
}

private static SecureString String2SecureString(string password)
{
SecureString remotePassword = new SecureString();
for (int i = 0; i < password.Length; i++)
remotePassword.AppendChar(password[i]);

return remotePassword;
}

简短形式的脚本:

Param($Session)

Import-PSSession $Session -CommandName Get-Mailbox, Get-MailboxStatistics -ErrorAction SilentlyContinue | Out-Null

Get-Mailbox -ResultSize 5 | SElectObject Name, Alias, ...

脚本就是这样工作的,但是当我尝试注释掉 Import-PSSession 部分时,我得到了未知术语 Get-Mailbox 错误。

在此先致谢并致以最诚挚的问候滚

最佳答案

您需要取消对 ISS 内容的注释。做这样的事情:

$iss = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
$iss.ImportPSModule($module)

用 Exchange 模块的名称替换 $module,或者只用模块名称填充变量。

然后当您创建 RunspacePool 时,执行如下操作:

$runspacePool = [System.Management.Automation.Runspaces.RunspaceFactory]::CreateRunspacePool($minRunspaces, $maxRunspaces, $iss, $Host)

这应该使模块可用于从运行空间池创建的所有运行空间。

关于带 RunspacePool 的 C# PowerShell - 如何导入 Exchange Cmdlet,如 Get-Mailbox?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25303124/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com