2013/10/11

PowerShell Studio 2012 - WinForms - GUI ToolMaking

In my previous post I showed how to create a quick PowerShell GUI to append some colored text in a RichTextBox control using Sapien PowerShell Studio 2012.

Today I will go a bit further and show you how to create a tool to query some information from a remote computer. I will first send the Output to Out-GridView cmdlet and then show you how to send it to a DataGridView control inside the GUI.

The tool will query Services, Processes and Shares from a Remote Computer.
You will need to specify the ComputerName and the Credential required to perform those actions. The goal is to show how to create something very simple so I did not write any Error Handling or any conditional code in this version.

One cool thing to mention when using PowerShell Studio 2012 is, if you add some controls like a DataGridView, a Listview or a ListBox, PowerShell Studio 2012 will add some functions to help you Load/Add/Refresh those controls. I will show you below in the part "Replacing the Out-Gridview by a DataGridView Control"





Overview


  • ToolMaking - Video
  • ToolMaking - Step By Step
    • Creating and Editing the GUI
    • Adding your PowerShell Code
    • Test the GUI, using Out-Gridview cmdlet for the output
    • Replacing the Out-Gridview by a DataGridView Control
    • Modifying your PowerShell code for DataGridView
    • Test the GUI using the DataGridView for the output
    • Download (PS1 and PFF)


ToolMaking - Video





Creating and Editing the GUI

Insert your controls. Here I used 3 buttons and one TextBox

Rename your button text properties and rename the textbox control (Design Name property) so it will be easier to find it when writing the PowerShell code.



Adding your PowerShell Code

Here is the code I used for each of my events.
I basically do some basic Get-WmiObject queries on different classes related to the Services/Processes and Shared. Note the Output is sent to the pipeline to Out-GridView.

$buttonCredential_Click={
    # Ask for Credential
    $global:cred = Get-Credential -Credential 'FX\Administrator'
}

$buttonServices_Click={
    # Query the Services on the computername specified in the textbox
    Get-WmiObject Win32_Service -ComputerName $textboxComputerName.Text -Credential $cred | Select-Object __Server,Name | Out-GridView
}

$buttonProcesses_Click={
    # Query the Processes on the computername specified in the textbox
    Get-WmiObject Win32_Process -ComputerName $textboxComputerName.Text -Credential $cred | Select-Object __Server,Name | Out-GridView
}

$buttonShares_Click={
    # Query the Shares on the computername specified in the textbox
    Get-WmiObject Win32_Share -ComputerName $textboxComputerName.Text -Credential $cred | Select-Object __Server,Name | Out-GridView
}


Test the GUI, using Out-Gridview cmdlet for the output


Here is the result when you click on one of the 3 buttons. Each of them invoke the events:
  • $buttonServices_Click
  • $buttonProcesses_Click
  • $buttonShares_Click


You can define all sort of Events for each control, take a look below


Replacing the Out-Gridview by a DataGridView Control


Expend your Form and add a DataGridView control.



When you add the DataGridView to your form, you will notice that PowerShell Studio 2012 automatically add one ore more functions that can interact with this kind of control, you can write your own of course but this make things simpler for people who don't know which properties to modify or methods to invoke.


#region Control Helper Functions
function Load-DataGridView
{
    <#
    .SYNOPSIS
        This functions helps you load items into a DataGridView.

    .DESCRIPTION
        Use this function to dynamically load items into the DataGridView control.

    .PARAMETER  DataGridView
        The ComboBox control you want to add items to.

    .PARAMETER  Item
        The object or objects you wish to load into the ComboBox's items collection.
    
    .PARAMETER  DataMember
        Sets the name of the list or table in the data source for which the DataGridView is displaying data.

    #>
    Param (
        [ValidateNotNull()]
        [Parameter(Mandatory=$true)]
        [System.Windows.Forms.DataGridView]$DataGridView,
        [ValidateNotNull()]
        [Parameter(Mandatory=$true)]
        $Item,
        [Parameter(Mandatory=$false)]
        [string]$DataMember
    )
    $DataGridView.SuspendLayout()
    $DataGridView.DataMember = $DataMember
    
    if ($Item -is [System.ComponentModel.IListSource]`
    -or $Item -is [System.ComponentModel.IBindingList] -or $Item -is [System.ComponentModel.IBindingListView] )
    {
        $DataGridView.DataSource = $Item
    }
    else
    {
        $array = New-Object System.Collections.ArrayList
        
        if ($Item -is [System.Collections.IList])
        {
            $array.AddRange($Item)
        }
        else
        {    
            $array.Add($Item)    
        }
        $DataGridView.DataSource = $array
    }
    
    $DataGridView.ResumeLayout()
}
#endregion


Modifying your PowerShell Code for DataGridView


Now all you have to do is removing the Out-GridView and send the output to the function Load-DataGridView. This function will do the job for you and load everything.


$buttonCredential_Click={
    # Ask for Credential
    $global:cred = Get-Credential -Credential 'FX\Administrator'
}

$buttonServices_Click={
    # Query the Services on the computername specified in the textbox
    $Services = Get-WmiObject Win32_Service -ComputerName $textboxComputerName.Text -Credential $cred | Select-Object __Server,Name
    Load-DataGridView -DataGridView $datagridview1 -Item $Services
}

$buttonProcesses_Click={
    # Query the Processes on the computername specified in the textbox
    $Processes = Get-WmiObject Win32_Process -ComputerName $textboxComputerName.Text -Credential $cred | Select-Object __Server,Name
    Load-DataGridView -DataGridView $datagridview1 -Item $Processes
}

$buttonShares_Click={
    # Query the Shares on the computername specified in the textbox
    $Shares = Get-WmiObject Win32_Share -ComputerName $textboxComputerName.Text -Credential $cred | Select-Object __Server,Name
    Load-DataGridView -DataGridView $datagridview1 -Item $shares
}


Test the GUI using the DataGridView for the output





Download (PS1 and PFF)




Thanks for Reading! If you have any questions, leave a comment or send me an email at fxcat@lazywinadmin.com. I invite you to follow me on Twitter: @lazywinadm

6 comments:

  1. Which version of powershell, are you using? V 2 or v 3?

    ReplyDelete
    Replies
    1. Hey Anala, I have PowerShell v4 on my PC.
      However the script should work with v2 and v3.

      Delete
    2. I had developed a Tool in using the Sapien community edition in powershell v2. However, it didn't worked in v3.
      I had reported this issue here : https://connect.microsoft.com/PowerShell/feedback/details/775034/scope-of-variables-inside-form-scripts#details . However, I got no response.
      I guess, you are using the paid version of Sapien. Is this issue got fixed in Paid version of sapien tool?

      Delete
    3. PowerShell Studio 2012 supports v3 and v4.
      I did not really work with the community edition.

      Do they still update the Community version ? Anyway, you should ask your question again on their forum.

      Delete
    4. Are you sure it supports PowerShell v4? Their product page is still touting how they are "...ready for PowerShell V3 when you are.". Can you point me to where they say it's now supported? I can't find a thing.

      Delete
    5. Michael,

      Check here: http://www.sapien.com/blog/2013/08/12/service-release-8122013/

      PowerShell Studio 2012 v3.1.22:

      ADD: Support for PowerShell v4
      ADD: TextBox – Watermark control set
      FIX: Incorrect shortcut key for Create Region in the editor’s context menu
      UPD: ProgressBarOverlap will now refresh when the text is changed
      UPD: Other minor changes and fixes

      Delete