Powershell - Close form after time period - winforms

I have a power-shell form prompting user if they would like to postpone a shutdown time (the time of the shutdown is given by another ps script as an argument which is calculated in the initial script).
I'd like to close the form after 30 minutes of inactivity, how would I go about this?
Powershell Code (Form):
#creating the form object
$form = New-Object System.Windows.Forms.Form
#setting the from title
$form.Text = "System warning"
#setting the form dimesnions and positions
$form.Size = New-Object System.Drawing.Size(300,250)
$form.StartPosition = "CenterScreen"
#claculate time before shut down:
$StartDate=(GET-DATE)
#this ill have to be replaced by a parameter which indicates the shut down date
$EndDate = $EndDate | Get-Date
$timeDifference = NEW-TIMESPAN –Start $StartDate –End $EndDate
$secondsTilShutdown = $timeDifference.TotalSeconds
#time remaining message
$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10,20)
$label.Size = New-Object System.Drawing.Size(280,40)
$label.Text = "This computer is scheduled to shutdown at " + $EndDate
$form.Controls.Add($label)
#second message
$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10,70)
$label.Size = New-Object System.Drawing.Size(280,20)
$label.Text = "Postpone the shutdown by : "
$form.Controls.Add($label)
#setting up the drop down box (time in minutes)
$TimePeriods = 60, 120, 180, 240
$DropDown = new-object System.Windows.Forms.ComboBox
$DropDown.Location = new-object System.Drawing.Size(10,90)
$DropDown.Size = new-object System.Drawing.Size(130,30)
ForEach ($time in $TimePeriods) {
[void] $DropDown.Items.Add([string]($time/60) + " hours")
}
#1 hour is the default
$DropDown.SelectedItem = $DropDown.Items[0]
$Form.Controls.Add($DropDown)
#creating the postpone button
$OKButton = New-Object System.Windows.Forms.Button
#position of the button on the form
$OKButton.Location = New-Object System.Drawing.Point(25,130)
#size of the button
$OKButton.Size = New-Object System.Drawing.Size(100,50)
#text of the button
$OKButton.Text = "Postpone"
#the value that the from dialog will return if we click on ok
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
#assigns a key down on the enter key to the button
$form.AcceptButton = $OKButton
#adds the button to the form
$form.Controls.Add($OKButton)
#creating the ignore button
$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Point(175,130)
$CancelButton.Size = New-Object System.Drawing.Size(100,50)
$CancelButton.Text = "Continue with scheduled shutdown"
$CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$form.CancelButton = $CancelButton
$form.Controls.Add($CancelButton)
$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Point(10,40)
$textBox.Size = New-Object System.Drawing.Size(260,20)
$form.Controls.Add($textBox)
$form.Topmost = $True
$form.Add_Shown({$textBox.Select()})
$result = $form.ShowDialog()
###processing form results :
#if the postpone button button was selected
if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{
#logic
}
elseif($result -eq [System.Windows.Forms.DialogResult]::Cancel)
{
#we do not push back the shut down time
}

use a timer, i give you a example to timer wich close form
Function ClearAndClose()
{
$Timer.Stop();
$Form.Close();
$Form.Dispose();
$Timer.Dispose();
$Script:CountDown=5
}
Function Button_Click()
{
ClearAndClose
}
Function Timer_Tick()
{
$Label.Text = "Your system will reboot in $Script:CountDown seconds"
--$Script:CountDown
if ($Script:CountDown -lt 0)
{
ClearAndClose
}
}
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$Form = New-Object system.Windows.Forms.Form
$Form.Text = "Attention redémarrage!!"
$Form.Size = New-Object System.Drawing.Size(250,100)
$Form.StartPosition = "CenterScreen"
$Form.Topmost = $True
$Label = New-Object System.Windows.Forms.Label
$Label.AutoSize = $true
$Label.Location = New-Object System.Drawing.Size(20,5)
$Button = New-Object System.Windows.Forms.Button
$Button.Location = New-Object System.Drawing.Size(55,35)
$Button.Size = New-Object System.Drawing.Size(120,23)
$Button.Text = "STOP"
$Button.DialogResult=[System.Windows.Forms.DialogResult]::OK
$Timer = New-Object System.Windows.Forms.Timer
$Timer.Interval = 1000
$Form.Controls.Add($Label)
$Form.Controls.Add($Button)
$Script:CountDown = 6
$Button.Add_Click({Button_Click})
$Timer.Add_Tick({ Timer_Tick})
$Timer.Start()
$Form.ShowDialog()

