Configueroa
Configueroa

Reputation: 325

Using a Job within the While($true) loop of a PowerShell script

If the Pattern "Idle" is found at the immediate run of the script - it successfully sends the email. The problem is it should be able to keep looking within the while($true) loop with the start-sleep interval. This is not happening - it will wait for 60 minutes and then exit - even when the pattern "Idle" was written as the last line.

do I need a while loop within the Start-Job? I tried this code using a Wait with no luck: Get-Content $file -Tail 1 -Wait | Select-string -Pattern "Idle" -Quiet

$job = Start-Job {
    # Note: $file should be the absolute path of your file
    Get-Content $File -Raw | Select-string -Pattern "Idle" -Quiet
}

while($true)
{
    # if the job has completed
    if($job.State -eq 'Completed')
    {
        $result = $job|Receive-Job

        # if result is True
        if($result)
        {
            $elapsedTime.Stop()
            $duration = $elapsedTime.Elapsed.ToString("hh\:mm\:ss")
            
            # .... send email logic here
            # for success result

            break #=> This is important, don't remove it
        }

        # we don't need a else here,
        # if we are here is because $result is false
        
        $elapsedTime.Stop()
        $duration = $elapsedTime.Elapsed.ToString("hh\:mm\:ss")

        # .... send email logic here
        # for unsuccessful result
        
        break #=> This is important, don't remove it
    }

    # if this is running for more than
    # 60 minutes break the loop
    if($elapsedTime.Elapsed.Minutes -ge 60)
    {
        $elapsedTime.Stop()
        $duration = $elapsedTime.Elapsed.ToString("hh\:mm\:ss")
        
        # .... send email logic here
        # for script running longer 
        # than 60 minutes

        break #=> This is important, don't remove it
    }
    
    Start-Sleep -Milliseconds 500
}

Get-Job|Remove-Job

Upvotes: 2

Views: 5240

Answers (1)

mklement0
mklement0

Reputation: 439427

  • You indeed need Get-Content's -Wait switch to keep checking a file for new content in (near) real time (new content is checked for once every second).

    • However, doing so waits indefinitely, and only ends if the target files is deleted, moved, or renamed.
  • Therefore, with -Wait applied, your job may never reach status 'Completed' - but there's no need to wait for that, given that Receive-Job can receive job output while the job is running, as it becomes available.

  • However, you mustn't use Select-String's -Quiet switch, because it will only ever output one result, namely $true once the first match is found - and will produce no further output even if content added later also matches.

Therefore, you probably want something like the following:

$job = Start-Job {
  # Use Get-Content with -Wait, but don't use Select-String with -Quiet
  Get-Content $File -Raw -Wait | Select-string -Pattern "Idle"
}

while ($true)
{
  # Check for available job output, if any.
  if ($result = $job | Receive-Job) {

      $duration = $elapsedTime.Elapsed.ToString("hh\:mm\:ss")
          
      # .... send email logic here
      # for success result
      break

  }

  # if this is running for more than
  # 60 minutes break the loop
  if($elapsedTime.Elapsed.Minutes -ge 60)
  {
      $elapsedTime.Stop()
      $duration = $elapsedTime.Elapsed.ToString("hh\:mm\:ss")
      
      # .... send email logic here
      # for script running longer 
      # than 60 minutes
      
      # Forcefully remove the background job.
      $job | Remove-Job -Force

      break
  }
  
  Start-Sleep -Milliseconds 500
}

Note:

  • $job | Receive-Job either produces no output, if none happens to be available, or one or more [Microsoft.PowerShell.Commands.MatchInfo] instances reported by Select-Object.

  • Using this command as an if-statement conditional (combined with an assignment to $result) means that one or more [Microsoft.PowerShell.Commands.MatchInfo] instances make the conditional evaluate to $true, based on PowerShell's implicit to-Boolean coercion logic - see the bottom section of this answer.

Upvotes: 3

Related Questions