Powershell - как вызвать две функции с помощью Start-Job внутри функции и передать список имен компьютеров?

У меня есть основной скрипт, который импортирует модуль \ путь \ к \ functions.psm1, я вызываю функцию в основном скрипте с именем: Run_Scans $ ServerList, который взят из functions.psm1, из Run_Scans я пытаюсь вызвать две другие функции (Scan1 , Scan2) с помощью Start-Job, но не может передать переменную серверов другим функциям. Я пробовал несколько разных способов: либо задание не выполняется, либо завершается, но список серверов проходит. Любая помощь будет принята с благодарностью.

#This is from the main script#
Import-Module "path\to\Functions.psm1"
Run_Scans $ServerList

#This is from functions.psm1#
Function Run_Scans ($Servers){
#Start-Job -Name 'Scan1' -ScriptBlock {Run_Scan1 $using:Servers}
#Start-Job -Name 'Scan2' -ScriptBlock {Run_Scan2 $using:Servers}

$Scan = {
    param ($Servers)
    Run_Scan1 $Servers
    Run_Scan2 $Servers
}
Start-Job -ScriptBlock $Scan -ArgumentList $Servers
}

Function Run_Scan1 ($Servers){
    scan code
}
Function Run_Scan2 ($Servers){
    scan code
}

ОБНОВИТЬ:

Мне удалось сделать следующее:

$ServerList = "Serv1","Serv2","Serv3"
Start-Job -InitializationScript $Initialization -ScriptBlock {param($servers) echo $servers} -args (,$servers)

Receive-Job 

Вывод:

Serv1

Serv2

Serv3

Но когда я пытаюсь включить вызов функции:

$Initialization = [scriptblock]::Create("Import-Module -Name 'Pathto\Functions.psm1'")
Start-Job -InitializationScript $Initialization -ScriptBlock {param($servers) Run_Scan1 $servers} -args (,$servers)

Я получаю следующие ошибки:

Термин «Run_Scan1» не распознается как имя командлета, функции, файла сценария или работающей программы.

Невозможно проиндексировать в нулевой массив.

Окончательное решение:

Start-Job -InitializationScript {Import-Module "Pathto\Functions.ps1"}  -ScriptBlock { param($Servers) Run_Scan1 $Servers } -ArgumentList (,$servers)

person Chris    schedule 14.04.2020    source источник
comment
Фоновое задание выполняется в сеансе в независимом дочернем процессе PowerShell, который ничего не знает о состоянии вызывающего, поэтому функции Run_Scan1 и Run_Scan2 там не будут доступны. Кроме того, если $Servers является массивом, вам нужно будет передать его как -ArgumentList (, $Servers), как показано в ответе js2010.   -  person mklement0    schedule 15.04.2020
comment
Если вы импортируете модуль с -InitializationScript, разве это не сделает эту функцию доступной?   -  person Chris    schedule 15.04.2020
comment
Да, это должно сработать; обратите внимание, что в PS 6 фоновое задание выполняется в $HOME\Documents, а не в текущем каталоге вызывающего абонента, поэтому обязательно учтите это в Pathto\Functions.psm1 - см. этот ответ.   -  person mklement0    schedule 15.04.2020
comment
Спасибо за помощь   -  person Chris    schedule 15.04.2020


Ответы (1)


Для массивов я рекомендую использовать scope. Задания плохо обрабатывают параметры массива. Используйте start-threadjob, если он у вас есть.

$servers = echo server1 server2

start-job { param($servers) $servers } -args $servers | receive-job -wait -auto

server1


start-job { $using:servers } | receive-job -wait -auto          

server1
server2

Или есть этот нелепый (,) обходной путь:

start-job { param($servers) $servers } -args (,$servers) | receive-job -wait -auto

server1
server2
person js2010    schedule 14.04.2020
comment
Хороший улов (хотя большая проблема OP - это недоступность функций в фоновом задании). Обратите внимание, однако, что такое поведение - хотя и удивительное и требует неясного обходного пути - является конструктивным и применяется ко всем командлетам, которые принимают аргументы передачи через параметр -ArgumentList, имеющий значение массива - см. этот ответ. - person mklement0; 15.04.2020
comment
Возможно, вы можете добавить к своему ответу и другую часть решения, а именно необходимость импортировать модуль с функциями, вызываемыми в задании; Крис отредактировал это в своем вопросе, но лучше оставить это как часть ответа: Start-Job -InitializationScript {Import-Module "Pathto\Functions.ps1"} -ScriptBlock { param($Servers) Run_Scan1 $Servers } -ArgumentList (,$servers) - person mklement0; 16.04.2020