Related

Powershell - how do I change a variable from a listbox item to a combobox item?

I'm attempting to clean up my GUI by removing listboxes of items that users can select to a constrained combobox (using DropDownList to lock user-input) in Powershell. Thus far, I haven't been able to get the variable to reflect the combobox item that is chosen.
Ideally, I want to get $Env to equal the text string chosen in the Combobox replacing $listbox
I attempted trying to follow powershell combobox items to variable to no avail as I don't understand how to use the "SelectedIndexChanged" event...I may just not fully understand the syntax on how to use this...a code example would be awesome.
The current code I have:
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$form = New-Object System.Windows.Forms.Form
$form.Text = "Select an environment"
$form.Size = New-Object System.Drawing.Size(190,250)
$form.StartPosition = "CenterScreen"
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Point(10,180)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$form.AcceptButton = $OKButton
$form.Controls.Add($OKButton)
$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10,20)
$label.Size = New-Object System.Drawing.Size(280,20)
$label.Text = "Please select an environment:"
$form.Controls.Add($label)
$listBox = New-Object System.Windows.Forms.ListBox
$listBox.Location = New-Object System.Drawing.Point(10,40)
$listBox.Size = New-Object System.Drawing.Size(150,20)
$listBox.Height = 140
[void] $listBox.Items.AddRange(#("PROD", "QA1", "QA2", "TR"))
$form.Controls.Add($listBox)
$form.Topmost = $True
do
{
$result = $form.ShowDialog()
if ($ListBox.SelectedIndices.Count -lt 1 -and $result -eq [System.Windows.Forms.DialogResult]::OK)
{
Write-Warning 'Nothing was selected, please select a server.'
}
}
until (($result -eq [System.Windows.Forms.DialogResult]::OK -and $listBox.SelectedIndices.Count -ge 1) -or $result -ne [System.Windows.Forms.DialogResult]::OK)
if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{
$Env -eq $listBox.SelectedItem
}
Here is a quickguid for using events in powershell:
Use | Get-Member -MemberType Event on your WinForms-object to get a list of available events > $OKButton | Get-Member -MemberType Event.
Add a scriptblock that shall be executed, once the event triggers. > $OKButton.add_Click({$ScriptGoesHere}). Watch out for the scope of the scriptblock (PS> help about_scopes)
I reworked your script with events instead of a loop and added comments at the important parts. Events are a lot easier to handle, if you have multiple things going on. But the scopes are kind of a drawback.
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$form = New-Object System.Windows.Forms.Form
$form.Text = "Select an environment"
$form.Size = New-Object System.Drawing.Size(380,250)
$form.StartPosition = "CenterScreen"
$form.Topmost = $True
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Point(10,180)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
#$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK #Moved to the event
$form.AcceptButton = $OKButton
$form.Controls.Add($OKButton)
$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10,20)
$label.Size = New-Object System.Drawing.Size(280,20)
$label.Text = "Please select an environment:"
$form.Controls.Add($label)
$listBox = New-Object System.Windows.Forms.ListBox
$listBox.Location = New-Object System.Drawing.Point(10,40)
$listBox.Size = New-Object System.Drawing.Size(150,140) # the second number is the height
#$listBox.Height = 140
[void] $listBox.Items.AddRange(#("PROD", "QA1", "QA2", "TR"))
$form.Controls.Add($listBox)
$comboBox = New-Object System.Windows.Forms.ComboBox
$comboBox.Location = New-Object System.Drawing.Point(190,40)
$comboBox.Size = New-Object System.Drawing.Size(150,20)
[void] $comboBox.Items.AddRange(#("PROD", "QA1", "QA2", "TR"))
$form.Controls.Add($comboBox)
#region Events
#register some events that trigger actions
$listBox.add_SelectedIndexChanged({
#The event is actually $listBox.SelectedIndexChanged but we want to ADD an action. add_SelectedIndexChanged is not listed in get-member.
$ListSelected = $listBox.SelectedItem
Write-Host "ListSelected = $ListSelected"
# You will note that $ListSelected is not available outside the event yet. It is in the scope of the scriptblock.
})
$comboBox.add_SelectedIndexChanged({
#To prevent trouble with the scope, define the variables in a higher scope
$script:SelectedItem = $comboBox.SelectedItem
$global:SelectedIndex = $comboBox.SelectedItem
write-host "SelectedItem = $SelectedItem"
})
$script:OKScript = {
# or define the whole ScriptBlock in a higher scope...
if( $comboBox.SelectedIndex -ge 0){
$Env = $comboBox.SelectedItem #Be carefull $env is the beginning of environmental variables like $env:path
$form.DialogResult = [System.Windows.Forms.DialogResult]::OK
$form.close()
}else{
Write-Warning 'Nothing was selected, please select a server.'
}
}
# ...and DotSource it to execute it in the same scope:
$OKButton.add_Click({. $OKScript})
#endregion
$result = $form.ShowDialog()
<# This would work but we use events
if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{
$SelectedItem = $comboBox.SelectedItem
$SelectedIndex = $comboBox.SelectedItem
}
#>
write-host "`r`nform is closed`r`nhere are the results:"
"ListSelected = $ListSelected"
"result = $result"
"env = $env"
"SelectedIndex = $SelectedIndex"
"SelectedItem = $SelectedItem"

How to make a label of GUI PowerShell has same location in any display executed?

I made a GUI contain some label. Once I execute this code in other computer or notebook, the location of those label changed. How do I make the location can be same no matter the display that I execute the code?
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
$Form = New-Object System.Windows.Forms.Form
$Form.ClientSize = '578,400'
$Form.text = "Form"
$Form.BackColor = "#c1daf7"
$Form.TopMost = $false
$Form.WindowState = 'Maximized'
$Label1 = New-Object System.Windows.Forms.Label
$Label1.text = "UNDER PROCESS"
$Label1.AutoSize = $true
$Label1.Location = New-Object System.Drawing.Point(600, 300)
$Label1.Font = 'Microsoft Sans Serif,30,style=Bold,Underline'
$Label1.ForeColor = "#d0021b"
$Label2 = New-Object System.Windows.Forms.Label
$Label2.text = "WAITING"
$Label2.AutoSize = $true
$Label2.Location = New-Object System.Drawing.Point(770, 500)
$Label2.Font = 'Microsoft Sans Serif,20,style=Bold'
$Label2.ForeColor = "#fb0505"
$Form.controls.AddRange(#($Label1, $Label2))
[void]$Form.ShowDialog()
UPDATED
I updated my code with a full code.
I tried this but it return me error:
Exception calling "ShowDialog" with "0" argument(s): "Form that is already visible cannot be displayed as a modal dialog box. Set the form's visible property to false before calling showDialog."
Param (
[string]$Path = '*.*',
[string]$MaxAttempts = 5
)
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
# set things up for the timer
$script:nAttempts = 0
$timer = New-Object System.Windows.Forms.Timer
$timer.Interval = 1000 # 1 second
$timer.Add_Tick({
$global:Result = $null
$script:nAttempts++
$file = Get-Item -Path $Path
if ($file) {
$global:Result = [PSCustomObject]#{
Exists = $true
FileName = $file.FullName
Attempts = $script:nAttempts
}
$timer.Dispose()
$Form.Close()
}
elseif ($script:nAttempts -ge $MaxAttempts) {
$global:Result = [PSCustomObject]#{
Exists = $false
FileName = ''
Attempts = $script:nAttempts
}
$timer.Dispose()
$Form.Close()
}
})
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
$Form = New-Object system.Windows.Forms.Form
$Form.ClientSize = '617,418'
$Form.text = "Auto"
$Form.BackColor = "#8b572a"
$Form.TopMost = $false
$Form.WindowState = 'Maximized'
$Label1 = New-Object system.Windows.Forms.Label
$Label1.text = "UNDER AUTOMATION PROCESS"
$Label1.AutoSize = $true
$Label1.width = 25
$Label1.height = 10
$Label1.Anchor = 'top,right,bottom,left'
$Label1.ForeColor = "#ffffff"
$Label1.Anchor = "None"
$Label1.TextAlign = "MiddleCenter"
$Label2 = New-Object system.Windows.Forms.Label
$Label2.text = "Waiting for the job..."
$Label2.AutoSize = $true
$Label2.width = 25
$Label2.height = 10
$Label2.ForeColor = "#ffffff"
$Label2.Anchor = "None"
$Label2.TextAlign = "MiddleCenter"
$Form.controls.AddRange(#($Label1,$Label2))
[void]$Form.Show()
Write-Host $Form.Height
Write-Host $Form.Width
$Label1.location = New-Object System.Drawing.Point(($Form.Width*0.35), ($Form.Height*0.4))
$Label2.location = New-Object System.Drawing.Point(($form.Width*0.43), ($Form.Height*0.5))
$L_S = (($Form.Width/2) - ($Form.Height / 2)) / 15
$L_S
$Label1.Font = "Microsoft Sans Serif, $L_S, style=Bold"
$Label2.Font = "Microsoft Sans Serif, $L_S, style=Bold"
$Form.controls.AddRange(#($Label1,$Label2))
# start the timer as soon as the dialog is visible
$Form.Add_Shown({ $timer.Start() })
[void]$Form.ShowDialog()
# clean up when done
$Form.Dispose()
I updated my code, I tried this, but it still return me an error. Anyone can help me to fix it please. Thanks
Updated 2nd
Param (
[string]$Path = '*.*',
[string]$MaxAttempts = 5
)
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
# set things up for the timer
$script:nAttempts = 0
$timer = New-Object System.Windows.Forms.Timer
$timer.Interval = 1000 # 1 second
$timer.Add_Tick({
$global:Result = $null
$script:nAttempts++
$file = Get-Item -Path $Path
if ($file) {
$global:Result = [PSCustomObject]#{
Exists = $true
FileName = $file.FullName
Attempts = $script:nAttempts
}
$timer.Dispose()
$Form.Close()
}
elseif ($script:nAttempts -ge $MaxAttempts) {
$global:Result = [PSCustomObject]#{
Exists = $false
FileName = ''
Attempts = $script:nAttempts
}
$timer.Dispose()
$Form.Close()
}
})
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
$Form = New-Object system.Windows.Forms.Form
# $Form.ClientSize = '617,418'
$Form.text = "AutoGM"
$Form.BackColor = "#9b9b9b"
$Form.TopMost = $false
$Form.Width = [System.Windows.Forms.SystemInformation]::PrimaryMonitorSize.Width
$Form.Height = [System.Windows.Forms.SystemInformation]::PrimaryMonitorSize.Height
$FontSize = ($Form.Width / 100) + ($Form.Height/100) + 5
$Label1 = New-Object system.Windows.Forms.Label
$Label1.text = "UNDER PROCESS"
$Label1.AutoSize = $true
# $Label1.width = 25
# $Label1.height = 10
$Label1.Anchor = "None"
$Label1.Location = New-Object System.Drawing.Point(($form.Width*0.3), ($Form.Height*0.3))
$Label1.Font = "Microsoft Sans Serif,$FontSize,style=Bold"
$Label1.ForeColor = "#000000"
$Label2 = New-Object system.Windows.Forms.Label
$Label2.text = "Waiting..."
$Label2.AutoSize = $true
# $Label2.width = 25
# $Label2.height = 10
$Label2.Location = New-Object System.Drawing.Point(($form.Width*0.4), ($Form.Height*0.4))
$Label2.Anchor = "None"
$Label2.Font = "Microsoft Sans Serif,$FontSize"
$Label2.ForeColor = "#000000"
$img = [System.Drawing.Image]::Fromfile(".\img.png")
$pictureBox = new-object Windows.Forms.PictureBox
$pictureBox.Location = New-Object System.Drawing.Point(($form.Width*0.45), ($Form.Height*0.5))
$pictureBox.Width = $Form.Size.Width / 5
$pictureBox.Height = $Form.Size.Height / 5
$pictureBox.Image = $img
$form.controls.add($pictureBox)
$Form.controls.AddRange(#($Label1,$Label2))
# Write-Host $Form.Height
# Write-Host $Form.Width
# $Label1.location = New-Object System.Drawing.Point(($Form.Width*0.35), ($Form.Height*0.4))
# $Label2.location = New-Object System.Drawing.Point(($form.Width*0.43), ($Form.Height*0.5))
# $L_S = (($Form.Width/2) - ($Form.Height / 2)) / 15
# $Label1.Font = "Microsoft Sans Serif, $L_S, style=Bold"
# $Label2.Font = "Microsoft Sans Serif, $L_S, style=Bold"
# $Form.controls.AddRange(#($Label1,$Label2))
# start the timer as soon as the dialog is visible
$Form.Add_Shown({ $timer.Start() })
[void]$Form.ShowDialog()
# clean up when done
$Form.Dispose()
As stated by Niraj it depends on the resolution of the monitor being used so instead ask yourself where do you want it to show? in mid-mid? mid-left? this can be achieved using some math, see below for a simple example, it uses the $form width en height to calculate the correct position for the labels.
$Label1.Location = New-Object System.Drawing.Point(($form.Width*0.5), ($Form.Height*0.5))
$Label2.Location = New-Object System.Drawing.Point(($form.Width*0.5), ($Form.Height*0.4))

How to prevent null/whitespace value in Windows Form textbox (using Powershell)?

I made a Windows Form (this is the last portion of it) that allows the user to enter a search term in a textbox. The whole script checks a server for log files, and downloads them to the user's machine. The textbox data contains a string (date, account #, etc.)...and if left blank it is treated as a wildcard, downloading every log file in the folder chosen. I'm not sure if I can disable the "ok" button until data is entered or give a pop-up/message box prompting the user to enter a search term? I left the prior code/variables out of this example, as it has no bearing on the issue. I appreciate any help in advance!
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$form = New-Object System.Windows.Forms.Form
$form.Text = "Enter search criteria"
$form.Size = New-Object System.Drawing.Size(300,200)
$form.StartPosition = "CenterScreen"
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Point(75,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$form.AcceptButton = $OKButton
$form.Controls.Add($OKButton)
$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10,20)
$label.Size = New-Object System.Drawing.Size(280,20)
$label.Text = "Enter search term"
$form.Controls.Add($label)
$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Point(10,40)
$textBox.Size = New-Object System.Drawing.Size(260,20)
$form.Controls.Add($textBox)
$form.Topmost = $True
$form.Add_Shown({$textBox.Select()})
$result = $form.ShowDialog()
if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{
$Search = $textBox.Text
$Search
}
$UserPath = "C:\GetFiles\getfiles"
& cmd /c $UserPath" "$Search
Here would be one way you could handle it.
$okbutton.enabled = $false # make this a default
if(![string]::IsNullOrEmpty($textbox.text)) #only enable when you have text in the text box
{
$okbutton.enabled = $true
}
You'll have to use an event from the textbox to change the value of the $okbutton to enabled once text has been entered. I believe this is the event you'll need:
https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.control.textchanged?view=netframework-4.7.2
Depending on what you are doing you may need some of the other events as well.
I figured it out. Thank you to Thom Schumacher for helping me with the syntax necessary to complete this:
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$form = New-Object System.Windows.Forms.Form
$form.Text = "Enter search criteria"
$form.Size = New-Object System.Drawing.Size(300,200)
$form.StartPosition = "CenterScreen"
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Point(75,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$form.AcceptButton = $OKButton
$form.Controls.Add($OKButton)
$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10,20)
$label.Size = New-Object System.Drawing.Size(280,20)
$label.Text = "Enter loan number or date to search"
$form.Controls.Add($label)
$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Point(10,40)
$textBox.Size = New-Object System.Drawing.Size(260,20)
$form.Controls.Add($textBox)
$form.Topmost = $True
$form.Add_Shown({$textBox.Select()})
do
{
$result = $form.ShowDialog()
if ([string]::IsNullOrEmpty($textbox.text))
{
Write-Warning 'Please enter search term.'
}
}
until(![string]::IsNullOrEmpty($textbox.text))
{
}
if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{
$Search = $textBox.Text
$Search
}

return value from function with combobox

I have a small GUI that will connect to a vCenter in a list. The forms open in the order I want, but I can't carry values between them. I've tried so many return calls I don't know what else to do.
Here is the code. Basically, the first form opens and asks for which vCenter you want. Then prompts you to authenticate (this all works wonderfully). But the problem comes in after the script is done. I don't get any return values.
function Connect-Vc ($vcArg)
{
$Form2 = $null
$selectedVC = $vcArg.selecteditem
$viconnection = $null
if ($global:defaultviserver -ne $null)
{
Disconnect-viserver * -confirm:$false
}
$clusterselection = $null
$DropDownTo = $null
$credential = Get-Credential -Message "Please Enter Elevated Credentials To Access $selectedVC. You can enter assuming you're an administrator on $selectedVC."
$username = $credential.Username
$password = $credential.GetNetworkCredential().Password
$viconnection = connect-viserver $selectedVC -User $username -Password $password
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Windows.Forms.Application]::EnableVisualStyles()
$Form2 = New-Object System.Windows.Forms.Form
$Form2.AutoSize = $True
$Form2.AutoSizeMode = "GrowAndShrink"
$Form2.width = 600
$Form2.height = 500
$Form2.Text = ”Vcenter Selection”
$Form2.StartPosition = "CenterScreen"
#First item selection*******************
$DropDownLabel1 = new-object System.Windows.Forms.Label
$DropDownLabel1.Location = new-object System.Drawing.Size(140,10)
$DropDownLabel1.size = new-object System.Drawing.Size(130,30)
$DropDownLabel1.Text = "$selectedVC"
$Form2.Controls.Add($DropDownLabel1)
$DropDownLabel2 = new-object System.Windows.Forms.Label
$DropDownLabel2.Location = new-object System.Drawing.Size(10,10)
$DropDownLabel2.size = new-object System.Drawing.Size(100,40)
$DropDownLabel2.Text = "Connected to Vcenter"
$Form2.Controls.Add($DropDownLabel2)
#Second item selection*******************
[array]$clusterselection = get-cluster
$DropDownTo = New-Object System.Windows.Forms.ComboBox
$DropDownTo.Location = New-Object System.Drawing.Size(140,50)
$DropDownTo.Size = New-Object System.Drawing.Size(130,30)
$DropdownTo.DropDownStyle = 2
ForEach ($Item2 in $clusterselection)
{
[void] $DropDownTo.Items.Add($Item2)
}
$Form2.Controls.Add($DropDownTo)
$DropDownLabel3 = new-object System.Windows.Forms.Label
$DropDownLabel3.Location = new-object System.Drawing.Size(10,50)
$DropDownLabel3.size = new-object System.Drawing.Size(100,40)
$DropDownLabel3.Text = "Select Cluster Location"
$Form2.Controls.Add($DropDownLabel3)
#Third item selection*******************
$DropDownType = New-Object System.Windows.Forms.ComboBox
$DropDownType.Location = New-Object System.Drawing.Size(140,90)
$DropDownType.Size = New-Object System.Drawing.Size(130,30)
$DropDownType.DropDownStyle = 2
ForEach ($Item3 in $typeOfServer)
{
[void] $DropDownType.Items.Add($Item3)
}
$Form2.Controls.Add($DropDownType)
$DropDownLabel4 = new-object System.Windows.Forms.Label
$DropDownLabel4.Location = new-object System.Drawing.Size(10,90)
$DropDownLabel4.size = new-object System.Drawing.Size(100,40)
$DropDownLabel4.Text = "Select Type of Server"
$Form2.Controls.Add($DropDownLabel4)
#Fourth item Input*******************
$InputName = New-Object System.Windows.Forms.Textbox
$InputName.Location = New-Object System.Drawing.Size(140,130)
$InputName.Size = New-Object System.Drawing.Size(130,30)
$InputName.MaxLength = 15
$Form2.Controls.Add($InputName)
$inputLabel = new-object System.Windows.Forms.Label
$inputLabel.Location = new-object System.Drawing.Size(10,130)
$inputLabel.size = new-object System.Drawing.Size(100,40)
$inputLabel.Text = "Enter Name of Server"
$Form2.Controls.Add($inputLabel)
#Fifth item selection*******************
$dropDownMem = New-Object System.Windows.Forms.Combobox
$dropDownMem.Location = New-Object System.Drawing.Size(140,170)
$dropDownMem.Size = New-Object System.Drawing.Size(130,30)
$dropDownMem.DropDownStyle = 2
ForEach ($Item5 in $mem)
{
[void] $dropDownMem.Items.Add($Item5)
}
$Form2.Controls.Add($dropDownMem)
$DropDownLabel5 = new-object System.Windows.Forms.Label
$DropDownLabel5.Location = new-object System.Drawing.Size(10,170)
$DropDownLabel5.size = new-object System.Drawing.Size(100,40)
$DropDownLabel5.Text = "Select Memory Quantity in GB"
$Form2.Controls.Add($DropDownLabel5)
#Sixth item selection*******************
$dropDownvCpu = New-Object System.Windows.Forms.Combobox
$dropDownvCpu.Location = New-Object System.Drawing.Size(140,210)
$dropDownvCpu.Size = New-Object System.Drawing.Size(130,30)
$dropDownvCpu.DropDownStyle = 2
ForEach ($Item6 in $vCpu)
{
[void] $dropDownvCpu.Items.Add($Item6)
}
$Form2.Controls.Add($dropDownvCpu)
$DropDownLabel6 = new-object System.Windows.Forms.Label
$DropDownLabel6.Location = new-object System.Drawing.Size(10,210)
$DropDownLabel6.size = new-object System.Drawing.Size(100,40)
$DropDownLabel6.Text = "Select Virtual CPU's"
$Form2.Controls.Add($DropDownLabel6)
#Seventh item selection*******************
$dropDownOS = New-Object System.Windows.Forms.Combobox
$dropDownOS.Location = New-Object System.Drawing.Size(140,250)
$dropDownOS.Size = New-Object System.Drawing.Size(130,30)
$dropDownOS.DropDownStyle = 2
ForEach ($Item7 in $operatingSystem)
{
[void] $dropDownOS.Items.Add($Item7)
}
$Form2.Controls.Add($dropDownOS)
$DropDownLabel7 = new-object System.Windows.Forms.Label
$DropDownLabel7.Location = new-object System.Drawing.Size(10,250)
$DropDownLabel7.size = new-object System.Drawing.Size(100,40)
$DropDownLabel7.Text = "Select Operating System"
$Form2.Controls.Add($DropDownLabel7)
#Defines buttons for click to accept*********************
#$Button1 = new-object System.Windows.Forms.Button
#$Button1.Location = new-object System.Drawing.Size(10,300)
#$Button1.Size = new-object System.Drawing.Size(100,20)
#$Button1.Text = "Provision Vm"
#$Button1.Add_Click({Provision-VM})
#$Button1.Add_Click({Get-Account $oRphanedAcct})
#Defines buttons for click to accept*********************
$Button2 = new-object System.Windows.Forms.Button
$Button2.Location = new-object System.Drawing.Size(10,330)
$Button2.Size = new-object System.Drawing.Size(100,20)
$Button2.Text = "Provision Vm"
$Button2.Add_Click({Provision-VM -arg1 "$choice4" -arg2 "$choice5" -arg3 "$Choice3"})
#Defines buttons for click to accept*********************
$Button3 = new-object System.Windows.Forms.Button
$Button3.Location = new-object System.Drawing.Size(140,330)
$Button3.Size = new-object System.Drawing.Size(100,20)
$Button3.Text = "Close Form"
#$Button3.Add_Click({Return-Drop})
$Button3.Add_Click({$Form2.Dispose()})
#Defines buttons for click to accept*********************
$Button4 = new-object System.Windows.Forms.Button
$Button4.Location = new-object System.Drawing.Size(275,330)
$Button4.Size = new-object System.Drawing.Size(100,20)
$Button4.Text = "Ok Button"
$Button4.Dialogresult = [System.Windows.Forms.DialogResult]::OK
$Form2.AcceptButton = $Button4
$Form2.Controls.Add($Button2)
$Form2.Controls.Add($Button3)
$Form2.Controls.Add($Button4)
$Form2.Topmost = $True
$Form2.ShowDialog()
$Form2.refresh()
return $DropdownTo.SelectedItem
return $DropDownType.SelectedItem.ToString()
return $InputName.SelectedItem.ToString()
return $DropDownMem.SelectedItem.ToString()
return $DropDownVcpu.SelectedItem.ToString()
return $DropDownOS.SelectedItem.ToString()
return $Button3
return $Button4
}
#Main function definition********************
function Menu
{
$clusterselection = $null
$global:defaultviserver = $null
[array]$VCItems = "VCSelection","VCSelection2","VCSelection3"
[array]$typeOfServer = "Vanilla", "IIS", "SQL", "SQL_Cluster_Node"
[array]$operatingSystem = "Windows2012", "Windows2016"
[array]$mem = "2","4","6","8","10","12","32","64"
[array]$vCpu = "2","4","6","8","10","12"
#Function for Closing Form Upon no input
function Return-Drop
{
If (($dropDownVC.SelectedItem -ne $null) -or ($DropDownTO.SelectedItem -ne $null) -or ($DropDownType.SelectedItem -ne $null))
{
$Form.Close()
}
}
#Function for connecting to Vcenter
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Windows.Forms.Application]::EnableVisualStyles()
$Form = New-Object System.Windows.Forms.Form
$Form.AutoSize = $True
$Form.AutoSizeMode = "GrowAndShrink"
$Form.width = 600
$Form.height = 500
$Form.Text = ”Vcenter Selection”
$Form.StartPosition = "CenterScreen"
#First item selection*******************
$DropDownVC = New-Object System.Windows.Forms.ComboBox
$DropDownVC.Location = New-Object System.Drawing.Size(140,10)
$DropDownVC.Size = New-Object System.Drawing.Size(130,30)
$DropDownVC.DropDownStyle = 2
$DropDownVC.TabIndex = 0
ForEach ($Item1 in $VCItems)
{
[void] $DropDownVC.Items.Add($Item1)
}
$DropDownVC.SelectedItem = $DropDownVC.Items[0]
$Form.Controls.Add($DropDownVC)
$DropDownLabel1 = new-object System.Windows.Forms.Label
$DropDownLabel1.Location = new-object System.Drawing.Size(10,10)
$DropDownLabel1.size = new-object System.Drawing.Size(100,40)
$DropDownLabel1.Text = "Select Vcenter to connect to"
$Form.Controls.Add($DropDownLabel1)
#Defines buttons for click to connect to VC*********************
$Button5 = new-object System.Windows.Forms.Button
$Button5.Location = new-object System.Drawing.Size(290,10)
$Button5.Size = new-object System.Drawing.Size(100,20)
$Button5.Text = "Connect"
$Button5.Add_Click({$form.visible = $false;$t = Connect-Vc -vcArg $DropDownVC})
$Form.Controls.Add($Button5)
$Form.Topmost = $True
$Form.Add_Shown({$Form.Activate()})
$Form.ShowDialog()
$Choice1 = $DropDownVC.SelectedItem.ToString()
enter code here
return $Choice1
}

