Reputation: 325
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
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).
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