[PowerShell][Example] Foreach Parallel
Lets start off with a scenario; You need to get the OS version off of multiple machines. Yes this example should do nicely :). Easy right? Sure, but lets up the game... and say you have a lot of machines and you don't want to have to wait around for it. OK yeah there are a bunch of ways to do that... Alright then, you want to limit how many jobs you send at any given time... ugh... (now I have to keep track of that too?) Well as long as you're on PowerShell 4.0 (recommend 5 as there were some changes), This is yet another super easy PowerShell task. Check out my below example:
$machines = gc '.\machines.txt'
function get-OSVersion{
param(
[string] $computer = "localhost"
)
$OS = Get-WmiObject -Computer $computer -Class Win32_OperatingSystem
return $OS.Version
}
workflow myTask {
param(
[string[]] $machines
)
foreach -parallel -throttle 2 ($machine in $machines){
$startTime = Get-Date
$version = get-OSVersion $machine
"$startTime : Finished for $machine - OS Version $version"
}
}
myTask -machines $machines
Easy right, alright have a good one...
Ok, fine, i'll explain it a bit. First I get a list of machines, nothing special there. I wrote a function for the main work because that's how I roll (vs just throwing it in the body). Here's were it gets fun, I create a workflow (just like you would a function) and it even allows a param, just like a function. You even call it like a function. However, this allows us to use parallel options including the foreach -parallel. it works just like a foreach, but it just kicks everything off... well that is unless you throttle it, then it kicks off that quantity, in this case 2. Keep in mind that write-host doesn't work in a workflow, unless you used "InlineScript({write-host "blah blah"})", just keep in mine doing so creates issues with how variables are accessed. Here's the output:
09/08/2017 11:00:20 : Finished for MyMachine - OS Version 10.0.15063
09/08/2017 11:00:20 : Finished for localhost - OS Version 10.0.15063
09/08/2017 11:00:24 : Finished for https://www.garudax.id/redir/invalid-link-page?url=127%2e0%2e0%2e1 - OS Version 10.0.15063
As you can see, two kicked off at the same time, leaving the third to kick off 4 seconds later. (Yes, I queried my machine 3 times...get over it)
Happy Scripting!
P.S. I can hear some people screaming why waste your time on creating a function or, you can get that in one line. Yes I know.
workflow myTask {
$machines = gc '.\machines.txt'
foreach -parallel -Throttle 2 ($machine in $machines){
$startTime = Get-Date
$version = (Get-WmiObject -Computer $machine -Class Win32_OperatingSystem).Version
"$startTime : Finished for $machine - OS Version $version"
}
}
myTask
There you happy?!? I like to write things out explicitly so that they are able to be reused via dotsource, or that they are somewhat self documenting. I even like using regions to group things together. Call it my style.
P.P.S. apparantly if you put the loopback IP in, LinkedIn Changes it to a page can't be found link.. so just be aware :)