Как правильно управлять пространством выполнения powershell без использования пула? - PullRequest
0 голосов
/ 05 июня 2019

Мне нужно выполнить несколько командлетов в удаленном сеансе PowerShell в определенном порядке: напр.если эта группа рассылки существует, добавьте этого пользователя в группу, но я продолжаю получать сообщения о состоянии пространства выполнения или о том, что я создал слишком много областей выполнения, и мне нужно подождать некоторое время.Я не могу использовать пул пространства выполнения, потому что для каждого сеанса мне нужно получить результат командлета перед выполнением других командлетов.

Я попытался выполнить блочный сценарий командлетов (два или три командлета, которые зависят отрезультат других) в том же пространстве выполнения, но я получаю недопустимое состояние пространства выполнения, потому что пространство выполнения не открыто.Я удаляю пространство выполнения после завершения сценария блока командлетов и тоже располагаю сеансом Powerhell.

После поиска на этом сайте ответов на некоторые вопросы я читаю чей-то ответ в связанном вопросе, где он сказал, что пространство выполнения иСеанс PowerShell следует отбрасывать после каждого вызова и создавать заново, но через короткое время я получаю сообщение о том, что не могу создать больше пространств выполнения.

    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);
    }

Как правильно я управляю пространством выполнения, чтобы убедиться, чтокаждый скрипт блока командлетов выполняется правильно?

Большое спасибо !!!

1 Ответ

1 голос
/ 05 июня 2019

Я нашел этот шаблон Runspaces Упрощенный (насколько это возможно) от 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
...