function Get-PCBatchInvoke {
    [CmdletBinding()]
    param (
        [Parameter()]
        [string[]]
        $Computers
    )
    $Tenant = (Connect-ISM)[1]
    $Headers = (Connect-ISM)[0]

    $OnlineComputers = @()
    $OfflineComputers = @()
    $output = @()
    $itemIndex = 0
    foreach($comp in $Computers){
        $itemIndex++
        BatchInvokesProgressBar -item $comp -currentItemIndex $itemIndex -TotalItems $Computers.Count -stage 1
        $Connection = Test-Connection -ComputerName $comp -Count 1
        if($Connection){
            $OnlineComputers += $comp
        }
        else{
            $OfflineComputers += $comp
        }
    }
    BatchInvokesProgressBar -stage 2
    $invokeJob = Invoke-Command -ScriptBlock ${function:Get-PCLocal} -ComputerName $OnlineComputers -SessionOption (New-PSSessionOption -NoMachineProfile -OpenTimeout 45000) -AsJob
    $offlineJobs = @()
    if($OfflineComputers.count -gt 0){
        foreach($computer in $OfflineComputers){
            $offlineJobs += Start-Job -ScriptBlock ${function:Get-SCCMQueryBlock} -ArgumentList $computer
        }
    }
    BatchInvokesProgressBar -stage 3
    $output += $invokeJob | Receive-Job -Wait -AutoRemoveJob | Select-Object * -ExcludeProperty RunspaceId, PSComputerName, PSShowComputerName, PSSourceJobInstanceId
    $itemIndex = 0
    $contactedhosts = $output.Hostname
    BatchInvokesProgressBar -stage 4
    $missedhosts = $OnlineComputers | Where-Object -FilterScript {$_ -notin $contactedhosts}
    $missedJobs = @()
    if($missedhosts.count -gt 0){
        $i = 1
        foreach($computer in $missedhosts){
            $missedJobs += Start-Job -ScriptBlock ${function:Get-SCCMQueryBlock} -ArgumentList $computer,$i
            $i++
        }
    }
    $output += $offlineJobs | Receive-Job -Wait -AutoRemoveJob | Select-Object * -ExcludeProperty RunspaceId, PSComputerName, PSShowComputerName, PSSourceJobInstanceId
    $output += $missedJobs | Receive-Job -Wait -AutoRemoveJob | Select-Object * -ExcludeProperty RunspaceId, PSComputerName, PSShowComputerName, PSSourceJobInstanceId
    BatchInvokesProgressBar -stage 5
    #CMDB cycle of missed hosts
    $missedhosts = $Computers | Where-Object -FilterScript {$_ -notin $output.Hostname}
    if($missedhosts.count -gt 0){
        foreach($computer in $missedhosts){
            $output += Get-CMDBFallback $computer
        }
    }
    
    return $output

}

function BatchInvokesProgressBar {
    param (
        $item,
        $currentItemIndex,
        $TotalItems,
        $stage
    )
    switch ($stage) {
        1 { Write-Progress -Activity "Connecting to computers" -Status "$item ($currentItemIndex/$TotalItems)" -PercentComplete (($currentItemIndex/$TotalItems) * 100) -Id 0}
        2 { Write-Progress -Activity "Spinning up jobs" -PercentComplete ((10/100) * 100) -Id 0}
        3 { Write-Progress -Activity "Querying online computers" -PercentComplete ((20/100)*100) -Id 0}
        4 { Write-Progress -Activity "Querying SCCM for offline computers"  -PercentComplete ((75/100) * 100) -Id 0}
        5 { Write-Progress -Activity "Querying CMDB for computers not in SCCM"  -PercentComplete ((85/100) * 100) -Id 0}
        Default {}
    }

}