Powershell GUI, define variables per button - powershell

Right now i write an gui for a simple filter script for completnes this is the whole script right now
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$objForm = New-Object System.Windows.Forms.Form
$objForm.StartPosition = "CenterScreen"
$objForm.Size = New-Object System.Drawing.Size(1200,800)
$objForm.Text = "Test GUI"
$form = New-Object System.Windows.Forms.Form
$form.Size = New-Object System.Drawing.Size(900,600)
$dataGridView = New-Object System.Windows.Forms.DataGridView
$dataGridView.Size=New-Object System.Drawing.Size(800,400)
#Filtern
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(30,10)
$OKButton.Size = New-Object System.Drawing.Size(300,92)
$OKButton.Text = "Filtern"
$OKButton.Name = "Filter"
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::None
$OKButton.Add_Click({$i= 0
$path = "C:\temp\smtpfilter\LNS5filter.txt"
$length = (Get-Content $path).Length
#Datum, Hostname und Message Nummer
$result = Get-Content $path | ForEach-Object {
if($_ -match '(\d{2}\.\d{2}\.\d{4} \d{2}:\d{2}:\d{2}).*\(((?:\d{1,3}\.){3}\d{1,3})\) disconnected\.?\s+(\d+) message\[s\]'){
try {
#$dns = [System.Net.Dns]::GetHostEntry($matches[2]).HostName
}
catch {
#$dns = 'Not available'
}
[PsCustomObject]#{
IP = $matches[2]
Messages = [int]$matches[3]
#DNSName = $dns
Date = [datetime]::ParseExact($matches[1], 'dd.MM.yyyy HH:mm:ss', $null)
}}
$i++
if($i % 1000 -eq 0){
Write-Progress -activity "Searching for matches" -status "Scanned: $i of $($length)" -percentComplete (($i / $length) * 100)
}}
Write-Progress -activity "Searching for matches" -status "Scanned: $i of $($length)" -percentComplete (($i / $length) * 100)
#Messages Counted
$cumulative = $result | Group-Object -Property IP | ForEach-Object {
[PsCustomObject]#{
IP = $_.Name
Messages = ($_.Group | Measure-Object -Property Messages -Sum).Sum
#DNSName = $_.Group[0].DNSName
Date = ($_.Group | Sort-Object Date)[-1].Date
}
}})
$objForm.Controls.Add($OKButton)
#Ergebnis Anzeigen
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(30,112)
$OKButton.Size = New-Object System.Drawing.Size(300,92)
$OKButton.Text = "Ergebnis anzeigen"
$OKButton.Name = "Egebnis Button"
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::None
$OKButton.Add_Click({$objTextBox1 = New-Object System.Windows.Forms.TextBox
$objTextBox1.Multiline = $True;
$objTextBox1.Location = New-Object System.Drawing.Size(360,10)
$objTextBox1.Size = New-Object System.Drawing.Size(800,600)
$objTextBox1.Text = $cumulative | Out-String
$objTextBox1.Font = "courier New, 13"
$objTextBox1.Scrollbars = "Vertical"
$objForm.Controls.Add($objTextBox1)
#outgridview
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(30,214)
$OKButton.Size = New-Object System.Drawing.Size(300,92)
$OKButton.Text = "Ergebnis in GridView"
$OKButton.Name = "GridView"
$OKButton.DialogResult = "OK"
$OKButton.Add_Click({$cumulative | Out-GridView})
$objForm.Controls.Add($OKButton)
#Export CSV
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(30,316)
$OKButton.Size = New-Object System.Drawing.Size(300,92)
$OKButton.Text = "Export CSV (in C:/temp)"
$OKButton.Name = "CSV"
$OKButton.DialogResult = "OK"
$OKButton.Add_Click({$cumulative | Export-Csv -Path 'C:\temp\SMTPresult.Csv'})
$objForm.Controls.Add($OKButton) })
$objForm.Controls.Add($OKButton)
[void] $objForm.ShowDialog()
The first $OKButton should basically filter the .txt file which is defined in $path and then in the lower part count the results together, when i press it an progressbar starts in the background in the ISE, but i noticed that there is no result saved in $result or in $cumulative. If it would work than i guess i could display the results with the lower button.
What do i miss here, cant i define varaibles with buttons?

