________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
<#
.SYNOPSIS
Calls a scriptblock at a specified interval and shows output in DataGridView.
.DESCRIPTION
PowerShell Script Monitoring form.
Calls a scriptblock at a specified interval and shows the output that is generated by the execution of the scriptblock in a datagridview.
The standard Powershell Out-GridView cmdlet does not sort numeric and date-columns correctly, but sorts all columns as text.
This function creates a datagridview that sorts all columns according to their type.
.PARAMETER Interval
Specifies the refresh interval in seconds.
Defaults to 0 (no refresh).
.PARAMETER ScriptBlock
Specifies the scriptblock to execute.
If no scriptblock is specified, a blank form opens where you can enter a scriptblock.
The scriptblock must ONLY return 1 or more output-objects.
Any other output will result in obscure error-messages.
.INPUTS
None. You cannot pipe objects to this function.
.OUTPUTS
This function returns an array with events from an eventlog for a computer.
This function returns an empty array if no matching events could be found.
.NOTES
Written by /\/\o\/\/ 2007
http://thePowerShellGuy.com: basic Out-Datatable
FurBall : added automatic type-detection, so
- columns are not sorted as text, but according to their type
- numeric columns will be right-aligned
: added option to run scriptblock from textbox
: added option to save output to .csv
: added standard module-documentation
EXAMPLE
C:\ps> Start-Monitor.ps1
Description
----------
Opens a blank form where you can enter a scriptblock.
Press Ctrl-R to execute the scriptblock.
EXAMPLE
C:\ps> Start-Monitor.ps1 -Interval 30 -ScriptBlock {(gps | select PSResources,cpu -ExcludeProperty TotalProcessorTime)}
Description
----------
EXAMPLE
C:\ps> Start-Monitor.ps1 -Interval 30 -ScriptBlock {(gps | select PSConfiguration,cpu -ExcludeProperty TotalProcessorTime)}
Description
----------
EXAMPLE
C:\ps> & 'D:\Work_PowerShell\Scripts\Common files\Start-Monitor.ps1' -Interval 30 -scriptblock {(Get-Service )}
Description
----------
EXAMPLE
C:\ps> Start-Monitor.ps1 -Interval 30 -ScriptBlock {(Get-Service | Where-Object { $_.Name -match "ms"} | select Name,Status,DisplayName,CanShutDown,CanStop )}
Description
----------
EXAMPLE
C:\ps> Start-Monitor.ps1 -Interval 30 -ScriptBlock {( Get-WmiObject win32_service | select Name,DisplayName,Startmode,State,Status )}
Description
----------
EXAMPLE
C:\ps> Start-Monitor.ps1 -ScriptBlock {(Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=TRUE | select -PROPERTY Caption,DefaultIPGateway,Description,DHCPEnabled,DHCPServer,DNSDomain,DNSDomainSuffixSearchOrder,DNSEnabledForWINSResolution,DNSHostName,DNSServerSearchOrder,DomainDNSRegistrationEnabled,FullDNSRegistrationEnabled,IPAddress,IPEnabled,IPFilterSecurityEnabled,IPPortSecurityEnabled,IPSecPermitIPProtocols,IPSecPermitTCPPorts,IPSecPermitUDPPorts,IPSubnet,IPXAddress,IPXEnabled,MACAddress,TcpipNetbiosOptions,WINSEnableLMHostsLookup,WINSHostLookupFile,WINSPrimaryServer,WINSScopeID,WINSSecondaryServer)}
.LINK
http://thePowerShellGuy.com
http://www.fourcats.nl/start-monitor.html
#>
PARAM([int]$Interval=0,[ScriptBlock]$ScriptBlock)
Function IsNumeric
{Param ( $ValueToTest )
[void][reflection.assembly]::LoadWithPartialName("'Microsoft.VisualBasic")
if ([Microsoft.VisualBasic.Information]::isnumeric($ValueToTest) -or $ValueToTest -is [UInt16]){
return $true}
else{
return $false}
}
# Helper function to translate the scriptblock output into a DataTable
Function Out-DataTable {
$DT = new-object Data.datatable
$first = $true
$script:ColumnsToRightAlign = @()
foreach ($item in $input){
$DR = $DT.NewRow()
$Item.PsObject.get_properties() | foreach {
if ($first) {
if ($_.value -eq $null){
$Col = New-Object Data.DataColumn
$Col.ColumnName = $_.Name.ToString()
}
else{
$strDataType = ($_.value).GetType()
if (((IsNumeric $_.value) -eq $true ) -or ($_.value -is [datetime]) ){$script:ColumnsToRightAlign += $_.Name.ToString()}
if ($_.value -is [bool]){
$Col = New-Object Data.DataColumn
$Col.ColumnName = $_.Name.ToString()
}
else{
$Col = New-Object "System.Data.DataColumn" ($_.Name.ToString(),$strDataType)
}
}
$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
}
}
$DT.Rows.Add($DR)
$first = $false
}
return @(,($DT))
}
# Load assembly
[void][System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")
# Make form
$form = new-object System.Windows.Forms.form
$form.text = "PowerShell Script Monitor: $ScriptBLock "
$form.Size = new-object System.Drawing.Size(900,410)
$richTextBoxScriptblock = New-Object System.Windows.Forms.RichTextBox
$richTextBoxScriptblock.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
$richTextBoxScriptblock.Font = New-Object System.Drawing.Font("Courier New",8.25,0,3,1)
$richTextBoxScriptblock.Location = New-Object System.Drawing.Point(80,1)
$richTextBoxScriptblock.Name = "richTextBoxNetworkDetails"
$richTextBoxScriptblock.Size = New-Object System.Drawing.Size(800,20)
$richTextBoxScriptblock.TabIndex = 1
$richTextBoxScriptblock.Text = ""
$form.Controls.Add($richTextBoxScriptblock)
# Add DataGrid
$DG = New-Object windows.forms.DataGridView
$DG.Dock = [System.Windows.Forms.DockStyle]::Fill
$DG.ColumnHeadersHeightSizeMode = [System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode]::AutoSize
$DG.AutoSizeRowsMode = [System.Windows.Forms.DataGridViewAutoSizeRowsMode]::AllCells
$DG.AllowUserToAddRows = $false
$DG.AllowUserToDeleteRows = $false
$DG.AllowUserToOrderColumns = $true
$DG.ReadOnly = $true
$DG.SelectionMode = 'FullRowSelect'
$System_Windows_Forms_DataGridViewCellStyle_1 = New-Object System.Windows.Forms.DataGridViewCellStyle
$System_Windows_Forms_DataGridViewCellStyle_1.BackColor = [System.Drawing.Color]::FromArgb(255,255,250,205)
$DG.AlternatingRowsDefaultCellStyle = $System_Windows_Forms_DataGridViewCellStyle_1
$System_Windows_Forms_DataGridViewCellStyle_2 = New-Object System.Windows.Forms.DataGridViewCellStyle
$System_Windows_Forms_DataGridViewCellStyle_2.BackColor = [System.Drawing.Color]::FromArgb(255,255,255,240)
$DG.RowsDefaultCellStyle = $System_Windows_Forms_DataGridViewCellStyle_2
$System_Windows_Forms_DataGridViewCellStyle_8 = New-Object System.Windows.Forms.DataGridViewCellStyle
$System_Windows_Forms_DataGridViewCellStyle_8.Alignment = 16
$System_Windows_Forms_DataGridViewCellStyle_8.BackColor = [System.Drawing.Color]::FromArgb(255,255,255,255)
$System_Windows_Forms_DataGridViewCellStyle_8.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",8.25,0,3,0)
$System_Windows_Forms_DataGridViewCellStyle_8.ForeColor = [System.Drawing.Color]::FromArgb(255,0,0,0)
$System_Windows_Forms_DataGridViewCellStyle_8.SelectionBackColor = [System.Drawing.Color]::FromArgb(255,109,109,109)
$System_Windows_Forms_DataGridViewCellStyle_8.SelectionForeColor = [System.Drawing.Color]::FromArgb(255,255,215,0)
$System_Windows_Forms_DataGridViewCellStyle_8.WrapMode = 2
$DG.DefaultCellStyle = $System_Windows_Forms_DataGridViewCellStyle_8
$System_Windows_Forms_DataGridViewCellStyle_11 = New-Object System.Windows.Forms.DataGridViewCellStyle
$System_Windows_Forms_DataGridViewCellStyle_11.Alignment = 16
$System_Windows_Forms_DataGridViewCellStyle_11.BackColor = [System.Drawing.Color]::FromArgb(255,255,215,0)
$System_Windows_Forms_DataGridViewCellStyle_11.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",8.25,1,3,0)
$System_Windows_Forms_DataGridViewCellStyle_11.ForeColor = [System.Drawing.Color]::FromArgb(255,0,0,0)
$System_Windows_Forms_DataGridViewCellStyle_11.SelectionBackColor = [System.Drawing.Color]::FromArgb(255,51,153,255)
$System_Windows_Forms_DataGridViewCellStyle_11.SelectionForeColor = [System.Drawing.Color]::FromArgb(255,255,255,255)
$System_Windows_Forms_DataGridViewCellStyle_11.WrapMode = 1
$DG.ColumnHeadersDefaultCellStyle = $System_Windows_Forms_DataGridViewCellStyle_11
$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
$Refresh ={
$col = $DG.SortedColumn
$sortOrder = $DG.SortOrder
$ScriptBlock = [scriptblock]::Create($richTextBoxScriptblock.Text)
$script:DT = (&$ScriptBlock | Out-DataTable )
$script:DG.DataSource = $DT.psObject.baseobject
foreach($columnname in $Script:ColumnsToRightAlign) {
$DG.Columns[$columnname].DefaultCellStyle.Alignment = [System.Windows.Forms.DataGridViewContentAlignment]::MiddleRight
}
if ("$sortOrder" -ne 'None' ) {$DG.Sort($DG.columns[($col.name)],"$SortOrder")}
$rows.Text = " [ Rows : $($script:DT.rows.count) ] "
}
$msi1.add_Click($Refresh)
$Mi.DropDownItems.Add($msi1)
$Msi2 = new-object System.Windows.Forms.ToolStripMenuItem("&Save")
$Msi2.ShortcutKeys = 0x20053
$Msi2.add_Click({
$openfiledialog1 = New-Object System.Windows.Forms.OpenFileDialog
$openfiledialog1.FileName = "MyOutputfile"
$openfiledialog1.ShowHelp = $true
$openfiledialog1.Filter = "CSV | *.csv"
$openfiledialog1.CheckFileExists = $false
$openfiledialog1.InitialDirectory = "C:\Temp"
$result = $openfiledialog1.ShowDialog()
if ($result -eq 'Ok'){
$DT | Export-Csv -Path $openfiledialog1.FileName -NoTypeInformation -UseCulture
if ($?){[void](New-Object -comobject Wscript.Shell).Popup("$($openfiledialog1.FileName) was successfully saved", 0,"",0) }
}
})
$Mi.DropDownItems.Add($Msi2)
$Msi3 = new-object System.Windows.Forms.ToolStripMenuItem("&Quit")
$Msi3.ShortcutKeys = 0x20051
$Msi3.add_Click({$form.close()})
$Mi.DropDownItems.Add($Msi3)
$ms.Items.Add($mi)
$form.Controls.Add($ms)
# statusStrip
$statusStrip = new-object System.Windows.Forms.StatusStrip
$rows = new-object System.Windows.Forms.ToolStripStatusLabel
$rows.BorderStyle = 'SunkenInner'
$rows.BorderSides = 'All'
[void]$statusStrip.Items.add($rows)
$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 ] "
[void]$statusStrip.Items.add($status)
$command = new-object System.Windows.Forms.ToolStripStatusLabel
$command.Spring = $true
$command.BorderStyle = 'SunkenInner'
$command.BorderSides = 'All'
$command.Text = "$ScriptBlock"
[void]$statusStrip.Items.add($command)
$form.Controls.Add($statusStrip)
# Make Timer
if ($Interval -gt 0 ) {
$timer = New-Object System.Windows.Forms.Timer
if ($Interval -gt 30 ) {$timer.Interval = 5000} Else {$timer.Interval = 1000}
$SecsToInterval = $interval
$timer.add_Tick({
$SecsToInterval -= ($timer.Interval / 1000)
if ( $SecsToInterval -eq 0 ) {
$SecsToInterval = $interval
$command.BackColor = 'Red'
$command.Text = "refreshing..."
$statusStrip.Update()
Invoke-Command $Refresh
}
$command.BackColor = 'Control'
$Status.Text = " [ next refresh in : $(new-Timespan -sec $SecsToInterval) ] [ refresh interval : $Interval Seconds ] "
$command.Text = "$ScriptBlock"
$statusStrip.Update()
})
$timer.Enabled = $true
$timer.Start()
}
# show Form
$form.Add_Shown({
if ($ScriptBlock){
$richTextBoxScriptblock.Text = $ScriptBlock
Invoke-Command $Refresh
$DG.AutoResizeColumns()
}
$form.Activate()
})
$form.showdialog()