Powershell mask password - powershell

I would like to prompt user to enter a list of passwords, one line at a time. When the person types the passwords, it should appear as *
I have a function
function Read-MultiLineInputBoxDialogPwd([string]$Message, [string]$WindowTitle, [string]$DefaultText){
Add-Type -AssemblyName System.Drawing
Add-Type -AssemblyName System.Windows.Forms
# Create the label
$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Size(10,10)
$label.Size = New-Object System.Drawing.Size(280,20)
$label.AutoSize = $true
$label.Text = $Message
# Create the TextBox used to capture the user's text
$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Size(10,40)
$textBox.Size = New-Object System.Drawing.Size(575,200)
$textBox.AcceptsReturn = $true
$textBox.AcceptsTab = $false
$textBox.Multiline = $true
$textBox.ScrollBars = 'Both'
$textBox.Text = $DefaultText
$textBox.UseSystemPasswordChar = $True
# Create the OK button.
$okButton = New-Object System.Windows.Forms.Button
$okButton.Location = New-Object System.Drawing.Size(415,250)
$okButton.Size = New-Object System.Drawing.Size(75,25)
$okButton.Text = "OK"
$okButton.Add_Click({ $form.Tag = $textBox.Text; $form.Close() })
# Create the Cancel button.
$cancelButton = New-Object System.Windows.Forms.Button
$cancelButton.Location = New-Object System.Drawing.Size(510,250)
$cancelButton.Size = New-Object System.Drawing.Size(75,25)
$cancelButton.Text = "Cancel"
$cancelButton.Add_Click({ $form.Tag = $null; $form.Close() })
# Create the form.
$form = New-Object System.Windows.Forms.Form
$form.Text = $WindowTitle
$form.Size = New-Object System.Drawing.Size(610,320)
$form.FormBorderStyle = 'FixedSingle'
$form.StartPosition = "CenterScreen"
$form.AutoSizeMode = 'GrowAndShrink'
$form.Topmost = $True
$form.AcceptButton = $okButton
$form.CancelButton = $cancelButton
$form.ShowInTaskbar = $true
# Add all of the controls to the form.
$form.Controls.Add($label)
$form.Controls.Add($textBox)
$form.Controls.Add($okButton)
$form.Controls.Add($cancelButton)
# Initialize and show the form.
$form.Add_Shown({$form.Activate()})
$form.ShowDialog() > $null # Trash the text of the button that was clicked.
# Return the text that the user entered.
return $form.Tag
}
And I call the function
$multiLineTextPwd = Read-MultiLineInputBoxDialogPwd -Message "All possible passwords" -WindowTitle "Passwords" -DefaultText "Please enter all possible passwords, one line at a time..."
But when it pops up, the text still appears in plaintext, even though I set the following
$textBox.UseSystemPasswordChar = $True
How to fix this?

I honestly feel that this would be better accomplished by having a single-line text box and an 'Add Another Password' button where the user could enter a password, and then click the button to add another password. You would just keep adding them to an array, and would have to make sure that when they submit that it checks for anything in that box and adds anything left to the array before performing actions.
All password masking references when I went and looked at the MSDN listing for the Textbox class all specifically state Single Line Textbox, so it may well be that you can't use masking with a multiline textbox.

If you read the documentation here you'll see that for multiline text boxes, the UseSystemPasswordChar has no effect.

implement keydown event of mutiline textbox, append * into TB, and append key code string into a string variable.

Related

Ms Powershell 5: Displaying highlighted item from a Listbox

