Executing Code after Script Is Done

by Dec 4, 2015

For monitoring purposes, it is often not known how long a script needs to run. So here, an endless loop is used. The script runs for as long as the user wants, and stops only when the user aborts the script by pressing CTRL+C or closing PowerShell.

When you enclose such an endless loop inside a try block and add a finally block, you can continue such a script. When the user decides to abort the script, your finally block picks up and continues. Here, you could show some results, for example.

The following example detects whether the Internet Explorer was launched, and logs this. When the user aborts the script by pressing CTRL+C, the log file is opened, and the results are presented. Simply change the value of $name to monitor other programs, but make sure you specify the application name only, without the file extension.

#requires -Version 3

# log results here
$path = "$env:temp\logresult.txt"

# name of application to monitor
$name = 'iexplore'

# keep track of process IDs
$info = @{}

try
{
  # make sure log file is present and empty
  $null = New-Item -Path $path -ItemType File -Force
  Write-Host "Monitoring $name - press CTRL+C to end." -ForegroundColor Red

  # monitor endless loop
  while ($true)
  {
    # check for new instances
    Get-Process -Name $name -ErrorAction Ignore |
    ForEach-Object {
      $id = $_.Id

      # add new processes to list of monitored instances
      if ($info.ContainsKey($id) -eq $false)
      {
        $info.$id = $_
        '{0} - START {1} pid={2}' -f (Get-Date -Format 'HH:mm:ss fff'),$name, $id |
        Add-Content -Path $path
      }
    }  

    # check for closed instances
    # get a copy (you cannot manipulate an enumeration while examining it)
    $instances = $info.Values | Select-Object -Property ID, HasExited
    $instances | ForEach-Object {
      $id = $_.ID
      if ($_.HasExited)
      {
        '{0} - EXIT {1} pid={2}' -f (Get-Date -Format 'HH:mm:ss fff'),$name, $id |
        Add-Content -Path $path

        if ($info.ContainsKey($id)) { $info.Remove($id) }
      }
    }
    # wait a moment
    Start-Sleep -Seconds 1
  }

}
finally
{
  # when script is aborted, display log
  notepad $path
}

Twitter This Tip! ReTweet this Tip!