This is a -very- minimalistic script to run N commands at a time from a list. If you are on a supported Windows system, it will have PowerShell.
There is no error checking or proper help information. It writes stdout to the specified log file, but does nothing with the exit code from the command. If something fails, it would need to be identified from the log file.
To use this, put the following code into the file Invoke-JobList.ps1
Create a .csv file with the commands you want to run and a different log file name for each command. The log file name cannot be the same for multiple commands. If you have 5000 commands to process, you will probably need to write a script/program to produce it.
I provided a sample .csv file and a batch file that I used for testing. You do not need to use to.bat
.
=== Get-Content .\Invoke-JobList.ps1
[CmdletBinding()]
Param (
[Parameter(Mandatory=$true)]
[string[]]$jobFile
,[Parameter(Mandatory=$false)]
[int]$nConcurrent = 2
)
$jobs = Import-Csv -Path $jobFile
$jobHash = @{}
$nJobsRunning = 0
foreach ($job in $jobs) {
if ($nJobsRunning -lt $nConcurrent) {
Write-Verbose -Message "starting command $($job.command)"
$j = Start-Job -ScriptBlock ([ScriptBlock]::Create($job.command))
$jobHash[$j] = $job.logfile
$nJobsRunning++
}
while ($nJobsRunning -ge $nConcurrent) {
# wait for one or more jobs to state Completed
$jobsRunning = Get-Job
foreach ($jobRun in $jobsRunning) {
if (($null -ne $jobHash[$jobRun]) -and ($jobRun.State -eq 'Completed')) {
Receive-Job -Job $jobRun | Out-File -FilePath $jobHash[$jobRun]
Remove-Job -Job $jobRun
$jobHash.Remove($jobRun)
$nJobsRunning--
}
}
}
}
Write-Verbose -Message $($nJobsRunning.ToString() + " remaining jobs")
# Wait for all remaining jobs to complete
while ($nJobsRunning -gt 0) {
$jobsRunning = Get-Job
foreach ($jobRun in $jobsRunning) {
if (($null -ne $jobHash[$jobRun]) -and ($jobRun.State -eq 'Completed')) {
Receive-Job -Job $jobRun | Out-File -FilePath $jobHash[$jobRun]
Remove-Job -Job $jobRun
$jobHash.Remove($jobRun)
$nJobsRunning--
}
}
}
=== Get-Content .\joblist3.csv
command,logfile
C:\src\jobs\to.bat 10,ss-001.txt
C:\src\jobs\to.bat 10,ss-002.txt
C:\src\jobs\to.bat 10,ss-003.txt
C:\src\jobs\to.bat 10,ss-004.txt
C:\src\jobs\to.bat 10,ss-005.txt
C:\src\jobs\to.bat 10,ss-006.txt
C:\src\jobs\to.bat 10,ss-007.txt
=== Get-Content .\to.bat
@ECHO OFF
SET "TO=%1"
IF "%TO%" == "" (SET "TO=5")
REM Cannot use TIMEOUT command
ping -n %TO% localhost
EXIT /B 0
Invoke it with parameters.
.\Invoke-JobList.ps1 -jobFile joblist3.csv -nConcurrent 3 -Verbose