I want to be able to display the currently highlighted item from a scrolling list box, without having to click it.
I have set up the list box so that only one item is displayed. The selection changes via the scroll buttons. I want to be able to read the item displayed without having to click it - so .Add_Click is not suitable.
Example code below:
Many thanks
# Listbox test
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
# set up form
$form = New-Object System.Windows.Forms.Form
$form.Text = "List Box Test"
$form.Size = New-Object System.Drawing.Size(500,200)
$form.StartPosition = "Manual"
$form.Location = New-Object System.Drawing.Point(10, 10)
# Set up list
$List1 = New-Object System.Windows.Forms.ListBox
$List1.Location = New-Object System.Drawing.Point(10, 10)
$List1.Height = 30
$List1.Width = 150
$List1.font = 'arial, 16pt'
[void] $List1.Items.Add('Clubs')
[void] $List1.Items.Add('Diamonds')
[void] $List1.Items.Add('Hearts')
[void] $List1.Items.Add('Spades')
$form.Controls.Add($List1)
# Question: how do I get the highlighted item from the list box to show here, before it is clicked?
# ----------------------------------------------------------------------------------------
# display selection
$TextBox1 = New-Object System.Windows.Forms.TextBox
$TextBox1.Location = New-Object System.Drawing.Point(10,50)
$TextBox1.Size = New-Object System.Drawing.Size(300,30)
$TextBox1.Font = 'arial, 12pt'
$TextBox1.text = "Highlighted item to show here ..."
$form.Controls.Add($TextBox1)
# ----------------------------------------------------------------------------------------
# set up button
$Button1 = New-Object System.Windows.Forms.Button
$Button1.Location = New-Object System.Drawing.Point(10,100)
$Button1.Size = New-Object System.Drawing.Size(50,20)
$Button1.Text = "OK"
$Button1.DialogResult = [System.Windows.Forms.DialogResult]::OK
$form.Controls.Add($Button1)
$form.Topmost = $true
$null = $form.ShowDialog()
Just add a SelectedIndexChanged event handler to the listbox:
$List1.Add_SelectedIndexChanged({
$TextBox1.Text = $this.SelectedItem.ToString() # or do: $this.items[$this.SelectedIndex].ToString()
})
Since a Listbox only contains text, you could leave out the .ToString().
P.S. Don't forget to remove the form from memory when all done with
$form.Dispose()

Password Reset with GUI Improvements

