I have a Powershell script that, when firing, grabs data from a couple of flat files, parses it, puts it into a comma-delimited fashion then places it in memory. This data is then passed to a Windows Chart Object (downloaded from here) and a chart is generated.
But how do I refresh it automatically?
I've looked at PoshBoard, but I would like to just grab new data on a time interval and update the existing control.
Here's my proposed logic:
- Get data (coded successfully)
- Parse Data (coded successfully)
- Create and display form (coded successfully)
- Update said form
without interrupting display
--- Run steps 1-2 again on a 30 minute timer and pass it to the chart.
Please note: I create/display the form on a background job, thus it is on a separate thread, otherwise the ".Show()" and ".ShowDialog()" form calls lock up the script. This is being used to monitor important memory usage statistics on gajillion-dollar systems and I can't have scripts locking up.
Please excuse the dirtiness of it. Here's the script:
New-Item -ItemType f -Path c:/batch/lcontents.txt -Force
New-Item -ItemType f -Path c:/batch/gajilliondollarsystem.txt -Force
$form = $null
$zid = Read-Host "What is your ZID?"
$PW = read-host "What is your password?"
""
"If this hangs for more than 20 seconds, your credentials are wrong."
""
# Get contents of /import/sftw/vmstat_***.txt
c:\batch\plink.exe ***-admin -l $zid -pw $PW "cat /import/sftw/vmstat_***.txt" > c:\batch\lcontents.txt
""
"Credentials accepted."
""
# Select specific information from cat file for last 36 hours (Every half hour (72), 3 entries per (72x3 = 216)
Select-String -Path C:\batch\lcontents.txt -SimpleMatch "CDT", "Free memory", "Inactive memory" | select -last 216 > c:\batch\lcontentsnew.txt
# Extract contents of lcontentsnew into memory
$loglist = gc c:\batch\lcontentsnew.txt | ?{$_.trim() -ne ""} | %{ $_ -replace ".*txt:\d+:"}
# rewrite in comma-delimited fashion
$count1 = 0
$count2 = 1
$count3 = 2
$gajilliondollarsystemlist = @()
do {
$gajilliondollarsystemlist += "$($loglist[$count1].trim()),$($loglist[$count2].trim()),$($loglist[$count3].trim())"
$count1+=3
$count2+=3
$count3+=3
}
until ($count1 -gt $loglist.count-3)
add-content c:\batch\gajilliondollarsystem.txt $gajilliondollarsystemlist
#Import-CSV for grouping purposes
$list = import-csv c:\batch\gajilliondollarsystem.txt -Delimiter "," -Header "Date","Inactive","Free"
$list | export-csv C:\Batch\gajilliondollarsystem.csv -Delimiter "," -NoTypeInformation
$ldate = $list.date
$linactive = ($list.inactive -replace " M inactive memory").trim()
$lfree = ($list.free -replace " M free memory").trim()
# Convert free and inactive to integers
$linactiveint = @()
$lfreeint = @()
foreach ($l in $linactive) {
$linactiveint += [int]$l
}
foreach ($l in $lfree) {
$lfreeint += [int]$l
}
#Combine free and inactive quantities into $lcombined
$count = 0
$lcombined = @()
do
{
$lcombined += ($linactiveint[$count] + $lfreeint[$count])
$count++
}
until ($count -eq $lfreeint.count)
function GraphData {
# load the appropriate assemblies for charting
[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms.DataVisualization")
# create chart object
$Chart = New-object System.Windows.Forms.DataVisualization.Charting.Chart
$Chart.Width = 900
$Chart.Height = 300
$Chart.Left = 0
$Chart.Top = 0
# create a chartarea to draw on and add to chart
$ChartArea = New-Object System.Windows.Forms.DataVisualization.Charting.ChartArea
$Chart.ChartAreas.Add($ChartArea)
# add data to chart
[void]$Chart.Series.Add("Inactive")
[void]$Chart.Series.Add("Free")
[void]$Chart.Series.Add("Combined")
$Chart.Series[0].Points.DataBindXY($args[0], $args[2])
$Chart.Series[1].Points.DataBindXY($args[0], $args[1])
$Chart.Series[2].Points.DataBindXY($args[0], $args[3])
# set chart type
$Chart.Series[0].ChartType = [System.Windows.Forms.DataVisualization.Charting.SeriesChartType]::Line
$Chart.Series[1].ChartType = [System.Windows.Forms.DataVisualization.Charting.SeriesChartType]::Line
$Chart.Series[2].ChartType = [System.Windows.Forms.DataVisualization.Charting.SeriesChartType]::Line
#format the lines
$chart.series[0].BorderWidth = 3
$chart.series[0].Color = "Blue"
$chart.series[1].BorderWidth = 3
$chart.series[1].Color = "Red"
$chart.series[2].BorderWidth = 3
$chart.series[2].Color = "Green"
# add title and axes labels
[void]$Chart.Titles.Add("gajilliondollarsystem Memory Monitoring Trend (36 Hrs.)")
# change chart area colour
$Chart.BackColor = [System.Drawing.Color]::Transparent
# Legend Properties
$chart.legends.add("Inactive")
$chart.legends.add("Free")
$chart.legends.add("Combined")
#axis titles
$chart.chartareas.axisx.title = "Date"
$chart.chartareas.axisy.title = "Memory in MB"
# save chart to file
$Chart.SaveImage($Env:USERPROFILE + "\Desktop\Chart.png", "PNG")
# display the chart on a form
$Chart.Anchor = [System.Windows.Forms.AnchorStyles]::Bottom -bor [System.Windows.Forms.AnchorStyles]::Right -bor
[System.Windows.Forms.AnchorStyles]::Top -bor [System.Windows.Forms.AnchorStyles]::Left
$Form = New-Object Windows.Forms.Form
$Form.Text = "PowerShell Chart $(get-date)"
$Form.Width = 950
$Form.Height = 325
$Form.controls.add($Chart)
# $Form.Add_Shown({$Form.Activate()})
$form.startposition = "CenterScreen"
$Form.ShowDialog()
}
#clear-host
Start-Job $function:GraphData -argumentlist @($ldate, $lfreeint, $linactiveint, $lcombined)
clear-host
Read-Host "Press ENTER to continue."
get-job | %{remove-job $_ -Force}