Modify this Powershell custom input box to store multiple variables? - powershell

This textbox was a powershell tip of the week and i really like it.
But I didn't manage to work with it to have 2 variables or even 3 in one input window.
Does anyone know how to do this ? Any help is upvoted immediately.
The Code of the Textbox is here : Input Textbox
The full code is here :
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$objForm = New-Object System.Windows.Forms.Form
$objForm.Text = "Data Entry Form"
$objForm.Size = New-Object System.Drawing.Size(300,200)
$objForm.StartPosition = "CenterScreen"
$objForm.KeyPreview = $True
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Enter")
{$x=$objTextBox.Text;$objForm.Close()}})
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Escape")
{$objForm.Close()}})
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(75,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.Add_Click({$x=$objTextBox.Text;$objForm.Close()})
$objForm.Controls.Add($OKButton)
$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Size(150,120)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = "Cancel"
$CancelButton.Add_Click({$objForm.Close()})
$objForm.Controls.Add($CancelButton)
$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(10,20)
$objLabel.Size = New-Object System.Drawing.Size(280,20)
$objLabel.Text = "Please enter the information in the space below:"
$objForm.Controls.Add($objLabel)
$objTextBox = New-Object System.Windows.Forms.TextBox
$objTextBox.Location = New-Object System.Drawing.Size(10,40)
$objTextBox.Size = New-Object System.Drawing.Size(260,20)
$objForm.Controls.Add($objTextBox)
$objForm.Topmost = $True
$objForm.Add_Shown({$objForm.Activate()})
[void] $objForm.ShowDialog()
$x

You need to repeat adding a few more text boxes:
$OKButton.Add_Click({
$x=$objTextBox.Text
$y=$objTextBox2.Text
$z=$objTextBox3.Text
$objForm.Close()})
...
$objTextBox2 = New-Object System.Windows.Forms.TextBox
$objTextBox2.Location = New-Object System.Drawing.Size(10,65)
$objTextBox2.Size = New-Object System.Drawing.Size(260,20)
$objForm.Controls.Add($objTextBox2)
$objTextBox3 = New-Object System.Windows.Forms.TextBox
$objTextBox3.Location = New-Object System.Drawing.Size(10,90)
$objTextBox3.Size = New-Object System.Drawing.Size(260,20)
$objForm.Controls.Add($objTextBox3)
...
$x,$y,$z
You might need to adjust the Y locations of the OK & Close buttons.

Related

PowerShell GUI containing multiple ListBoxes

I am trying to modify the code found in the Microsoft Documentation (https://learn.microsoft.com/en-us/powershell/scripting/samples/multiple-selection-list-boxes?view=powershell-7.2) to contain 2 ListBoxes: One single select, and one multiple selected.
This issue is only listBox2 is showing up.
What I have so far:
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$form = New-Object System.Windows.Forms.Form
$form.Text = 'Data Entry Form'
$form.Size = New-Object System.Drawing.Size(600,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)
$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Point(150,120)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = 'Cancel'
$CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$form.CancelButton = $CancelButton
$form.Controls.Add($CancelButton)
#Single Select Start
$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 = 'Select Primary USB from the list below:'
$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(260,20)
#Single Select End
#Multiple Item Select Start
$label2 = New-Object System.Windows.Forms.Label
$label2.Location = New-Object System.Drawing.Point(310,20)
$label2.Size = New-Object System.Drawing.Size(280,20)
$label2.Text = 'Select Secondary USB(s) from the list below:'
$form.Controls.Add($label2)
$listBox2 = New-Object System.Windows.Forms.Listbox
$listBox2.Location = New-Object System.Drawing.Point(310,40)
$listBox2.Size = New-Object System.Drawing.Size(260,20)
$listBox2.SelectionMode = 'MultiExtended'
#Multiple Item Select End
$testArray = gdr
ForEach($n in $testArray){
if(($n.Root.Length -lt 4) -And ($n.Root.Length -gt 0) -And ($n.Root -ne "\") -And ($n.Root -ne "C:\")){
[void] $listBox.Items.Add($n.Root)
[void] $listBox2.Items.Add($n.Root)
}
}
$listBox.Height = 70
$listBox2.Height = 70
$form.Controls.Add($listBox1)
$form.Controls.Add($listBox2)
$form.Topmost = $true
$result = $form.ShowDialog()
if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{
$x = $listBox1.SelectedItem
$y = $listBox2.SelectedItems
Write-Host "Single Item Selected" $x
Write-Host "Multiple Items Selected" $y
}
P.S. Can someone please make a new tag for PowerShell-GUI
istbox1 doesn't exist....change:
$form.Controls.Add($listBox1)
to
$form.Controls.Add($listBox)
Or rename the object to $listbox1

Powershell GUI script: read variable from textbox

I'm trying to pass the input of the two textboxes to the logic part of the script at the bottom. But that's not happening and I can't figure out the problem... I tried rewriting the code from [here][1].
Add-Type -AssemblyName System.Drawing
$form = New-Object System.Windows.Forms.Form
$form.Text = 'CompareGroups'
$form.Size = New-Object System.Drawing.Size(300,250)
$form.StartPosition = 'CenterScreen'
$okButton = New-Object System.Windows.Forms.Button
$okButton.Location = New-Object System.Drawing.Point(75,170)
$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)
$cancelButton = New-Object System.Windows.Forms.Button
$cancelButton.Location = New-Object System.Drawing.Point(150,170)
$cancelButton.Size = New-Object System.Drawing.Size(75,23)
$cancelButton.Text = 'Cancel'
$cancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$form.CancelButton = $cancelButton
$form.Controls.Add($cancelButton)
$label1 = New-Object System.Windows.Forms.Label
$label1.Location = New-Object System.Drawing.Point(10,20)
$label1.Size = New-Object System.Drawing.Size(280,20)
$label1.Text = 'Source-PC:'
$form.Controls.Add($label1)
$label2 = New-Object System.Windows.Forms.Label
$label2.Location = New-Object System.Drawing.Point(10,80)
$label2.Size = New-Object System.Drawing.Size(280,20)
$label2.Text = 'Target-PC:'
$form.Controls.Add($label2)
$textBox1 = New-Object System.Windows.Forms.TextBox
$textBox1.Location = New-Object System.Drawing.Point(10,40)
$textBox1.Size = New-Object System.Drawing.Size(260,20)
$form.Controls.Add($textBox1)
$textBox2 = New-Object System.Windows.Forms.TextBox
$textBox2.Location = New-Object System.Drawing.Point(10,100)
$textBox2.Size = New-Object System.Drawing.Size(260,20)
$form.Controls.Add($textBox2)
$form.Topmost = $true
$form.Add_Shown({$textBox1.Select()})
$result = $form.ShowDialog()
if (($result -eq [System.Windows.Forms.DialogResult]::OK)) {
$sourcePc = $textBox.Text
$targetPc = $textBox2.Text
$CopyFromPC = Get-ADComputer $sourcePc -Properties MemberOf
$CopyToPC = Get-ADComputer $targetPc -Properties MemberOf
if (($CopyFromPC.MemberOf | out-string) -eq ($CopyTopc.MemberOf | out-string)) {
Write-Host "Groups are the same."
} else {
$CopyFromPC.MemberOf | Where {$CopyTopc.MemberOf -notcontains $_} | Out-GridView -PassThru | Add-ADGroupMember -Members $CopyTopc -verbose
[System.Windows.Forms.MessageBox]::Show("Groups got copied successfully","CompareGroups",0)
}
}
[1]: https://learn.microsoft.com/en-us/powershell/scripting/samples/creating-a-custom-input-box?view=powershell-7
You added a textbox called textbox1 and not textbox.
Change the variablename from $sourcePc = $textBox.Text to $sourcePc = $textBox1.Text

How to prompt for restart based on uptime?

I am trying to create a powershell script that will prompt the user to restart their computer based on their uptime. Preferably I want it to prompt on day 5 and force a restart on day 7.
This script
(get-date)-([System.Management.ManagementDateTimeconverter]::ToDateTime((Get-WmiObject win32_operatingsystem).lastbootuptime))|select days
Gives me the uptime days and if it returns an amount greater than 5 I want it to run
$objForm = New-Object System.Windows.Forms.Form
$objForm.Text = "Shutdown | Restart"
$objForm.Size = New-Object System.Drawing.Size(300,300)
$objForm.StartPosition = "CenterScreen"
$objForm.FormBorderStyle = "FixedSingle"
$objForm.KeyPreview = $True
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Escape")
{$objForm.Close()}})
$SButton = New-Object System.Windows.Forms.Button
$SButton.Location = New-Object System.Drawing.Size(15,220)
$SButton.Size = New-Object System.Drawing.Size(75,25)
$SButton.Text = "Shutdown"
$SButton.Add_Click({Stop-Computer -Force})
$objForm.Controls.Add($SButton)
$RButton = New-Object System.Windows.Forms.Button
$RButton.Location = New-Object System.Drawing.Size(110,220)
$RButton.Size = New-Object System.Drawing.Size(75,25)
$RButton.Text = "Restart"
$RButton.Add_Click({Restart-Computer -Force})
$objForm.Controls.Add($RButton)
$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Size(205,220)
$CancelButton.Size = New-Object System.Drawing.Size(75,25)
$CancelButton.Text = "Cancel"
$CancelButton.Add_Click({$objForm.Close()})
$objForm.Controls.Add($CancelButton)
$outlook = #(Get-Process | ?{ $_.Name -eq "outlook" }).Count
$word = #(Get-Process | ?{ $_.Name -eq "winword" }).Count
$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(10,20)
$objLabel.Size = New-Object System.Drawing.Size(280,120)
$objLabel.Text = "Please ensure you have saved your work before proceeding.`n`nYou currently have $outlook Outlook and $word Word windows open."
$objForm.Controls.Add($objLabel)
$objForm.Topmost = $True
$objForm.Add_Shown({$objForm.Activate()})
And if possible I want it to force the restart if it's greater than 7

