A few times in PowerGUI or generally I have needed the user to select a single entity so that I can use this entity further in the code to narrow down the output, with this in mind i created a quick PrimalForms form which can be used as a function and a single object selected, the below code can be used within GUI apps like PowerGUI or vEcoShell or just from the powershell prompt.
For example if you wanted to select just the VMs from one host you could present the user a nice GUI with all the hosts added to the dropdown box with the following simple code:
# Send the Hosts to the GUI function Select-GUIObject "Host" (Get-VMHost) # Get the VMs for the selected host $SelObj | Get-VM | Out-GridView
So the GUI box presented from the Select-GUIObject would look like so:
Once the host was selected and the OK button was pressed the VMs would be returned in $selObj and a list of VMs can be gained as in the next line of code and the following output from Out-Gridview:
Other examples of this function can be used with Get-VM or Get-Datastore or whatever you like, this is one of the areas I have spoken to the people at Quest and I believe they may be making some improvements to PowerGUI & vEcoShell to make input easier.
The code:
Function Select-GUIObject ($ObjName, $Object) { #Generated Form Function function GenerateForm { ######################################################################## # Code Generated By: SAPIEN Technologies PrimalForms (Community Edition) v1.0.7.0 # Generated By: Alan Renouf (http://virtu-al.net) ######################################################################## #region Import the Assemblies [reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null [reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null #endregion #region Generated Form Objects $form1 = New-Object System.Windows.Forms.Form $button1 = New-Object System.Windows.Forms.Button $label1 = New-Object System.Windows.Forms.Label $comboBox1 = New-Object System.Windows.Forms.ComboBox $InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState #endregion Generated Form Objects #---------------------------------------------- #Generated Event Script Blocks #---------------------------------------------- #Provide Custom Code for events specified in PrimalForms. $button1_OnClick= { $global:SelObj = $comboBox1.SelectedItem $form1.close() } $handler_label2_Click= { } $OnLoadForm_StateCorrection= {#Correct the initial state of the form to prevent the .Net maximized form issue $form1.WindowState = $InitialFormWindowState $Object | Foreach { $comboBox1.items.add($_) $comboBox1.SelectedIndex=0 } $Combobox1.visible = $true $label1.visible = $true $button1.visible = $true $form1.Text = "Please select a $ObjName" } #---------------------------------------------- #region Generated Form Code $form1.AutoScaleMode = 0 $form1.Text = "Please wait loading $ObjName...." $form1.Name = "form1" $form1.DataBindings.DefaultDataSourceUpdateMode = 0 $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Height = 66 $System_Drawing_Size.Width = 392 $form1.ClientSize = $System_Drawing_Size $form1.FormBorderStyle = 1 $form1.Controls.Add($InfoLabel) $button1.TabIndex = 2 $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Height = 23 $System_Drawing_Size.Width = 75 $button1.Size = $System_Drawing_Size $button1.Name = "button1" $button1.UseVisualStyleBackColor = $True $button1.Visible = $False $button1.Text = "OK" $System_Drawing_Point = New-Object System.Drawing.Point $System_Drawing_Point.X = 300 $System_Drawing_Point.Y = 21 $button1.Location = $System_Drawing_Point $button1.DataBindings.DefaultDataSourceUpdateMode = 0 $button1.add_Click($button1_OnClick) $form1.Controls.Add($button1) $label1.TabIndex = 1 $label1.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",8.25,1,3,1) $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Height = 23 $System_Drawing_Size.Width = 50 $label1.Size = $System_Drawing_Size $label1.Name = "label1" $label1.Visible = $False $label1.Text = "$ObjName:" $System_Drawing_Point = New-Object System.Drawing.Point $System_Drawing_Point.X = 8 $System_Drawing_Point.Y = 26 $label1.Location = $System_Drawing_Point $label1.DataBindings.DefaultDataSourceUpdateMode = 0 $form1.Controls.Add($label1) $System_Drawing_Point = New-Object System.Drawing.Point $System_Drawing_Point.X = 64 $System_Drawing_Point.Y = 21 $comboBox1.Location = $System_Drawing_Point $comboBox1.Visible = $False $comboBox1.DataBindings.DefaultDataSourceUpdateMode = 0 $comboBox1.FormattingEnabled = $True $comboBox1.Name = "comboBox1" $comboBox1.TabIndex = 0 $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Height = 21 $System_Drawing_Size.Width = 217 $comboBox1.Size = $System_Drawing_Size $form1.Controls.Add($comboBox1) #endregion Generated Form Code #Save the initial state of the form $InitialFormWindowState = $form1.WindowState #Init the OnLoad event to correct the initial state of the form $form1.add_Load($OnLoadForm_StateCorrection) #Show the Form $form1.ShowDialog()| Out-Null } #End Function #Call the Function GenerateForm } Connect-VIServer myvcenter.mydomain.com Select-GUIObject "VM" (Get-VM) Write-host "You Selected $SelObj" Select-GUIObject "Datastore" (Get-Datastore) Write-host "You Selected $SelObj" # Send the Hosts to the GUI function Select-GUIObject "Host" (Get-VMHost) # Get the VMs for the selected host $SelObj | Get-VM | Out-GridView
You have a typo here:
$label1.Text = “$ObjName:”
should be:
$label1.Text = “$ObjName”
Hi,
This is a really useful function!
I’ve hit a snag recently when trying to use it with Get-ESXImageProfile.
When I supply this as the object I get the following in the drop downbox instead of the Image name:
VMware.ImageBuilder.Types.ImageProfile
I’ve tried a few things but can’t see why this object gets treated differently.
I’m guessing that the PowerCLI object is slightly different.
Any ideas will be appreciated.
Thanks, Craig.
Pingback: PowerShell Hacker #13
Nice Alan. That’s really handy, thanks for sharing.
Si
Yeah good idea, I guess i should have done it like that really.
Nice work Alan.
Don’t need to worry about forms code anymore when needing a simple selection box.
If I may suggest one modification:
instead of putting the output of the function in the global variable, $selObj it would be more cool to write the selected object to the pipeline using the Write-Output cmdlet. This way the function actually returns the selected object and one could store it in any local variable and don’t need to remember the global variable name, like
$selVMHost = Select-GUIObject “Host” (Get-VMHost)
or even use the pipeline like
Select-GUIObject “Host” (Get-VMHost) | Get-VM | Out-GridView
Arnim