I’m experienced with PowerShell but not with GUI development.
I’ve put together a script that reaches out to a JEA PowerShell remote end point on a PDC emulator domain controller, retrieves certain EventLog events, parses them to identify locked out AD accounts and provide details like when account locked and the computer name where the bad password attempts came from.
Now, the task is to put a GUI on that.
I put together a form like
$FormWidth = 800 Add-Type -assembly System.Windows.Forms # Main form $main_form = New-Object System.Windows.Forms.Form $main_form.Text ='View locked-out accounts in xxx AD domain' $main_form.Width = $FormWidth $main_form.Height = 550 $main_form.AutoSize = $true # Messaging Label Element: $MessageLabel = New-Object System.Windows.Forms.Label $MessageLabel.Location = New-Object System.Drawing.Point(10,10) $MessageLabel.MaximumSize = New-Object System.Drawing.Size(($FormWidth-20),0) # Word-Wraps text in Label $MessageLabel.AutoSize = $true $main_form.Controls.Add($MessageLabel) # Irrelevent code removed.. $MessageLabel.Text = "Successfully established remote connection to server $JEAServern
n" $MessageLabel.Text += "Scanning Security Event Logs on $JEAServer for event 4740 (Account Locked-out)n
n" # Irrelevent code removed.. # Scan label: $ScanLabel = New-Object System.Windows.Forms.Label $ScanLabel.Location = New-Object System.Drawing.Point(10,120) $ScanLabel.MaximumSize = New-Object System.Drawing.Size(($FormWidth-20),0) # Word-Wraps text in Label $ScanLabel.AutoSize = $true $main_form.Controls.Add($ScanLabel) $ScanLabel.Text = "$(Get-Date -format 'dd MMMM yyyy hh:mm:ss tt'): Identified the following locked-out user accounts:n
n" # Sample $EventList: $EventList = @( [PSCustomObject]@{User = 'abc'; DC = 'myDC1'; TimeStamp = ((Get-Date).AddMinutes(-5)); SourceComputer = 'xyz'} [PSCustomObject]@{User = 'bcd'; DC = 'myDC1'; TimeStamp = ((Get-Date).AddMinutes(-15)); SourceComputer = 'klm'} ) if ($EventList) { $ScanLabel.Text = "$(Get-Date -format 'dd MMMM yyyy hh:mm:ss tt'): Identified the following locked-out user accounts:n
n" # Present Data in a DataGridView $dataGridView = New-Object System.Windows.Forms.DataGridView $dataGridView.Size= "$($FormWidth-20),300" $dataGridView.Location = "10,160" $dataGridView.AllowUserToAddRows = $false $dataGridView.ColumnCount = 4 $dataGridView.Columns[0].Name = "User" $dataGridView.Columns[1].Name = "DC" $dataGridView.Columns[2].Name = "TimeStamp" $dataGridView.Columns[3].Name = "SourceComputer" foreach ($Event in $EventList) { $dataGridView.Rows.Add($Event.User, $Event.DC, $Event.TimeStamp, $Event.SourceComputer) } $dataGridView.AutoSizeColumnsMode = 10 # https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.datagridviewautosizecolumnsmode $dataGridView.AutoSizeRowsMode = 10 $main_form.Controls.Add($dataGridView) } else { $ScanLabel.Text += "$(Get-Date -format 'dd MMMM yyyy hh:mm:ss tt'): No Locked-out accounts found`n" } $main_form.ShowDialog()
With output similar to:
Question:
- Generally, how do I make an element; such as a label appear on the form without having to wait to the end of the script?
‘$main_form.ShowDialog()’ seems to stop the script from processing further. That’s why I have it all the way at the end.
For example, if I add ‘$main_form.ShowDialog()’ at line 24, I will have to close the form interactively for the script to proceed…