Embedding Powershell in to Windows Forms

I'm writing a small GUI based (windows form) powershell tool for my team and my own use based on things that we repetitively do every day (like check if a service is running, start/stop/restart, check for amt of memory, cpu spikes, check for win updates, if C drv is really full etc).
So basically I have a form with a bunch of buttons with some logic (check if they have entered the right hostname, or if the service exists or not, displays/starts/stops services from multiple machines etc). I'm trying to display at least the output of these cmdlets in a textbox or richtextbox or datagridview, but can't seem to figure out how or which to use...
For example get-service (either all or one particular service or wild-card) should be shown in the richtextbox, right now i'm just using popup windows and out-gridview.

Even better (i understand this must be very hard, I saw PowerShellTunnel) will be to be able to embed Powershell window inside a win form, is that even possible? Basically capture console screen and display it...
Any useful/alternate ideas or suggestions, examples, links, anything at all on this topic will help me move forward with this project....thanks for your help in advance..
emkaydAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

emkaydAuthor Commented:
Thanks for the reply, but I don't understand how that thread is relevant to what I have asked for...
0
Kamaraj SubramanianApplication Support AnalystCommented:
are you creating a form ( using vb.net ? )

how you are creating form ?
0
Defend Against the Q2 Top Security Threats

Were you aware that overall malware worldwide was down a surprising 42% from Q1'18? Every quarter, the WatchGuard Threat Lab releases an Internet Security Report that analyzes the top threat trends impacting companies worldwide. Learn more by viewing our on-demand webinar today!

emkaydAuthor Commented:
I'm using Primal Forms to generate my GUI code, but before i realized there was a free community version of Primal Forms i did write the code without any 'visual' guide. But to answer your question, no i don't believe that is VB.NET code.
It is Powershell code which has ability to call .NET libraries to create GUI.
0
emkaydAuthor Commented:
Ok, since nobody has really answered my question, I think I might have asked it in a very confusing way. Let me attempt to make it a little clear -
I was hoping to get some insight/help/suggestion on the following -

1. How to format the result of this (with a title based on computernames) to show in a richtexbox or datagridview in a windows form (this is inside a 'for' loop)---> Get-WmiObject -class win32_service -computername $x[$y] -credential $cred | Select DisplayName, Name, State, Status, StartMode | Sort-Object Displayname |

2. Is it possible to have a username and password (not visible) Textboxes in the form and use those values from there everytime i use $cred? Right now $cred = Get-Credential, it's popping a challenge window. I have ask for credentials a lot of times because our environment is such, we have multiple domains and can't use one domain or service account for all.

3. A way to capture some of the errors that show up in the console right now, for instance, if the credentials entered doesn't have admin rights or if the user entered the wrong password etc.

Please let me know if you have any questions or need screenshots of what i have current to understand better. Thank you very much in advance.
0
emkaydAuthor Commented:
Really? Nobody can even attempt at answering some of the questions I have?
0
emkaydAuthor Commented:
Does anyone have any ideas about question no. 2 (to get admin credentials via win forms, basically type once and leave it there and all button clicks will get their $credential from those 2 Textboxes, instead of getting prompted every time)? I have figured out Q#1.
0
Brent ChallisPrincipal: ITCommented:
As PowerShell is based on the .NET Framework you can use it to work with .NET functionality in exactly the same way that you can use languages such as C#, VB.NET or the myriad of other languages.  I too use PrimalForms for some GUI based utilities that I have.  While it is possible to export the work as straight PowerShell script in a PS1 file, I have chosen to package it into an EXE file from PrimalForms.  I have also written manual code to create a Windows Form based application (see example below which reads a file and populates listboxes on the forms).

Re you questions:
1. The best way to get this information is probably to create a DataGridView on a form and populate it.  The code I used to do this in a PrimalForms project is listed at the beginning of the attached code.

2. As all the controls are the windows controls you can create a TextBox and set the password character property to provide a login form.  There is an explaination of how to create a credential object using a name and password that is supplied here: http://blogs.technet.com/b/gary/archive/2009/07/23/creating-a-ps-credential-from-a-clear-text-password-in-powershell.aspx

3. If you want to be able to trap errors occurring as the code executes you need to use a try/catch block.  e.g.

try
          {
             $wc = new-object System.Net.WebClient
             $wc.DownloadFile("http://www.contoso.com/MyDoc.doc")
          }
          catch [System.Net.WebException],[System.IO.IOException]
          {
              "Unable to download MyDoc.doc from http://www.contoso.com."
          }
          catch
          {
              "An error occurred that could not be resolved."
          }
This will let you write code to process any information that you want to keep/log.


#Code to populate a DataGridView

	$details = (Get-WmiObject -class win32_service | 
             Select DisplayName, Name, State, Status, StartMode | Sort-Object Displayname  )
	$array = New-Object System.Collections.ArrayList
	$array.AddRange($details)
	$datagridviewResults.DataSource = $array

