WinForms - Multiple Forms - Office 365 PS Session

I’ve purchased Powershell Pro Tools and I am currently using it to develop in Visual Studio with WinForms but I am not sure how to make my application multi-form and have my Office 365 remote session cross over to the new form and back again - any help would be appreciated. Thanks.

Here’s a walk through of how to accomplish this.

First, create your main form. I put three buttons. One “connects” and the other two open additional form windows. You can set variables within any event handler since all the forms will share the same runspace. I setup click event handlers to execute when each button is clicked.

My form looks like this.

image

The form1.ps1 contains this code.

$Connect = {
    # This is where you can connect to your O365 session
    $Global:SessionId = [Guid]::NewGuid()
    [System.Windows.Forms.MessageBox]::Show("You are connected! Session ID: $SessionId")
}
$OpenFormX = {
    # Open Form X
    & (Join-Path $PSScriptRoot 'formx.ps1')
}
$OpenFormY = {
    # Open Form Y
    & (Join-Path $PSScriptRoot 'formy.ps1')
}
Add-Type -AssemblyName System.Windows.Forms
. (Join-Path $PSScriptRoot 'form1.designer.ps1')
$Form1.ShowDialog()

The designer code is here.

$Form1 = New-Object -TypeName System.Windows.Forms.Form
[System.Windows.Forms.Button]$Button1 = $null
[System.Windows.Forms.Button]$Button2 = $null
[System.Windows.Forms.Button]$Button3 = $null
function InitializeComponent
{
$Button1 = (New-Object -TypeName System.Windows.Forms.Button)
$Button2 = (New-Object -TypeName System.Windows.Forms.Button)
$Button3 = (New-Object -TypeName System.Windows.Forms.Button)
$Form1.SuspendLayout()
#
#Button1
#
$Button1.Location = (New-Object -TypeName System.Drawing.Point -ArgumentList @([System.Int32]12,[System.Int32]200))
$Button1.Name = [System.String]'Button1'
$Button1.Size = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]70,[System.Int32]49))
$Button1.TabIndex = [System.Int32]0
$Button1.Text = [System.String]'Connect'
$Button1.UseCompatibleTextRendering = $true
$Button1.UseVisualStyleBackColor = $true
$Button1.add_Click($Connect)
#
#Button2
#
$Button2.Location = (New-Object -TypeName System.Drawing.Point -ArgumentList @([System.Int32]88,[System.Int32]200))
$Button2.Name = [System.String]'Button2'
$Button2.Size = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]82,[System.Int32]49))
$Button2.TabIndex = [System.Int32]1
$Button2.Text = [System.String]'Open Form X'
$Button2.UseCompatibleTextRendering = $true
$Button2.UseVisualStyleBackColor = $true
$Button2.add_Click($OpenFormX)
#
#Button3
#
$Button3.Location = (New-Object -TypeName System.Drawing.Point -ArgumentList @([System.Int32]176,[System.Int32]200))
$Button3.Name = [System.String]'Button3'
$Button3.Size = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]96,[System.Int32]49))
$Button3.TabIndex = [System.Int32]2
$Button3.Text = [System.String]'Open Form Y'
$Button3.UseCompatibleTextRendering = $true
$Button3.UseVisualStyleBackColor = $true
$Button3.add_Click($OpenFormY)
#
#Form1
#
$Form1.Controls.Add($Button3)
$Form1.Controls.Add($Button2)
$Form1.Controls.Add($Button1)
$Form1.Text = [System.String]'Form1'
$Form1.ResumeLayout($false)
Add-Member -InputObject $Form1 -Name base -Value $base -MemberType NoteProperty
Add-Member -InputObject $Form1 -Name Button1 -Value $Button1 -MemberType NoteProperty
Add-Member -InputObject $Form1 -Name Button2 -Value $Button2 -MemberType NoteProperty
Add-Member -InputObject $Form1 -Name Button3 -Value $Button3 -MemberType NoteProperty
}
. InitializeComponent

Next, we can create the two forms. They are nearly identical in this example but you can create as many different forms are you like.

formx.ps1 displays the form name and the value of the variable we used in the connect function.

$Load = {
    $txtVariable.Text = "Session ID is: $Global:SessionId"
}
Add-Type -AssemblyName System.Windows.Forms
. (Join-Path $PSScriptRoot 'formx.designer.ps1')
$frmFormX.ShowDialog()

image

The designer code is below.

