March 22nd, 2010

Hey, Scripting Guy! How Can I Use the DataGrid Control in Windows PowerShell?

Bookmark and Share
 

About the author: Ravikanth works at Dell, Inc., as a lead engineer in the Microsoft SharePoint solutions team. He loves automation and is a Windows PowerShell fanatic. He writes regularly on his blog about topics related to Windows PowerShell, SharePoint, and Microsoft server virtualization. He is also a moderator on the Hey, Scripting Guy! forum and a regular speaker at Bangalore IT Pro user group meetings.

 

In an earlier blog post, Ed Wilson showed us how to create GUI using Windows PowerShell and SAPIEN PrimalForms. Using PrimalForms is a very powerful and easy way to create GUI for your Windows PowerShell scripts. You can export the code required to script a GUI to a Windows PowerShell script and then customize it to make it more useful. Behind the scenes, we use the System.Windows.Forms namespace to generate a GUI. There are many GUI controls supported by this namespace. In today’s post, we will see an example that shows how to use the DataGrid control to display the information in a tabular form. 

First, we design a GUI form using SAPIEN’s PrimalForms Community Edition. Let us call this Process Manager. The design is quite simple. We place a DataGrid control and three buttons, each with some custom text representing the action. When loaded, this form will list the running processes and let us stop a selected process or refresh the process information displayed in the grid.

Image of Process Manager


After the design is complete, we export the form to a Windows PowerShell script using the “Export PowerShell” option. This generates the necessary code to create the GUI form in Windows PowerShell. Now, we need to edit this script to add the custom code we need to create our process manager.

We need to perform the following script changes to make our process manager functional.

1.       Capture a list of processes and display all of that in the data grid when we open the form.

2.       Enable all three buttons to function as expected.

Before we go further into the details of this script, let us quickly look at how the DataGrid control is created. The following code shows the code generated by PrimalForms to add the DataGrid control to the main form:

$dataGrid1 = New-Object System.Windows.Forms.DataGrid

$System_Drawing_Size = New-Object System.Drawing.Size

$System_Drawing_Size.Width = 492

$System_Drawing_Size.Height = 308

$dataGrid1.Size = $System_Drawing_Size

$dataGrid1.DataBindings.DefaultDataSourceUpdateMode = 0

$dataGrid1.HeaderForeColor = [System.Drawing.Color]::FromArgb(255,0,0,0)

$dataGrid1.Name = “dataGrid1”

$dataGrid1.DataMember = “”

$dataGrid1.TabIndex = 0

$System_Drawing_Point = New-Object System.Drawing.Point

$System_Drawing_Point.X = 13

$System_Drawing_Point.Y = 48

$dataGrid1.Location = $System_Drawing_Point

 

$form1.Controls.Add($dataGrid1)

 

We use System.Windows.Forms.DataGrid namespace to create an instance as $datagrid1. After this instance is created, we assign values to properties such as size of the grid, name, and various other properties. We are not done yet. We need to assign a data source to display the process information in the grid.

To display process information in the data grid at script startup, we need to add the necessary code to the form load event—$form1.Add_Load(). Because a Refresh button would also display process information in the grid, we will create a function so that we can reuse the code for both the form load and refresh button click events.

The following code shows the function we created to display process information in the data grid:

function Get-ProcessInfo {

      $array = New-Object System.Collections.ArrayList

      $Script:procInfo = Get-Process | Select Id,Name,Path,Description,VM,WS,CPU,Company | sort -Property Name

      $array.AddRange($procInfo)

      $dataGrid1.DataSource = $array

      $form1.refresh()

}

 

Within the Get-ProcessInfo function, we are creating an instance of the System.Collections.ArrayList object and the $procInfo object, and putting them in the script scope so that they are available to other functions as required. After we retrieve the process information using the Get-Process cmdlet, we add $procInfo to $array, and assign $array as the data source to the $dataGrid1 object. After the DataSource property is assigned, we make sure we display data in the grid by refreshing the form using $form1.refresh().

To make sure process information is displayed in the grid at script startup, we add the following code to $OnLoadForm_UpdateGrid:

 

$OnLoadForm_UpdateGrid=

{

      Get-ProcessInfo

}

 

We then call it using the $form1.add_load() event:

 

#Add Form event

$form1.add_Load($OnLoadForm_UpdateGrid)

 

This will result in process information being displayed in the data grid, as shown here:

Image of process information displayed in the data grid

Now, let us move on to the second part of this process manager GUI. We need to enable “refresh”, “Kill process” and “Close” buttons on this form. The refresh button will refresh the process information displayed in the data grid, Kill process will terminate the selected process and close button will close the main form. For adding the code required to perform what is required, we use the button click events and assign code to Add_click() events of each button.

Because we already have the code required to refresh the form as the Get-ProcessInfo function, we just call this function within the $button1.Add_click() event:

$button1_OnClick=

{

      Get-ProcessInfo

}

 

#Add the event

$button1.add_Click($button1_OnClick)

 

To stop a selected process, we add the following code to $button2_OnClick and add it to $button2.Add_click() event:

$button2_OnClick=

{

      $selectedRow = $dataGrid1.CurrentRowIndex

      if (($procid=$Script:procInfo[$selectedRow].Id)) {

                  Stop-Process -Id $procid -Confirm

            }

}

 

#add the event

$button2.add_Click($button2_OnClick)

 

In the above code, we get the selected row’s index into the $selectedRow variable and then use $selectedRow to retrieve the process ID of the selected process. You can select a process by either clicking the row header or anywhere within the row. When a row is selected, you can see a marker on the row header as shown in the following image.

Image of row being selected

 

After the process ID is captured in $procid, we use the Stop-Process cmdlet to terminate the process. We also use the -Confirm parameter with the Stop-Process cmdlet.

 

So, when you run this script using the Windows PowerShell ISE and attempt to stop a process, you will see something similar to what is shown in the following image.

Image of what is dispayed when you attempt to stop process

Finally, we assign $form1.Close() to $button3_OnClick, and add it to $button3.add_click() event to enable the Close button.


The complete code for this article is on the
Script Center Script Repository.

What we have seen so far is a basic implementation of data grid. We can automate the data grid refresh using the timer class. You can also a see a bit more advanced example of data grid control along with the TreeView control in the Windows PowerShell Remote File Explorer script at http://psremoteexplorer.codeplex.com/.

 

Author

0 comments

Discussion are closed.