1
votes

I have a main script that imports a module \path\to\functions.psm1, I call a function in the main script named: Run_Scans $ServerList, which is from functions.psm1, From Run_Scans I try and call two other functions (Scan1,Scan2) using Start-Job, but cannot get the servers variable to pass to the other functions. I've tried several different ways with either the job fails or completes but the server list does pass through. Any help would greatly be appreciated.

#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
}

UPDATE:

I was able to do the following:

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

Receive-Job 

Output:

Serv1

Serv2

Serv3

But when I try to incorporate calling the function:

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

I get the following errors:

The term 'Run_Scan1' is not recognized as the name of a cmdlet, function, script file, or operable program.

Cannot index into a null array.

FINAL Solution:

Start-Job -InitializationScript {Import-Module "Pathto\Functions.ps1"}  -ScriptBlock { param($Servers) Run_Scan1 $Servers } -ArgumentList (,$servers)
1
The background job runs in a session in an independent PowerShell child process that knows nothing about the state of the caller, so the Run_Scan1 and Run_Scan2 functions won't be available there. Aside from that, if $Servers is an array, you'd have to pass it as -ArgumentList (, $Servers) as shown in js2010's answer. - mklement0
If you Import-Module with -InitializationScript wouldn't that make the function available? - Chris
Yes, that should work; note that in PS 6- the background job runs in $HOME\Documents, not in the caller's current directory, so be sure to account for that in Pathto\Functions.psm1 - see this answer. - mklement0
Thanks for the help - Chris

1 Answers

0
votes

For arrays, I recommend the using scope. Jobs don't handle array parameters well. Use start-threadjob if you have it.

$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

Or there's this ridiculous (, ) workaround:

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

server1
server2