Run Function multiple times concurrently

I want to call a Function multiple times, with different parameters, and have it run concurrently.

I’ve tested this by running the two commands below in PowerShell_ISE, and two Powershell sessions open and it runs as expected. But I want to schedule this, I’ve tried having the scheduler call a ps1 file with those commands in it, and nothing. I’ve tried having 2 scheduled Actions with each individual command, and nothing. How can I get these 2 commands run concurrently, or at least not wait until each has completed before calling the next?

Start-Process powershell.exe -ArgumentList "Execute-CrmSync 'cttest'"
Start-Process powershell.exe -ArgumentList "Execute-CrmSync 'ctdev'"

Is this something you need to happen when you manually run it or for a Scheduled Task kind of deal?

 

I would think Out-Null after the first command OR using the -Wait command should do it.

As far as getting your scheduled execution, there are tons of resources online about accomplishing this. For your specific question, one option would be to run them as jobs.

$script = {
    Param($server)
    Start-Process powershell.exe -ArgumentList "Execute-CrmSync $server"
}
$jobs = 'cttest','ctdev' | foreach{
    Start-Job -ScriptBlock $script -ArgumentList $_
}
$results = $jobs | Wait-Job | Receive-Job
$jobs | Remove-Job
Write-Output $results

I want to run it via Scheduled task.

When I run it manually, it does what I’d expect, 2 PowerShell sessions start and run the fucntion in the command. When run via a Scheduled task it doesn’t run.

The -Wait will do the opposite from what I want.

I tried the Out-Null and no change.

Doug, I’ve already got scripts that do that type of thing, it’s not what I want to do in this case.

I want to call a Function multiple times, with different parameters, and have it run concurrently.

Not what you said.

How can I get these 2 commands run concurrently, or at least not wait until each has completed before calling the next?

I answered this specific question.

OK, well perhaps not brilliantly explained. But the end result I’m aiming for is 1 scheduled task, with a separate Action for each command, each command will call the function with it’s parameter value. If that’s not possible, I can go down the other path of using a script and Start-Job. That I already use and have no problem with (so far).

Whatever script you has that works like you want, you just need to get it to run as a scheduled task. Am I understanding you correctly? If so, there are literally dozens of examples on the internet. Here are a few.

https://community.spiceworks.com/how_to/17736-run-powershell-scripts-from-task-scheduler
https://o365reports.com/2019/08/02/schedule-powershell-script-task-scheduler/
https://redmondmag.com/articles/2016/05/13/automatically-run-powershell-scripts-at-a-scheduled-time.aspx
https://devblogs.microsoft.com/scripting/use-scheduled-tasks-to-run-powershell-commands-on-windows/

Have you looked at workflows using foreach -parallel?

https://docs.microsoft.com/en-us/powershell/module/psworkflow/about/about_foreach-parallel?view=powershell-5.1

Thanks Rob, I’m looking for a way of using an Action in a Scheduled Task to run each command by passing the function name and a parameter and not have to wait for each Action to complete before the next are started.

I’m aware of Workflows and use that in a few of the scripts I’ve written. I’m also comfortable with Start-Job and use that in some of my scripts.

If there’s no way for me to get the individual Actions, in a Scheduled job to work, I’ll most likely just call a file, eg: -file “D:\Scripts\CrmSync\MasterCrmSync.ps1”, and use Start-Job.

I was hoping to avoid using a file and start-job and call the function directly from the Scheduled Task Action but not wait for each Action to complete before running the next Action.

Action 1

Execute-CrmSync -Environment 'cttest'

Action 2

Execute-CrmSync -Environment 'ctdev'

 

What is wrong with calling your working scripts with task scheduler? What are you hoping to gain by putting the commands in directly versus just calling a script?

I apologize, but I am not tracking. You want to

  1. Have a single script
  2. Execute multiple tasks synchronously in the script
  3. Initiate the single script from Task Scheduler

Script:

function Execute-CrmSync {
    [CmdletBinding()]
    param (
        $Environment
    )
    begin{
        $start = Get-Date
    }
    process{
        Start-Sleep -Seconds 15
    }
    end{
        [pscustomobject]@{
            Environment = $Environment
            Start       = $start
            End         = Get-Date
        }
    }
}

workflow Test-CrmSync
{
    $tasks = 'cttest','ctdev'

    ForEach -Parallel ($task in $tasks)
    {
        Execute-CrmSync -Environment $task
    }
}

Test-CrmSync

Output:

Environment           : ctdev
Start                 : 5/14/2020 10:57:39 AM
End                   : 5/14/2020 10:57:54 AM
PSComputerName        : localhost
PSSourceJobInstanceId : d932618c-665f-4992-a248-872e49710ab6

Environment           : cttest
Start                 : 5/14/2020 10:57:39 AM
End                   : 5/14/2020 10:57:54 AM
PSComputerName        : localhost
PSSourceJobInstanceId : d932618c-665f-4992-a248-872e49710ab6

Both tasks are initiated at the same time, in a single script which could be executed in task scheduler. Please explain what exactly is not working in this example.

No, single script I can do, workflows etc, no problem. The issue I’m trying to address is how to get the Scheduler Action to call the function and then move to the next Action, ie not wait untill it’s completed, but just move to next Action and call the same function but with a different parameter value. In a Schedued Task, there is the Action tab, in that I have 2 Actions, each calls the Function with a different parameter value. But it waits untill the 1st Action is completed before proceeding the 2nd Action.

I’m trying to avoid having have to add a 3rd step to this, and having a Scheduler Action call a script, that loops through and calls the Function.

 

So, this is a Task Scheduler question, not Powershell.

https://serverfault.com/questions/978536/can-scheduled-task-actions-run-in-parallel

Multi-threading, parallelization, synchronous execution of an Action is not supported by Task Scheduler. Per the suggestion in the thread above, you would need to execute the task in something that does support this functionality, like Powershell.

Currently, I’ve 2 Scheduled tasks, each has 1 Action. I want to combine these 2 Scheduled tasks into 1 Scheduled task with 2 Actions. But I want to have the Action call the Function and move onto the next Action, not wait untill the Action has completed which is what is happening now.

Scheduled Task 1

Action: Execute-CrmSync 'ctdev'

Scheduled Task 2

Action: Execute-CrmSync 'cttest'

 

Thanks for that Rob. As there is this https://docs.microsoft.com/en-us/powershell/module/scheduledtasks/?view=win10-ps i had wondered if there maybe a way using that. ie: using PowerShell.

Yes there is a way using powershell. Call powershell.exe with your working script as the argument. One scheduled task, running 2 actions concurrently. I still do not understand what it is you are going to gain even if it were possible.