Powershell Listview : Add 6 items lists in 6 different columns - winforms

I have an issue with my PS script including a listview.
I need to check the content of 6 directorys and show the content in 6 different columns :
The issue is that i can't get a correct visual, they are all in the same column
Here is my code :
$Form = New-Object Windows.Forms.Form
$Form.Text = "New Test"
$Form.Width = 1550
$Form.Height = 800
$Listview = New-Object System.Windows.Forms.ListView
$Listview.Location = New-Object System.Drawing.Size(15,10)
$Listview.Size = New-Object System.Drawing.Size(550,10)
$Listview.AutoResizeColumns([System.Windows.Forms.ColumnHeaderAutoResizeStyle]::ColumnContent)
$Listview.View = "Details"
$Listview.FullRowSelect = $true
$Listview.GridLines = $true
$Listview.Height = 650
$Listview.Width =1500
$Listview.AllowColumnReorder = $true
$Listview.Sorting = [System.Windows.Forms.SortOrder]::None
#[void]$Listview.Columns.Add('Null',0)
[void]$Listview.Columns.Add('Scripts',150)
[void]$Listview.Columns.Add('Applications',150)
[void]$Listview.Columns.Add('Systems',500)
[void]$Listview.Columns.Add('Databases',100)
[void]$Listview.Columns.Add('Datas',150)
[void]$Listview.Columns.Add('Backups',500)
$oButton = New-Object Windows.Forms.Button
$oButton.Text = "List"
$oButton.Top = 700
$oButton.Left = 350
$oButton.Width = 150
$oButton.Anchor = [System.Windows.Forms.AnchorStyles]::Bottom -bor [System.Windows.Forms.AnchorStyles]::Right
$a = (Get-ChildItem "C:\Scripts\").Name
$b = (Get-ChildItem "C:\Applications\").Name
$c = (Get-ChildItem "C:\Systems\").Name
$d = (Get-ChildItem "C:\Databases\").Name
$e = (Get-ChildItem "C:\Datas\").Name
$f = (Get-ChildItem "C:\Backups\").Name
$Entry = New-Object System.Windows.Forms.ListViewItem($_.Null)
foreach($mp in $a){
$Entry1 = New-Object System.Windows.Forms.ListViewItem($_.Scripts)
$Listview.Items.Add($mp)
}
foreach($mp1 in $b){
$Entry2 = New-Object System.Windows.Forms.ListViewItem($_.Applications)
$Listview.Items.Add($Entry2).SubItems.Add($mp1)
}
foreach($mp2 in $c){
$Entry3 = New-Object System.Windows.Forms.ListViewItem($_.Systems)
$Listview.Items.Add($Entry3).SubItems.Add($mp2)
}
foreach($mp3 in $d){
$Entry4 = New-Object System.Windows.Forms.ListViewItem($_.Databases)
$Listview.Items.Add($Entry4).SubItems.Add($mp3)
}
foreach($mp4 in $e){
$Entry5 = New-Object System.Windows.Forms.ListViewItem($_.Datas)
$Listview.Items.Add($Entry5).SubItems.Add($mp4)
}
foreach($mp5 in $f){
$Entry6 = New-Object System.Windows.Forms.ListViewItem($_.Backup)
$Listview.Items.Add($Entry6).SubItems.Add($mp5)
}
$Form.Add_Shown({$Form.Activate()})
$Form.controls.add($oButton)
$Form.controls.add($Listview)
$Form.ShowDialog()
I tried a lot of change but im still blocked
Thanks in advance for you help
Regards

Related

How to close form GUI after checking existing file in PowerShell?

I want to check an existing file, if the process still waiting for the file, it will display a GUI window. After the file is exist, the window will close automatically.
I tried this code, the window can not close, even the file already exist.
Checking the file:
$SN = "708TSTA"
$MAC = "2E5961370"
function Find {
$n = 0
while (-not (Get-ChildItem -Name "D:\SERVER\" | Where-Object {$_ -like "*$SN-$MAC*"})) {
Start-Sleep -s 1
D:\Auto\GUI.ps1
$n++
(Get-ChildItem -Name "D:\SERVER\" | Where-Object {$_ -like "*$SN-$MAC*"})
Write-Host "Attempt no $n"
}
Write-Host ">>Flag found after $n attempts"
return $true
}
if (Find) {
Write-Host "Found"
}
GUI.ps1:
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
$Form = New-Object System.Windows.Forms.Form
$Form.ClientSize = '578,400'
$Form.Text = "Form"
$Form.BackColor = "#c1daf7"
$Form.WindowState = 'Maximized'
$Form.FormBorderStyle = "FixedDialog"
$Label1 = New-Object System.Windows.Forms.Label
$Label1.Text = "UNDER PROCESS"
$Label1.AutoSize = $true
$Label1.Width = 25
$Label1.Height = 10
$Label1.Location = New-Object System.Drawing.Point(600,300)
$Label1.Font = 'Microsoft Sans Serif,30,style=Bold,Underline'
$Label1.ForeColor = "#d0021b"
$Label2 = New-Object System.Windows.Forms.Label
$Label2.Text = "WAITING"
$Label2.AutoSize = $true
$Label2.Width = 25
$Label2.Height = 10
$Label2.Location = New-Object System.Drawing.Point(770,500)
$Label2.Font = 'Microsoft Sans Serif,20,style=Bold'
$Label2.ForeColor = "#fb0505"
$Check = Get-ChildItem -Name "D:\SERVER\" | Where-Object {$_ -like "*$SN-$MAC*"}
if($Check) {
Write-Host "File Exist"
$Form.Close()
}
$Form.Controls.AddRange(#($Label1,$Label2))
[void]$Form.ShowDialog()
Instead of doing Start-Sleep inside the GUI, it is better to use a timer so the form stays responsive.
I changed the code of the GUI.ps1 (not the way it looks) like this:
Param (
[string]$Path = '*.*',
[string]$MaxAttempts = 5
)
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
# set things up for the timer
$script:nAttempts = 0
$timer = New-Object System.Windows.Forms.Timer
$timer.Interval = 1000 # 1 second
$timer.Add_Tick({
$global:Result = $null
$script:nAttempts++
$file = Get-Item -Path $Path
if ($file) {
$global:Result = [PSCustomObject]#{
Exists = $true
FileName = $file.FullName
Attempts = $script:nAttempts
}
$timer.Dispose()
$Form.Close()
}
elseif ($script:nAttempts -ge $MaxAttempts) {
$global:Result = [PSCustomObject]#{
Exists = $false
FileName = ''
Attempts = $script:nAttempts
}
$timer.Dispose()
$Form.Close()
}
})
$Form = New-Object System.Windows.Forms.Form
$Form.ClientSize = '578,400'
$Form.Text = "Form"
$Form.BackColor = "#c1daf7"
$Form.WindowState = 'Maximized'
$Form.FormBorderStyle = "FixedDialog"
$Label1 = New-Object System.Windows.Forms.Label
$Label1.Text = "UNDER PROCESS"
$Label1.AutoSize = $true
$Label1.Width = 25
$Label1.Height = 10
$Label1.Location = New-Object System.Drawing.Point(600,300)
$Label1.Font = 'Microsoft Sans Serif,30,style=Bold,Underline'
$Label1.ForeColor = "#d0021b"
$Label2 = New-Object System.Windows.Forms.Label
$Label2.Text = "WAITING"
$Label2.AutoSize = $true
$Label2.Width = 25
$Label2.Height = 10
$Label2.Location = New-Object System.Drawing.Point(770,500)
$Label2.Font = 'Microsoft Sans Serif,20,style=Bold'
$Label2.ForeColor = "#fb0505"
$Form.Controls.AddRange(#($Label1,$Label2))
# start the timer as soon as the dialog is visible
$Form.Add_Shown({ $timer.Start() })
[void]$Form.ShowDialog()
# clean up when done
$Form.Dispose()
And to call it from your other script, use:
$SN = "708TSTA"
$MAC = "2E5961370"
function Test-FileExists {
$file = Get-Item -Path "D:\*$SN-$MAC*"
if ($file) {
$global:Result = [PSCustomObject]#{
Exists = $true
FileName = $file.FullName
Attempts = 1
}
}
else {
& "D:\GUI.ps1" -Path "D:\*$SN-$MAC*" -MaxAttempts 3
}
}
# call the function that can call the GUI.ps1 script
Test-FileExists
# check the Global result object
if ($global:Result.Exists) {
Write-Host "File '$($global:Result.FileName)' Exists. Found after $($global:Result.Attempts) attempts." -ForegroundColor Green
}
else {
Write-Host "File not found after $($global:Result.Attempts) attempts." -ForegroundColor Red
}
Update
As per your comments, I understand that the calling script should show the form (which does nothing more that show on screen) AND is responsible for closing it after the file has been found.
The code below should do what you ask by defining the $Form as a global variable and by using the .Show() method of the form instead of ShowDialog():
GUI.ps1
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
$global:Form = New-Object System.Windows.Forms.Form
$global:Form.ClientSize = '578,400'
$global:Form.Text = "Form"
$global:Form.BackColor = "#c1daf7"
$global:Form.WindowState = 'Maximized'
$global:Form.FormBorderStyle = "FixedDialog"
$global:Form.ControlBox = $false # hide sizing and close buttons
$global:Form.TopMost = $true
$Label1 = New-Object System.Windows.Forms.Label
$Label1.Text = "UNDER PROCESS"
$Label1.AutoSize = $true
$Label1.Width = 25
$Label1.Height = 10
$Label1.Location = New-Object System.Drawing.Point(600,300)
$Label1.Font = 'Microsoft Sans Serif,30,style=Bold,Underline'
$Label1.ForeColor = "#d0021b"
$Label2 = New-Object System.Windows.Forms.Label
$Label2.Text = "WAITING"
$Label2.AutoSize = $true
$Label2.Width = 25
$Label2.Height = 10
$Label2.Location = New-Object System.Drawing.Point(770,500)
$Label2.Font = 'Microsoft Sans Serif,20,style=Bold'
$Label2.ForeColor = "#fb0505"
$global:Form.Controls.AddRange(#($Label1,$Label2))
# don't use ShowDialog() here because it will block the calling script
$global:Form.Show()
the calling script
function Test-FileExists {
[CmdletBinding()]
param (
[parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)]
[string]$Path,
[string]$Pattern = '*.*'
)
$nAttempts = 1
$file = Get-ChildItem -Path $Path -Filter $Pattern -File | Select-Object -First 1
if (!$file) {
# show the GUI
& "D:\GUI.ps1"
do {
Start-Sleep -Seconds 1
$nAttempts++
Write-Verbose "Attempt No. $nAttempts"
$file = Get-ChildItem -Path $Path -Filter $Pattern -File | Select-Object -First 1
} until ($file)
# clean up the form
$global:Form.Dispose()
$global:Form = $null
}
Write-Verbose "File '$($file.FullName)' Exists. Found after $nAttempts attempt(s)."
return $true
}
$SN = "708TSTA"
$MAC = "2E5961370"
# call the function that can call the GUI.ps1 script
if (Test-FileExists -Path 'D:\SERVER\SHARE' -Pattern "*$SN-$MAC*" -Verbose) {
Write-Host "Found"
}
Hope that helps

Intermittent error (index into null) with detection of SelectedIndex change in Windows Forms

I'm getting an intermittent error with this method of changing a forms text label according to the selected item in a Listview box.
Example code as below, changing the entry will intermittently give:
Cannot index into a null array.
At C:\temp\test.ps1:62 char:5
+ $SelectedPath.Text = $VMsListBox.SelectedItems.SubItems[1].Text
# Import namespaces
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$form = New-Object System.Windows.Forms.Form
$form.Text = 'Demo'
$form.Size = '580,545'
$form.StartPosition = 'CenterScreen'
$form.FormBorderStyle = 'FixedSingle'
$form.MaximizeBox = $false
# Listview box to display found open files
$VMsListBox = New-Object System.Windows.Forms.ListView
$VMsListBox.View = [System.Windows.Forms.View]::Details
$VMsListBox.Location = '15,120'
$VMsListBox.size = '435,10'
$VMsListBox.Height = 250
$VMsListBox.Columns.Add('Name') | Out-Null
$VMsListBox.Columns.Add('Path') | Out-Null
$VMsListBox.FullRowSelect = $true
$VMsListBox.MultiSelect = $false
# Selected file label
$SelectedFnameLbl = New-Object System.Windows.Forms.Label
$SelectedFnameLbl.Location = '10,25'
$SelectedFnameLbl.Size = '80,19'
$SelectedFnameLbl.Text = 'File Name:'
# Selected file name
$SelectedFname = New-Object System.Windows.Forms.Label
$SelectedFname.Location = '100,25'
$SelectedFname.Size = '300,19'
$SelectedFname.Text = 'n/a'
$SelectedFname.AutoEllipsis = $true
# Path Label
$SelectedFileLbl = New-Object System.Windows.Forms.Label
$SelectedFileLbl.Location = '10,45'
$SelectedFileLbl.Size = '80,19'
$SelectedFileLbl.Text = 'File Path:'
# Selected filepath
$SelectedPath = New-Object System.Windows.Forms.Label
$SelectedPath.Location = '100,45'
$SelectedPath.Size = '300,19'
$SelectedPath.Text = 'n/a'
$SelectedPath.AutoEllipsis = $true
$form.Controls.AddRange(#($VMsListBox,$SelectedFileLbl,$SelectedPath,$SelectedFnameLbl,$SelectedFname))
# Populate ListView
$Files = Get-ChildItem -Path 'c:\temp' -File
$Files | ForEach-Object {
$Entry = New-Object System.Windows.Forms.ListViewItem($_.Name) -ErrorAction Stop
$Entry.SubItems.Add($_.FullName) | Out-Null
$VMsListBox.Items.Add($Entry) | Out-Null
}
$VMsListBox_SelectedIndexChanged={
$SelectedFname.Text = $VMsListBox.SelectedItems.Text
$SelectedPath.Text = $VMsListBox.SelectedItems.SubItems[1].Text
Write-Host "Entry changed"
}
$VMsListBox.Add_SelectedIndexChanged($VMsListBox_SelectedIndexChanged)
# Show form
$form.ShowDialog() | Out-Null
$form.Dispose()
Can anyone point me where I'm going wrong please? Or is there a better way of doing this
Ok, I found this
Apparently retained legacy behaviour and the fix is to check for null:
$VMsListBox_SelectedIndexChanged={
If($VMsListbox.SelectedItems -ne $Null){
$SelectedFname.Text = $VMsListBox.SelectedItems.Text
$SelectedPath.Text = $VMsListBox.SelectedItems.SubItems[1].Text
Write-Host "Entry changed"
}
}

Using a function to populate a textbox in Powershell

I currently have a script that queries our AD for the users' AD attribute "Department".
Right now, the script will run "successfully" but all output for Textbox2 goes to the console instead of TextBox2.
If I change my function Get-CCUsers to be a query without variables, like Get-ADUser -Filter "Department -eq 19330" (we use numbers for our departments) then the output shows in TextBox2 as I want it to.
How can I get my function to populate TextBox2?
BTW, this script was cobbled together with my limited understanding, and there may well be superfluous or nonsense lines in here.
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$form = New-Object System.Windows.Forms.Form
$form.Text = 'Howard Center Profile Migration'
$form.Size = New-Object System.Drawing.Size(800,650)
$form.StartPosition = 'CenterScreen'
$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Point(150,120)
$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 = 'Please enter the Cost Center # in the space below:'
$form.Controls.Add($label)
$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Point(10,40)
$textBox.Size = New-Object System.Drawing.Size(100,20)
$form.Controls.Add($textBox)
$RunButton = New-Object System.Windows.Forms.Button
$RunButton.Location = New-Object System.Drawing.Point(75,120)
$RunButton.Size = New-Object System.Drawing.Size(75,23)
$RunButton.Text = 'RUN'
#$RunButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
<#$RunButton.Add_Click({
#add here code triggered by the event
$TextBox2.Text = Get-Process | Format-Table -Property ProcessName, Id, CPU -AutoSize | Out-String
})
#>
$form.AcceptButton = $RunButton
$form.Controls.Add($RunButton)
$label2 = New-Object System.Windows.Forms.Label
$label2.Location = New-Object System.Drawing.Point(10,70)
$label2.Size = New-Object System.Drawing.Size(280,20)
$label2.Text = 'When you are ready click the Run button below'
$form.Controls.Add($label2)
$TextBox2 = New-Object system.windows.Forms.TextBox
$TextBox2.Text = ""
$TextBox2.Multiline = $true
$TextBox2.BackColor = "#013686"
$TextBox2.ScrollBars = "Both"
$TextBox2.Width = 750
$TextBox2.Height = 450
$TextBox2.location = new-object system.drawing.point(10,150)
$TextBox2.Font = "Microsoft Sans Serif,10"
$TextBox2.ForeColor = "#ffffff"
$Form.controls.Add($TextBox2)
$form.Topmost = $true
function Get-CCUsers {
Write-Host "The textbox text is $textbox.Text"
$dept = $textBox.Text
$deptUsers = Get-ADUser -Filter "Department -eq $dept"
ForEach ($user in $deptUsers) {
IF ( ((get-aduser $user).enabled) -eq $True ) {
$UHomeDir = (Get-ADUser $user -Properties HomeDirectory).HomeDirectory
$UProfPath = (Get-ADUser $user -Properties ProfilePath).ProfilePath
Write-Host "$user, $UHomeDir, $UProfPath"
}
}
}
$RunButton.Add_Click({
$TextBox2.Text = Get-CCUsers
})
$TextBox2.Add_TextChanged({
$TextBox2.SelectionStart = $TextBox2.Text.Length
$TextBox2.ScrollToCaret()
})
$form.Add_Shown({$Form.Update()})
$result = $form.ShowDialog()
$global:x = $textBox.Text
# $x
# if ($result -eq [System.Windows.Forms.DialogResult]::OK)
#{
#}
I have made your script working changing the 'Get-CCUSers' function
function Get-CCUsers {
Write-Host "The textbox text is $textbox.Text"
$dept = $textBox.Text
$deptUsers = Get-ADUser -Filter "Department -eq '$dept'"
$res = #()
ForEach ($user in $deptUsers) {
IF ( ((get-aduser $user).enabled) -eq $True ) {
$UHomeDir = (Get-ADUser $user -Properties HomeDirectory).HomeDirectory
$UProfPath = (Get-ADUser $user -Properties ProfilePath).ProfilePath
$res += "$user, $UHomeDir, $UProfPath"
}
}
return $res
}
In short:
I removed the Write-Host (the output was actually redirected to stdout)
I added a $res in the function initialized as array
In the ForEach loop, results are added as items in the array
The $res is returned by the function, and then used $RunButton

return value from function with combobox

I have a small GUI that will connect to a vCenter in a list. The forms open in the order I want, but I can't carry values between them. I've tried so many return calls I don't know what else to do.
Here is the code. Basically, the first form opens and asks for which vCenter you want. Then prompts you to authenticate (this all works wonderfully). But the problem comes in after the script is done. I don't get any return values.
function Connect-Vc ($vcArg)
{
$Form2 = $null
$selectedVC = $vcArg.selecteditem
$viconnection = $null
if ($global:defaultviserver -ne $null)
{
Disconnect-viserver * -confirm:$false
}
$clusterselection = $null
$DropDownTo = $null
$credential = Get-Credential -Message "Please Enter Elevated Credentials To Access $selectedVC. You can enter assuming you're an administrator on $selectedVC."
$username = $credential.Username
$password = $credential.GetNetworkCredential().Password
$viconnection = connect-viserver $selectedVC -User $username -Password $password
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Windows.Forms.Application]::EnableVisualStyles()
$Form2 = New-Object System.Windows.Forms.Form
$Form2.AutoSize = $True
$Form2.AutoSizeMode = "GrowAndShrink"
$Form2.width = 600
$Form2.height = 500
$Form2.Text = ”Vcenter Selection”
$Form2.StartPosition = "CenterScreen"
#First item selection*******************
$DropDownLabel1 = new-object System.Windows.Forms.Label
$DropDownLabel1.Location = new-object System.Drawing.Size(140,10)
$DropDownLabel1.size = new-object System.Drawing.Size(130,30)
$DropDownLabel1.Text = "$selectedVC"
$Form2.Controls.Add($DropDownLabel1)
$DropDownLabel2 = new-object System.Windows.Forms.Label
$DropDownLabel2.Location = new-object System.Drawing.Size(10,10)
$DropDownLabel2.size = new-object System.Drawing.Size(100,40)
$DropDownLabel2.Text = "Connected to Vcenter"
$Form2.Controls.Add($DropDownLabel2)
#Second item selection*******************
[array]$clusterselection = get-cluster
$DropDownTo = New-Object System.Windows.Forms.ComboBox
$DropDownTo.Location = New-Object System.Drawing.Size(140,50)
$DropDownTo.Size = New-Object System.Drawing.Size(130,30)
$DropdownTo.DropDownStyle = 2
ForEach ($Item2 in $clusterselection)
{
[void] $DropDownTo.Items.Add($Item2)
}
$Form2.Controls.Add($DropDownTo)
$DropDownLabel3 = new-object System.Windows.Forms.Label
$DropDownLabel3.Location = new-object System.Drawing.Size(10,50)
$DropDownLabel3.size = new-object System.Drawing.Size(100,40)
$DropDownLabel3.Text = "Select Cluster Location"
$Form2.Controls.Add($DropDownLabel3)
#Third item selection*******************
$DropDownType = New-Object System.Windows.Forms.ComboBox
$DropDownType.Location = New-Object System.Drawing.Size(140,90)
$DropDownType.Size = New-Object System.Drawing.Size(130,30)
$DropDownType.DropDownStyle = 2
ForEach ($Item3 in $typeOfServer)
{
[void] $DropDownType.Items.Add($Item3)
}
$Form2.Controls.Add($DropDownType)
$DropDownLabel4 = new-object System.Windows.Forms.Label
$DropDownLabel4.Location = new-object System.Drawing.Size(10,90)
$DropDownLabel4.size = new-object System.Drawing.Size(100,40)
$DropDownLabel4.Text = "Select Type of Server"
$Form2.Controls.Add($DropDownLabel4)
#Fourth item Input*******************
$InputName = New-Object System.Windows.Forms.Textbox
$InputName.Location = New-Object System.Drawing.Size(140,130)
$InputName.Size = New-Object System.Drawing.Size(130,30)
$InputName.MaxLength = 15
$Form2.Controls.Add($InputName)
$inputLabel = new-object System.Windows.Forms.Label
$inputLabel.Location = new-object System.Drawing.Size(10,130)
$inputLabel.size = new-object System.Drawing.Size(100,40)
$inputLabel.Text = "Enter Name of Server"
$Form2.Controls.Add($inputLabel)
#Fifth item selection*******************
$dropDownMem = New-Object System.Windows.Forms.Combobox
$dropDownMem.Location = New-Object System.Drawing.Size(140,170)
$dropDownMem.Size = New-Object System.Drawing.Size(130,30)
$dropDownMem.DropDownStyle = 2
ForEach ($Item5 in $mem)
{
[void] $dropDownMem.Items.Add($Item5)
}
$Form2.Controls.Add($dropDownMem)
$DropDownLabel5 = new-object System.Windows.Forms.Label
$DropDownLabel5.Location = new-object System.Drawing.Size(10,170)
$DropDownLabel5.size = new-object System.Drawing.Size(100,40)
$DropDownLabel5.Text = "Select Memory Quantity in GB"
$Form2.Controls.Add($DropDownLabel5)
#Sixth item selection*******************
$dropDownvCpu = New-Object System.Windows.Forms.Combobox
$dropDownvCpu.Location = New-Object System.Drawing.Size(140,210)
$dropDownvCpu.Size = New-Object System.Drawing.Size(130,30)
$dropDownvCpu.DropDownStyle = 2
ForEach ($Item6 in $vCpu)
{
[void] $dropDownvCpu.Items.Add($Item6)
}
$Form2.Controls.Add($dropDownvCpu)
$DropDownLabel6 = new-object System.Windows.Forms.Label
$DropDownLabel6.Location = new-object System.Drawing.Size(10,210)
$DropDownLabel6.size = new-object System.Drawing.Size(100,40)
$DropDownLabel6.Text = "Select Virtual CPU's"
$Form2.Controls.Add($DropDownLabel6)
#Seventh item selection*******************
$dropDownOS = New-Object System.Windows.Forms.Combobox
$dropDownOS.Location = New-Object System.Drawing.Size(140,250)
$dropDownOS.Size = New-Object System.Drawing.Size(130,30)
$dropDownOS.DropDownStyle = 2
ForEach ($Item7 in $operatingSystem)
{
[void] $dropDownOS.Items.Add($Item7)
}
$Form2.Controls.Add($dropDownOS)
$DropDownLabel7 = new-object System.Windows.Forms.Label
$DropDownLabel7.Location = new-object System.Drawing.Size(10,250)
$DropDownLabel7.size = new-object System.Drawing.Size(100,40)
$DropDownLabel7.Text = "Select Operating System"
$Form2.Controls.Add($DropDownLabel7)
#Defines buttons for click to accept*********************
#$Button1 = new-object System.Windows.Forms.Button
#$Button1.Location = new-object System.Drawing.Size(10,300)
#$Button1.Size = new-object System.Drawing.Size(100,20)
#$Button1.Text = "Provision Vm"
#$Button1.Add_Click({Provision-VM})
#$Button1.Add_Click({Get-Account $oRphanedAcct})
#Defines buttons for click to accept*********************
$Button2 = new-object System.Windows.Forms.Button
$Button2.Location = new-object System.Drawing.Size(10,330)
$Button2.Size = new-object System.Drawing.Size(100,20)
$Button2.Text = "Provision Vm"
$Button2.Add_Click({Provision-VM -arg1 "$choice4" -arg2 "$choice5" -arg3 "$Choice3"})
#Defines buttons for click to accept*********************
$Button3 = new-object System.Windows.Forms.Button
$Button3.Location = new-object System.Drawing.Size(140,330)
$Button3.Size = new-object System.Drawing.Size(100,20)
$Button3.Text = "Close Form"
#$Button3.Add_Click({Return-Drop})
$Button3.Add_Click({$Form2.Dispose()})
#Defines buttons for click to accept*********************
$Button4 = new-object System.Windows.Forms.Button
$Button4.Location = new-object System.Drawing.Size(275,330)
$Button4.Size = new-object System.Drawing.Size(100,20)
$Button4.Text = "Ok Button"
$Button4.Dialogresult = [System.Windows.Forms.DialogResult]::OK
$Form2.AcceptButton = $Button4
$Form2.Controls.Add($Button2)
$Form2.Controls.Add($Button3)
$Form2.Controls.Add($Button4)
$Form2.Topmost = $True
$Form2.ShowDialog()
$Form2.refresh()
return $DropdownTo.SelectedItem
return $DropDownType.SelectedItem.ToString()
return $InputName.SelectedItem.ToString()
return $DropDownMem.SelectedItem.ToString()
return $DropDownVcpu.SelectedItem.ToString()
return $DropDownOS.SelectedItem.ToString()
return $Button3
return $Button4
}
#Main function definition********************
function Menu
{
$clusterselection = $null
$global:defaultviserver = $null
[array]$VCItems = "VCSelection","VCSelection2","VCSelection3"
[array]$typeOfServer = "Vanilla", "IIS", "SQL", "SQL_Cluster_Node"
[array]$operatingSystem = "Windows2012", "Windows2016"
[array]$mem = "2","4","6","8","10","12","32","64"
[array]$vCpu = "2","4","6","8","10","12"
#Function for Closing Form Upon no input
function Return-Drop
{
If (($dropDownVC.SelectedItem -ne $null) -or ($DropDownTO.SelectedItem -ne $null) -or ($DropDownType.SelectedItem -ne $null))
{
$Form.Close()
}
}
#Function for connecting to Vcenter
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Windows.Forms.Application]::EnableVisualStyles()
$Form = New-Object System.Windows.Forms.Form
$Form.AutoSize = $True
$Form.AutoSizeMode = "GrowAndShrink"
$Form.width = 600
$Form.height = 500
$Form.Text = ”Vcenter Selection”
$Form.StartPosition = "CenterScreen"
#First item selection*******************
$DropDownVC = New-Object System.Windows.Forms.ComboBox
$DropDownVC.Location = New-Object System.Drawing.Size(140,10)
$DropDownVC.Size = New-Object System.Drawing.Size(130,30)
$DropDownVC.DropDownStyle = 2
$DropDownVC.TabIndex = 0
ForEach ($Item1 in $VCItems)
{
[void] $DropDownVC.Items.Add($Item1)
}
$DropDownVC.SelectedItem = $DropDownVC.Items[0]
$Form.Controls.Add($DropDownVC)
$DropDownLabel1 = new-object System.Windows.Forms.Label
$DropDownLabel1.Location = new-object System.Drawing.Size(10,10)
$DropDownLabel1.size = new-object System.Drawing.Size(100,40)
$DropDownLabel1.Text = "Select Vcenter to connect to"
$Form.Controls.Add($DropDownLabel1)
#Defines buttons for click to connect to VC*********************
$Button5 = new-object System.Windows.Forms.Button
$Button5.Location = new-object System.Drawing.Size(290,10)
$Button5.Size = new-object System.Drawing.Size(100,20)
$Button5.Text = "Connect"
$Button5.Add_Click({$form.visible = $false;$t = Connect-Vc -vcArg $DropDownVC})
$Form.Controls.Add($Button5)
$Form.Topmost = $True
$Form.Add_Shown({$Form.Activate()})
$Form.ShowDialog()
$Choice1 = $DropDownVC.SelectedItem.ToString()
enter code here
return $Choice1
}

Creating a progress bar for a search function

I am trying to make a progress bar in a powershell generated GUI that will show the progress of a search as the system caches all the groups in AD (there are about 12,000 so this just otherwise causes the system to hang for a short while)
I managed to build the bar etc but I cannot get it to fill the bar as the system adds the groups. Here is what I have so far:
[reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null
[reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null
$Form = New-Object System.Windows.Forms.Form
$Form.width = 345
$Form.height = 345
$Form.StartPosition = "CenterScreen"
$Form.ShowInTaskbar = $True
$Form.FormBorderStyle = 'FixedToolWindow'
$ExitButt = new-object System.Windows.Forms.Button
$ExitButt.Location = new-object System.Drawing.Size(235,5)
$ExitButt.Size = new-object System.Drawing.Size(100,20)
$ExitButt.Text = "Exit"
$Form.Controls.Add($ExitButt)
$ExitButt.Add_Click({$Form.Close()})
$Prog = New-Object System.Windows.Forms.ProgressBar
$Prog.Maximum = 10000
$Prog.Minimum = 0
$Prog.Location = new-object System.Drawing.Size(50,50)
$Prog.size = new-object System.Drawing.Size(100,50)
$Form.Controls.Add($Prog)
$Button = new-object System.Windows.Forms.Button
$Button.Location = new-object System.Drawing.Size(120,100)
$Button.Size = new-object System.Drawing.Size(100,30)
$Button.Text = "Start Progress"
$Form.Controls.Add($Button)
$Button.add_click(
{
$GroupsList = Get-ADGroup -Server "server" -Filter *
$Count = ($GroupsList | Measure-Object).Count
$prog.Value = $Count
}
)
$form.ShowDialog() | Out-Null
To update a WinForms ProgressBar just set its Value property.
Eg.
# Initialisation...
$myProgBar.Minimum = 1;
$myProgBar.Maximum = 100;
# When something happens...
$myProgBar.Value = 50;
will set it to half way.

Resources