Get value back from a text box class

We have a script that was written by someone who is no longer with us. I am new to powershell and this function is not returning a value:
# prompt user for ip/dns address input.
Function get-ip
{
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
# Creates a message box that accepts dns/ip address input.
$objForm = New-Object System.Windows.Forms.Form
$objForm.Text = "User Input Required"
$objForm.Size = New-Object System.Drawing.Size(300,200)
$objForm.StartPosition = "CenterScreen"
$objForm.KeyPreview = $True
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Enter")
{$x=$objTextBox.Text;$objForm.Close()}})
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Escape")
{$objForm.Close()}})
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(75,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.Add_Click({$x=$objTextBox.Text;$objForm.Close()})
$objForm.Controls.Add($OKButton)
$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Size(150,120)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = "Cancel"
$CancelButton.Add_Click({$objForm.Close()})
$objForm.Controls.Add($CancelButton)
$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(10,20)
$objLabel.Size = New-Object System.Drawing.Size(280,40)
$objLabel.Text = "Please enter the IP address of the server you want to connect to:"
$objForm.Controls.Add($objLabel)
$objTextBox = New-Object System.Windows.Forms.TextBox
$objTextBox.Location = New-Object System.Drawing.Size(10,70)
$objTextBox.Size = New-Object System.Drawing.Size(260,20)
$objForm.Controls.Add($objTextBox)
$objForm.Topmost = $True
$objForm.Add_Shown({$objForm.Activate()})
[void] $objForm.ShowDialog()
}
I'm calling it as such:
$ip = get-ip
I enter in a value and I'm not getting anything in the $ip.
How do I capture the value of a text box?
FOR MARTIN
I made the changes that Martin suggested and here is my new code:
# prompt user for ip/dns address input.
Function get-ip
{
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
# Creates a message box that accepts dns/ip address input.
$objForm = New-Object System.Windows.Forms.Form
$objForm.Text = "User Input Required"
$objForm.Size = New-Object System.Drawing.Size(300,200)
$objForm.StartPosition = "CenterScreen"
$objForm.KeyPreview = $True
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Enter")
{$script:x=$objTextBox.Text;$objForm.Close()}})
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Escape")
{$objForm.Close()}})
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(75,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.Add_Click({$script:x=$objTextBox.Text;$objForm.Close()})
$objForm.Controls.Add($OKButton)
$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Size(150,120)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = "Cancel"
$CancelButton.Add_Click({$objForm.Close()})
$objForm.Controls.Add($CancelButton)
$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(10,20)
$objLabel.Size = New-Object System.Drawing.Size(280,40)
$objLabel.Text = "Please enter the IP address of the server you want to connect to:"
$objForm.Controls.Add($objLabel)
$objTextBox = New-Object System.Windows.Forms.TextBox
$objTextBox.Location = New-Object System.Drawing.Size(10,70)
$objTextBox.Size = New-Object System.Drawing.Size(260,20)
$objForm.Controls.Add($objTextBox)
$objForm.Topmost = $True
$objForm.Add_Shown({$objForm.Activate()})
[void] $objForm.ShowDialog()
$x
}
I get the same error message as before:
PS E:\Dropbox\Powershell Scripts\SSS Cloud Icons> .\cloudicons.ps1
Creating Directories...
mkdir : Cannot bind argument to parameter 'Path' because it is an empty string.
At E:\Dropbox\Powershell Scripts\SSS Cloud Icons\cloudicons.ps1:80 char:4
+ md $_.userName
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [mkdir], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,mkdir
Did I miss something?
** UPDATE **
I was asked how I was calling get-ip:
# Insert user entered IP into pipeline.
$ip = get-ip
# Sets user entered IP into new file called propanehasip.rdp.
(get-content .\propanetest.rdp) -replace 'full address:s:INSERTIPHERE',"full address:s:$ip" | Out-File propanehasip.rdp
Write-Host "Creating Directories..."
Import-Csv $csv | ForEach-Object {
# Creates directories based on the userName field.
md $_.userName
# Creates icons based on propanehasip.rdp and WSID fields.
(get-content ".\propanehasip.rdp") -replace 'remoteapplicationcmdline:s:INSERTWSIDHERE',"remoteapplicationcmdline:s:$($_.wsid1)" | out-file ".\$($_.username)\Propane $($_.wsid1).rdp"
(get-content ".\propanehasip.rdp") -replace 'remoteapplicationcmdline:s:INSERTWSIDHERE',"remoteapplicationcmdline:s:$($_.wsid2)" | out-file ".\$($_.username)\Propane $($_.wsid2).rdp"
}
}
UPDATE #2
I figured out how to debug this in visual studio. The error is happening on this line:
(get-content .\propanetest.rdp) -replace 'full address:s:INSERTIPHERE',"full address:s:$ip" | Out-File propanehasip_new.rdp
$x is only valid inside the block (the scope of variable $x), if you change it to $script:x and add an $x before the ending } of your function, then it works.
The additional $x is needed to represent the return value of your function.
Changes:
$objForm.KeyPreview = $True
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Enter")
{$script:x=$objTextBox.Text;$objForm.Close()}})
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Escape")
{$objForm.Close()}})
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(75,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.Add_Click({$script:x=$objTextBox.Text;$objForm.Close()})
$objForm.Controls.Add($OKButton)
End of function:
$objForm.Add_Shown({$objForm.Activate()})
[void] $objForm.ShowDialog()
$x
}
And... this script is taken from here and should demonstrate the use of Windows.Forms. However, i didnt found the date, when it was posted.