For anyone who might get the same Problem i got the result after trying. The Problem was the scope of both of my variables $result & $cummulative. Since they were created in an Button they also only function in that Button. To use them after i clicked the Button i just had to add $global:
So in the end it looked like
$OKButton.Add_Click({$i= 0
$length = (Get-Content $path).Length
#Datum, Hostname und Message Nummer
$global:result = Get-Content $path | ForEach-Object {
if($_ -match '(\d{2}\.\d{2}\.\d{4} \d{2}:\d{2}:\d{2}).*\(((?:\d{1,3}\.){3}\d{1,3})\) disconnected\.?\s+(\d+) message\[s\]'){
try {
#$dns = [System.Net.Dns]::GetHostEntry($matches[2]).HostName
}
catch {
#$dns = 'Not available'
}
[PsCustomObject]#{
IP = $matches[2]
Messages = [int]$matches[3]
#DNSName = $dns
Date = [datetime]::ParseExact($matches[1], 'dd.MM.yyyy HH:mm:ss', $null)
}}
$i++
if($i % 1000 -eq 0){
Write-Progress -activity "Searching for matches" -status "Scanned: $i of $($length)" -percentComplete (($i / $length) * 100)
}}
Write-Progress -activity "Searching for matches" -status "Scanned: $i of $($length)" -percentComplete (($i / $length) * 100)
#Messages Counted
$global:cumulative = $result | Group-Object -Property IP | ForEach-Object {
[PsCustomObject]#{
IP = $_.Name
Messages = ($_.Group | Measure-Object -Property Messages -Sum).Sum
#DNSName = $_.Group[0].DNSName
Date = ($_.Group | Sort-Object Date)[-1].Date
}
}})
$objForm.Controls.Add($OKButton)

Related

List AD groups, create a CSV

