powershell combobox items to variable - winforms

I am trying to create a powershell Script with a Gui that gives the user a drop list of available drives and then when the user selects the drive and clicks ok the script maps that drive as M:\
But I cant work out how to get the selected item in the combo box to be passed into the variable $MapDrive
#List of Drives To Map
$DriveList = #("0. DGL_Data","1. P1","2. DGLFSG3","3. p3 (TPC)","4. p4","6. p6","7. p7","8. p8","9. p9","10. p10","11. p11","12. p12")
#Displays With Drive to Map
$MapDrive = convert.ToString($Dropdown.SelectedItem)
Function MapDrive {
If ($MapDrive -eq $DriveList[0]){
Write-Output Sucess > "C:\Users\andy.burton\Desktop\Practice Selector\Success.txt"}
ElseIf ($MapDrive -eq $DriveList[1]){
Write-Output BooYah > "C:\Users\andy.burton\Desktop\Practice Selector\Yes.txt"
}
Else {
Write-Output Failure > "C:\Users\andy.burton\Desktop\Practice Selector\Failed.txt"}
}
#test Function
Function test {
Write-Output $MapDrive > "C:\Users\andy.burton\Desktop\Practice Selector\Success.txt"
}
#Function to Create Form
Function GenerateForm {
#Define Drive Selector Main Form
Add-Type -AssemblyName System.Windows.Forms
$DGL = New-Object system.Windows.Forms.Form
$DGL.Text = "DGL Practice Manager"
$DGL.TopMost = $true
$DGL.BackgroundImage = [system.drawing.image]::FromFile("C:\Users\andy.burton\Desktop\Practice Selector\Images\medical.jpg")
$DGL.Icon = New-Object system.drawing.icon("C:\Users\andy.burton\Desktop\Practice Selector\Images\medical2.ico")
$DGL.Width = 600
$DGL.Height = 265
$DGL.MinimizeBox = $False
$DGL.MaximizeBox = $False
#Label to Display Instuctions
$label2 = New-Object system.windows.Forms.Label
$label2.Text = "Select which drive"
$label2.BackColor = "#e4f3fa"
$label2.AutoSize = $true
$label2.Width = 25
$label2.Height = 10
$label2.location = new-object system.drawing.point(20,28)
$label2.Font = "Microsoft Sans Serif,10"
$DGL.controls.Add($label2)
#Dropdown Box For Selecting Practice
$Dropdown = New-Object system.windows.Forms.ComboBox
$Dropdown.BackColor = "#e4f3fa"
$DropDown.DropDownStyle = [System.Windows.Forms.ComboBoxStyle]::DropDownList
$Dropdown.Width = 243
$Dropdown.Height = 20
$Dropdown.location = new-object system.drawing.point(21,73)
$Dropdown.Font = "Microsoft Sans Serif,10"
$DropDown.items.addrange($DriveList)
$DGL.controls.Add($Dropdown)
#Cancel Button to Cancel drive Selection
$Cancelbutton = New-Object system.windows.Forms.Button
$Cancelbutton.Text = "Cancel"
$Cancelbutton.Width = 60
$Cancelbutton.Height = 30
$Cancelbutton.location = new-object system.drawing.point(210,120)
$Cancelbutton.Font = "Microsoft Sans Serif,10"
$DGL.CancelButton = $Cancelbutton
$CancelButton.Add_Click({ $DGL.close();[System.Windows.Forms.Application]::Exit($null)})
$DGL.controls.Add($Cancelbutton)
#OK Button to Select Drive
$OKbutton = New-Object system.windows.Forms.Button
$OKbutton.Text = "OK"
$OKbutton.Width = 60
$OKbutton.Height = 30
$OKbutton.location = new-object system.drawing.point(140,120)
$OKbutton.Font = "Microsoft Sans Serif,10"
$DGL.AcceptButton = $OKbutton
$MapDrive = convert.ToString($Dropdown.SelectedItem)
#On click call PracticeSelectedCallBack to launch the application
$OKbutton.Add_Click({test ; $DGL.close()})
$DGL.controls.Add($OKbutton)
#Display the Form
$DGL.Add_Shown({$DGL.Activate()})
$DGL.ShowDialog()
}
GenerateForm
I also want to hide the powershell window but not the gui I have tried -window hidden but that hid everything

