0

I have a script which does its job perfectly fine, however I do want to convert the same to multi threaded since I need the job to execute every 5 minutes.

Below is the set of functions that I execute on each of the server.

$ServiceDetailsDataset=get-ServiceDetails -serverList $server
                Write-Verbose "service details collected"
                $ReadBytes=$($ServiceDetailsDataset.ReadBytes)
                $instances=$($ServiceDetailsDataset.Instances)
                $CPU=$($ServiceDetailsDataset.CPU)
                $dataSet=get-IODetails -ServiceDetails $($ServiceDetailsDataset.ServiceDetails) -computerName $server -Instances $Instances -ReadBytes  $ReadBytes -WriteBytes $($ServiceDetailsDataset.WriteBytes) -OtherBytes $($ServiceDetailsDataset.OtherBytes) -CPU $($ServiceDetailsDataset.CPU) -NumberOfLogicalProcessors $($ServiceDetailsDataset.NumberOfLogicalProcessors)
                Write-Verbose "Post IOI Details"
                $dataset|Out-GridView
                Write-Verbose "Inserting Data";
                Generate-InsertScript -aggrDataSet $dataset
                Write-Verbose "Data Insertion completed";

And to make this multi threaded I have modified the script to the below state.

Start-Job -ScriptBlock {
            if(check-IfSystemIsUp -server $server){

            
                $ServiceDetailsDataset=get-ServiceDetails -serverList $server
                Write-Verbose "service details collected"
                $ReadBytes=$($ServiceDetailsDataset.ReadBytes)
                $instances=$($ServiceDetailsDataset.Instances)
                $CPU=$($ServiceDetailsDataset.CPU)
                $dataSet=get-IODetails -ServiceDetails $($ServiceDetailsDataset.ServiceDetails) -computerName $server -Instances $Instances -ReadBytes  $ReadBytes -WriteBytes $($ServiceDetailsDataset.WriteBytes) -OtherBytes $($ServiceDetailsDataset.OtherBytes) -CPU $($ServiceDetailsDataset.CPU) -NumberOfLogicalProcessors $($ServiceDetailsDataset.NumberOfLogicalProcessors)
                Write-Verbose "Post IOI Details"
                $dataset|Out-GridView
                Write-Verbose "Inserting Data";
                Generate-InsertScript -aggrDataSet $dataset
                Write-Verbose "Data Insertion completed";
            }
        } -Name $server

While running the receive-job to get the job status, I do receive the below error.

enter image description here

How do I make it multi threaded without making changes to my function and by just adding the start-job cmdlet

Updated Question

Now this script has been modified as below.

foreach  ($server in $serverList){
        Write-Verbose "*****Collecting Service Details*********" 
        Start-Job -InitializationScript $functions -ArgumentList $server -ScriptBlock {
            if(check-IfSystemIsUp -server $args[0]){

            
                $ServiceDetailsDataset=get-ServiceDetails -serverList $args[0]
                Write-Verbose "service details collected"
                $ReadBytes=$($ServiceDetailsDataset.ReadBytes)
                $instances=$($ServiceDetailsDataset.Instances)
                $CPU=$($ServiceDetailsDataset.CPU)
                $dataSet=get-IODetails -ServiceDetails $($ServiceDetailsDataset.ServiceDetails) -computerName $args[0] -Instances $Instances -ReadBytes  $ReadBytes -WriteBytes $($ServiceDetailsDataset.WriteBytes) -OtherBytes $($ServiceDetailsDataset.OtherBytes) -CPU $($ServiceDetailsDataset.CPU) -NumberOfLogicalProcessors $($ServiceDetailsDataset.NumberOfLogicalProcessors)
                Write-Verbose "Post IOI Details"
                #$dataset|Out-GridView
                Write-Verbose "Inserting Data";
                Generate-InsertScript -aggrDataSet $dataset
                Write-Verbose "Data Insertion completed";
            }
        }

This works absolutely fine when I execute on two servers. But I do have 55 servers this script needs to be executed on and I am running this job as a SQL Job. The problem is its executing only for 40 odd servers. Is there some kind of throttling issue?

SQLDoctor
  • 343
  • 7
  • 16
  • You don't need threads to schedule a script. Create a scheduled task that runs your script. Simply creating a thread won't schedule anything – Panagiotis Kanavos Jul 01 '20 at 13:31
  • @PanagiotisKanavos Apologies if my requirement is clear, I am trying to make it a multi threaded program so to execute on multiple servers at the same time. – SQLDoctor Jul 01 '20 at 13:33
  • 1
    As for the error, it's also clear - there's no `check-IfSystemIsUp`. I suspect that's a function in a module that wasn't loaded? – Panagiotis Kanavos Jul 01 '20 at 13:33
  • If you want to run the same script block for multiple servers, use `ForEach-Object` with the list of servers as input. In Powershell Core you can [parallelize the loop](https://devblogs.microsoft.com/powershell/powershell-foreach-object-parallel-feature/) by adding the `-Parallel -ThrottleLimit n`, eg `$data | Foreach-Object -Parallel -ThrottleLimit 4 {...}` – Panagiotis Kanavos Jul 01 '20 at 13:36
  • @PanagiotisKanavos Thanks for the inputs, I have used "https://stackoverflow.com/questions/7162090/how-do-i-start-a-job-of-a-function-i-just-defined" to make sure the parameters are recognized, I added -ArguementList. – SQLDoctor Jul 01 '20 at 13:49
  • @PanagiotisKanavos All looks good except the JobID keeps increasing, is there a way to clean it up or will it be cleaned up automatically? – SQLDoctor Jul 01 '20 at 13:49
  • @PanagiotisKanavos I have updated my questions since I have the progres, please have a look at it. – SQLDoctor Jul 01 '20 at 14:30

0 Answers0