Leo Torres
asked on
Powershell GUI need button actions to work
I thought this was going to be simple. In concept it does not seems too hard. I have some template code that has been Provided to run a GUI.
I do know that this command does give me the data I need
Get-WmiObject Win32_Service -ComputerName $Targetserver | where{ ($_.StartMode -eq "Auto" -or $_.StartMode -eq "Disabled")-and $_.State -ne "Running" } | Select name, StartMode | Format-Table
But I cant translate it into the form as the checklistbox ($TargetServices) to be processed
GUI objective: Query $TargetServer variable and display services in CheckListBox with name and State. When the QueryServer button is pressed.
Here is the code
This is the error when Ran
I do know that this command does give me the data I need
Get-WmiObject Win32_Service -ComputerName $Targetserver | where{ ($_.StartMode -eq "Auto" -or $_.StartMode -eq "Disabled")-and $_.State -ne "Running" } | Select name, StartMode | Format-Table
But I cant translate it into the form as the checklistbox ($TargetServices) to be processed
GUI objective: Query $TargetServer variable and display services in CheckListBox with name and State. When the QueryServer button is pressed.
Here is the code
function OnApplicationLoad {
#Note: This function is not called in Projects
#Note: This function runs before the form is created
#Note: To get the script directory in the Packager use: Split-Path $hostinvocation.MyCommand.path
#Note: To get the console output in the Packager (Windows Mode) use: $ConsoleOutput (Type: System.Collections.ArrayList)
#Important: Form controls cannot be accessed in this function
#TODO: Add modules and custom code to validate the application load
return $true #return true for success or false for failure
}
function OnApplicationExit {
#Note: This function is not called in Projects
#Note: This function runs after the form is closed
#TODO: Add custom code to clean up and unload modules when the application exits
$script:ExitCode = 0 #Set the exit code for the Packager
}
$FormEvent_Load={
#TODO: Initialize Form Controls here
}
#region Control Helper Functions
function Load-ListBox
{
<#
.SYNOPSIS
This functions helps you load items into a ListBox or CheckedListBox.
.DESCRIPTION
Use this function to dynamically load items into the ListBox control.
.PARAMETER ListBox
The ListBox control you want to add items to.
.PARAMETER Items
The object or objects you wish to load into the ListBox's Items collection.
.PARAMETER DisplayMember
Indicates the property to display for the items in this control.
.PARAMETER Append
Adds the item(s) to the ListBox without clearing the Items collection.
.EXAMPLE
Load-ListBox $ListBox1 "Red", "White", "Blue"
.EXAMPLE
Load-ListBox $listBox1 "Red" -Append
Load-ListBox $listBox1 "White" -Append
Load-ListBox $listBox1 "Blue" -Append
.EXAMPLE
Load-ListBox $listBox1 (Get-Process) "ProcessName"
#>
Param (
[ValidateNotNull()]
[Parameter(Mandatory=$true)]
[System.Windows.Forms.ListBox]$ListBox,
[ValidateNotNull()]
[Parameter(Mandatory=$true)]
$Items,
[Parameter(Mandatory=$false)]
[string]$DisplayMember,
[switch]$Append
)
if(-not $Append)
{
$listBox.Items.Clear()
}
if($Items -is [System.Windows.Forms.ListBox+ObjectCollection])
{
$listBox.Items.AddRange($Items)
}
elseif ($Items -is [Array])
{
$listBox.BeginUpdate()
foreach($obj in $Items)
{
$listBox.Items.Add($obj)
}
$listBox.EndUpdate()
}
else
{
$listBox.Items.Add($Items)
}
$listBox.DisplayMember = $DisplayMember
}
#endregion
$buttonQueryServer_Click={
#TODO: Place custom script here
Load-ListBox $listBox (Get-WmiObject Win32_Service -ComputerName "Spiderman" | where{ ($_.StartMode -eq "Auto" -or $_.StartMode -eq "Disabled") -and $_.State -ne "Running" } | Select name, StartMode ) "ServiceNames"
}
This is the error when Ran
>> Running (CheckBoxList.psf) Script...
>> Building (CheckBoxList.psf) ...
>> Platform: V4 64Bit (STA)
ERROR: Load-ListBox : Cannot validate argument on parameter 'ListBox'. The argument is null. Provide a valid value for the argument, and then try running the command
ERROR: again.
CheckBoxList.psf (105): ERROR: At Line: 105 char: 15
ERROR: + Load-ListBox $listBox (Get-WmiObject Win32_Service -ComputerName "Spiderman" | ...
ERROR: + ~~~~~~~~
ERROR: + CategoryInfo : InvalidData: (:) [Load-ListBox], ParameterBindingValidationException
ERROR: + FullyQualifiedErrorId : ParameterArgumentValidationError,Load-ListBox
ERROR:
>> Execution time: 00:00:18
>> Script Ended
ASKER
I guess I don't have the command in the right place with in the code. I know the command works and it returns data I just need to pass the dataset to the CheckboxList which is my struggle.
As for the Get-Service sure I can use that as long as I can bring back all service that are not running whether its on "Automatic" or "Disabled". And I also forgot in the code but I also need to list Service that are in a Starting State.
As for the Get-Service sure I can use that as long as I can bring back all service that are not running whether its on "Automatic" or "Disabled". And I also forgot in the code but I also need to list Service that are in a Starting State.
Re "Pass the dataset to the Checkboxlist": that is definitely an issue, as the list receives a bunch of strings, and cannot handle the underlying objects, so you need to do the formatting pre-display and the parsing after submitting choices. Don't underestimate that parts.
Re "Starting State", you already get those. Everything different from "Running" will we pass thru.
A slightly improved way to ask for the services using WMI is:
Please ignore my note about Get-Service - it does not reveal the start mode, so is not suited for your needs here.
Re "Starting State", you already get those. Everything different from "Running" will we pass thru.
A slightly improved way to ask for the services using WMI is:
Get-WmiObject Win32_Service -ComputerName $TargetServer | where{ 'Auto', 'Disabled' -contains $_.StartMode -and $_.State -ne 'Running' } | Select name, StartMode, State
Note that I've also added the State info, which gets important for "Starting", maybe hinting that there is an issue with that service.Please ignore my note about Get-Service - it does not reveal the start mode, so is not suited for your needs here.
ASKER
Thanks for the code. Sorry about delay. Code now works great! Except for one minor detail you are returning an array of items. I need to have columns for each item.
function Load-ListBox
{
Param (
[ValidateNotNull()]
[Parameter(Mandatory=$true)]
[System.Windows.Forms.ListBox]$ListBox,
[ValidateNotNull()]
[Parameter(Mandatory=$true)]
$Items,
[Parameter(Mandatory=$false)]
[string]$DisplayMember,
[switch]$Append
)
if(-not $Append)
{
$listBox.Items.Clear()
}
if($Items -is [System.Windows.Forms.ListBox+ObjectCollection])
{
$listBox.Items.AddRange($Items)
}
elseif ($Items -is [Array])
{
$listBox.BeginUpdate()
foreach($obj in $Items)
{
$listBox.Items.Add($obj)
}
$listBox.EndUpdate()
}
else
{
$listBox.Items.Add($Items)
}
$listBox.DisplayMember = $DisplayMember
}
#endregion
$Output = New-Object System.Windows.Forms.TextBox
$buttonGetServices_Click={
#TODO: Place custom script here
New-Variable -Name Servername -Value ($tb_ServerName.Text) -Scope: global -ErrorAction: SilentlyContinue
#$Services = (Get-Service -ComputerName $Servername.Text | Where-Object { $_.Status -eq "stopped" -or $_.Status -eq "Starting" }).DisplayName
#-and $_.Name -like "*IBM*"
$Services = Get-WmiObject Win32_Service -ComputerName $Servername.Text | where{ 'Auto', 'Disabled' -contains $_.StartMode -and $_.State -ne 'Running' } | Select name, StartMode, State
$Chk_list_box.Items.Clear()
$Chk_list_box.Visible = $True
$Output.Visible = $False
FOREACH ($Service in $Services)
{
$Chk_list_box.Items.Add("$Service") | Out-Null
}
}
That is what I stated in http:#a40394901: You need to do some formatting first. This is completely up to you how to do. But remember, what you stuff in you will get back! You are using a simple listbox, only able to display a line of string.
You can try if appending | format-table -auto to the Get-WMIObject line supplies you with something suitable - but that depends on the font used, and how you want to proceed with the selected (= checked) data.
You can try if appending | format-table -auto to the Get-WMIObject line supplies you with something suitable - but that depends on the font used, and how you want to proceed with the selected (= checked) data.
ASKER
So what should I be adding to get desired result. Format-table? will translate to GUI? If so how and where should I declare it.
Try if this in line 48 works for you;
Another way is to display a tab or comma seperated (unaligned) list, and parse out the first element of the result, like with
$objServices = Get-WmiObject Win32_Service -ComputerName $Servername.Text | where{ 'Auto', 'Disabled' -contains $_.StartMode -and $_.State -ne 'Running' } | select Select name, StartMode, State
$Services = $objServices | Format-Table -auto
The result after pressing the "StartServices" button will be the complete string, which will be needed to match against $Services to find out the current index in $objServices, to get the real service name.Another way is to display a tab or comma seperated (unaligned) list, and parse out the first element of the result, like with
$Services = Get-WmiObject Win32_Service -ComputerName $Servername.Text | where{ 'Auto', 'Disabled' -contains $_.StartMode -and $_.State -ne 'Running' } | % { ($_.name, StartMode, State) -join "`t") }
ASKER
Format table produced this result
Join with tab produced this code
Here is a working version you can run on your PC. Now from selected Items I must start select items. if Disabled Set to Automatic and start. If service is in starting State. Stop it and start it again
Join with tab produced this code
Here is a working version you can run on your PC. Now from selected Items I must start select items. if Disabled Set to Automatic and start. If service is in starting State. Stop it and start it again
#------------------------------------------------------------------------
# Source File Information (DO NOT MODIFY)
# Source ID: 7c0daeca-b0d3-4607-9de3-217431ac5002
# Source File: C:\Users\LeandroT\Documents\SAPIEN\PowerShell Studio 2014\Files\StartServices2.psf
#------------------------------------------------------------------------
#region File Recovery Data (DO NOT MODIFY)
<#RecoveryData:
tA0AAB+LCAAAAAAABAC9V11v2jAUfZ+0/2DlOQKSED4kiNRm7TSNbtVg3d6Qk1yoh2NXttOS/fo5
H7S0gZJ0BSEhB1/73HPPvQcY/YCQ34NIP2GFkV5IwtnYsA3v4weERt8FWRKG6SWh8A3H4E0VFmoK
4p6EIO3WnVyM2pWg4mjwB0KFVHoHY2OaSgVx6xdhEX+QrUsu4uLdRLu2THRTZtJtdbKXifyEqkTA
mEGiBKYmuk4CSsKvkM74Ctg46PexG7o9a+h0oTMYGojpVMbGQt9nGSi8JTQSOs7wOVOCU1kw1Ile
C34HQqXlAZ8SYGpK/oLh9fpdE/Vtd9TeBO05lNE2vBzrYOwM1srwMp7V0It7jV3GTTiOyjvn2XrU
znc3oYfrO8EB0KMXmGYoWUeAeK3M1TpMeIiVTsHwHMdE1qBSjX1l3kKscaZQ0um4JrKdGvEzHHxh
Eaz1mTrRuZi1k8nCzyhZatJXJIoo+FrRHSf1UOXy1hc7u/mcr48ud0E1W/+P2t1+bbWfABuK3Wkk
tv0OGpwnSnF2dAmCHOYzPPrwW5XoWraWoupu+6SoANdWxHKHjcev6qT7xq9ZRj8l3BCZYDpVKYVz
HK58TrkwvJlIdvbYtinrb4dwtaMS83zjhUU3biD/FsIVRBMiTzLL/u1qTjXWPODrZj2UZYKVImx5
wXBAIdpfvb3dZ2eub9U3gu1sazdez9JW4LrDRp1XdY5nUj5/OJMSYl1ukJvY8pPUK+W7wgwvIdaN
0TpLFI9z/k8yOnVldKxg4QzcHo6cXhccPbePSC+RYxlyQUnwDs3yCkrB7xQY7z4ChxGzH8SnARL4
QQ/SW7A6zsJd9BeWFbkd7ODDWL9jehpOROgB4SLd+ONJ2PlcwEnolay0SWhqR+D2+Fi4yqi9/S/N
+wc8jhYCtA0AAA==#>
#endregion
<#
.NOTES
--------------------------------------------------------------------------------
Code generated by: SAPIEN Technologies, Inc., PowerShell Studio 2014 v4.1.74
Generated on: 11/7/2014 1:40 AM
Generated by: LeandroT
Organization: Ultimate
--------------------------------------------------------------------------------
.DESCRIPTION
GUI script generated by PowerShell Studio 2014
#>
#----------------------------------------------
#region Application Functions
#----------------------------------------------
function OnApplicationLoad {
#Note: This function is not called in Projects
#Note: This function runs before the form is created
#Note: To get the script directory in the Packager use: Split-Path $hostinvocation.MyCommand.path
#Note: To get the console output in the Packager (Windows Mode) use: $ConsoleOutput (Type: System.Collections.ArrayList)
#Important: Form controls cannot be accessed in this function
#TODO: Add modules and custom code to validate the application load
return $true #return true for success or false for failure
}
function OnApplicationExit {
#Note: This function is not called in Projects
#Note: This function runs after the form is closed
#TODO: Add custom code to clean up and unload modules when the application exits
$script:ExitCode = 0 #Set the exit code for the Packager
}
#endregion Application Functions
#----------------------------------------------
# Generated Form Function
#----------------------------------------------
function Call-StartServices2_psf {
#----------------------------------------------
#region Import the Assemblies
#----------------------------------------------
[void][reflection.assembly]::Load('mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089')
[void][reflection.assembly]::Load('System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089')
[void][reflection.assembly]::Load('System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089')
[void][reflection.assembly]::Load('System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089')
[void][reflection.assembly]::Load('System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
[void][reflection.assembly]::Load('System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089')
[void][reflection.assembly]::Load('System.DirectoryServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
[void][reflection.assembly]::Load('System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089')
[void][reflection.assembly]::Load('System.ServiceProcess, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
#endregion Import Assemblies
#----------------------------------------------
#region Generated Form Objects
#----------------------------------------------
[System.Windows.Forms.Application]::EnableVisualStyles()
$form1 = New-Object 'System.Windows.Forms.Form'
$labelServer = New-Object 'System.Windows.Forms.Label'
$Servername = New-Object 'System.Windows.Forms.TextBox'
$buttonGetServices = New-Object 'System.Windows.Forms.Button'
$Chk_list_box = New-Object 'System.Windows.Forms.CheckedListBox'
$InitialFormWindowState = New-Object 'System.Windows.Forms.FormWindowState'
#endregion Generated Form Objects
#----------------------------------------------
# User Generated Script
#----------------------------------------------
function OnApplicationLoad {
#Note: This function is not called in Projects
#Note: This function runs before the form is created
#Note: To get the script directory in the Packager use: Split-Path $hostinvocation.MyCommand.path
#Note: To get the console output in the Packager (Windows Mode) use: $ConsoleOutput (Type: System.Collections.ArrayList)
#Important: Form controls cannot be accessed in this function
#TODO: Add modules and custom code to validate the application load
return $true #return true for success or false for failure
}
function OnApplicationExit {
#Note: This function is not called in Projects
#Note: This function runs after the form is closed
#TODO: Add custom code to clean up and unload modules when the application exits
$script:ExitCode = 0 #Set the exit code for the Packager
}
$form1_Load={
#TODO: Initialize Form Controls here
}
#region Control Helper Functions
function Load-ListBox
{
Param (
[ValidateNotNull()]
[Parameter(Mandatory = $true)]
[System.Windows.Forms.ListBox]$ListBox,
[ValidateNotNull()]
[Parameter(Mandatory = $true)]
$Items,
[Parameter(Mandatory = $false)]
[string]$DisplayMember,
[switch]$Append
)
if (-not $Append)
{
$listBox.Items.Clear()
}
if ($Items -is [System.Windows.Forms.ListBox+ObjectCollection])
{
$listBox.Items.AddRange($Items)
}
elseif ($Items -is [Array])
{
$listBox.BeginUpdate()
foreach ($obj in $Items)
{
$listBox.Items.Add($obj)
}
$listBox.EndUpdate()
}
else
{
$listBox.Items.Add($Items)
}
$listBox.DisplayMember = $DisplayMember
}
#endregion
$Output = New-Object System.Windows.Forms.TextBox
$buttonGetServices_Click = {
#TODO: Place custom script here
New-Variable -Name Servername -Value ($tb_ServerName.Text) -Scope: global -ErrorAction: SilentlyContinue
#$Services = (Get-Service -ComputerName $Servername.Text | Where-Object { $_.Status -eq "stopped" -or $_.Status -eq "Starting" }).DisplayName
#-and $_.Name -like "*IBM*"
#$Services = Get-WmiObject Win32_Service -ComputerName $Servername.Text | where{ 'Auto', 'Disabled' -contains $_.StartMode -and $_.State -ne 'Running' } | Select name, StartMode, State
#$objServices = Get-WmiObject Win32_Service -ComputerName $Servername.Text | where{ 'Auto', 'Disabled' -contains $_.StartMode -and $_.State -ne 'Running' } | select name, StartMode, State
#$Services = $objServices | Format-Table -auto
$Services = Get-WmiObject Win32_Service -ComputerName $Servername.Text | where{ 'Auto', 'Disabled' -contains $_.StartMode -and $_.State -ne 'Running' } | % { ($_.name, $_.DisplayName, $_.StartMode, $_.State) -join "`t`t" }
$Chk_list_box.Items.Clear()
$Chk_list_box.Visible = $True
$Output.Visible = $False
FOREACH ($Service in $Services)
{
$Chk_list_box.Items.Add("$Service") | Out-Null
}
}
#endregion
# --End User Generated Script--
#----------------------------------------------
#region Generated Events
#----------------------------------------------
$Form_StateCorrection_Load=
{
#Correct the initial state of the form to prevent the .Net maximized form issue
$form1.WindowState = $InitialFormWindowState
}
$Form_Cleanup_FormClosed=
{
#Remove all event handlers from the controls
try
{
$buttonGetServices.remove_Click($buttonGetServices_Click)
$form1.remove_Load($form1_Load)
$form1.remove_Load($Form_StateCorrection_Load)
$form1.remove_FormClosed($Form_Cleanup_FormClosed)
}
catch [Exception]
{ }
}
#endregion Generated Events
#----------------------------------------------
#region Generated Form Code
#----------------------------------------------
$form1.SuspendLayout()
#
# form1
#
$form1.Controls.Add($labelServer)
$form1.Controls.Add($Servername)
$form1.Controls.Add($buttonGetServices)
$form1.Controls.Add($Chk_list_box)
$form1.ClientSize = '674, 725'
$form1.Name = "form1"
$form1.Text = "Form"
$form1.add_Load($form1_Load)
#
# labelServer
#
$labelServer.Location = '33, 18'
$labelServer.Name = "labelServer"
$labelServer.Size = '305, 23'
$labelServer.TabIndex = 3
$labelServer.Text = "Server"
$labelServer.TextAlign = 'MiddleCenter'
#
# Servername
#
$Servername.Location = '33, 47'
$Servername.Name = "Servername"
$Servername.Size = '305, 20'
$Servername.TabIndex = 2
#
# buttonGetServices
#
$buttonGetServices.Location = '412, 45'
$buttonGetServices.Name = "buttonGetServices"
$buttonGetServices.Size = '159, 23'
$buttonGetServices.TabIndex = 1
$buttonGetServices.Text = "GetServices"
$buttonGetServices.UseVisualStyleBackColor = $True
$buttonGetServices.add_Click($buttonGetServices_Click)
#
# Chk_list_box
#
$Chk_list_box.FormattingEnabled = $True
$Chk_list_box.Location = '23, 117'
$Chk_list_box.Name = "Chk_list_box"
$Chk_list_box.Size = '615, 559'
$Chk_list_box.TabIndex = 0
$form1.ResumeLayout()
#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($Form_StateCorrection_Load)
#Clean up the control events
$form1.add_FormClosed($Form_Cleanup_FormClosed)
#Show the Form
return $form1.ShowDialog()
} #End Function
#Call OnApplicationLoad to initialize
if((OnApplicationLoad) -eq $true)
{
#Call the form
Call-StartServices2_psf | Out-Null
#Perform cleanup
OnApplicationExit
}
11-7-2014-1-40-04-AM.jpg
The code is missing the "Start Services" button, so I cannot try. And after trying to add the button my PowerGUI crashed :(.
But I expect you need to go thru $Chk_list_box content to check for checked entries, then reparse each line with something like ($curLine is the listbox entry as string):
How to do remote controll of services is a different topic.
But I expect you need to go thru $Chk_list_box content to check for checked entries, then reparse each line with something like ($curLine is the listbox entry as string):
$service = $curLine | convertFrom-CSV -del "`t" -header Name, StartMode, State
$service than contains the same properties as what you stuffed into the listbox.How to do remote controll of services is a different topic.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you!
BTW, I recommend to use Get-Service instead of using WMI. And you probably want to include some type of formatting, as the list box will contain just service name and state separated by a single space.