WPF PingMonitor for 1.0 (modification of post by view diff)
View followups from Joel Bennett | embed code: <script type="text/javascript" src="http://PoshCode.org/embed/980"></script>download | new post
This script should work in PowerShell 1.0 and 2.0, even without -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. There are only two callable functions here:
- New-PingMonitor creates the window and starts pinging hosts
- Add-PingHost adds hosts to the window. There should be a matching Remove-PingHost, but there isn’t.
- if(!(Get-Command New-BootsWindow -EA SilentlyContinue)) {
- Add-PsSnapin PoshWpf
- #Import-Module PowerBoots
- #Add-BootsContentProperty 'DataPoints', 'Series'
- [Void][Reflection.Assembly]::LoadFrom( (Convert-Path (Resolve-Path "~\Documents\WindowsPowershell\Libraries\WPFVisifire.Charts.dll")) )
- #Add-BootsFunction -Assembly "~\Documents\WindowsPowershell\Libraries\WPFVisifire.Charts.dll"
- #Add-BootsFunction ([System.Windows.Threading.DispatcherTimer])
- }
- if(Get-Command Ping-Host -EA SilentlyContinue) {
- $pingcmd = { (Ping-Host $args[0] -count 1 -Quiet).AverageTime }
- } else {
- $pingcmd = { [int]([regex]"time=(\d+)ms").Match( (ping $args[0] -n 1) ).Groups[1].Value }
- }
- $global:onTick = {
- Param($window=$global:pingWindow)
- Invoke-BootsWindow $window {
- try {
- foreach($s in $window.Content.Series.GetEnumerator()) {
- $ping = &$pingcmd $s.LegendText
- $points = $s.DataPoints
- foreach($dp in 0..$($points.Count - 1))
- {
- if(($dp+1) -eq $points.Count) {
- $points[$dp].YValue = $ping
- } else {
- $points[$dp].YValue = $points[$dp+1].YValue
- }
- }
- }
- } catch {
- Write-Output $_
- }
- }
- }
- function Add-PingHost {
- PARAM(
- [string[]]$target
- , [Visifire.Charts.RenderAs]$renderAs="Line"
- , [Windows.Window]$window = $global:pingWindow
- , [Switch]$Passthru
- )
- if($Window) {
- Invoke-BootsWindow $Window {
- foreach($h1 in $target) {
- Add-PingHostInternal $h1 $renderAs $window
- }
- }
- if($Passthru) { return $Window }
- } else {
- return New-PingMonitor $target $renderAs -Passthru:$Passthru
- }
- }
- function Add-PingHostInternal {
- PARAM(
- [string]$target
- , [Visifire.Charts.RenderAs]$renderAs="Line"
- , [System.Windows.Window]$window = $global:pingWindow
- )
- $start = $(get-random -min 10 -max 20)
- $ds = New-Object Visifire.Charts.DataSeries
- $ds.LegendText = $target
- $ds.RenderAs = $renderAs
- [void]$window.Content.Series.Add($ds)
- for($i=0;$i -lt 25;$i++) {
- $dp = New-Object Visifire.Charts.DataPoint
- $dp.YValue = $start
- [void]$ds.DataPoints.Add( $dp )
- }
- }
- function New-PingMonitor {
- PARAM (
- [string[]]$hosts = $(Read-Host "Please enter the name of a computer to ping")
- , [Visifire.Charts.RenderAs]$renderAs="Line"
- , [Switch]$Passthru
- )
- $global:pingWindow = New-BootsWindow -Async {
- Param($window) # New-Boots passes the window to us ...
- Write-Debug "Window: $window"
- # Make a timer
- $timer = New-Object System.Windows.Threading.DispatcherTimer
- $timer.Interval = "00:00:01.0"
- # Make a new scriptblock of the OnTick handle, passing it ourselves
- $tickover = ({ &$global:onTick $window }).GetNewClosure()
- $timer.Add_Tick( $tickover )
- # Stick the timer into the window....
- $window.Tag = @($timer, $tickover)
- # Make a chart
- $PingChart = New-Object Visifire.Charts.Chart
- $PingChart.Height = 300
- $PingChart.Width = 800
- $PingChart.watermark = $false
- #$PingChart.Add_Initialized( {$timer.Start();} )
- # Make a bunch of data series
- $hosts | % {
- $h1 = $_
- $start = $(get-random -min 10 -max 20)
- $ds = New-Object Visifire.Charts.DataSeries
- $ds.LegendText = $h1
- $ds.RenderAs = $renderAs
- $PingChart.Series.Add($ds)
- for($i=0;$i -lt 25;$i++) {
- $dp = New-Object Visifire.Charts.DataPoint
- $dp.YValue = $start
- $ds.DataPoints.Add( $dp )
- }
- }
- # we have to output the chart: whatever we output from here ends up in the window
- $PingChart
- } -On_ContentRendered {
- Write-Debug "Content Rendered. Tag: $($this.tag[0])"
- $this.tag[0].Start()
- } -On_Closing {
- $this.tag[0].Remove_Tick($this.tag[1])
- $this.tag[0].Stop()
- $global:pingWindow = $null
- } -Title "Ping Monitor" -Passthru
- if($Passthru) {
- return $global:pingWindow
- }
- }
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.
PowerShell Code Repository