The ComboBox has several events that you can tie into that will do various things. One of the events is a SelectedIndexChanged. You can add that event to your ComboBox object and update $MapDrive
This code $MapDrive = convert.ToString($Dropdown.SelectedItem) will only fire once during the initial compile. You have to use events to trigger code changes after compile during runtime.
Also, in Powershell you can use the following command [System.Windows.Forms.ComboBox] | gm to get a list of the methods, and properties of the object. You can use [System.Windows.Forms.checkedlistbox].GetEvents() to get a list of events of an object.

Related

Unable to process powershell function with content from windows form

function CalendarShare {
Add-MailboxFolderPermission -Identity ${FromUser.Text} -AccessRights Editor -User ${ToUser.Text}
}
When the program is running, it works until it processes the share calendar button. It states that it
cannot bind the argument parameter identity because it is null.
I have no idea what can cause this
Full code:
Add-Type -AssemblyNAme System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
#Declare Functions
function login {
$LiveCred = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $LiveCred -Authentication Basic -AllowRedirection
Import-PSSession $Session
$btnlogin.Visible = $False
}
function quitprogram {
$Form.Close()
Exit-PSSession []
}
function CalendarShare {
Add-MailboxFolderPermission -Identity ${FromUser.Text} -AccessRights Editor -User ${ToUser.Text}
}
#Creates base form
$Form = New-Object system.Windows.Forms.Form
$Form.ClientSize = '400,400'
$Form.Text = 'Powershell GUI'
$Form.TopMost = $False
#Creates Login button
$btnlogin = New-Object System.windows.Forms.button
$btnlogin.text = 'Login'
$btnlogin.width = 80
$btnlogin.height = 40
$btnlogin.location = New-Object System.Drawing.Point(150,5)
#Add_Click defines what to do on click
$btnlogin.Add_Click( {
login #function previously defined. Line 6
})
#Creates label for From user
$FromUserLabel = New-Object system.Windows.Forms.Label
$FromUserLabel.text = 'Share Calendar From User'
$FromUserLabel.AutoSize = $true
$FromUserLabel.width = 25
$FromUserLabel.height = 10
$FromUserLabel.location = New-Object System.Drawing.Point(130,100) #Define where it appears on the map
#Create first input. From User
$FromUser = New-Object system.Windows.Forms.TextBox
$FromUser.multiline = $False
$FromUser.width - 200
$FromUser.height = 20
$FromUser.location = New-Object System.Drawing.Point(135,125)
#Create label for To user
$ToUserLabel = New-Object system.Windows.Forms.Label
$ToUserLabel.text = 'Share Calendar To User'
$ToUserLabel.AutoSize = $True
$ToUserLabel.width = 25
$ToUserLabel.height = 10
$ToUserLabel.location = New-Object System.Drawing.Point(135,175)
#Create second input. To User
$ToUser = New-Object system.Windows.Forms.TextBox
$ToUser.multiline = $False
$ToUser.width - 200
$ToUser.height = 20
$ToUser.location = New-Object System.Drawing.Point(135,200)
#Create Share Button Calendar
$btnsharecalendar = New-Object System.windows.Forms.button
$btnsharecalendar.text = 'Share Calendar'
$btnsharecalendar.width = 165
$btnsharecalendar.height = 30
$btnsharecalendar.location = New-Object System.Drawing.Point(105,275)
#Define Add_Click below
$btnsharecalendar.Add_Click({
CalendarShare
})
#Create button to close program
$btnquit = New-Object System.windows.Forms.button
$btnquit.text = 'Quit'
$btnquit.width = 80
$btnquit.height = 40
$btnquit.location = New-Object System.Drawing.Point(150,325)
#Add_Click defines what to do on click
$btnquit.Add_Click( {
quitprogram #function previously defined. Line 12
})
#Allows form to work
$Form.Controls.AddRange(#($btnlogin,$FromUserLabel,$FromUser,$ToUserLabel,$ToUser,$btnsharecalendar,$btnquit))
$Form.ShowDialog()
Note: This is assuming that both $FromUser and $ToUser are textboxes
You aren't using your variable correctly for the identity parameter, should be:
function CalendarShare {
Add-MailboxFolderPermission -Identity $FromUser.Text -AccessRights Editor -User $ToUser.Text}
}

