Как ограничить количество одновременно работающих заданий PowerShell (PS Jobs)

Недавно передо мной встала задача получения результатов выполнения некоторой команды на нескольких тысячах хостов. Т.к. выполнение команды занимает некоторое время, логичным способом ускорения процесса будет параллельный запуск нескольких команд одновременно. В случае PowerShell, для этого у нас есть прекрасный инструмент Background Jobs.
Однако ресурсы компьютера, где я запускал все эти задания, ограничены и он не выдерживал одновременной работы более 100 заданий. К сожалению, в PowerShell пока не встроено никакого способа ограничения количества одновременно выполняющихся заданий, равно как и очереди для них.

Я не первый, кто столкнулся с такой проблемой: официальный блог Hey, Scripting Guy! предлагает способ организации очереди, с использованием объектов .NET Framework. Признаюсь, честно, у меня не получилось заставить этот метод работать и, в итоге, я сообразил, что очередь заданий можно организовать гораздо проще, всё что нужно, это:

  • Цикл
  • Проверка на кол-во текущих работающих заданий
  • Переменная, разрешающая отправку следующего задания на выполнение

Получилась вот такая обёртка, реализующая эти три условия:

Мой вариант чрезвычайно похож на решение (которое я нашёл, как обычно, уже ПОСЛЕ того, как придумал свой вариант), предложенное в комментарии на StackOverflow, но, как там и заметили, в варианте, предложенном на SO, есть вероятность пропуска некоторых элементов для обработки.

Как показало исследование Бо Прокса, фоновые задания PowerShell проигрывают в скорости выполнения раздельным средам исполнения (runspaces). Как использовать несколько сред исполнения, Бо подробно рассказывает в своём блоге.

Другие варианты организации очереди, которые могут вам помочь: