PoshCode Logo PowerShell Code Repository

WPF PingMonitor for 2.0 (modification of post by Joel Bennett view diff)
diff | embed code: <script type="text/javascript" src="http://PoshCode.org/embed/981"></script>download | new post

This script ONLY works in PowerShell 2.0, but it doesn’t require -STA (single threaded apartment) mode.
A PowerBoots script to demonstrate the power of PoshWpf: Create a New-PingMonitor window which uses Visifire charts to display the recent ping history of multiple servers simultaneously, and interact with it while it’s running, adding hosts at will. There are only two callable functions here:

  1. if(!(Get-Command New-BootsWindow -EA SilentlyContinue)) {
  2.    # Add-PsSnapin PoshWpf
  3.    Import-Module PowerBoots
  4.    Add-BootsContentProperty 'DataPoints', 'Series'
  5.    #[Void][Reflection.Assembly]::LoadFrom( (Convert-Path (Resolve-Path "~\Documents\WindowsPowershell\Libraries\WPFVisifire.Charts.dll")) )
  6.    Add-BootsFunction -Assembly "~\Documents\WindowsPowershell\Libraries\WPFVisifire.Charts.dll"
  7.    Add-BootsFunction ([System.Windows.Threading.DispatcherTimer])
  8. }
  9.  
  10. if(Get-Command Ping-Host -EA SilentlyContinue) {
  11.    $pingcmd = { (Ping-Host $args[0] -count 1 -Quiet).AverageTime }
  12. } else {
  13.    $pingcmd = { [int]([regex]"time=(\d+)ms").Match( (ping $args[0] -n 1) ).Groups[1].Value }
  14. }
  15.  
  16. $global:onTick = {
  17. $window = $this.Tag
  18.    #  Invoke-BootsWindow $window {
  19.       try {
  20.          foreach($s in $window.Content.Series.GetEnumerator()) {
  21.             $ping = &$pingcmd $s.LegendText
  22.             $points = $s.DataPoints
  23.             foreach($dp in 0..$($points.Count - 1))
  24.             {
  25.                if(($dp+1) -eq $points.Count) {
  26.                   $points[$dp].YValue = $ping
  27.                } else {
  28.                   $points[$dp].YValue = $points[$dp+1].YValue
  29.                }
  30.             }
  31.          }
  32.       } catch {
  33.          Write-Output $_
  34.       }
  35.    #  }
  36. }
  37.  
  38. function Add-PingHost {
  39. [CmdletBinding()]
  40. Param(
  41.    [Parameter(Position=0,ValueFromPipeline=$true)]
  42.    [string[]]$target
  43. ,
  44.    [Parameter(Position=1)]
  45.    [Visifire.Charts.RenderAs]$renderAs="Line"
  46. ,  
  47.    [Parameter(Position=2)]
  48.    [System.Windows.Window]$window = $global:pingWindow
  49. ,
  50.    [Parameter()]
  51.    [Switch]$Passthru
  52. )
  53. PROCESS {
  54.    if($Window) {
  55.       Invoke-BootsWindow $Window {
  56.          $target | Add-PingHostInternal -render $renderAs -window $window
  57.       }
  58.       return $Window
  59.    } else {
  60.       return New-PingMonitor -Hosts $target -RenderAs $renderAs
  61.    }
  62. }
  63. }
  64.  
  65. function Add-PingHostInternal {  
  66. [CmdletBinding()]
  67. Param(
  68.    [Parameter(Position=0,ValueFromPipeline=$true)]
  69.    [string]$target
  70. ,
  71.    [Parameter(Position=1)]
  72.    [Visifire.Charts.RenderAs]$renderAs="Line"
  73. ,  
  74.    [Parameter(Position=2)]
  75.    [System.Windows.Window]$window = $global:pingWindow
  76. )
  77. Process {
  78.    $start = $(get-random -min 10 -max 20)
  79.    $window.Content.Series.Add( $(
  80.       DataSeries { 1..25 | %{DataPoint -YValue $start} } -LegendText $target -RenderAs $renderAs
  81.    ) )
  82. }
  83. }
  84.  
  85. function New-PingMonitor {
  86. [CmdletBinding()]
  87. Param(
  88.    [Parameter(Position=0,ValueFromPipeline=$true)]
  89.    [string[]]$hosts = $(Read-Host "Please enter the name of a computer to ping")
  90. ,
  91.    [Parameter(Position=1)]
  92.    [Visifire.Charts.RenderAs]$renderAs="Line"
  93. ,
  94.    [Parameter()]
  95.    [Switch]$Passthru
  96. )
  97. Process {
  98.    $script:renderAs = $renderAs
  99.    $script:Hosts = $Hosts
  100.      
  101.    $global:pingWindow = New-BootsWindow -Async {
  102.       Param($window) # New-Boots passes the window to us ...
  103.       # Make a new scriptblock of the OnTick handle, passing it ourselves
  104.       # Make a timer, and stick it in the window....
  105.       $window.Tag = @((DispatcherTimer -Interval "00:00:01.0" -On_Tick $global:onTick -Tag $window), $global:onTick)
  106.      
  107.       Chart {
  108.          foreach($h in $hosts) {
  109.             $script:start = get-random -min 10 -max 20
  110.             DataSeries {
  111.                foreach($i in 1..25) {
  112.                   DataPoint -YValue $script:start
  113.                }
  114.             } -LegendText $h -RenderAs $renderAs
  115.          }
  116.       } -watermark $false
  117.    } -On_ContentRendered {
  118.       $this.tag[0].Start()
  119.    } -On_Closing {
  120.       $this.tag[0].Remove_Tick($this.tag[1])
  121.       $this.tag[0].Stop()
  122.       $global:pingWindow = $null
  123.       Remove-BootsWindow $this
  124.    } -Title "Ping Monitor" -Passthru -height 300 -width 800
  125.  
  126.    if($Passthru) {
  127.       return $global:pingWindow
  128.    }
  129. }
  130. }

Submit a correction or amendment below (
click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:


Remember me