I try to create a form which ask the share name, search depth and output filename and create a CSV file (which will require further processing, but this is not important now).
I have the graphical design and the script, but I cannot merge them to actually work together.
Here is the code:
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
$Form = New-Object System.Windows.Forms.Form
$Form.Text = "Folder Group Details v1.6"
$Form.Size = New-Object System.Drawing.Size(700,400)
$Form.StartPosition = "Manual"
$Form.Location = New-Object System.Drawing.Size(90,90)
$Form.KeyPreview = $True
$Form.MaximumSize = $Form.Size
$Form.MinimumSize = $Form.Size
$Form.MinimizeBox = $True
$Form.MaximizeBox = $False
$Form.WindowState = "Normal"
$Form.SizeGripStyle = "Hide"
$Font = New-Object System.Drawing.Font("Times New Roman",14,[System.Drawing.FontStyle]::Bold)
$Form.Width = $objImage.Width
$Form.Height = $objImage.Height
# Title
$Title = New-Object System.Windows.Forms.label
$Title.Location = New-Object System.Drawing.Size(150,10)
$Title.Size = New-Object System.Drawing.Size(500,70)
$Title.BackColor = "Transparent"
$Title.ForeColor = "darkblue"
$Title.Text = "Create a CSV file for the given path and depth"
$Form.Controls.Add($Title)
$Title.Font = $Font
# Start button
$Start_Button = New-Object System.Windows.Forms.Button
$Start_Button.Location = New-Object System.Drawing.Size(50,300)
$Start_Button.Size = New-Object System.Drawing.Size(100,30)
$Start_Button.Text = "Start"
$Start_Button.Font = $Font
$Start_Button.Add_Click($Button_Click)
$Form.Controls.Add($Start_Button)
#Cancel button
$Cancel_Button = New-Object System.Windows.Forms.Button
$Cancel_Button.Location = New-Object System.Drawing.Size(550,300)
$Cancel_Button.Size = New-Object System.Drawing.Size(100,30)
$Cancel_Button.Text = "Cancel"
$Cancel_Button.Font = $Font
$Cancel_Button.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$Form.Controls.Add($Cancel_Button)
$arg0_label = New-Object System.Windows.Forms.Label
$arg0_label.Location = New-Object System.Drawing.Point(50,80)
$arg0_label.Size = New-Object System.Drawing.Size(280,20)
$arg0_label.Text = 'Please enter the root of path:'
$Form.Controls.Add($arg0_label)
$arg0_textBox = New-Object System.Windows.Forms.TextBox
$arg0_textBox.Location = New-Object System.Drawing.Point(80,100)
$arg0_textBox.Size = New-Object System.Drawing.Size(250,30)
$arg0_textBox.Multiline = $False
$arg0_textbox.AcceptsReturn = $False
$Form.Controls.Add($arg0_textBox)
$arg2_label = New-Object System.Windows.Forms.Label
$arg2_label.Location = New-Object System.Drawing.Point(50,130)
$arg2_label.Size = New-Object System.Drawing.Size(280,20)
$arg2_label.Text = 'Please enter the depth of search:'
$Form.Controls.Add($arg2_label)
$arg2_textBox = New-Object System.Windows.Forms.TextBox
$arg2_textBox.Location = New-Object System.Drawing.Point(80,150)
$arg2_textBox.Size = New-Object System.Drawing.Size(250,30)
$arg2_textBox.Multiline = $False
$arg2_textbox.AcceptsReturn = $False
$Form.Controls.Add($arg2_textBox)
$arg1_label = New-Object System.Windows.Forms.Label
$arg1_label.Location = New-Object System.Drawing.Point(50,180)
$arg1_label.Size = New-Object System.Drawing.Size(280,20)
$arg1_label.Text = 'Please enter the output file full path and name:'
$Form.Controls.Add($arg1_label)
$arg1_textBox = New-Object System.Windows.Forms.TextBox
$arg1_textBox.Location = New-Object System.Drawing.Point(80,200)
$arg1_textBox.Size = New-Object System.Drawing.Size(250,30)
$arg1_textBox.Multiline = $False
$arg1_textbox.AcceptsReturn = $False
$Form.Controls.Add($arg1_textBox)
#$outfile = "$arg1_textBox.Text"
# Button event
$Button_Click = {
$RootPath = $arg0_textBox.Text
$OutFile = $arg1_textBox.Text
$recurse_max = $arg2_textBox.Text
$recurse_current = 0
$Header = "Folder Path,IdentityReference,FileSystemRights,IsInherited"
Remove-Item $OutFile
Add-Content -Value $Header -Path $OutFile
function print_acl
{
$RootPath = $arg0_textBox.Text
$recurse_current = $arg1_textBox.Text
Write-Host "$RootPath : $recurse_current"
if ($RootPath -ne "" -and $null -ne $RootPath ) {
$ACLs = get-acl $RootPath | ForEach-Object { $_.Access }
Foreach ($ACL in $ACLs){
$rights = $ACL.FileSystemRights -replace ", ", ":"
$OutInfo = $RootPath + "," + $ACL.IdentityReference + "," + $rights + "," + $ACL.IsInherited
Add-Content -Value $OutInfo -Path $OutFile
}
if ($recurse_current -lt $recurse_max) {
$Folders = Get-ChildItem $RootPath | Where-Object {$_.psiscontainer -eq $true}
foreach ($Folder in $Folders){
$recurse_current = $arg1_textBox.Text + 1
print_acl $Folder.Fullname $recurse_current
}
}
}
}
print_acl $RootPath $recurse_current
}
$Form.Topmost = $True
$Form.Add_Shown({$Form.Activate()})
[void] $Form.ShowDialog()
The problem is I don't understand why the Start button don't do anything.
What do I do wrong?
I'm a very beginner in this field so sorry for being so lame.
Thank you.
There's no need to make your own recursive function for Get-ChildItem - it has a -Depth Parameter
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
$Form = New-Object System.Windows.Forms.Form
$Form.Text = "Folder Group Details v1.6"
$Form.Size = '700,400'
$Form.StartPosition = "Manual"
$Form.Location = '90,90'
$Form.KeyPreview = $True
$Form.MaximumSize = $Form.Size
$Form.MinimumSize = $Form.Size
$Form.MinimizeBox = $True
$Form.MaximizeBox = $False
$Form.WindowState = "Normal"
$Form.SizeGripStyle = "Hide"
$Font = New-Object System.Drawing.Font("Times New Roman",14,[System.Drawing.FontStyle]::Bold)
$Form.Width = $objImage.Width
$Form.Height = $objImage.Height
# Title
$Title = New-Object System.Windows.Forms.label
$Title.Location = '150,10'
$Title.Size = '500,70'
$Title.BackColor = "Transparent"
$Title.ForeColor = "darkblue"
$Title.Text = "Create a CSV file for the given path and depth"
$Form.Controls.Add($Title)
$Title.Font = $Font
# Start button
$Start_Button = New-Object System.Windows.Forms.Button
$Start_Button.Location = '50,300'
$Start_Button.Size = '100,30'
$Start_Button.Text = "Start"
$Start_Button.Font = $Font
$Start_Button.Add_Click($Button_Click)
$Form.Controls.Add($Start_Button)
#Cancel button
$Cancel_Button = New-Object System.Windows.Forms.Button
$Cancel_Button.Location = '550,300'
$Cancel_Button.Size = '100,30'
$Cancel_Button.Text = "Cancel"
$Cancel_Button.Font = $Font
$Cancel_Button.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$Form.Controls.Add($Cancel_Button)
$arg0_label = New-Object System.Windows.Forms.Label
$arg0_label.Location = '50,80'
$arg0_label.Size = '280,20'
$arg0_label.Text = 'Please enter the root of path:'
$Form.Controls.Add($arg0_label)
$arg0_textBox = New-Object System.Windows.Forms.TextBox
$arg0_textBox.Location = '80,100'
$arg0_textBox.Size = '250,30'
$arg0_textBox.Multiline = $False
$arg0_textbox.AcceptsReturn = $False
$Form.Controls.Add($arg0_textBox)
$arg2_label = New-Object System.Windows.Forms.Label
$arg2_label.Location = '50,130'
$arg2_label.Size = '280,20'
$arg2_label.Text = 'Please enter the depth of search:'
$Form.Controls.Add($arg2_label)
$arg2_textBox = New-Object System.Windows.Forms.TextBox
$arg2_textBox.Location = '80,150'
$arg2_textBox.Size = '250,30'
$arg2_textBox.Multiline = $False
$arg2_textbox.AcceptsReturn = $False
$Form.Controls.Add($arg2_textBox)
$arg1_label = New-Object System.Windows.Forms.Label
$arg1_label.Location = '50,180'
$arg1_label.Size = '280,20'
$arg1_label.Text = 'Please enter the output file full path and name:'
$Form.Controls.Add($arg1_label)
$arg1_textBox = New-Object System.Windows.Forms.TextBox
$arg1_textBox.Location = '80,200'
$arg1_textBox.Size = '250,30'
$arg1_textBox.Multiline = $False
$arg1_textbox.AcceptsReturn = $False
$Form.Controls.Add($arg1_textBox)
# Button event
$Button_Click = {
$RootPath = $arg0_textBox.Text
$OutFile = $arg1_textBox.Text
$recurse_max = $arg2_textBox.Text
$Results = Get-ChildItem -Path $RootPath -Depth $recurse_max | Where-Object {$_.psiscontainer -eq $true} | ForEach-Object {
$FileDetail = $_
$ACLs = get-acl $_.FullName | ForEach-Object { $_.Access }
$ACLs | ForEach-Object {
$rights = $_.FileSystemRights -replace ", ", ":"
[pscustomobject]#{Folder=$FileDetail.Name;Path=$FileDetail.FullName;IdentityReference=$_.IdentityReference;FileSystemRights=$rights;IsInherited=$_.IsInherited}
}
}
$Results | Export-Csv -Path $OutFile -NoTypeInformation
}
$Form.Topmost = $True
$Form.Add_Shown({$Form.Activate()})
[void] $Form.ShowDialog()

