PowerShell GUI ScripBlock Monitor Script

PowerShell GUI ScripBlock Monitor Script


I made a GUI script for monitoring PowerShell scriptblocks:

It will take and Interval in Seconds and it will show the result in a GUI datagrid, refreshed at the set interval
(by re-running the scriptBlock )

Standard if you start the Acript you get a process list refreshed every 30 seconds :

But that is just an example as default ! ,

This script will

  • Take any Scriptblock as a parameter,
  • Run The Scriptblock at specified interval,
  • Convert the output to a dataTable and show it in the datagrid.
  • Alow to sort the output


PoSH> C:\PowerShell\Scripts\startmonitor.ps1                                                  
PoSH> C:\PowerShell\Scripts\start-monitor.ps1 -s {get-service | select name,displayname,status}                           
PoSH> C:\PowerShell\Scripts\start-monitor.ps1 5 {1 | select @{Name='Random';Expression={(new-object random).next(100)}}, {get-date},{pwd},{"ProcessCount $((gps).count)"}}  
PoSH> C:\PowerShell\Scripts\start-monitor.ps1 -s {        
>> gwmi win32_service -filter "State = 'Stopped' and startmode = 'auto'" |                                                
>> select ame,displayname,state,startmode                    
>> }                                                         
PoSH> C:\PowerShell\Scripts\start-monitor.ps1 5 {sc "TestLog$((new-object random).next(100)).log" 'foo';ls *.log | select directoryname,name,length,LastWriteTime}  

The latter 2 examples show how flexible you are with the scriptblocks

See the logfile list grow in last example

the statusbar will countdown to the next refresh and you also can use Ctr-R to refresh by hand.

the Script looks like this :

*edit 22-01-’07* updated the script a part of it was missing (timer start .. add_shown ) this seems to be a problem with live writer and pasting in large “Raw HTML”  text,

thanks, to “P ” for mentioning that in the comments


# Start-Monitor.ps1 
# PowerShell Script Monitoring form  
# Calls a scriptblock a a specified interval and shows output in DataGridView
# Start-Monitor -interval [sec] -ScriptBlock {}
# /\/\o\/\/ 2007    
PARAM([int]$Interval=30,[ScriptBlock]$ScriptBlock={(gps | select PSResources,cpu -ExcludeProperty TotalProcessorTime)})
# Helper function to translate the scriptblock output into a DataTable
Function out-DataTable {
  $dt=new-object Data.datatable  
  $First=$trueforeach ($itemin$input){  
    $Item.PsObject.get_properties() |foreach {  
      if ($first) {  
        $Col=new-object Data.DataColumn  
        $Col.ColumnName =$_.Name.ToString()  
        $DT.Columns.Add($Col)       }  
      if ($_.value -eq$null) {  
        $DR.Item($_.Name) ="[empty]"  
      elseif ($_.IsArray) {  
        $DR.Item($_.Name) =[string]::Join($_.value ,";")  
      else {  
        $DR.Item($_.Name) =$_.value  
  return @(,($dt))
# Make form  $form=new-object System.Windows.Forms.form   
$form2=new-object System.Windows.Forms.form   
$Form.text ="PowerShell Script Monitor: $ScriptBLock "$form.Size =new-object System.Drawing.Size(810,410)  
# Add DataGrid$DG=new-object windows.forms.DataGridView 
$DG.Dock = [System.Windows.Forms.DockStyle]::Fill 
$dg.ColumnHeadersHeightSizeMode = [System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode]::AutoSize 
$dg.SelectionMode ='FullRowSelect'$form.Controls.Add($DG) 
# Build Menu    $MS=new-object System.Windows.Forms.MenuStrip   
$Mi=new-object System.Windows.Forms.ToolStripMenuItem("&File")   
$Msi1=new-object System.Windows.Forms.ToolStripMenuItem("&Refresh") 
$Msi1.ShortcutKeys =0x20052$msi1.add_Click({
    $script:dt= (&$scriptBlock|out-dataTable )
    $script:DG.DataSource =$DT.psObject.baseobject
    if ("$sortOrder"-ne'None' ) {$dg.Sort($dg.columns[($col.name)],"$SortOrder")}
    $Rows.Text =" [ Rows : $($script:dt.rows.count) ] "
$Msi2=new-object System.Windows.Forms.ToolStripMenuItem("&Quit")   
# statusStrip$statusStrip=new-object System.Windows.Forms.StatusStrip
$Rows=new-object System.Windows.Forms.ToolStripStatusLabel
$Rows.BorderStyle ='SunkenInner'$Rows.BorderSides ='All'
$status=new-object System.Windows.Forms.ToolStripStatusLabel
$status.BorderStyle ='SunkenInner'$status.BackColor ='ButtonHighlight'$status.BorderSides ='All'$Status.Text =" [ Next Refresh in : $(new-Timespan -sec $Interval) ] [ Refresh Interval : $Interval Seconds ] "
$Command=new-object System.Windows.Forms.ToolStripStatusLabel
$Command.Spring =$true$Command.BorderStyle ='SunkenInner'$Command.BorderSides ='All'$Command.Text ="$ScriptBlock"
# Make Timer $timer=New-Object System.Windows.Forms.Timer 
if ($interval-gt30 ) {$timer.Interval =5000} Else {$timer.Interval =1000}
  $SecsToInterval-= ($timer.Interval /1000)
 if ( $SecsToInterval-eq0 ) {
    $SecsToInterval=$interval$Command.BackColor ='Red'$statusStrip.Update()
    $script:dt= (&$scriptBlock|out-dataTable )
    $script:DG.DataSource =$DT.psObject.baseobject
    if ("$sortOrder"-ne'None' ) {$dg.Sort($dg.columns[($col.name)],"$SortOrder")}
    $Rows.Text =" [ Rows : $($script:dt.rows.count) ] "
  $Command.BackColor ='Control'$Status.Text =" [ Next Refresh in : $(new-Timespan -sec $SecsToInterval) ] [ Refresh Interval : $Interval Seconds ] "$statusStrip.Update()
$timer.Enabled =$true$timer.Start()
# show Form  $Form.Add_Shown({
  $script:dt= (&$scriptBlock|out-dataTable )
  $script:DG.DataSource =$DT.psObject.baseobject
  $Rows.Text =" [ Rows : $($script:dt.rows.count) ] "$dg.AutoResizeColumns()

Try out some other commands as scriptblock, The script is pretty flexible, this way of monitoring ( Polling )is not perfect but still you might find this script very usefull in on the fly tasks, It is easy to startup and it is handy to watch some things on the fly like this.