How can i lock a form in position on the desktop?

I'm trying to make a form in PowerShell that gets locked to a fixed position on the desktop.
Because whenever I press the "Show Desktop" button on the bottom right corner on Win 8.1, the form disappears until I open a different window and close it.
I just want it there like it's a widget, here's a part of the code i'm using:
Add-Type -AssemblyName System.Windows.Forms
Add-Type -Assembly System.Drawing
$Image = [System.Drawing.Image]::Fromfile("Panel.png")
$Form = New-Object system.Windows.Forms.Form
$Form.BackgroundImage = $Image
$Form.BackgroundImageLayout = "None"
$Form.Text = "Reboot Server"
$Form.Width = 517
$Form.Height = 134
$Form.ControlBox = $False
$Form.StartPosition = 'Manual'
$Form.Location = "1390, 300"
$Form.FormBorderStyle = 'None'
$Form.BackColor = "#000000"
$Form.MaximizeBox = $False
$Form.MinimizeBox = $False
$Form.Icon = "icon.ico"
$Form.Image = [System.Drawing.Image]::Fromfile("Panel.png")
$Form.ShowInTaskbar = $False
$Font = New-Object System.Drawing.Font("Tahoma",10, [System.Drawing.FontStyle]::Bold)
$Form.Font = $Font
$Label = New-Object System.Windows.Forms.Label
$Label.Text = ""
$Label.AutoSize = $True
$Form.Controls.Add($Label)
' Button 1 - Reboot Server'
$Button1 = new-object System.Windows.Forms.Button
$Button1.Location = new-object System.Drawing.Size(234,51)
$Button1.Size = new-object System.Drawing.Size(77,55)
$Button1.AutoSize = $True
$Button1.Add_Click({start-process "Reboot.lnk"})
$Button1.FlatStyle = [System.Windows.Forms.FlatStyle]::Flat
$Button1.FlatAppearance.BorderSize=0
$Button1.BackColor = "Transparent"
$Button1.ForeColor = "Transparent"
$Button1.FlatAppearance.MouseDownBackColor = "Transparent"
$Button1.FlatAppearance.MouseOverBackColor = "Transparent"
$Button1.FlatAppearance.BorderColor = "#252525"
$Form.Controls.Add($Button1)
'----------------------------------------
$Form.ShowDialog() | Out-Null
Exit 0
For gadget style positions try to use a little snippet that I have made:
$Poistion = 'RightBottom'
$Coordinates = switch ($Poistion)
{
'LeftTop' { 0, 0 }
'LeftBottom' { 0, $([System.Windows.Forms.Screen]::PrimaryScreen.WorkingArea.Bottom - $Form.Height) }
'RightTop' { $([System.Windows.Forms.Screen]::PrimaryScreen.WorkingArea.Width - $Form.Width), 0 }
'RightBottom' { $([System.Windows.Forms.Screen]::PrimaryScreen.WorkingArea.Width - $Form.Width), $([System.Windows.Forms.Screen]::PrimaryScreen.WorkingArea.Bottom - $Form.Height) }
}
$Form.Location = New-Object System.Drawing.Point($Coordinates)
To keep your form up at the time when you activate "Show Desktop" set TopMost property to $True and MinimizeBox property to $False. Like so:
$Form.TopMost = $True
$Form.MinimizeBox = $False
When you click on Show Desktop or use its hotkey (Win+D) windows tries to send Minimize All command to running applications. After minimizing all the windows that can be minimized, it then takes the desktop and "raises" it to the top of the window stack so that no other windows cover it.
You could also try to use sizing events. Like so:
$Form_Resize={
$Form.WindowState = 'Normal'
}
$Form.add_Resize($Form_Resize)

Make Entire Borderless Form Draggable from Certain Object

I have a borderless winform (WPF is not an option) that I am trying to make draggable from an object that is serving as a custom sidebar. I have searched around and found some things that allow me to drag the sidebar within the form, but I need to be able to move $Form with the sidebar. Any thoughts? It seems like I will need to use Add-Type with some C# here.
Ok, since we don't have the code to your form, here's a demo for you. It is just a not-pretty borderless form that uses a label to demonstrate the various events needed to drag the entire form around. (in your case this would be the sidebar)
Add-Type -AssemblyName System.Windows.Forms
# set up some globals for dragging
$global:dragging = $false
$global:mouseDragX = 0
$global:mouseDragY = 0
#Form
$form = New-Object System.Windows.Forms.Form
$form.FormBorderStyle = "None"
$form.Font = New-Object System.Drawing.Font("Microsoft Sans Serif", 9.0, [System.Drawing.FontStyle]::Regular, [System.Drawing.GraphicsUnit]::Point)
$form.MinimumSize = New-Object System.Drawing.Size(456, 547)
$form.AutoScaleDimensions = New-Object System.Drawing.SizeF(7.0, 15.0)
$form.AutoScaleMode = [System.Windows.Forms.AutoScaleMode]::Font
$form.ClientSize = New-Object System.Drawing.Size(440, 509)
$form.ShowIcon = $false
$form.StartPosition = "CenterScreen"
$form.TopMost = $true
#lblDrag (this is the object used for dragging the form)
$lblDrag = New-Object System.Windows.Forms.Label
$lblDrag.Name = "lblDrag"
$lblDrag.BackColor = [System.Drawing.Color]::LightYellow
$lblDrag.Location = New-Object System.Drawing.Point(172, 226)
$lblDrag.Size = New-Object System.Drawing.Size(117, 27)
$lblDrag.Anchor = "Top","Right"
$lblDrag.BorderStyle = "FixedSingle"
$lblDrag.Text = "Drag form.."
$lblDrag.TextAlign = [System.Drawing.ContentAlignment]::MiddleCenter
# set the 'dragging' flag and capture the current mouse position
$lblDrag.Add_MouseDown( { $global:dragging = $true
$global:mouseDragX = [System.Windows.Forms.Cursor]::Position.X - $form.Left
$global:mouseDragY = [System.Windows.Forms.Cursor]::Position.Y -$form.Top
})
# move the form while the mouse is depressed (i.e. $global:dragging -eq $true)
$lblDrag.Add_MouseMove( { if($global:dragging) {
$screen = [System.Windows.Forms.Screen]::PrimaryScreen.WorkingArea
$currentX = [System.Windows.Forms.Cursor]::Position.X
$currentY = [System.Windows.Forms.Cursor]::Position.Y
[int]$newX = [Math]::Min($currentX - $global:mouseDragX, $screen.Right - $form.Width)
[int]$newY = [Math]::Min($currentY - $global:mouseDragY, $screen.Bottom - $form.Height)
$form.Location = New-Object System.Drawing.Point($newX, $newY)
}})
# stop dragging the form
$lblDrag.Add_MouseUp( { $global:dragging = $false })
# add a button so you will be able to close the form
$btnClose = New-Object System.Windows.Forms.Button
$btnClose.Name = "btnClose"
$btnClose.Anchor = "Top","Right"
$btnClose.Location = New-Object System.Drawing.Point(172, 454)
$btnClose.Size = New-Object System.Drawing.Size(117, 27)
$btnClose.Text = "&Close"
$btnClose.UseVisualStyleBackColor = $true
$btnClose.UseMnemonic = $true
$btnClose.DialogResult = [System.Windows.Forms.DialogResult]::OK
# add controls to the form
$form.Controls.Add($btnClose)
$form.Controls.Add($lblDrag)
$form.AcceptButton = $btnClose
# show the form and play around with the dragging label
$form.ShowDialog()
# when done, dispose of the form
$form.Dispose()

