Powershell 7 ForEach-Object Parallel автоматически разрывает переменную c при передаче в команду invoke - PullRequest
1 голос
/ 17 июня 2020

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


    Write-Host "Confirm correct OS is installed" -ForegroundColor Yellow -BackgroundColor Black

    $FQDNs | ForEach-Object {
        Invoke-Command -ComputerName $_ -Credential $Credentials -ScriptBlock { 
            $OS = (Get-CimInstance -ClassName CIM_OperatingSystem).Caption
            Write-Host "$Using:_`: $OS" -ForegroundColor Green -BackgroundColor Black
            Write-Output "$Using:_`: $OS"
        }
    }
} 

, если я добавлю параметр -Parallel, он немедленно выйдет из строя с ошибкой ниже. Как еще я должен передать переменную, если автоматическая c переменная - это единственный способ, которым я вижу, что объект foreach передает их? (Я надеюсь, что это не так)

ForEach-Object: C:\Scripts\Checklist.ps1:53
Line |
  53 |      $FQDNs | ForEach-Object -Parallel {
     |               ~~~~~~~~~~~~~~~~~~~~~~~~~~
     | The value of the using variable '$using:_' cannot be retrieved because
     | it has not been set in the local session.

Вот сценарий со вставленным параметром Parallel, чтобы показать, где именно я это делаю


    Write-Host "Confirm correct OS is installed" -ForegroundColor Yellow -BackgroundColor Black

    $FQDNs | ForEach-Object -Parallel {
        Invoke-Command -ComputerName $_ -Credential $Credentials -ScriptBlock { 
            $OS = (Get-CimInstance -ClassName CIM_OperatingSystem).Caption
            Write-Host "$Using:_`: $OS" -ForegroundColor Green -BackgroundColor Black
            Write-Output "$Using:_`: $OS"
        }
    }
}

Ответы [ 2 ]

1 голос
/ 19 июня 2020

Команда вызова computername comp1, comp2, comp3 уже выполняется параллельно.

# elevated prompt
start-service winrm
invoke-command localhost,localhost,localhost { sleep 10 } 
(get-history)[-1] | fl

Id                 : 3
CommandLine        :     invoke-command localhost,localhost,localhost { sleep 10 }
ExecutionStatus    : Completed
StartExecutionTime : 6/19/2020 10:05:02 AM
EndExecutionTime   : 6/19/2020 10:05:13 AM  # 11 seconds for all three
1 голос
/ 19 июня 2020

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

Фактически вы столкнетесь с той же проблемой, если поочередно используете Invoke-Command с -ThrottleLimit и массивом имен компьютеров, переданным в -ComputerName, чтобы использовать преимущества параллелизма, а не ForEach-Object с -Parallel.

Чтобы решить эту проблему, попробуйте использовать [scriptblock]::Create() для сборки ваш блок скрипта, чтобы соблюдается правильный контекст, как описано в этом ответе .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...