I am working on a Password Reset Script with a GUI and have 3 questions If any body is able to help me :) the premise is that when I user scans their card it will show their username and password, it functions as it should be I want to develop it further.
If the box is empty and ‘okay’ is selected then it uses every row in the CSV, is there a way to set it up so the OK button can't be pressed until something is entered. The RFID scanner used always hits a return.
After the pop box has been displayed I want to add a timer for 15 seconds before it closed and then when the pop-up box disappears it then asks for the next person to scan their card. As it stands at the moment, when the message box appears it closes the original form. Is there any way for me to keep the entry form open rather than it shutting, and show the message box over the top of the form? I basically want to reset the form after the user has been given their details.
When I have the form created at the top I can style it. Am I able to do the same for the message box so it can be styled? Thank you so much in advance.
Any help would be massively appreciated. I am still learning the basics of PowerShell
Code
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$Spreadsheet = Import-CSV "C:\Desktop\Password Reset\Passwords.csv" -Header First,Second,Username,Password,RFID
$form = New-Object System.Windows.Forms.Form
$form.Text = 'Password Reset System'
$form.Size = New-Object System.Drawing.Size(800,600) #Box Size
$form.StartPosition = 'CenterScreen'
$Form.BackColor = "#A4F9F4"
$Form.ForeColor = "#000000"
$okButton = New-Object System.Windows.Forms.Button
$okButton.Location = New-Object System.Drawing.Point(350,350) #OK Button Location
$okButton.Size = New-Object System.Drawing.Size(100,24) #OK Button Size
$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(270,300) #Label Location
$label.Size = New-Object System.Drawing.Size(280,20) #Label Size
$label.Text = 'Scan your Card:'
$form.Controls.Add($label)
$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Point(270,320) #Textbox Location
$textBox.Size = New-Object System.Drawing.Size(260,20) #Textbox Size
$form.Controls.Add($textBox)
$form.Topmost = $true
$form.Add_Shown({$textBox.Select()})
$result = $form.ShowDialog()
if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{
$resetCardNumber = $textBox.Text
$targetUser = $Spreadsheet | Where-Object RFID -eq $resetCardNumber
}
if($targetUser){
Set-ADAccountPassword $targetUser.Username -Reset -NewPassword (Convertto-Securestring -AsPlainText $targetUser.Password -Force)
#Write-Host "Password reset to $($targetUser.Password) for $($targetUser.First) $($targetUser.Second) "($($targetUser.Username))" with card number $($targetUser.RFID)"
[System.Windows.MessageBox]::Show("Your Username: $($targetUser.Username) `nYour Password: $($targetUser.Password) ")
}
else {
#Write-Host "User with Card Number '$resetCardNumber' could not be found!"
[System.Windows.MessageBox]::Show("Your Username could not be found in the system")
}
CSV File below:
First,Second,Username,Password,RFID
John,Smith,JS219401,YourPassword,84192011
Barry,Henry,BH219401,YourPassword,92832839
Hopefully, below (read the inline comments) explains your questions 1 and 2.
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
[System.Windows.Forms.Application]::EnableVisualStyles()
$Spreadsheet = Import-CSV "C:\Desktop\Password Reset\Passwords.csv" -Header First,Second,Username,Password,RFID
$form = New-Object System.Windows.Forms.Form
$form.Text = 'Password Reset System'
$form.Size = New-Object System.Drawing.Size(800,600) #Box Size
$form.StartPosition = 'CenterScreen'
$Form.BackColor = "#A4F9F4"
$Form.ForeColor = "#000000"
$okButton = New-Object System.Windows.Forms.Button
$okButton.Location = New-Object System.Drawing.Point(350,350) #OK Button Location
$okButton.Size = New-Object System.Drawing.Size(100,24) #OK Button Size
$okButton.Text = 'OK'
# remove the next line if you want the mainform to stay open
# $okButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
# initialize the button's Enabled status to $false
$okButton.Enabled = $false
# add event handler code for the button's Click event
# this can only be the case if the button was Enabled
$okButton.Add_Click({
$resetCardNumber = $textBox.Text
$targetUser = $Spreadsheet | Where-Object {$_.RFID -eq $resetCardNumber}
if($targetUser){
Set-ADAccountPassword $targetUser.Username -Reset -NewPassword (Convertto-Securestring -AsPlainText $targetUser.Password -Force)
#Write-Host "Password reset to $($targetUser.Password) for $($targetUser.First) $($targetUser.Second) "($($targetUser.Username))" with card number $($targetUser.RFID)"
[System.Windows.MessageBox]::Show("Your Username: $($targetUser.Username) `nYour Password: $($targetUser.Password) ")
}
else {
#Write-Host "User with Card Number '$resetCardNumber' could not be found!"
[System.Windows.MessageBox]::Show("Your Username could not be found in the system")
}
# reset the form by clearing out the textbox
$textBox.Text = '' # this also triggers the OK button to become disabled
})
$form.AcceptButton = $okButton
$form.Controls.Add($okButton)
$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(270,300) #Label Location
$label.Size = New-Object System.Drawing.Size(280,20) #Label Size
$label.Text = 'Scan your Card:'
$form.Controls.Add($label)
$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Point(270,320) #Textbox Location
$textBox.Size = New-Object System.Drawing.Size(260,20) #Textbox Size
# add a TextChanged event handler to toggle the OK button's Enabled status
$textBox.Add_TextChanged({
$okButton.Enabled = (![string]::IsNullOrWhiteSpace($this.Text))
})
$form.Controls.Add($textBox)
$form.Topmost = $true
$form.Add_Shown({$textBox.Select()})
$result = $form.ShowDialog()
# Important, remove the form from memory when done
$form.Dispose()
I'm not really sure what you mean with the third question though: "Am I able to do the same for the message box so it can be styled?"
Since you're using a System.Windows.MessageBox, there is nothing you can do about its default appearance, since A message box is a prefabricated modal dialog box that displays a text message to a user.
If you want a self-styled messagebox, you'll have to create one yourself.

Powershell Form With Two Text Inputs and drop down selection