Invoking a scriptblock when clicking a radio button

I want my GUI to be able to dynamically produce an event based on the user clicking either Radio Button 1 or Radio Button 2.
I have seen some good tutorials on this but its called during a click on a button. I want to call it OnClick of the radio button.
Here is the code I have so far:
#Load Assemblies
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") | Out-Null
$net = New-Object -ComObject Wscript.Network
Add-Type -AssemblyName System.Windows.Forms
#Create the Form
#Draw form
function SQLDoTasks{
$Form = New-Object System.Windows.Forms.Form
$Form.width = 800
$Form.height = 600
$Form.BackColor = "lightblue"
$Form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::Fixed3D
$Form.Text = "Daily DBA Tasks"
$Form.maximumsize = New-Object System.Drawing.Size(525,350)
$Form.startposition = "centerscreen"
$Form.KeyPreview = $True
$Form.Add_KeyDown({if ($_.KeyCode -eq "Enter") {}})
$Form.Add_KeyDown({if ($_.KeyCode -eq "Escape")
{$Form.Close()}})
# Create a group that will contain your radio buttons
$MyGroupBox = New-Object System.Windows.Forms.GroupBox
$MyGroupBox.Location = '40,30'
$MyGroupBox.size = '400,150'
$MyGroupBox.text = "Specify the Sql environment?"
#Declare option buttons to allow user to select Dev or System Test
$RadioButton1 = New-Object System.Windows.Forms.RadioButton #create the radio button
$RadioButton1.Location = '20,40'
$RadioButton1.size = '350,20'
$RadioButton1.Checked = $false #is checked by default
$RadioButton1.Text = "Dev" #labeling the radio button
$RadioButton1.Checked($event)
#Declare option buttons to allow user to select Dev OR System Test
$RadioButton2 = New-Object System.Windows.Forms.RadioButton #create the radio button
$RadioButton2.Location = '20,70'
$RadioButton2.size = '350,20'
#$RadioButton2.Location = new-object System.Drawing.Point(10,40) #location of the radio button(px) in relation to the group box's edges (length, height)
#$RadioButton2.size = New-Object System.Drawing.Size(80,20) #the size in px of the radio button (length, height)
$RadioButton2.Checked = $false #is checked by default
$RadioButton2.Text = "System test" #labeling the radio button
$RadioButton2.Checked($event)
$event={
if ($RadioButton1.Checked){
[System.Windows.Forms.MessageBox]::Show("You select Dev")}
elseif ($RadioButton2.Checked){
[System.Windows.Forms.MessageBox]::Show("You Selected System Test")}
}
#Create List Box
$ListBox1 = New-Object System.Windows.Forms.ListBox
$ListBox1.Location = New-Object System.Drawing.Size(20,200)
$ListBox1.Size = New-Object System.Drawing.Size(260,20)
$ListBox1.Height = 80
#POPULATE WHAT IT WILL HOLD
$Servers = get-content -path "xxxx.csv"
write-host $Servers
ForEach ($Server in $Servers){
#$NL = "`r`n"
[void] $ListBox1.Items.Add($Server)
}
#Create the Form
# Add all the GroupBox controls on one line
$Form.Controls.Add($ListBox1)
$form.Controls.AddRange(#($MyGroupBox))
$MyGroupBox.Controls.AddRange(#($Radiobutton1,$RadioButton2))
$Form.Add_Shown({$Form.Activate()})
$dialogResult =$Form.ShowDialog()
}
SQLDoTasks
First, you have to declare the $event scriptblock before you add the event handler. So I would define both buttons, then the scriptblock and then add the handlers. Also, you probably should use the Add_Click callback:
#....
$RadioButton2 = New-Object System.Windows.Forms.RadioButton #create the radio button
$RadioButton2.Location = '20,70'
$RadioButton2.size = '350,20'
#$RadioButton2.Location = new-object System.Drawing.Point(10,40) #location of the radio button(px) in relation to the group box's edges (length, height)
#$RadioButton2.size = New-Object System.Drawing.Size(80,20) #the size in px of the radio button (length, height)
$RadioButton2.Checked = $false #is checked by default
$RadioButton2.Text = "System test" #labeling the radio button
$event={
if ($RadioButton1.Checked){
[System.Windows.Forms.MessageBox]::Show("You select Dev")}
elseif ($RadioButton2.Checked){
[System.Windows.Forms.MessageBox]::Show("You Selected System Test")}
}
$RadioButton1.Add_Click($event)
$RadioButton2.Add_Click($event)

Transfering file chosen text in Browse Dialog box to the Text Input field in Powershell

Trying for the first time a custom dialog box in Powershell v3. I wanted to add a browse button to the form. I have it so it shows the browse button but I cant seem to figure out the part where we take the file name from the OpenFileDialog object and get it to appear in the objTextBox field. I've researched but cant seem to find any article that explains this part of the process.
$objTextBox = New-Object System.Windows.Forms.TextBox
$objTextBox.Name = 'Text1'
$objTextBox.Location = New-Object System.Drawing.Size(10,40)
$objTextBox.Size = New-Object System.Drawing.Size(260,20)
$objForm.Controls.Add($objTextBox)
#File Browser Code.
$FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property #{
InitialDirectory = [Environment]::GetFolderPath('Desktop')
}
$browse_button = New-Object system.Windows.Forms.Button
$browse_button.Text = "Choose...."
$browse_button.Location = New-Object System.Drawing.Size(10,75)
$browse_button.Size = New-Object System.Drawing.Size(100,27)
$browse_button.Add_Click({[void]$FileBrowser.ShowDialog()})
$objForm.Controls.Add($browse_button)
I think I would approach it slightly differently. I'd make a function (which I just happen to keep on hand) that displays the Browse Files dialog, and outputs a string. Then for the Add_Click set the textbox's value = the function. Something like:
Function Get-FilePath{
[CmdletBinding()]
Param(
[String]$Filter = "|*.*",
[String]$InitialDirectory = "C:\")
[void][System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")
$OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
$OpenFileDialog.initialDirectory = $InitialDirectory
$OpenFileDialog.filter = $Filter
[void]$OpenFileDialog.ShowDialog()
$OpenFileDialog.filename
}
$objTextBox = New-Object System.Windows.Forms.TextBox
$objTextBox.Name = 'Text1'
$objTextBox.Location = New-Object System.Drawing.Size(10,40)
$objTextBox.Size = New-Object System.Drawing.Size(260,20)
$objForm.Controls.Add($objTextBox)
$browse_button = New-Object system.Windows.Forms.Button
$browse_button.Text = "Choose...."
$browse_button.Location = New-Object System.Drawing.Size(10,75)
$browse_button.Size = New-Object System.Drawing.Size(100,27)
$browse_button.Add_Click({$objTextBox.Text = Get-FilePath -InitialDirectory "$env:UserProfile\Desktop"})
$objForm.Controls.Add($browse_button)
$browse_button.Text = "Choose...."
$browse_button.Location = New-Object System.Drawing.Size(10,75)
$browse_button.Size = New-Object System.Drawing.Size(100,27)
$browse_button.Add_Click({[void]$FileBrowser.ShowDialog()})
$objForm.Controls.Add($browse_button)

Resources