繁体   English   中英

不使用运行空间池来管理Powershell运行空间的正确方法是什么?

[英]What is the right way to manage powershell runspace without using runspace pool?

我需要按一定顺序在远程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块脚本?

非常感谢你!!!

我发现克里斯西·勒梅尔(Chrissy LeMaire)尽可能简化了此模板“ 简化的运行空间” ,您所要做的就是传递脚本块

下面是模板

# 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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM