Thursday, January 11, 2007

Exchange 2007 diagnostic logging Powershell quick set winform script

One of the things that has been dropped from the GUI (Exchange Management Console) in Exchange 2007 is the ability to set the diagnostic level of different Exchange components. You now have to use the Exchange Management Shell cmdlets get-eventloglevel and set-eventloglevel. While functional if you have to enable a number of different categories if you are trying to diagnose certain problems it can be a little cumbersome to try and come up with a different command-line for each one of the possible 150 components you might want to change. Because I do tend to enable and disable these things a fair bit when trying to fix a problems or diagnose why a piece a code or script might not be working I thought I’d come up with a little Powershell winform that would give me a GUI to do this with and allow me to quickly set the diagnostic logging level on a number of components with a few clicks of the mouse.

The script first starts by presenting a Winform to the user with one combo box which is populated with all the names of the Exchange servers in the Org populated from the Get-Exchangeserver cmdlet. When a servername is selected the getdiagvalues function runs which uses the get-eventloglevel cmdlet to fill a datagrid with all the current log levels for all components on that server. To set a new log level just select the row (or rows if you want to do multiple) and then the new log level from the combo box at the top of the form and press the apply button. When the apply button is pressed the UpdateLogLevel function is run this function first checks to see if multiple row in the grid where selected or just one row and then builds and executes the set-eventloglevel commandlet. After this it reruns the getdiagvalues function which repopulates the datagrid with the updated values.

The script is designed to run from within the Exchange Management shell it should work for remote servers okay but I haven’t really tested this and the set-eventloglevel doesn’t take a server parameter (where get-eventloglevel does).

I’ve put a download copy of the script here the script itself looks like


[System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")
Function getdiagvalues{
$daTable.clear()
$dgDataGrid.DataSource = $daTable
get-eventloglevel -Server $snServerNameDrop.SelectedItem.ToString() | ForEach-Object{
$daTable.Rows.Add($_.Identity,$_.EventLevel)
}
$dgDataGrid.DataSource = $daTable
}

Function UpdateLogLevel{
if ($dgDataGrid.SelectedRows.Count -eq 0){
$idIdtoSet = $dgDataGrid.Rows[$dgDataGrid.CurrentCell.RowIndex].Cells[0].Value
set-eventloglevel -Identity $idIdtoSet -Level $llLoglevelDrop.Text
}
else{
$msgbox = new-object -comobject wscript.shell
$lcLoopCount = 0
while ($lcLoopCount -le ($dgDataGrid.SelectedRows.Count-1)) {
# [void]$msgbox.popup($dgDataGrid.SelectedRows[$lcLoopCount].Cells[0].Value,0,"Cant Do MX lookup",1)
set-eventloglevel -Identity $dgDataGrid.SelectedRows[$lcLoopCount].Cells[0].Value -Level $llLoglevelDrop.SelectedItem
$lcLoopCount += 1}
}
getdiagvalues
}

$form = new-object System.Windows.Forms.form

$llLableloc = 50
$VlLoc = 50

$Dataset = New-Object System.Data.DataSet
$daTable = New-Object System.Data.DataTable
$daTable.TableName = "Diag"
$daTable.Columns.Add("Identity")
$daTable.Columns.Add("Current Setting")


# Add Server DropLable
$snServerNamelableBox = new-object System.Windows.Forms.Label
$snServerNamelableBox.Location = new-object System.Drawing.Size(10,20)
$snServerNamelableBox.size = new-object System.Drawing.Size(100,20)
$snServerNamelableBox.Text = "ServerName"
$form.Controls.Add($snServerNamelableBox)

# Add Server Drop Down
$snServerNameDrop = new-object System.Windows.Forms.ComboBox
$snServerNameDrop.Location = new-object System.Drawing.Size(130,20)
$snServerNameDrop.Size = new-object System.Drawing.Size(130,30)
get-exchangeserver | ForEach-Object{$snServerNameDrop.Items.Add($_.Name)}
$snServerNameDrop.Add_SelectedValueChanged({getdiagvalues})
$form.Controls.Add($snServerNameDrop)

# Add New Log Level Drop Down
$llLoglevelDrop = new-object System.Windows.Forms.ComboBox
$llLoglevelDrop.Location = new-object System.Drawing.Size(350,20)
$llLoglevelDrop.Size = new-object System.Drawing.Size(70,30)
$llLoglevelDrop.Items.Add("Lowest")
$llLoglevelDrop.Items.Add("Low")
$llLoglevelDrop.Items.Add("Medium")
$llLoglevelDrop.Items.Add("High")
$llLoglevelDrop.Items.Add("Expert")
$form.Controls.Add($llLoglevelDrop)

# Add Apply Button

$exButton = new-object System.Windows.Forms.Button
$exButton.Location = new-object System.Drawing.Size(430,20)
$exButton.Size = new-object System.Drawing.Size(60,20)
$exButton.Text = "Apply"
$exButton.Add_Click({UpdateLogLevel})
$form.Controls.Add($exButton)

# New setting Group Box

$OfGbox = new-object System.Windows.Forms.GroupBox
$OfGbox.Location = new-object System.Drawing.Size(300,0)
$OfGbox.Size = new-object System.Drawing.Size(200,50)
$OfGbox.Text = "New Log Level Settings"
$form.Controls.Add($OfGbox)

# Add DataGrid View

$dgDataGrid = new-object System.windows.forms.DataGridView
$dgDataGrid.Location = new-object System.Drawing.Size(10,80)
$dgDataGrid.size = new-object System.Drawing.Size(500,500)
$dgDataGrid.AutoSizeColumnsMode = "AllCells"
$dgDataGrid.SelectionMode = "FullRowSelect"
$form.Controls.Add($dgDataGrid)


$form.Text = "Exchange 2007 Diagnostic Logging Form"
$form.size = new-object System.Drawing.Size(600,600)
$form.autoscroll = $true
$form.topmost = $true

$form.ShowDialog()