PowerShell function to watch the result of a command invocation, alerting you when the output either matches a specified string, lacks a specified string, or has simply changed.
##############################################################################
##
## Watch-Command
##
## From Windows PowerShell Cookbook (O'Reilly)
## by Lee Holmes (http://www.leeholmes.com/guide)
##
##############################################################################
<#
.SYNOPSIS
Watches the result of a command invocation, alerting you when the output
either matches a specified string, lacks a specified string, or has simply
changed.
.EXAMPLE
PS > Watch-Command { Get-Process -Name Notepad | Measure } -UntilChanged
Monitors Notepad processes until you start or stop one.
.EXAMPLE
PS > Watch-Command { Get-Process -Name Notepad | Measure } -Until "Count : 1"
Monitors Notepad processes until there is exactly one open.
.EXAMPLE
PS > Watch-Command { Get-Process -Name Notepad | Measure } -While 'Count : \d\s*\n'
Monitors Notepad processes while there are between 0 and 9 open
(once number after the colon).
#>
[CmdletBinding(DefaultParameterSetName = "Forever")]
param(
## The script block to invoke while monitoring
[Parameter(Mandatory = $true, Position = 0)]
[ScriptBlock] $ScriptBlock,
## The delay, in seconds, between monitoring attempts
[Parameter()]
[Double] $DelaySeconds = 1,
## Specifies that the alert sound should not be played
[Parameter()]
[Switch] $Quiet,
## Monitoring continues only until while the output of the
## command remains the same.
[Parameter(ParameterSetName = "UntilChanged", Mandatory = $false)]
[Switch] $UntilChanged,
## The regular expression to search for. Monitoring continues
## until this expression is found.
[Parameter(ParameterSetName = "Until", Mandatory = $false)]
[String] $Until,
## The regular expression to search for. Monitoring continues
## until this expression is not found.
[Parameter(ParameterSetName = "While", Mandatory = $false)]
[String] $While
)
Set-StrictMode -Version 3
$initialOutput = ""
## Start a continuous loop
while($true)
{
## Run the provided script block
$r = & $ScriptBlock
## Clear the screen and display the results
Clear-Host
$ScriptBlock.ToString().Trim()
""
$textOutput = $r | Out-String
$textOutput
## Remember the initial output, if we haven't
## stored it yet
if (-not $initialOutput)
{
$initialOutput = $textOutput
}
## If we are just looking for any change,
## see if the text has changed.
if ($UntilChanged)
{
if ($initialOutput -ne $textOutput)
{
break
}
}
## If we need to ensure some text is found,
## break if we didn't find it.
if ($While)
{
if ($textOutput -notmatch $While)
{
break
}
}
## If we need to wait for some text to be found,
## break if we find it.
if ($Until)
{
if ($textOutput -match $Until)
{
break
}
}
## Delay
Start-Sleep -Seconds $DelaySeconds
}
## Notify the user
if (-not $Quiet)
{
[Console]::Beep(1000, 1000)
}