【发布时间】:2017-07-15 06:09:39
【问题描述】:
如何让第二个 $scriptBlock 像第一个 $scriptBlock 一样工作?两者的区别是第一个从命令返回单个对象,第二个应该从多个命令返回一个对象数组?
要测试此代码,您只需填写$servers 的服务器名称和$connectionUri 的Exchange powershell 超链接,并在注释掉第一个$scriptBlock(工作)和第二个$scriptBlock(不工作)之间交替)。
谢谢
cls
Write-Host "Aynchronous";
# Create session state
$stopWatch = [System.Diagnostics.Stopwatch]::StartNew();
$myString = "this is session state!";
$sessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault();
$sessionstate.Variables.Add((New-Object -TypeName System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList "myString" ,$myString, "example string"));
# Create runspace pool consisting of $numThreads runspaces
$minimumAmountOfThreads = 1;
$maximumAmountOfThreads= 15;
$RunspacePool = [RunspaceFactory]::CreateRunspacePool(1, 15, $sessionState, $Host);
$RunspacePool.Open();
$servers = @("server1","server2","server3");
$connectionUri = "http://[something]/powershell";
$threads = @();
$Jobs = @();
$asynchronousThreadCount = 0;
foreach ($server in $servers)
{
$scriptBlock = "import-pssession (new-pssession -ConfigurationName Microsoft.Exchange -ConnectionUri $connectionUri) -AllowClobber; get-exchangeserver $server;"; # working
#$scriptBlock = "import-pssession (new-pssession -ConfigurationName Microsoft.Exchange -ConnectionUri $connectionUri) -AllowClobber; $returnValue = @(); $returnValue += Get-MailboxDatabase -Server $server; return $returnValue;"; # NOT working
#$scriptBlock = "import-module 'activedirectory'; Get-ADDomain"; # working
#$scriptBlock = "import-module 'activedirectory'; $returnValue = @(); $returnValue += Get-ADDomain; return $returnValue;" # NOT working
$asynchronousThreadCount ++;
$runspaceObject = [PSCustomObject] @{
Runspace = [PowerShell]::Create()
Invoker = $null
}
$runspaceObject.Runspace.RunSpacePool = $runspacePool;
$runspaceObject.Runspace.AddScript($scriptBlock) | Out-Null;
$runspaceObject.Runspace.AddArgument($c) | Out-Null;
$runspaceObject.Invoker = $runspaceObject.Runspace.BeginInvoke();
$threads += $runspaceObject;
$elapsed = $StopWatch.Elapsed;
Write-Host "A synchronous created thread $asynchronousThreadCount " $elapsed;
}
Write-Host $threads.Count;
Write-Host "";
Write-Host "Waiting.." -NoNewline;
Do {
Write-Host "." -NoNewline;
Start-Sleep -Seconds 1;
} While ( $runspaceObject.Invoker.IsCompleted -contains $false );
$resultsAsynchronous = @();
foreach ($tr in $threads)
{
$resultsAsynchronous += $tr.Runspace.EndInvoke($tr.Invoker);
$tr.Runspace.Dispose();
}
$procCountMultiThread = $resultsAsynchronous.Count;
$runspacePool.Close();
$runspacePool.Dispose();
$elapsed = $StopWatch.Elapsed;
Write-Host "Multithread elapsed time: $elapsed";
Write-Host "Asynchronous return value count " $resultsAsynchronous.Count;
$resultsAsynchronous #| fl fqdn, AdminDisplayVersion;
【问题讨论】:
-
请更具体地说明“不工作”。你检查过
$tr.Runspace.Streams.Error吗? -
是的,没有错误。返回的唯一标记为不起作用的是具有“模块”、“名称”和“导出命令”的 pssession 哈希表。使用工作版本,您还会收到该哈希表和 cmdlet 返回值。我试着做它,以便您可以尝试代码,如果您这样做,您就会明白我的意思。
-
我没有要测试的交换环境
-
如果您有 AD 环境,我可以使用此代码复制相同的行为,而不是原始代码中的“$scriptBlock”变量
code#$scriptBlock = "import-module 'activedirectory'; 获取-ADDomain"; # working $scriptBlock = "import-module 'activedirectory'; $returnValue = @(); $returnValue += Get-ADDomain; return $returnValue;" # 不工作
标签: multithreading powershell runspace