Load Function on start of Form

I would like to know how I can load a function when form is started?
In this example I would like to launch the function test() which adds a line to the RichTextBox. I don't want a button and when I try $form1.Show the form doesn't work.
$ErrorActionPreference = 'Continue'
Function test {
$richtextbox1.AppendText("testttt `n")
}
function CreateForm {
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$form1 = New-Object System.Windows.Forms.Form
#Form Parameter
$form1.Text = ""
$form1.Name = ""
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 600
$System_Drawing_Size.Height = 500
$form1.ClientSize = $System_Drawing_Size
$Form1.MinimizeBox = $false
$Form1.MaximizeBox = $true
$form1.ControlBox = $true
$form1.Topmost = $true
$Form1.AutoSize = $true
$Form1.ShowInTaskbar = $false
$form1.StartPosition = "CenterScreen"
$label1 = New-Object System.Windows.Forms.Label
$label1.Location = New-Object System.Drawing.Point(200, 40)
$label1.Size = New-Object System.Drawing.Size(400, 40)
$label1.Text = ""
$label1.Font = New-Object System.Drawing.Font("Microsoft Sans Serif", 18, [System.Drawing.FontStyle]::Bold)
$form1.Controls.Add($label1)
$label2 = New-Object System.Windows.Forms.Label
$label2.Location = New-Object System.Drawing.Point(50, 125)
$label2.Size = New-Object System.Drawing.Size(400, 40)
$label2.Text = "Step : "
$label2.Font = New-Object System.Drawing.Font("Microsoft Sans Serif", 18, [System.Drawing.FontStyle]::Bold)
$form1.Controls.Add($label2)
$label3 = New-Object System.Windows.Forms.Label
$label3.Location = New-Object System.Drawing.Point(50, 175)
$label3.Size = New-Object System.Drawing.Size(400, 40)
$label3.Text = " in Progress"
$label3.Font = New-Object System.Drawing.Font("Microsoft Sans Serif", 18, [System.Drawing.FontStyle]::Bold)
$form1.Controls.Add($label3)
$richTextBox1 = New-Object System.Windows.Forms.RichTextBox
$richTextBox1.Location = New-Object System.Drawing.Point(50, 250)
$richTextBox1.Size = New-Object System.Drawing.Size(500, 200)
$richTextBox1.Text = " : `n"
$richTextBox1.Font = New-Object System.Drawing.Font("Microsoft Sans Serif", 18, [System.Drawing.FontStyle]::Bold)
$form1.Controls.Add($richTextBox1)
$InitialFormWindowState = $form1.WindowState
#Show the Form
$form1.ShowDialog()
test
}
CreateForm
The CreateForm-function will freeze on $form1.ShowDialog() until the form is closed, so test will never run. What you can do is add test as an eventhandler to the Shown-event that is trigged on the first launch of a form.
Replace:
$form1.ShowDialog()
test
with:
$form1.add_Shown({ test } )
$form1.ShowDialog()
You can also run the function before showing the dialog since it only modifies the form anyways (or just do the modifications directly in the form-code):
test
$form1.ShowDialog()

Resources