# encoding: ascii
# api: powershell
# title: New-SelfRestartingTask
# description: Restarts applications using a ManagementEventWatcher to watch for an InstanceDeletionEvent … use at your own risk ;)
# version: 5.0
# type: function
# license: CC0
# function: New-SelfRestartingTask
# x-poshcode-id: 1795
# x-archived: 2010-04-24T23:04:42
#
#
function New-SelfRestartingTask {
#.Notes
#  For production use you should consider investigating more specific matching in the Query clause.
#
#  There are many possibilities here: you could watch for instances of a process with specific command-line parameters, or a certain caption, etc. Or, you could match against one process, but fire off a different one when it crashes. 
#
#  Have a look at the Win32_Process class to see all the properties available for matching.
#.Link
#  Win32_Process Class http://msdn.microsoft.com/en-us/library/aa394372%28VS.85%29.aspx
#.Link
#  __InstanceDeletionEvent http://msdn.microsoft.com/en-us/library/aa394652%28VS.85%29.aspx
#.Link
#  ScriptCenter article on Events http://www.microsoft.com/technet/scriptcenter/topics/winpsh/events.mspx
#.Synopsis
#  Restarts an application when it exits or crashes
#.Description
#  Create a WMIEvent handler to watch for the termination of a specific executable and restart it.
#
#.Parameter Application
#  The path to an application you want to restart when it crashes
#
#.Parameter Parameters
#  Parameters to be passed to the application when we (re)start it
#
#.Parameter Start
#  Automatically start the process (even if it's already running)
#
#.Parameter Interval
#  Polling interval to check whether the application has exited or not
#
#.Example
#  New-SelfRestartingTask notepad -Start
#
# Description
# -----------
# Starts notepad right away and monitors for crash or exit and restarts it.
#
#.Example
# New-SelfRestartingTask C:\Program` Files\Internet` Explorer\IExplore.exe http://HuddledMasses.org
#
# Description
# -----------
# Monitors for the termination of Internet Explorer and restarts it pointed at my blog.
# Note that this does NOT start IE, so it could already be running, or you should start it by hand later...
#
param(
[Parameter(Mandatory=$true, Position=0)]
[string]$Application
,
[Parameter(Mandatory=$false)]
[double]$Interval = 5.0
,
[Parameter(Mandatory=$false)]
[switch]$Start
,
[Parameter(ValueFromRemainingArguments=$true)]
[string[]]$Parameters
)

$ExecutablePath = gcm $Application -type application | select -expand definition -first 1 | %{ $_ -replace '\\','\\' }

if($Parameters) {
   $Parameters = "-ArgumentList `"$($Parameters -join '", "')`""
}

$sb = Invoke-Expression "{ Start-Process `"$ExecutablePath`" $Parameters }"

Register-WMIEvent -Action $sb -Query "Select * From __InstanceDeletionEvent Within $Interval Where TargetInstance ISA 'Win32_Process' And TargetInstance.ExecutablePath='$ExecutablePath'" | Out-Null

if($Start){ 
   sleep -milli 500
   &$sb 
}

}