# Demonstration code to create a .NET Windows Form, populate it with controls and use it
# to read and process a file.

# Load the .NET Assemblies
[void][System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")
[void][reflection.assembly]::LoadWithPartialName("System.Drawing")

function LoadCSV(){
	# Clear any items that may exist in the lists.
	$count = $form.Controls["lstNames"].Items.Count - 1
	for ($i = $count;$i -ge 0;$i--)
	{
		$form.Controls["lstNames"].Items.RemoveAt($i)
		$form.Controls["lstEmails"].Items.RemoveAt($i)
		$form.Controls["lstphones"].Items.RemoveAt($i)
	}

	[System.Windows.Forms.OpenFileDialog]$ofd = New-Object System.Windows.Forms.OpenFileDialog
	$ofd.ShowHelp = $True
	$ofd.Filter = "CSV Files (*.csv)|*.csv|All Files (*.*)|*.*"
	if ($ofd.ShowDialog() -eq "OK")
    {
     	$details = Import-Csv -Path $ofd.FileName
        foreach ($line in $details)
        {
			$form.Controls["lstNames"].Items.Add($line.Name)
			$form.Controls["lstEmails"].Items.Add($line.Email)
			$form.Controls["lstphones"].Items.Add($line.Phone)
		}
	}
}

function ProcessDetails()
{
    Clear-Host
	for ($i = 0;$i -lt $form.Controls["lstNames"].Items.Count;++$i)
	{
		Write-Host $form.Controls["lstNames"].Items[$i] " - " $form.Controls["lstEmails"].Items[$i] " - " $form.Controls["lstphones"].Items[$i]
	}
}

function BuildForm()
{
	#Create the form
	$form = new-object Windows.Forms.form
	$form.Size = new-object System.Drawing.Size @(800,300)   
	$form.text = "Demo Form created with PowerShell"  
	
	#Create the buttons
	$btnLoadCSV = New-Object System.Windows.Forms.Button 
	$btnLoadCSV.Width=100
	$btnLoadCSV.Location = New-Object System.Drawing.Size(350, 10)
	$btnLoadCSV.Text = "Load CSV File"
	
	$btnProcessCSV = New-Object System.Windows.Forms.Button 
	$btnProcessCSV.Width = 100
	$btnProcessCSV.Text = "Process CSV Data"
	$btnProcessCSV.Location = New-Object System.Drawing.Size(350, 35)
	
	#Create the list boxes and their assosciated labels.
	#Names
	$lblNames = New-Object System.Windows.Forms.Label
	$lblNames.Text = "Names"
	$lblNames.Location = New-Object System.Drawing.Size(50, 75)
	
	$lstNames = New-Object System.Windows.Forms.ListBox
	$lstNames.Name = "lstNames"
	$lstNames.Width = 200
	$lstNames.Height = 100
	$lstNames.Location = New-Object System.Drawing.Size(50, 100)
	
	#Email addresses
	$lblEmails = New-Object System.Windows.Forms.Label
	$lblEmails.Text = "Email Addresses"
	$lblEmails.Location = New-Object System.Drawing.Size(300, 75)
	
	$lstEmails = New-Object System.Windows.Forms.ListBox
	$lstEmails.Name = "lstEmails"
	$lstEmails.Width = 200
	$lstEmails.Height = 100
	$lstEmails.Location = New-Object System.Drawing.Size(300, 100)
	
	#Phone numbers
	$lblPhones = New-Object System.Windows.Forms.Label
	$lblPhones.Text = "Phone Numbers"
	$lblPhones.Location = New-Object System.Drawing.Size(550, 75)
	
	$lstPhones = New-Object System.Windows.Forms.ListBox
	$lstPhones.Name = "lstPhones"
	$lstPhones.Width = 200
	$lstPhones.Height = 100
	$lstPhones.Location = New-Object System.Drawing.Size(550, 100)
	
	#Add the controls to the form
	$form.Controls.Add($btnLoadCSV)
	$form.Controls.Add($btnProcessCSV)
	$form.Controls.Add($lstNames)
	$form.Controls.Add($lstEmails)
	$form.Controls.Add($lstPhones)
	$form.Controls.Add($lblNames)
	$form.Controls.Add($lblEmails)
	$form.Controls.Add($lblPhones)
	
	$btnLoadCSV.add_click({LoadCSV})
	$btnProcessCSV.add_click({ProcessDetails})
	return $form
}

$form = BuildForm;
$form.ShowDialog();

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
R3C0NCommented:
EMKAYD,

I was creating a form in Powershell using PrimalForms and am also a member of EE and came across your post. Here are some things I came across.

Advanced Cred Function for storing passwords with Powershell on disk, Posted 5 days ago...

http://poshcode.org/3532

This link is more of MS general explanation of storing Cred usernames and passwwords to disk.

http://technet.microsoft.com/en-us/magazine/ff714574.aspx

-R3c0n
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.