How to remove checked margin in tray icon context menu - powershell

I've created this little script running in tray. I've noticed that contex menu text is not placed completely to the left. After a little investigation I found out that it is because there is a space left for .checked state indicator. I found out that it can be removed by .showcheckedmargin property of ContextMenuStrip but have no idea how to implement that.
Please advise.
add-type -AssemblyName 'System.Windows.Forms'
Add-Type -AssemblyName 'System.Drawing'
Add-Type -AssemblyName 'PresentationFramework'
$2 = "BASE64 CODE"
$bitmap = New-Object System.Windows.Media.Imaging.BitmapImage
$bitmap.BeginInit()
$bitmap.StreamSource = [System.IO.MemoryStream][System.Convert]::FromBase64String($2)
$bitmap.EndInit()
$bitmap.Freeze()
$image = [System.Drawing.Bitmap][System.Drawing.Image]::FromStream($bitmap.StreamSource)
$icon = [System.Drawing.Icon]::FromHandle($image.GetHicon())
$app = New-Object System.Windows.Forms.NotifyIcon
$app.Text = ""
$app.Icon = $icon
$app.Visible = $true
$Zenek = New-Object System.Windows.Forms.MenuItem
$Zenek.Text = "Zenek"
$NetExt = New-Object System.Windows.Forms.MenuItem
$NetExt.Text = "NetExt"
$Busy = New-Object System.Windows.Forms.MenuItem
$Busy.Text = "BUSY"
$Time = New-Object System.Windows.Forms.MenuItem
$Time.Text = "Time"
$Exit = New-object System.Windows.Forms.MenuItem
$Exit.Text = "Exit"
$context = New-Object System.Windows.Forms.ContextMenu
$app.ContextMenu = $context
$app.ContextMenu.MenuItems.AddRange(#($Zenek, $NetExt, $Busy, $Time, $Exit))
$keepAwakeScript = {
while (1) {
$wsh = New-Object -ComObject WScript.Shell
$wsh.SendKeys('+{F15}')
Start-Sleep -seconds 59
}
}
Start-Job -ScriptBlock $keepAwakeScript -Name "keepAwake"|out-null
$Zenek.Add_Click({Set-Clipboard -Value "SOME TEXT"})
$NetExt.Add_Click({Set-Clipboard -Value "SOME OTHER TEXT"})
$Busy.Add_Click({
$running = Get-Job|?{$_.Name -like 'KAPS'}
$icon = new-object System.Drawing.Icon("MY PRIVATE LOCATION\red.ico")
$app.Icon = $icon
if($running -eq $null){
Start-Job -Name KAPS -ScriptBlock{
while ($true){
$shell = New-Object -ComObject WScript.Shell
$shell.SendKeys('{CAPSLOCK}')
Start-Sleep 1
}
}
}else{
Stop-Job KAPS
Remove-Job KAPS
$icon = [System.Drawing.Icon]::FromHandle($image.GetHicon())
$app.Icon = $icon
}
})
$Time.Add_Click({
$main = New-Object System.Windows.Forms.Form
$main.ClientSize = '200,200'
$main.MinimizeBox = $false
$main.MaximizeBox = $false
$label = New-Object System.Windows.Forms.Label
$label.Size = '190,30'
$label.Location = '10,10'
$label.Text = 'Ile minut?'
$font = New-Object System.Drawing.Font("Arial", 23)
$label.Font = $font
$textbox = New-Object System.Windows.Forms.TextBox
$textbox.Size = '50,100'
$textbox.Location = '10,70'
$button = New-Object System.Windows.Forms.Button
$button.Size = '50,50'
$button.Location = '10,120'
$button.Text = 'GO'
$button.Add_Click({
$timer.Start()
$textbox.Visible =$false
$button.Visible = $false
$label.Visible = $false
$script:1 = New-TimeSpan -minutes ([int]$textbox.Text)
$label2.Visible = $true
$label2.Text = $1.ToString("mm\:ss")
})
$timer = New-Object System.Windows.Forms.Timer
$timer.Enabled = $false
$timer.Interval = '1000'
$second = New-TimeSpan -Seconds 1
$timer.Add_Tick({
$script:1 = $1.Subtract($second)
$label2.Text = $1.ToString("mm\:ss")
if($script:1.TotalSeconds -le 0){$timer.Stop(); $timer.Dispose(); [System.Windows.Forms.Application]::SetSuspendState("Hibernate", $true, $false); $main.Close(); $main.Dispose()}
})
$label2 = New-Object System.Windows.Forms.Label
$label2.Size = '190,30'
$label2.Location = '10,10'
$label2.Text = $1
$font = New-Object System.Drawing.Font("Arial", 23)
$label2.Font = $font
$label2.Visible = $false
$main.Controls.Add($textbox)
$main.Controls.Add($button)
$main.Controls.Add($label)
$main.Controls.Add($label2)
$main.ShowDialog()
})
$Exit.Add_Click({
$app.Visible = $false
Stop-Job -Name "keepAwake"
$appContext.ExitThread()
Stop-Process -Id $PID
})
$appContext = New-Object System.Windows.Forms.ApplicationContext
[void][System.Windows.Forms.Application]::Run($appContext)

For anyone with the same problem. I've managed to figure it out.
Another post from SO allowed me to do so.
I had to replace .ContextMenu with .ContextMenuStrip for the Menu itself,
replace .MenuItem with .ToolStripMenuItem, add .ShowImageMargin to ContextMenuStrip variable, then finall add items via .Items.AddRange(#()).
Before
After
In the end the code looks like this and works as intended.
add-type -AssemblyName 'System.Windows.Forms'
Add-Type -AssemblyName 'System.Drawing'
Add-Type -AssemblyName 'PresentationFramework'
$2 =
"BASE 64 CODE"
$bitmap = New-Object System.Windows.Media.Imaging.BitmapImage
$bitmap.BeginInit()
$bitmap.StreamSource = [System.IO.MemoryStream][System.Convert]::FromBase64String($2)
$bitmap.EndInit()
$bitmap.Freeze()
$image = [System.Drawing.Bitmap][System.Drawing.Image]::FromStream($bitmap.StreamSource)
$icon = [System.Drawing.Icon]::FromHandle($image.GetHicon())
$app = New-Object System.Windows.Forms.NotifyIcon
$app.Text = ""
$app.Icon = $icon
$app.Visible = $true
$Zenek = New-Object System.Windows.Forms.ToolStripMenuItem
$Zenek.Text = "Zenek"
$Zenek.Checked = $true
$NetExt = New-Object System.Windows.Forms.ToolStripMenuItem
$NetExt.Text = "NetExt"
$Busy = New-Object System.Windows.Forms.ToolStripMenuItem
$Busy.Text = "BUSY"
$Time = New-Object System.Windows.Forms.ToolStripMenuItem
$Time.Text = "Time"
$Exit = New-object System.Windows.Forms.ToolStripMenuItem
$Exit.Text = "Exit"
$sep = New-Object System.Windows.Forms.ToolStripSeparator
$context = New-Object System.Windows.Forms.ContextMenuStrip
$context.ShowImageMargin = $false
$context.Items.AddRange(#($Zenek, $NetExt, $Busy, $Time, $sep, $Exit))
$app.ContextMenuStrip = $context
$keepAwakeScript = {
while (1) {
$wsh = New-Object -ComObject WScript.Shell
$wsh.SendKeys('+{F15}')
Start-Sleep -seconds 59
}
}
Start-Job -ScriptBlock $keepAwakeScript -Name "keepAwake"|out-null
$Zenek.Add_Click({Set-Clipboard -Value "SOME TEXT"})
$NetExt.Add_Click({Set-Clipboard -Value "SOME OTHER TEXT"})
$Busy.Add_Click({
$running = Get-Job|?{$_.Name -like 'KAPS'}
$icon = new-object System.Drawing.Icon("MY PRIVATE LOCATION\red.ico")
$app.Icon = $icon
if($running -eq $null){
Start-Job -Name KAPS -ScriptBlock{
while ($true){
$shell = New-Object -ComObject WScript.Shell
$shell.SendKeys('{CAPSLOCK}')
Start-Sleep 1
}
}
}else{
Stop-Job KAPS
Remove-Job KAPS
$icon = [System.Drawing.Icon]::FromHandle($image.GetHicon())
$app.Icon = $icon
}
})
$Time.Add_Click({
$main = New-Object System.Windows.Forms.Form
$main.ClientSize = '200,200'
$main.MinimizeBox = $false
$main.MaximizeBox = $false
$label = New-Object System.Windows.Forms.Label
$label.Size = '190,30'
$label.Location = '10,10'
$label.Text = 'Ile minut?'
$font = New-Object System.Drawing.Font("Arial", 23)
$label.Font = $font
$textbox = New-Object System.Windows.Forms.TextBox
$textbox.Size = '50,100'
$textbox.Location = '10,70'
$button = New-Object System.Windows.Forms.Button
$button.Size = '50,50'
$button.Location = '10,120'
$button.Text = 'GO'
$button.Add_Click({
$timer.Start()
$textbox.Visible =$false
$button.Visible = $false
$label.Visible = $false
$script:1 = New-TimeSpan -minutes ([int]$textbox.Text)
$label2.Visible = $true
$label2.Text = $1.ToString("mm\:ss")
})
$timer = New-Object System.Windows.Forms.Timer
$timer.Enabled = $false
$timer.Interval = '1000'
$second = New-TimeSpan -Seconds 1
$timer.Add_Tick({
$script:1 = $1.Subtract($second)
$label2.Text = $1.ToString("mm\:ss")
if($script:1.TotalSeconds -le 0){$timer.Stop(); $timer.Dispose(); [System.Windows.Forms.Application]::SetSuspendState("Hibernate", $true, $false); $main.Close(); $main.Dispose()}
})
$label2 = New-Object System.Windows.Forms.Label
$label2.Size = '190,30'
$label2.Location = '10,10'
$label2.Text = $1
$font = New-Object System.Drawing.Font("Arial", 23)
$label2.Font = $font
$label2.Visible = $false
$main.Controls.Add($textbox)
$main.Controls.Add($button)
$main.Controls.Add($label)
$main.Controls.Add($label2)
$main.ShowDialog()
})
$Exit.Add_Click({
$app.Visible = $false
Stop-Job -Name "keepAwake"
$appContext.ExitThread()
#Stop-Process -Id $PID
})
$appContext = New-Object System.Windows.Forms.ApplicationContext
[void][System.Windows.Forms.Application]::Run($appContext)

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()

Need help gui background-job double-hop issue and script freezing

I'm having an issue with double hopping scriptblock for background job that either does nothing or freezes the script. Explenation below.
The idea for the script is to get a list of files (very large count, ~200k) and then process them in three individual ways (get hashcodes and get true duplicates, compare filenames and get pseudo duplicates, get zero length files). At this moment I'm working on hashes. The result of $job1 is a string (array?) that cannot be piped to get-filehash. This results in $job2 looping through each string in order to get hashes. As background-jobs work on scriptblocks and foreach loop has scriptblock component a double hop is created. I've worked around that by using invoke-command combined with [scriptblock]::Create() method inside job scriptblock. That unfortunately freezes the form. My question to you is as follows. How do I force $job1 result to be of system.io.fileinfo type OR how do I unfreeze script while Invoke-command is in progress?
Add-Type -AssemblyName System.Windows.Forms
add-type -AssemblyName system.drawing
[System.Windows.Forms.Application]::EnableVisualStyles()
$path = "C:\"
$window = New-Object system.Windows.Forms.Form
$window.Size = New-Object system.Drawing.Size #(400,400)
$window.StartPosition = "CenterScreen"
$window.Font = New-Object System.Drawing.Font("Calibri",11,[System.Drawing.FontStyle]::Bold)
$window.Text = "STARTING UP"
$ProgressBar1 = New-Object System.Windows.Forms.ProgressBar
$ProgressBar1.Location = New-Object System.Drawing.Point(10, 10)
$ProgressBar1.Size = New-Object System.Drawing.Size(365, 20)
$ProgressBar1.Style = "Marquee"
$ProgressBar1.MarqueeAnimationSpeed = 20
$ProgressBar1.UseWaitCursor = $true
$ProgressBar1.Visible = $false
$button = New-Object System.Windows.Forms.Button
$button.size = New-Object system.drawing.size #(50,50)
$button.Location = New-Object System.Drawing.Point(20, 70)
$button.Text = "TEST"
$window.Controls.add($button)
$label = New-Object System.Windows.Forms.Label
$label.Size = New-Object System.Drawing.Size #(100, 50)
$label.Location = New-Object System.Drawing.Point (80, 70)
$label.BorderStyle = 'Fixed3D'
$label.ForeColor = 'green'
$label.TextAlign = 'middlecenter'
$window.Controls.Add($label)
$timer = New-Object System.Windows.Forms.Timer
$timer.Interval = 1000
$timer.add_Tick({$script:time2 =((get-date)-$script:time1).ToString("hh\:mm\:ss")
$label2.text = $script:time2
})
$button.add_Click(
{$1 = Get-Date
$Script:time1 = Get-Date
$timer.start()
$ProgressBar1.BringToFront()
$ProgressBar1.Show()
$this.Enabled = $false
$job = Start-Job -ScriptBlock {
Get-ChildItem -File -recurse $HOME -ErrorAction SilentlyContinue|select -ExpandProperty FullName
}
while($job.State -eq 'Running') {
[System.Windows.Forms.Application]::DoEvents()
}
$script:asd = $job | Receive-Job #-AutoRemoveJob -Wait
$ProgressBar1.Hide()
$this.Enabled = $true
$2 = ((get-date) - $1).ToString("hh\:mm\:ss")
$label.text = $2
$timer.stop()
}
)
$button2 = New-Object System.Windows.Forms.Button
$button2.Size = New-Object System.Drawing.Size #(50, 50)
$button2.Location = New-Object System.Drawing.Point (200, 70)
$button2.Text = 'Exit'
$window.Controls.Add($button2)
$button2.add_Click({$window.Close()})
$button3 = new-object System.Windows.Forms.Button
$button3.Size = New-Object System.Drawing.Size #(50, 50)
$button3.Location = New-Object System.Drawing.Point (20, 200)
$button3.Text = "Start"
$window.Controls.Add($button3)
$button3.add_Click({
$sb = foreach ($qwe in $Script:asd){Get-FileHash $qwe -Algorithm MD5|select -ExpandProperty Hash -OutVariable +Script:tester}
$ProgressBar2.BringToFront()
$ProgressBar2.Show()
$this.Enabled = $false
$job2 = start-job -Name 'asd' -scriptblock {
param($sb)
$sb = [scriptblock]::Create($sb)
Invoke-command -ScriptBlock $sb
}
while($job2.State -eq 'Running') {
[System.Windows.Forms.Application]::DoEvents()
}
Write-Host $Script:tester
$ProgressBar2.Hide()
$this.Enabled = $true
})
$label2 = New-Object System.Windows.Forms.Label
$label2.size = New-Object System.Drawing.Size #(100, 50)
$label2.Location = New-Object System.Drawing.Point (80, 200)
$label2.BorderStyle = 'Fixed3D'
$label2.ForeColor = 'green'
$label2.TextAlign = 'middlecenter'
$window.Controls.Add($label2)
$ProgressBar2 = New-Object System.Windows.Forms.ProgressBar
$ProgressBar2.Location = New-Object System.Drawing.Point(10, 330)
$ProgressBar2.Size = New-Object System.Drawing.Size(365, 20)
$ProgressBar2.Style = "Marquee"
$ProgressBar2.MarqueeAnimationSpeed = 20
$ProgressBar2.UseWaitCursor = $true
$ProgressBar2.Visible = $false
$window.Controls.Add($ProgressBar2)
$groupbox = New-Object System.Windows.Forms.GroupBox
$groupbox.size = New-Object system.drawing.size #(377, 365)
$groupbox.Location = New-Object System.Drawing.point (4, -5)
$window.Controls.Add($groupbox)
$window.Controls.Add($ProgressBar1)
$window.ShowDialog()|out-null
For anyone interested. The answer was piping $job results to set-variable - $job|Wait-job|Receive-Job|Set-Variable -Name JOB_RESULT -Scope Script.
Then using $using: scope in $job2 scriptblock - $job2 = start-job -scriptblock { $using:JOB_RESULT|Get-FileHash -Algorithm MD5}

powershell gui creating local users

i need some help with my powershell gui. i want to create a gui for creating local useraccounts with some parameters provided in the checkbox i need to click. the gui is running but i need some help for the code lines for the checkboxes. what do i need to add that the code is running fone when i click the checkboxes? for example if i just click checkbox 1 i get an error the username is to long even i name the testaccount "testuser"
$PSDefaultParameterValues['*:Encoding'] = 'ascii'
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
#create form
$form = New-Object System.Windows.Forms.Form
$form.Width = 500
$form.Height = 400
$form.MaximizeBox = $false
$form.TopMost = $true
$objLabel = New-Object System.Windows.Forms.label
$objLabel.Location = New-Object System.Drawing.Size(10,20)
$objLabel.Size = New-Object System.Drawing.Size(130,15)
$objLabel.BackColor = "Transparent"
$objLabel.ForeColor = "Black"
$objLabel.Text = "name"
$Form.Controls.Add($objLabel)
#textbox with choosen user name
$txtBox = New-Object System.Windows.Forms.TextBox
$txtBox.Location = New-Object System.Drawing.Point (180, 20)
$txtBox.Size = New-Object System.Drawing.Size(280,100)
$form.Controls.Add($txtBox)
$objLabel2 = New-Object System.Windows.Forms.label
$objLabel2.Location = New-Object System.Drawing.Size(10,50)
$objLabel2.Size = New-Object System.Drawing.Size(130,15)
$objLabel2.BackColor = "Transparent"
$objLabel2.ForeColor = "Black"
$objLabel2.Text = "password"
$Form.Controls.Add($objLabel2)
#textbox with choosen password
$txtBox2 = New-Object System.Windows.Forms.TextBox
$txtBox2.Location = New-Object System.Drawing.Point (180, 50)
$txtBox2.Size = New-Object System.Drawing.Size(280,100)
$form.Controls.Add($txtBox2)
#create checkbox1
$checkBox = New-Object System.Windows.Forms.CheckBox
$checkBox.Location = New-Object System.Drawing.Point (10, 100)
$checkBox.Size = New-Object System.Drawing.Size(350,30)
$checkBox.Text = "PasswordNeverExpires"
$form.Controls.Add($checkBox)
#create checkbox2
$checkBox2 = New-Object System.Windows.Forms.CheckBox
$checkBox2.Location = New-Object System.Drawing.Point (10, 150)
$checkBox2.Size = New-Object System.Drawing.Size(350,30)
$checkBox2.Text = "UserMayChangePassword"
$form.Controls.Add($checkBox2)
#create checkbox2
$checkBox3 = New-Object System.Windows.Forms.CheckBox
$checkBox3.Location = New-Object System.Drawing.Point (10, 200)
$checkBox3.Size = New-Object System.Drawing.Size(350,30)
$checkBox3.Text = "AccountNeverExpires"
$form.Controls.Add($checkBox3)
#create user button
$Button = New-Object System.Windows.Forms.Button
$Button.Location = New-Object System.Drawing.Size(10,250)
$Button.Size = New-Object System.Drawing.Size(150,50)
$Button.Text = "create user"
$Button.Add_Click({
if(($checkBox.Checked -eq $false) -and ($checkBox2.Checked -eq $false) -and ($checkBox3.Checked -eq $false)) {
[System.Windows.Forms.Messagebox]::Show("No CheckBox checked")
}
#checkbox1 action
if ($checkBox.Checked -eq $true) {
$adminName = $txtBox
$securePassword = $txtBox2
$newUser = New-LocalUser -Name $adminName -Password $securePassword -Description $adminName -FullName $adminName #-ErrorAction Stop
$newUser | Set-LocalUser <#-PasswordNeverExpires $true#> -UserMayChangePassword $false <#-AccountNeverExpires#> #-ErrorAction Stop
Add-LocalGroupMember -Group "Administrators" -Member $adminName #-ErrorAction Stop
if(-not $?) {[System.Windows.Forms.MessageBox]::Show( "no success",'','OK',"Error")}
else {[System.Windows.Forms.MessageBox]::Show( "success",'','OK',"Information")}
}
#checkbox2 action
if ($checkBox2.Checked -eq $true) {
if(-not $?) {[System.Windows.Forms.MessageBox]::Show( "no success",'','OK',"Error")}
else {[System.Windows.Forms.MessageBox]::Show( "success",'','OK',"Information")}
}
#checkbox3 action
if ($checkBox3.Checked -eq $true) {
if(-not $?) {[System.Windows.Forms.MessageBox]::Show( "no success",'','OK',"Error")}
else {[System.Windows.Forms.MessageBox]::Show( "success",'','OK',"Information")}
}
})
$form.Controls.Add($Button2)
#end
[void]$form.ShowDialog()

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 GUI script: read variable from textbox

I'm trying to pass the input of the two textboxes to the logic part of the script at the bottom. But that's not happening and I can't figure out the problem... I tried rewriting the code from [here][1].
Add-Type -AssemblyName System.Drawing
$form = New-Object System.Windows.Forms.Form
$form.Text = 'CompareGroups'
$form.Size = New-Object System.Drawing.Size(300,250)
$form.StartPosition = 'CenterScreen'
$okButton = New-Object System.Windows.Forms.Button
$okButton.Location = New-Object System.Drawing.Point(75,170)
$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,170)
$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)
$label1 = New-Object System.Windows.Forms.Label
$label1.Location = New-Object System.Drawing.Point(10,20)
$label1.Size = New-Object System.Drawing.Size(280,20)
$label1.Text = 'Source-PC:'
$form.Controls.Add($label1)
$label2 = New-Object System.Windows.Forms.Label
$label2.Location = New-Object System.Drawing.Point(10,80)
$label2.Size = New-Object System.Drawing.Size(280,20)
$label2.Text = 'Target-PC:'
$form.Controls.Add($label2)
$textBox1 = New-Object System.Windows.Forms.TextBox
$textBox1.Location = New-Object System.Drawing.Point(10,40)
$textBox1.Size = New-Object System.Drawing.Size(260,20)
$form.Controls.Add($textBox1)
$textBox2 = New-Object System.Windows.Forms.TextBox
$textBox2.Location = New-Object System.Drawing.Point(10,100)
$textBox2.Size = New-Object System.Drawing.Size(260,20)
$form.Controls.Add($textBox2)
$form.Topmost = $true
$form.Add_Shown({$textBox1.Select()})
$result = $form.ShowDialog()
if (($result -eq [System.Windows.Forms.DialogResult]::OK)) {
$sourcePc = $textBox.Text
$targetPc = $textBox2.Text
$CopyFromPC = Get-ADComputer $sourcePc -Properties MemberOf
$CopyToPC = Get-ADComputer $targetPc -Properties MemberOf
if (($CopyFromPC.MemberOf | out-string) -eq ($CopyTopc.MemberOf | out-string)) {
Write-Host "Groups are the same."
} else {
$CopyFromPC.MemberOf | Where {$CopyTopc.MemberOf -notcontains $_} | Out-GridView -PassThru | Add-ADGroupMember -Members $CopyTopc -verbose
[System.Windows.Forms.MessageBox]::Show("Groups got copied successfully","CompareGroups",0)
}
}
[1]: https://learn.microsoft.com/en-us/powershell/scripting/samples/creating-a-custom-input-box?view=powershell-7
You added a textbox called textbox1 and not textbox.
Change the variablename from $sourcePc = $textBox.Text to $sourcePc = $textBox1.Text