$frmFormX = New-Object -TypeName System.Windows.Forms.Form
[System.Windows.Forms.Label]$Label1 = $null
[System.Windows.Forms.TextBox]$txtVariable = $null
function InitializeComponent
{
$Label1 = (New-Object -TypeName System.Windows.Forms.Label)
$txtVariable = (New-Object -TypeName System.Windows.Forms.TextBox)
$frmFormX.SuspendLayout()
#
#Label1
#
$Label1.Font = (New-Object -TypeName System.Drawing.Font -ArgumentList @([System.String]'Tahoma',[System.Single]15.75,[System.Drawing.FontStyle]::Regular,[System.Drawing.GraphicsUnit]::Point,([System.Byte][System.Byte]0)))
$Label1.Location = (New-Object -TypeName System.Drawing.Point -ArgumentList @([System.Int32]12,[System.Int32]9))
$Label1.Name = [System.String]'Label1'
$Label1.Size = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]100,[System.Int32]23))
$Label1.TabIndex = [System.Int32]0
$Label1.Text = [System.String]'Form X'
$Label1.UseCompatibleTextRendering = $true
#
#txtVariable
#
$txtVariable.Location = (New-Object -TypeName System.Drawing.Point -ArgumentList @([System.Int32]12,[System.Int32]48))
$txtVariable.Name = [System.String]'txtVariable'
$txtVariable.ReadOnly = $true
$txtVariable.Size = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]316,[System.Int32]21))
$txtVariable.TabIndex = [System.Int32]1
#
#frmFormX
#
$frmFormX.ClientSize = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]340,[System.Int32]83))
$frmFormX.Controls.Add($txtVariable)
$frmFormX.Controls.Add($Label1)
$frmFormX.Text = [System.String]'Form X'
$frmFormX.add_Load($Load)
$frmFormX.ResumeLayout($false)
$frmFormX.PerformLayout()
Add-Member -InputObject $frmFormX -Name base -Value $base -MemberType NoteProperty
Add-Member -InputObject $frmFormX -Name Label1 -Value $Label1 -MemberType NoteProperty
Add-Member -InputObject $frmFormX -Name txtVariable -Value $txtVariable -MemberType NoteProperty
}
. InitializeComponent

Next, you can create formy.ps1. This is almost exactly the same as formx.ps1.

$Load = {
    $txtVariable.Text = "Session ID is: $Global:SessionId"
}
Add-Type -AssemblyName System.Windows.Forms
. (Join-Path $PSScriptRoot 'formy.designer.ps1')
$frmFormY.ShowDialog()

The designer code is also similar.

$frmFormY = New-Object -TypeName System.Windows.Forms.Form
[System.Windows.Forms.Label]$Label1 = $null
[System.Windows.Forms.TextBox]$txtVariable = $null
function InitializeComponent
{
$Label1 = (New-Object -TypeName System.Windows.Forms.Label)
$txtVariable = (New-Object -TypeName System.Windows.Forms.TextBox)
$frmFormY.SuspendLayout()
#
#Label1
#
$Label1.Font = (New-Object -TypeName System.Drawing.Font -ArgumentList @([System.String]'Tahoma',[System.Single]15.75,[System.Drawing.FontStyle]::Regular,[System.Drawing.GraphicsUnit]::Point,([System.Byte][System.Byte]0)))
$Label1.Location = (New-Object -TypeName System.Drawing.Point -ArgumentList @([System.Int32]23,[System.Int32]16))
$Label1.Name = [System.String]'Label1'
$Label1.Size = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]81,[System.Int32]22))
$Label1.TabIndex = [System.Int32]0
$Label1.Text = [System.String]'Form Y'
$Label1.UseCompatibleTextRendering = $true
#
#txtVariable
#
$txtVariable.Location = (New-Object -TypeName System.Drawing.Point -ArgumentList @([System.Int32]23,[System.Int32]46))
$txtVariable.Name = [System.String]'txtVariable'
$txtVariable.ReadOnly = $true
$txtVariable.Size = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]338,[System.Int32]21))
$txtVariable.TabIndex = [System.Int32]1
#
#frmFormY
#
$frmFormY.ClientSize = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]373,[System.Int32]79))
$frmFormY.Controls.Add($txtVariable)
$frmFormY.Controls.Add($Label1)
$frmFormY.Text = [System.String]'Form Y'
$frmFormY.add_Load($Load)
$frmFormY.ResumeLayout($false)
$frmFormY.PerformLayout()
Add-Member -InputObject $frmFormY -Name base -Value $base -MemberType NoteProperty
Add-Member -InputObject $frmFormY -Name Label1 -Value $Label1 -MemberType NoteProperty
Add-Member -InputObject $frmFormY -Name txtVariable -Value $txtVariable -MemberType NoteProperty
}
. InitializeComponent

My resulting file layout looks like this.

image

Here’s the form in action.

multiform

1 Like

Thanks so much Adam :slightly_smiling_face:

1 Like