SoftwareSavant
SoftwareSavant

Reputation: 9737

Two logically opposite ending conditions in a while loop

I have a function in powershell that will stop a service or start the service depending upon an input parameter to the function. It is inside a loop that checks for a 5 count if it fails the first time. Right now it is set such that it should end when the status of the service is stopped. How can I check in the same loop if the status of the service is started... This is really a logical question of whether or not you can have diametrically opposite ending conditions in a while loop. But I have some abbreviated code for you...

[System.ServiceProcess.ServiceController]$service = Get-Service -Name $ServiceName -ComputerName $Remoteserver
[int]$waitCount = 5
do
{
    $waitCount--

    switch($service.Status)
    {
            { @(
            [System.ServiceProcess.ServiceControllerStatus]::ContinuePending,
            [System.ServiceProcess.ServiceControllerStatus]::PausePending,
            [System.ServiceProcess.ServiceControllerStatus]::StartPending,
            [System.ServiceProcess.ServiceControllerStatus]::StopPending) -contains $_ }
            {
                # A status change is pending. Do nothing.
                break;
            }
            { @(
            [System.ServiceProcess.ServiceControllerStatus]::Paused,
            [System.ServiceProcess.ServiceControllerStatus]::Running) -contains $_ }
            {
                # The service is paused or running. We need to stop it.
                if($StopOrStart -eq "stop"){
                    $service.Stop()
                    write-host("Stopped.")
                    break;
                }
            }
            { @(
            [System.ServiceProcess.ServiceControllerStatus]::Stopped) -contains $_ }
            {
             #if Stop or Start is equal to start then start the service.
                if($StopOrStart -eq "start"){
                    $service.Start()
                    write-host("Started.")
                    break;
                }
            }            
    }
    # Sleep, then refresh the service object.
    Sleep -Seconds 1
    $service.Refresh()
} while (($service.Status -ne [System.ServiceProcess.ServiceControllerStatus]::Stopped) -and $waitCount -gt 0) 

I am trying to come up with a way to end the while loop if $service.Status -ne Started if $StopOrStart is equal to "start"?

I really don't want to write two functions that do the same thing, one for starting services and one for stopping when I could have one that does it.

Upvotes: 1

Views: 250

Answers (2)

mjolinor
mjolinor

Reputation: 68243

Not tested:

$service = Get-Service -Name $ServiceName -ComputerName $Remoteserver
$waitCount = 5
do
{
    $waitCount--

    switch -Regex ($service.Status)
    {
       'Pending$'  
        {
          # A status change is pending. Do nothing.
          break;
        }

       'Paused'
        {
          # The service is paused.  We need to stop or start it.
            if($StopOrStart -eq "stop"){
                $service.Stop()
                write-host("Stopped.")}

            if($StopOrStart -eq "start"){
                $service.Start()
                write-host("Started.")}   
        }

       'Stopped'
        {
          if($StopOrStart -eq "Stop"){ Return }

          if($StopOrStart -eq "Start"){
            $service.Start()
            write-host("Started.")}

        }

     'Started'
       {
          if($StopOrStart -eq "Start"){ Return }

          if($StopOrStart -eq "Stop"){
            $service.Stop()
            write-host("Stopped.")}

       }      
    }

    # Sleep, then refresh the service object.
    Sleep -Seconds 1
    $service.Refresh()

 } While ($waitCount -gt 0)

Upvotes: 0

websch01ar
websch01ar

Reputation: 2123

Instantiate a Boolean for indicating if the operation was successful.

[bool]$WasSuccessful = $false

Then in your conditional steps test to ensure that the status was successfully set. If it was, then bail out. Matching how you were doing it:

[bool]$WasSuccessful = $false

[System.ServiceProcess.ServiceController]$service = Get-Service -Name $ServiceName -ComputerName $Remoteserver
[int]$waitCount = 5
do
{
    $waitCount--

    switch($service.Status)
    {
            { @(
            [System.ServiceProcess.ServiceControllerStatus]::ContinuePending,
            [System.ServiceProcess.ServiceControllerStatus]::PausePending,
            [System.ServiceProcess.ServiceControllerStatus]::StartPending,
            [System.ServiceProcess.ServiceControllerStatus]::StopPending) -contains $_ }
            {
                # A status change is pending. Do nothing.
                break;
            }
            { @(
            [System.ServiceProcess.ServiceControllerStatus]::Paused,
            [System.ServiceProcess.ServiceControllerStatus]::Running) -contains $_ }
            {
                # The service is paused or running. We need to stop it.
                if($StopOrStart -eq "stop"){
                    $service.Stop()
                    If ((Get-Service -ComputerName $Remoteserver -Name $ServiceName).Status -eq "Stopped") {
                        write-host("Stopped.")
                        $WasSuccessful = $true
                    }
                }
            }
            { @(
            [System.ServiceProcess.ServiceControllerStatus]::Stopped) -contains $_ }
            {
             #if Stop or Start is equal to start then start the service.
                if($StopOrStart -eq "start"){
                    If ((Get-Service -ComputerName $Remoteserver -Name $ServiceName).Status -eq "Running") {
                        write-host("Started")
                        $WasSuccessful = $true
                    }
                }
            }            
    }
    # Sleep, then refresh the service object.
    Sleep -Seconds 1
    $service.Refresh()
} while (($WasSuccessful -ne $true) -and $waitCount -gt 0)  

Upvotes: 1

Related Questions