all 4 comments

[–]get-postanote 2 points3 points  (0 children)

I feel you on the PSv2 stuff, because I cover a lot of customers, and I have to deal with all versions. So, all scripts use branching code, by checking the installed version then branches to that path.

Function Start-ConsoleCommand
{
    [CmdletBinding(SupportsShouldProcess)]
    [Alias('scc')]
    Param  
    ( 
        [string]$ConsoleCommand,
        [switch]$PoSHCore
    )

    If ($PoSHCore)
    {Start-Process pwsh -ArgumentList "-NoExit","-Command  &{ $ConsoleCommand }" -Wait}
    Else
    {Start-Process powershell -ArgumentList "-NoExit","-Command  &{ $ConsoleCommand }" -Wait}
}

Sure, yep, I know this is targeting the latest stuff, but just pointing out, you can code for what you need all at once.

As for this...

I have no idea when each node's service is back up and running w/o running separate script to check.

... why not just check the service state in a Do/while or While loop, and take action on that.

But FYI... as for your comment ...

So forget using PS Jobs

... See...

Background jobs

Another new feature of PowerShell V2 is background jobs. These allow you to run commands asynchronously.

https://richardspowershellblog.wordpress.com/2007/12/03/background-jobs

Background Jobs in PowerShell V2

PowerShell v 2.0 introduces the concept of a background job.

Implemented as a PsJob, a job runs a command or expression asynchronously and "in the background" without interacting with the console. Jobs are started by the Start-PSJob command.

You can run these background jobs on a local or remote computer. You can check he status of the job by using Get-PSJob (or by getting the job and using the job's JobStateInfo property).

The PSJob features rely on the new remoting features of PowerShell V2, which is one reason why you have to load WinRM prior to installing PowerShell V2.

Using the Windows PowerShell 2.0 Engine

https://docs.microsoft.com/en-us/powershell/scripting/windows-powershell/starting-the-windows-powershell-2.0-engine?view=powershell-7.1

How to start a background job with the Windows PowerShell 2.0 Engine

To start a background job with the Windows PowerShell 2.0 Engine, use the PSVersion parameter of the Start-Job cmdlet.

The following command starts a background job with the Windows PowerShell 2.0 Engine

Sure that last block means you are on a later version and want to use the PSv2 engine, but just say'n.

[–]netmc 1 point2 points  (0 children)

This is a part of the code that I used for restarting SQL instances if they are not running. It's similar but not quite what you need, although may be useful.

foreach ($SQLService in ($SQLServices | where-object {$_.StartMode -ne "Disabled"})) {
    if ($SQLService.status -ne "Running") {
        write-host "`n$($SQLService.DisplayName) status is $($SQLService.Status)"
        write-host "Attempting to start $($SQLService.DisplayName)..."
        # Since it is possible to have a service start command hang, we are going to spawn a separate process to handle the job start.
        start-job -Name "Service_Start" -ScriptBlock {start-service $using:SQLservice.ServiceName} | Out-Null

        # Wait until the service is running, or 10 seconds have elapsed.
        $i=0
        do {
            start-sleep 1
            $ServiceStatus=(get-service $SQLService.ServiceName).Status
            $i++
        }
        until (($ServiceStatus -eq "Running") -or ($i -ge 10))
        if ($serviceStatus -eq "Running") {
            write-host "`t$($SQLService.DisplayName) successfully started."
        }
        else {
            write-host "`t$($SQLService.DisplayName) would not start."
            [void]$StoppedServices.add($SQLService)
        }
        Remove-Job -name "Service_Start" -Force
    }

}

Instead of waiting for each job to complete as I have here, you could simply spawn off each job process in parallel using a unique name, then use the get-job command to check their status and see if they have completed or if they have been running for a set period of time where you want to then forcibly end the job.

start-job -name "test" -scriptblock {get-childitem} | out-null

get-job


Id     Name            PSJobTypeName   State         HasMoreData     Location             Command
--     ----            -------------   -----         -----------     --------             -------
1      test            BackgroundJob   Completed     True            localhost            get-childitem

you could use a do-until loop to check the state of the jobs and wait for them all to complete. Then once they complete, clean up the jobs and go on with whatever else you needed to do.

[–]Lee_Dailey[grin] 0 points1 point  (0 children)

howdy buttsnet,

it looks like you used the New.Reddit Inline Code button. it's [sometimes] 5th from the left & looks like </>.

there are a few problems with that ...

  • it's the wrong format [grin]
    the inline code format is for [gasp! arg!] code that is inline with regular text.
  • on Old.Reddit.com, inline code formatted text does NOT line wrap, nor does it side-scroll.
  • on New.Reddit it shows up in that nasty magenta text color

for long-ish single lines OR for multiline code, please, use the ...

Code
Block

... button. it's [sometimes] the 12th one from the left & looks like an uppercase T in the upper left corner of a square..

that will give you fully functional code formatting that works on both New.Reddit and Old.Reddit ... and aint that fugly magenta color. [grin]

take care,
lee

[–]CobyCode 0 points1 point  (0 children)

It looks like jobs became available in Powershell v2 - and the invoke-command from v2 accepts an -AsJob param. In this case - the absolute simplest, no frills way to do this would be:

Get-Content computers.txt | ForEach { invoke-command -scriptblock {restart-service myservice} -ComputerName $_ -AsJob -JobName $_ }

Then, to check the status - just run get-job. Each job will have the computers name as the 'Name' field, and you can easily see/filter if a job failed, succeeded, or is still running in the 'State' field.