I'm very rusty in the area of powershell and trying to pick it back up but I have something bothering me that I can't seem to figure out. I've created a form that has two text inputs for file locations and a drop down list. What I'm attempting to do is compare the two files received in a text input. I've got the script already for the compare but what I'm trying to figure out is how I distinguish the script to be run from the selection of the drop down list and also parse the two text inputs from the form to the relevant compare script. Below is the generic form created. Any help would be much appreciated.
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Windows.Forms.Application]::EnableVisualStyles()
$Form = New-Object system.Windows.Forms.Form
$Form.Size = New-Object System.Drawing.Size(700,700)
#You can use the below method as well
#$Form.Width = 400
#$Form.Height = 200
$form.MaximizeBox = $false
$Form.StartPosition = "CenterScreen"
$Form.FormBorderStyle = 'Fixed3D'
$Form.Text = "IAM Application Comparison Tool"
#application Drop down list
$Label = New-Object System.Windows.Forms.Label
$Label.Text = "Please select the application being compared"
$Label.AutoSize = $true
$Label.Location = New-Object System.Drawing.Size(10,10)
$Font = New-Object System.Drawing.Font("Arial",15,[System.Drawing.FontStyle]::Bold)
$form.Font = $Font
$Form.Controls.Add($Label)
#list of applications
$listBox = New-Object System.Windows.Forms.ListBox
$listBox.Location = New-Object System.Drawing.Point(10,50)
$listBox.Size = New-Object System.Drawing.Size(260,20)
$listBox.Height = 80
[void] $listBox.Items.Add('Terradata')
[void] $listBox.Items.Add('')
[void] $listBox.Items.Add('')
[void] $listBox.Items.Add('')
[void] $listBox.Items.Add('')
[void] $listBox.Items.Add('')
[void] $listBox.Items.Add('')
$form.Controls.Add($listBox)
#File path of previous months file
$Label = New-Object System.Windows.Forms.Label
$Label.Text = "Enter file path of previous months file"
$Label.AutoSize = $true
$Label.Location = New-Object System.Drawing.Size(20,200)
$Font = New-Object System.Drawing.Font("Arial",15,[System.Drawing.FontStyle]::Bold)
$form.Font = $Font
$Form.Controls.Add($Label)
#Input file path
$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Point(20,300)
$textBox.Size = New-Object System.Drawing.Size(450,20)
$form.Controls.Add($textBox)
#$formIcon = New-Object system.drawing.icon ("$env:USERPROFILE\desktop\Blog\v.ico")
#$form.Icon = $formicon
#File path of current month
$Label = New-Object System.Windows.Forms.Label
$Label.Text = "Enter file path of current months file"
$Label.AutoSize = $true
$Label.Location = New-Object System.Drawing.Size(20,400)
$Font = New-Object System.Drawing.Font("Arial",15,[System.Drawing.FontStyle]::Bold)
$form.Font = $Font
$Form.Controls.Add($Label)
#Input file path
$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Point(20,500)
$textBox.Size = New-Object System.Drawing.Size(450,20)
$form.Controls.Add($textBox)
#Run Required Compare script
$Okbutton = New-Object System.Windows.Forms.Button
$Okbutton.Location = New-Object System.Drawing.Size(170,600)
$Okbutton.Size = New-Object System.Drawing.Size(200,30)
$Okbutton.Text = "Compare Files"
$Okbutton.Add_Click()
$Form.Controls.Add($Okbutton)
$Form.ShowDialog()
Create a function that will run whenever the button is clicked.
for instance, your button event will be:
$Okbutton.Add_Click({ BtnClick })
then add the function that will do the compare, whenever the button is clicked the function will be called:
function BtnClick{
# do something / compare your texts
#compare $TextBox1.Text $TextBox2.Text
}
you have to give a different variable name for each textbox, this how you'll be able to access the values:
$input1 = $TextBox1.Text
$input2 = $TextBox2.Text
$input3 = $ComboBox1.Text
The easiest way to have your code distinguish between the different objects is to name them upon creation, so use different variable names for the textboxes and the like.
To act on the button click, you already started by writing $Okbutton.Add_Click(), but since there is no scriptblock to actually do something there, nothing would happen.
The listbox can also react on an event, in this case that would be the SelectedIndexChanged event.
Please see the revised code below that shows how to implement these event handlers
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
[void] [System.Windows.Forms.Application]::EnableVisualStyles()
$Form = New-Object system.Windows.Forms.Form
$Form.Size = New-Object System.Drawing.Size(700,700)
$Form.MaximizeBox = $false
$Form.StartPosition = "CenterScreen"
$Form.FormBorderStyle = 'Fixed3D'
$Form.Text = "IAM Application Comparison Tool"
$Font = New-Object System.Drawing.Font("Arial",15,[System.Drawing.FontStyle]::Bold)
$Form.Font = $Font
#application Drop down list
$LabelDropDown = New-Object System.Windows.Forms.Label
$LabelDropDown.Text = "Please select the application being compared"
$LabelDropDown.AutoSize = $true
$LabelDropDown.Location = New-Object System.Drawing.Size(10,10)
$Form.Controls.Add($LabelDropDown)
# list of applications
$listBox = New-Object System.Windows.Forms.ListBox
$listBox.Location = New-Object System.Drawing.Point(10,50)
$listBox.Size = New-Object System.Drawing.Size(260,20)
$listBox.Height = 80
# add the items to the listbox
$null = $listBox.Items.AddRange(#('Terradata','SomeApp','MyApp','ThirdPartyApp'))
# set the current selected item to be the first
$listBox.SelectedIndex = 0
# add functionality to react on index changed
$listBox.Add_SelectedIndexChanged({
# do something when the user chose a different app in the listbox
# for demo, just write the currently selected item in the console
Write-Host "Currently selected app in the listbox: $($this.SelectedItem)"
})
$Form.Controls.Add($listBox)
# File path of previous months file
$LabelPrevious = New-Object System.Windows.Forms.Label
$LabelPrevious.Text = "Enter file path of previous months file"
$LabelPrevious.AutoSize = $true
$LabelPrevious.Location = New-Object System.Drawing.Size(20,200)
$Form.Controls.Add($LabelPrevious)
# first Input file path
$textBoxFile1 = New-Object System.Windows.Forms.TextBox
$textBoxFile1.Location = New-Object System.Drawing.Point(20,300)
$textBoxFile1.Size = New-Object System.Drawing.Size(450,20)
$Form.Controls.Add($textBoxFile1)
# File path of current month
$LabelCurrent = New-Object System.Windows.Forms.Label
$LabelCurrent.Text = "Enter file path of current months file"
$LabelCurrent.AutoSize = $true
$LabelCurrent.Location = New-Object System.Drawing.Size(20,400)
$Form.Controls.Add($LabelCurrent)
# second Input file path
$textBoxFile2 = New-Object System.Windows.Forms.TextBox
$textBoxFile2.Location = New-Object System.Drawing.Point(20,500)
$textBoxFile2.Size = New-Object System.Drawing.Size(450,20)
$Form.Controls.Add($textBoxFile2)
# Run Required Compare script
$Okbutton = New-Object System.Windows.Forms.Button
$Okbutton.Location = New-Object System.Drawing.Size(170,600)
$Okbutton.Size = New-Object System.Drawing.Size(200,30)
$Okbutton.Text = "Compare Files"
# add functionality for comparing files
$Okbutton.Add_Click({
# your compare function comparing the file in $textbox1 against the file in $textbox2
# IF both fields contain a valid file path and name of course ;)
# for demo just output in console
Write-Host "Compare file '$($textBoxFile1.Text)' to '$($textBoxFile2.Text)'"
})
$Form.Controls.Add($Okbutton)
$Form.ShowDialog()
# important! dispose of the form when done
$Form.Dispose()
P.S. Inside the scriptblocks for the Click and the SelectedIndexChanged events, you can use automatic variable $this, which refers to the current form control object.

How to have multiple input fields in the same input box

I would like to have a tech enter in the username and the group name but in one input box. Anyone willing to tell me how to do this?
Function add-togroup{
#Adds members to group in AD
#$users = Read-Host "Enter a username"
Add-Type -AssemblyName Microsoft.VisualBasic;
$value = [Microsoft.VisualBasic.Interaction]::InputBox('Enter username',
'Username')
$value2 = [Microsoft.VisualBasic.Interaction]::InputBox('Enter group
name', 'XA Group','')
$group_membership = Get-ADPrincipalGroupMembership $users | select name |
format-table -auto
foreach($u in $value)
{
Add-ADGroupMember $value2 -Members $u
}
Write-Host $group_membership
}
So I am capable of using multiple dialogs in sequence but it would make for a better user experience if I could roll this into one single box /form.
If you are not satisfied with the basic forms available then one option you have is to roll your own in PowerShell with .Net forms. Just to show an example that you can build from...
[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" -or $_.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({$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)
$objTextBox2 = New-Object System.Windows.Forms.TextBox
$objTextBox2.Location = New-Object System.Drawing.Size(10,70)
$objTextBox2.Size = New-Object System.Drawing.Size(260,20)
$objForm.Controls.Add($objTextBox2)
$objForm.Topmost = $True
$objForm.Add_Shown({$objForm.Activate()})
[void]$objForm.ShowDialog()
$objTextBox.Text
$objTextBox2.Text
The borrows heavily from the great primer on the subject on TechNet which you should read as it walks you though this better. I removed some of the variable population logic as it was flawed and added another text box. The last two lines return the values entered by the "user". Aside from the addition of the text box I have left most other cosmetic changes up to you to help you get a better understanding of what is involved here.
Keep in mind the locations and sizes of newly added objects and be sure you actually add it to the form.
Since there is not GUI for form building it can seem daunting but its not really that hard to do. You just need to experiment. If you are so inclined there are 3rd party tools that will help with that.

Assign keyboard shortcuts to buttons in Powershell script

What I would like to do is to assign a button to a shortcut key, for example $TurnOnButton as key "Q", and $TurnOffButton as key "W" on my keyboard.
So basically, in my example below. When the script is running and the form is present, I would be able to push button "Q" on my keyboard to run calculator, and press button "W" to terminate it.
Is this possible with PowerShell?
Code example:
Add-Type -AssemblyName System.Windows.Forms
function Return-TurnOff
{
$x = Stop-Process -ProcessName calc
$x
}
function Return-TurnOn
{
$x = Start-Process calc
$x
}
$form = New-Object System.Windows.Forms.Form
$form.Text = "Title of the form"
$form.Size = New-Object System.Drawing.Size(300,200)
$form.minimumSize = New-Object System.Drawing.Size(300,200)
$form.maximumSize = New-Object System.Drawing.Size(300,200)
$form.StartPosition = "CenterScreen"
$TurnOffButton = New-Object System.Windows.Forms.Button
$TurnOffButton.Location = New-Object System.Drawing.Point(10,125)
$TurnOffButton.Size = New-Object System.Drawing.Size(55,25)
$TurnOffButton.Text = "Turn Off"
$TurnOffButton.Add_Click({Return-TurnOff})
$form.AcceptButton = $TurnOffButton
$form.Controls.Add($TurnOffButton)
$TurnOnButton = New-Object System.Windows.Forms.Button
$TurnOnButton.Location = New-Object System.Drawing.Point(10,65)
$TurnOnButton.Size = New-Object System.Drawing.Size(55,25)
$TurnOnButton.Text = "Turn On"
$TurnOnButton.Add_Click({Return-TurnOn})
$form.AcceptButton = $TurnOnButton
$form.Controls.Add($TurnOnButton)
$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Point(215,125)
$CancelButton.Size = New-Object System.Drawing.Size(55,25)
$CancelButton.Text = "Cancel"
$CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$form.CancelButton = $CancelButton
$form.Controls.Add($CancelButton)
$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10,15)
$label.Size = New-Object System.Drawing.Size(280,20)
$label.Text = "Label for textbox:"
$form.Controls.Add($label)
$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Point(10,35)
$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 you don't mind having the label on the button contain the letter that corresponds to the button AND pressing the Alt key, then it's very easy, just put an '&' before the letter in the button text you want to be the accelerator:
$TurnOnButton.Text = "Turn O&n"
$TurnOffButton.Text = "Turn O&ff"
would make Alt-N perform Turn On and Alt-F perform Turn Off.
A more complicated solution is to register for keyboard presses, but it will let you handle any keystroke whether or not Alt is pressed. $form|gm -MemberType event key* will show you the events whose name starts with "Key". You can then google for how to handle events from Powershell with WinForms.