Pass parameters from a input box to stored procedure using powershell-please read the whole thing, I know it's long

Hi have a script to create a input box using powershell.
It looks like this
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$objForm = New-Object System.Windows.Forms.Form
$objForm.Text = "Data Entry Form"
$objForm.Size = New-Object System.Drawing.Size(300,200)
$objForm.StartPosition = "CenterScreen"
$objForm.KeyPreview = $True
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Enter")
{$x=$objTextBox.Text;$objForm.Close()}})
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Escape")
{$objForm.Close()}})
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(75,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.Add_Click({$x=$objTextBox.Text;$objForm.Close()})
$objForm.Controls.Add($OKButton)
$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Size(150,120)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = "Cancel"
$CancelButton.Add_Click({$objForm.Close()})
$objForm.Controls.Add($CancelButton)
$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(10,20)
$objLabel.Size = New-Object System.Drawing.Size(280,20)
$objLabel.Text = "Please enter #from date:"
$objForm.Controls.Add($objLabel)
$objTextBox = New-Object System.Windows.Forms.TextBox
$objTextBox.Location = New-Object System.Drawing.Size(10,40)
$objTextBox.Size = New-Object System.Drawing.Size(260,20)
$objForm.Controls.Add($objTextBox)
$objForm.Topmost = $True
$objForm.Add_Shown({$objForm.Activate()})
[void] $objForm.ShowDialog()
$from
Now I want to pass the value $from I input into stored procedure parameter #from, I tried below but not working. Any suggestion?
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server=localhost;Database=AMSDataWarehouse Test;Integrated Security=SSPI"
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.Connection = $SqlConnection
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $SqlCmd
$SqlCmd.CommandText = "YQBreport1"
$cmd.Parameters.Add("#from", $from)| Out-Null
$Command.ExecuteNonQuery()
$from = $Command.Parameters["#from"].value
$DataSet = New-Object System.Data.DataSet
$SqlAdapter.Fill($DataSet)
$SqlConnection.Close()
$SQLResult =$DataSet.Tables[0]
$commands = $SQLResult | foreach-object -process { $_.output }> output.ps1
.\output.ps1
The line:
$OKButton.Add_Click({$x=$objTextBox.Text;$objForm.Close()})
Only works within the Add_click functionality. To make it accessible elsewhere you need to alter it slightly to:
$OKButton.Add_Click({$Global:x=$objTextBox.Text;$objForm.Close()})
$x is then a global parameter that you can pass to your procedure.
Yeah you can make a GUI in PowerShell using Windows Presentation Foundation (WPF). I've tried and failed.
Read in values like this:
$from = Read-Host '#From'
$from
Out-GridView is something new I just learned. You should look into it.
ls | Out-GridView -PassThru -Title 'GUI?'
Nice example how to create an input box in PowerShell (using Windows Forms)
http://technet.microsoft.com/en-us/library/ff730941.aspx