Using Forms with PowerShell – ITs awesome!

Using forms in PowerShell allows you to run interactive scripts that provide information or prompt for input. Ever need to force everyone to reboot? I know, I know… why on earth would you spend time on that Simon? Well (a) I’m absolutely bonkers… and (b) it’s fun! –ahem, refer to (a).

The main problem with using forms with PowerShell is that the script needs to run in the logged on users context, which prevents us performing any admin tasks. Depending on the requirements you may also need to deploy some PowerShell modules out to the workstations… uuurg that is already sounding OTT!

Well, for that I’ll share another post soon where I took a ‘queue’ approach and split the code to have a workstation-side script that runs in user context, and a server-side script that runs under a service account (assigned whichever admin permissions are required for its tasks). The workstation script gathers required data using forms etc., then writes a csv file into a shared folder on the server. The server script is checking the folder, sees a new file and processes it. Once a successful result is confirmed, the file is deleted. Meanwhile the workstation script has been in a ‘Please wait’ state, checking for the file deletion so it can continue knowing a server-side task is complete. “Coolio Glesias” I hear you say!

Anyway, that’s a longer post for another time! 🙂🙂🙂

This script below will prompt the user to reboot their workstation as soon as possible, with a mandatory reboot countdown visible. The form cannot be closed (unless the user can kill the PowerShell process – block that with a GPO that disables Task Manager and command line access). If the countdown reaches zero, a reboot is forced.

You can use GPO to deploy the script to a folder on each workstation, and also to configure a Scheduled Task for running it. Or in my case I am importing it into an MSP platform so it can be run automatically or on demand when a reboot is pending on client computers.

Aside from what it does (which is nothing fantastic!), it’s good example of using forms in PowerShell. I’ll post about my cross-domain password sync script soon which adds different types of message box as functions. Until then, Hei Konei Ra and have a Merry Xmas!


# displays a non-dismissable warning with countdown in top left of screen
# force the local machine to reboot after $timeinseconds e.g. 28800 seconds = 8 hours.

# update variables as required
# default 8 hour setting
$timeinseconds = 28800

# icon for top-left of forms
$formicon = "$env:SystemRoot\UUS\amd64\WindowsUpdateWarning.ico"

# load the stuff we need for the forms
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

# start the countdown

$Form = New-Object system.Windows.Forms.Form
$Form.Text = "SBEnterprises - Reboot Required"
$Form.Location = New-Object System.Drawing.Point(15,10)
$Form.AutoSize = $true # .Size = New-Object System.Drawing.Size(350,250)
$Form.AutoSizeMode = 'GrowAndShrink'
$Form.ShowInTaskbar = $false
$Form.Icon = New-Object System.Drawing.Icon "$formicon"
$Form.ShowIcon = $true
$Form.Font = New-Object System.Drawing.Font("Segoe UI",10)
$Label = New-Object System.Windows.Forms.Label
$Label.Location = New-Object System.Drawing.Point(5,10)
$Label.AutoSize = $true # .Size = New-Object System.Drawing.Size(350,250)
$Label.TextAlign = 'MiddleCenter'
$Label.UseWaitCursor = $false

While ($timeinseconds -gt 0) {

    $timespan = New-TimeSpan -Seconds $timeinseconds

    $hour = $timespan.Hours
    $min = $timespan.Minutes
    $sec = $timespan.Seconds

    $Label.Text = "WARNING!`nYour workstation requires a reboot to finish installing updates...`nPlease reboot as soon as possible.`n`nA mandatory reboot will occur in $hour hours, $min minutes, $sec seconds.`n`n"
    Start-Sleep -Seconds 1
    $timeinseconds = $timeinseconds - 1 

Restart-Computer -Force

# end