I am wanting to return to a previous funtion in Powershell, to rectify with user error if a variable is met?

The current script is as follows;
$HN = hostname
$DN = Get-ADComputer -identity $HN -Properties DistinguishedName | select-object -ExpandProperty DistinguishedName
#*
$OU = 'OU=Workstations,DC=$domain,DC=$domain,DC=$domain'
[array]$A = Get-ADOrganizationalUnit -SearchBase $OU -SearchScope OneLevel -Filter * | Select-Object -ExpandProperty Name
[array]$DropDownArray = $A | Sort-Object
function Return-DropDown {
if ($DropDown.SelectedItem -eq $B){
$DropDown.SelectedItem = $DropDown.Items[0]
$Form.Close()
}
else{
$Form.Close()
}
}
function SelectGroup{
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
$Form = New-Object System.Windows.Forms.Form
$Form.width = 600
$Form.height = 200
$Form.Text = ”DropDown”
$DropDown = new-object System.Windows.Forms.ComboBox
$DropDown.Location = new-object System.Drawing.Size(140,10)
$DropDown.Size = new-object System.Drawing.Size(300,80)
ForEach ($Item in $DropDownArray) {
[void] $DropDown.Items.Add($Item)
}
$Form.Controls.Add($DropDown)
$DropDownLabel = new-object System.Windows.Forms.Label
$DropDownLabel.Location = new-object System.Drawing.Size(10,10)
$DropDownLabel.size = new-object System.Drawing.Size(100,40)
$DropDownLabel.Text = "Select Group:"
$DropDown.Font = New-Object System.Drawing.Font("Calibri",15,[System.Drawing.FontStyle]::Bold)
$Button = new-object System.Windows.Forms.Button
$Button.Location = new-object System.Drawing.Size(140,50)
$Button.Size = new-object System.Drawing.Size(150,50)
$Button.Text = "Select an Item"
$Button.Font = New-Object System.Drawing.Font("Calibri",11,[System.Drawing.FontStyle]::Bold)
$Button.Add_Click({Return-DropDown})
$form.Controls.Add($Button)
$form.ControlBox = $false
$Button = new-object System.Windows.Forms.Button
$Button.Location = new-object System.Drawing.Size(290,50)
$Button.Size = new-object System.Drawing.Size(150,50)
$Button.Text = "Finish"
$Button.Font = New-Object System.Drawing.Font("Calibri",11,[System.Drawing.FontStyle]::Bold)
$Button.Add_Click({Move-ADObject -Identity "$DN" -TargetPath "$OU" | Return-DropDown})
$form.Controls.Add($Button)
$form.ControlBox = $false
$Form.Add_Shown({$Form.Activate()})
[void] $Form.ShowDialog()
$B = $dropdown.SelectedItem
return $B
}
$B = SelectGroup
I would like to develop this tool and add as an aditional option to return to the begining of the previous function;
$Button = new-object System.Windows.Forms.Button
$Button.Location = new-object System.Drawing.Size(290,50)
$Button.Size = new-object System.Drawing.Size(150,50)
$Button.Text = "Back"
$Button.Font = New-Object System.Drawing.Font("Calibri",11,[System.Drawing.FontStyle]::Bold)
$Button.Add_Click({Return to #* })
$form.Controls.Add($Button)
$form.ControlBox = $false
Not sure how to achieve this, hoping to find help on here.
I have looked at loops and breaks but nothing seems to fit or that i can adapt to achieve this.
If you're looking for simple repetition of the form function, you could do something like this (unless your tool hides the PowerShell window).
Do {
# Move these lines from #*
$OU = 'OU=Workstations,DC=$domain,DC=$domain,DC=$domain'
[array]$A = Get-ADOrganizationalUnit -SearchBase $OU -SearchScope
OneLevel -Filter * | Select-Object -ExpandProperty Name
[array]$DropDownArray = $A | Sort-Object
$B = SelectGroup
#{... Do Work on $B, if desired ...}
$Stop = Read-Host -Prompt 'Do you want to stop?'
} Until ($Stop -match '(Y|y|Yes|YES|yes)')
Otherwise you'll need to alter your "return-dropdown" function to not close your form and implement your "back" button another way.

Add an existing Progressbar into an GUI

I have writen an simple GUI for my command to display. When i press a button my script searches for matches in a Log File and while doing that it displays a Progressbar, but it only displays it in the ISE Window not in the GUI itself. How can i Display it in the GUI.
I found New-Object System.Windows.Forms.ProgressBar when searching for a way.
But in the examples i only found how they do new Bars not add existings that only exist inside of a Button.
This is my Script
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
#Dropdown/Serverauswahl
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$form = New-Object System.Windows.Forms.Form
$form.Text = 'Select a Computer'
$form.Size = New-Object System.Drawing.Size(600,400)
$form.StartPosition = 'CenterScreen'
$okButton = New-Object System.Windows.Forms.Button
$okButton.Location = New-Object System.Drawing.Point(150,240)
$okButton.Size = New-Object System.Drawing.Size(150,46)
$okButton.Text = 'OK'
$okButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$form.AcceptButton = $okButton
$form.Controls.Add($okButton)
$cancelButton = New-Object System.Windows.Forms.Button
$cancelButton.Location = New-Object System.Drawing.Point(300,240)
$cancelButton.Size = New-Object System.Drawing.Size(150,46)
$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,20)
$label.Size = New-Object System.Drawing.Size(560,40)
$label.Text = 'Please select a Server:'
$form.Controls.Add($label)
$listBox = New-Object System.Windows.Forms.ListBox
$listBox.Location = New-Object System.Drawing.Point(20,80)
$listBox.Size = New-Object System.Drawing.Size(540,40)
$listBox.Font = "courier New, 13"
$listBox.Height =150
[void] $listBox.Items.Add('LNS5')
[void] $listBox.Items.Add('LNS10')
[void] $listBox.Items.Add('LNS13')
[void] $listBox.Items.Add('LNS14')
[void] $listBox.Items.Add('LNS62')
$form.Controls.Add($listBox)
$form.Topmost = $true
$result = $form.ShowDialog()
if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{
$x = $listBox.SelectedItem
$path = "C:\temp\SMTPFilter\${x}filter.txt"
}
#zweites Fenster
$objForm = New-Object System.Windows.Forms.Form
$objForm.StartPosition = "CenterScreen"
$objForm.Size = New-Object System.Drawing.Size(1200,800)
$objForm.Text = "Test GUI"
$form = New-Object System.Windows.Forms.Form
$form.Size = New-Object System.Drawing.Size(900,600)
$dataGridView = New-Object System.Windows.Forms.DataGridView
$dataGridView.Size=New-Object System.Drawing.Size(800,400)
#Filtern
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(30,112)
$OKButton.Size = New-Object System.Drawing.Size(300,92)
$OKButton.Text = "Filtern"
$OKButton.Name = "Filter"
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::None
$OKButton.Add_Click({$i= 0
$length = (Get-Content $path).Length
$global:result = Get-Content $path | ForEach-Object {
if($_ -match '(\d{2}\.\d{2}\.\d{4} \d{2}:\d{2}:\d{2}).*\(((?:\d{1,3}\.){3}\d{1,3})\) disconnected\.?\s+(\d+) message\[s\]'){
[PsCustomObject]#{
IP = $matches[2]
Messages = [int]$matches[3]
Date = [datetime]::ParseExact($matches[1], 'dd.MM.yyyy HH:mm:ss', $null)
}}
$i++
if($i % 1000 -eq 0){
Write-Progress -activity "Searching for matches" -status "Scanned: $i of $($length)" -percentComplete (($i / $length) * 100)
}}
Write-Progress -activity "Searching for matches" -status "Scanned: $i of $($length)" -percentComplete (($i / $length) * 100)
#Messages Counted
$global:cumulative = $result | Group-Object -Property IP | ForEach-Object {
try {
$dns = [System.Net.Dns]::GetHostEntry($_.Name).HostName
}
catch {
$dns = 'Not available'
}
[PsCustomObject]#{
IP = $_.Name
Messages = ($_.Group | Measure-Object -Property Messages -Sum).Sum
DNSName = $dns
Date = ($_.Group | Sort-Object Date)[-1].Date
}
}})
$objForm.Controls.Add($OKButton)
#Ergebnis Anzeigen
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(30,214)
$OKButton.Size = New-Object System.Drawing.Size(300,92)
$OKButton.Text = "Ergebnis anzeigen"
$OKButton.Name = "Egebnis Button"
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::None
$OKButton.Add_Click({$objTextBox1 = New-Object System.Windows.Forms.TextBox
$objTextBox1.Multiline = $True;
$objTextBox1.Location = New-Object System.Drawing.Size(360,10)
$objTextBox1.Size = New-Object System.Drawing.Size(800,600)
$objTextBox1.Text = $cumulative | Out-String
$objTextBox1.Font = "courier New, 13"
$objTextBox1.Scrollbars = "Vertical"
$objForm.Controls.Add($objTextBox1)
#outgridview
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(30,316)
$OKButton.Size = New-Object System.Drawing.Size(300,92)
$OKButton.Text = "Ergebnis in GridView"
$OKButton.Name = "GridView"
$OKButton.DialogResult = "OK"
$OKButton.Add_Click({$cumulative | Out-GridView})
$objForm.Controls.Add($OKButton)
#Export CSV
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(30,418)
$OKButton.Size = New-Object System.Drawing.Size(300,92)
$OKButton.Text = "Export CSV (in C:/temp)"
$OKButton.Name = "CSV"
$OKButton.DialogResult = "OK"
$OKButton.Add_Click({$cumulative | Export-Csv -Path 'C:\temp\SMTPresult.Csv'})
$objForm.Controls.Add($OKButton) })
$objForm.Controls.Add($OKButton)
[void] $objForm.ShowDialog()
There is a ProgressBar control available which you can use:
System.Windows.Forms.ProgressBar
See https://mcpmag.com/articles/2014/02/18/progress-bar-to-a-graphical-status-box.aspx for an example
There is also a way of displaying a progressbar inside the taskbar button but you need to deploy a dll from the Microsoft WindowsAPICodePack so that it's available to the person running the script. If you're interested I'll dig out the details

