我需要按一定顺序在远程Powershell会话中执行一些cmdlet:例如。如果此通讯组存在,则将该用户添加到组中,但我不断遇到有关运行空间状态的错误,或者我创建了太多运行空间,因此我必须等待一段时间。我不能使用运行空间池,因为对于每个会话,在执行其他cmdlet之前我都需要获取cmdlet的结果。
我试图在同一运行空间中执行cmdlet块脚本(取决于其他结果的两个或三个chdlet),但是由于运行空间未打开,我得到了无效的运行空间状态。在完成cmdlet块脚本之后,我确实处理了运行空间,我也确实处理了powershell会话。
在该站点上搜索了一些答案之后,我阅读了某人在一个相关问题中的答案,他说在每次调用并重新创建运行空间和powershell会话soud后将其丢弃,但是不久之后我收到一条错误消息,说我无法创建更多的运行空间。
Collection<PSObject> resultado = new Collection<PSObject>();
try
{
WSManConnectionInfo connectionInfo = new WSManConnectionInfo(new Uri(LiveId), SchemaUri, Credenciales);
connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Basic;
Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo);
if (runspace != null && Credenciales != null)
{
PowerShell PS = PowerShell.Create();
PS.Runspace = runspace;
runspace.Open();
using (Pipeline pipeline = runspace.CreatePipeline())
{
Command cmd = new Command(comando);
foreach (KeyValuePair<string, string> parametro in parametros)
{
cmd.Parameters.Add(parametro.Key, parametro.Value);
}
pipeline.Commands.Add(cmd);
resultado = pipeline.Invoke();
}
runspace.Close();
runspace.Dispose();
PS.Dispose();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace + "/" + comando + parametros);
}
我应该如何正确管理运行空间,以确保每个cmdlet块脚本都能正确执行?
非常感谢!!
答案 0 :(得分:1)
我发现Chrissy LeMaire的模板Runspaces Simplified (as much as possible)非常有用,您要做的就是传递脚本块
下面是模板
# BLOCK 1: Create and open runspace pool, setup runspaces array with min and max threads
$pool = [RunspaceFactory]::CreateRunspacePool(1, [int]$env:NUMBER_OF_PROCESSORS+1)
$pool.ApartmentState = "MTA"
$pool.Open()
$runspaces = @()
# BLOCK 2: Create reusable scriptblock. This is the workhorse of the runspace. Think of it as a function.
$scriptblock = {
Param (
[string]$connectionString,
[object]$batch,
[int]$batchsize
)
$bulkcopy = New-Object Data.SqlClient.SqlBulkCopy($connectionstring,"TableLock")
$bulkcopy.DestinationTableName = "mytable"
$bulkcopy.BatchSize = $batchsize
$bulkcopy.WriteToServer($batch)
$bulkcopy.Close()
$dtbatch.Clear()
$bulkcopy.Dispose()
$dtbatch.Dispose()
# return whatever you want, or don't.
return $error[0]
}
# BLOCK 3: Create runspace and add to runspace pool
if ($datatable.rows.count -eq 50000) {
$runspace = [PowerShell]::Create()
$null = $runspace.AddScript($scriptblock)
$null = $runspace.AddArgument($connstring)
$null = $runspace.AddArgument($datatable)
$null = $runspace.AddArgument($batchsize)
$runspace.RunspacePool = $pool
# BLOCK 4: Add runspace to runspaces collection and "start" it
# Asynchronously runs the commands of the PowerShell object pipeline
$runspaces += [PSCustomObject]@{ Pipe = $runspace; Status = $runspace.BeginInvoke() }
$datatable.Clear()
}
# BLOCK 5: Wait for runspaces to finish
while ($runspaces.Status.IsCompleted -notcontains $true) {}
# BLOCK 6: Clean up
foreach ($runspace in $runspaces ) {
# EndInvoke method retrieves the results of the asynchronous call
$results = $runspace.Pipe.EndInvoke($runspace.Status)
$runspace.Pipe.Dispose()
}
$pool.Close()
$pool.Dispose()
# Bonus block 7
# Look at $results to see any errors or whatever was returned from the runspaces