Powershell Codewrap for repeat option and bug with form

I got a script which is handling some things. I know a lot say I should get more short scripts which are working. But there are many people which can't handle many files or scripts and want 1 which can do all, and I can't tell 600 people which script does what. I need a kind of assembling at least of a few.
I wanted to make a workaround for the canceld options. The easiest way is to wrap all the code in a do {} while () for sure. But are there any options where I can repeat a single option? Something like when it asks do you really want to cancel.
And a real annoying bug I can't fix is that after every single action the start form blops up again. I tried out diffrent ways to debug with a counter but it didn't count up and also I tried to put the function assembling at a other place didn't fix it as well. Don't know why it happens.
Code for repro
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
Set-PSDebug -Strict #Errorcall if a variable isnt declared
#Function Assembling
function Saveat()
{
#working
$Saveat = New-Object -Typename System.Windows.Forms.SaveFileDialog
$Saveat.filter = "CSV (*.csv)| *.csv"
#IF selection is canceld
$result = $form.ShowDialog()
[void]$Saveat.ShowDialog()
return $Saveat.FileName
}
function Compare($location1, $location2)
{
#work in progress
$CSV1 = Import-Csv -Path $location1 -UseCulture
$CSV2 = Import-Csv -Path $location2 -UseCulture
$Compared = Compare-Object -ReferenceObject $CSV1 -DifferenceObject $CSV2 |
select -ExpandProperty inputObject |
sort
[void] $CSV1
[void] $CSV2
return $Compared
}
function whichcsv()
{
#working
$location = New-Object System.Windows.Forms.OpenFileDialog
$location.Filter = "CSV (*.csv)| *.csv"
$result = $form.ShowDialog()
[void]$location.ShowDialog()
return $location.FileName
}
#Select which option Form
#region Initiate Form **This Form Blops up after every user action**
$form = New-Object System.Windows.Forms.Form
$form.Text = "CSV Liste"
$form.Size = New-Object System.Drawing.Size(300,300)
$form.StartPosition = "CenterScreen"
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Point(75,195)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$form.AcceptButton = $OKButton
$form.Controls.Add($OKButton)
$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Point(150,195)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$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,20)
$label.Size = New-Object System.Drawing.Size(280,20)
$label.Text = "Welche CSV Liste soll geladen werden:"
$form.Controls.Add($label)
$listBox = New-Object System.Windows.Forms.ListBox
$listBox.Location = New-Object System.Drawing.Point(10,40)
$listBox.Size = New-Object System.Drawing.Size(260,20)
$listBox.Height = 150
[void] $listBox.Items.Add("List Filter")
[void] $listBox.Items.Add("ADComputer")
[void] $listBox.Items.Add("AS400 Personal Not implemented yet")
[void] $listBox.Items.Add("ADBenutzer Not implemented yet")
#endregion
$form.Controls.Add($listBox)
$form.Topmost = $true
$result = $form.ShowDialog()
if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{
#Choosed Option
$x = $listBox.SelectedItem
switch ($x)
{
#Option 1 working
"List Filter"
{
#Select path of the CSV
$csvpath = whichcsv
#IF selection is canceld
if ($csvpath -eq "")
{
Write-Host "Operation Canceld"
}
else
{
#CSV Import and Filter set
$CSV = Import-Csv -Path $csvpath -UseCulture
$Filter = Read-Host "Please enter columname. Leave clear for cancel"
if ($Filter -eq "")
{
Write-Host "Operation canceld"
}
else
{
$y = $CSV | Select $Filter
Write-Host "CSV Successfull Imported and Filter set"
}
$SDestination = Saveat
if ($SDestination -eq "")
{
Write-Host "Operation Canceld"
}
else
{
Write-Host "Process started"
foreach ($y1 in $y)
{
New-Object PSObject -Property #{Inventarnummer=$y1.$Filter} | Export-Csv $SDestination -NoTypeInformation -Append
}
Write-Host "Process finished"
}
}
}
#Option 2 working
"ADComputer"
{
#Select path of the CSV
$csvpath = whichcsv
#IF selection is canceld
if ($csvpath -eq "")
{
Write-Host "Operation Canceld"
}
else
{
#CSV Import with filter
$CSV = Import-Csv -Path $csvpath -Delimiter ','
$Filter = Read-Host "Please enter columname. Leave clear for cancel"
if ($Filter -eq "")
{
Write-Host "Operation canceld"
}
else
{
$y = $CSV | Select $Filter
Write-Host "CSV Successfull Imported and Filter set"
}
#Path selection
$Saveworking = Saveat
$SaveFailed = Saveat
if($Saveworking -eq "")
{
Write-Host "Operation canceld"
}
elseif ($SaveFailed -eq "")
{
Write-Host "Operation canceld"
}
else
{
#Progress
Write-Host "Process Start"
foreach($n in $y)
{
try
{
$Computer = [system.net.dns]::resolve($n.$Filter) | Select HostName,AddressList
$IP = ($Computer.AddressList).IPAddressToString
Write-Host $n.$Filter $IP
New-Object PSObject -Property #{IPAddress=$IP; Name=$n.$Filter} | Export-Csv $Saveworking -NoTypeInformation -Append
}
catch
{
Write-Host "$($n.$Filter) is unreachable."
New-Object PSObject -Property #{Name=$n.$Filter} | Export-Csv $SaveFailed -NoTypeInformation -Append
}
}
Write-Host "Process successfull completed"
}
}
}
#Option 3 Not implemented yet
"AS400 Personal Not implemented yet"
{
Write-Host "Not implemented yet"
}
#Option 4 not implemented yet
"ADBenutzer Not implemented yet"
{
Write-Host "Not implemented yet"
}
}
}
else
{
Write-Host "Operation Canceld"
}
I guess you need to work with form events rather than .DialogResult.
For the Cancel button you would probably do something like: $CancelButton.Add_Click({[Void]$Form.Window.Close()})
For the OK button you would probably want to put the majority of your OK task in a function and invoke it from a similar event:
Function Task {
#Choosed Option
$x = $listBox.SelectedItem
switch ($x)
{
#Option 1 working
"List Filter"
{
#Select path of the CSV
$csvpath = whichcsv
...
$OkButton.Add_Click({Task})
(And close the dialog ([Void]$Form.Window.Close()) when the task is completed)

Build Checkbox list programmatically using powershell

I am trying to populate checkbox from value return in $domain = Get-MsolDomain which return domains available then generate the checkbox based on the value return and excluding the value from #mail. Thank you
Here is the code that i have so far:
$snapin = Get-PSSnapin | Where-Object {$_.Name -eq 'Microsoft.SharePoint.Powershell'}
if ($snapin -eq $null)
{
Write-Host -foregroundcolor Green "Loading SharePoint PowerShell Snapin"
Add-PSSnapin "Microsoft.SharePoint.Powershell"
}
Import-Module MSOnline
$credentials = Get-Credential
Connect-MsolService -Credential $credentials
$unlicensedUsersBatch500 = Get-MsolUser -UnlicensedUsersOnly -MaxResults 500
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$Form = New-Object System.Windows.Forms.Form
$Form.Size = New-Object System.Drawing.Size(600,700)
$Form.text ="Office 365 Licence Activation"
############################################## Start group boxes
$groupBox = New-Object System.Windows.Forms.GroupBox
$groupBox.Location = New-Object System.Drawing.Size(240,20)
$groupBox.size = New-Object System.Drawing.Size(200,100)
$groupBox.text = "Availabe Office 365 Domains:"
$Form.Controls.Add($groupBox)
$Checkboxes += New-Object System.Windows.Forms.CheckBox
$Checkboxes.Location = New-Object System.Drawing.Size(10,20)
$domain = Get-MsolDomain
foreach ($a in $domain)
{
for ($i=1;$i -lt 6; $i++)
{
$Checkboxes.Text = $a.Name
}
}
$groupBox.Controls.Add($Checkboxes)
I would do it as follows. Note that I created and populated $domain for the sake of testing, so you will need to replace that with your call to Get-MsolDomain.
Small plus, the size of the groupbox will grow automatically, based on the number of elements in $domain.
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$Form = New-Object System.Windows.Forms.Form
$Form.Size = New-Object System.Drawing.Size(600,700)
$Form.text ="Office 365 Licence Activation"
############################################## Start group boxes
$groupBox = New-Object System.Windows.Forms.GroupBox
$groupBox.Location = New-Object System.Drawing.Size(240,20)
$groupBox.text = "Availabe Office 365 Domains:"
$Form.Controls.Add($groupBox)
$Checkboxes += New-Object System.Windows.Forms.CheckBox
$Checkboxes.Location = New-Object System.Drawing.Size(10,20)
#$domain = Get-MsolDomain
$domain = #()
$domain += #{"Name"="domain1"}
$domain += #{"Name"="domain2"}
$domain += #{"Name"="domain3"}
$Checkboxes = #()
$y = 20
foreach ($a in $domain)
{
$Checkbox = New-Object System.Windows.Forms.CheckBox
$Checkbox.Text = $a.Name
$Checkbox.Location = New-Object System.Drawing.Size(10,$y)
$y += 30
$groupBox.Controls.Add($Checkbox)
$Checkboxes += $Checkbox
}
$groupBox.size = New-Object System.Drawing.Size(200,(40*$checkboxes.Count))
$form.ShowDialog()| Out-Null