I'm still a beginner with powershell, but love to learn and research all the things it can do.
So with that, I am looking to create a script that will output to a datagridview table. I created a simple enough form that has a multi-line text box where you can enter in a list of servers and then just a simple "check" button that calls my function to actually query each server for their services and outputs that info into the datagridview below it.
That part was easy enough for me to create. My thing is, I want it to do the following":
- query each server and pull the list of all services on that server
- then in the datagridview, I want it to show the service name in column 1, and then the count of how many servers have that service in column 2
Hope this make since. Can't really provide any code as I don't know how to properly write it! I'm thinking there is someway to generate the full list, then do a loop and count type thing, but not sure.
I thank you for any assistance with this. Been googling and reading up like crazy. Either not correct search criteria or something just isn't clicking for me.
Update - Adding in current script I have:
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$xForm = 800
$yForm = 800
$SVCForm = New-Object System.Windows.Forms.Form
$SVCForm.Text = "Automatic Services Query"
$SVCForm.Size = New-Object System.Drawing.Size($xForm,$yForm)
$SVCForm.FormBorderStyle = "FixedSingle"
$SVCForm.StartPosition = "CenterScreen"
$SVCForm.ControlBox = $true
$SVCForm.KeyPreview = $True
$SVCForm.ShowIcon = $false
$SVCForm.MinimizeBox = $True
$SVCForm.MaximizeBox = $false
$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Size(365,720)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = "Cancel"
$CancelButton.Add_Click({$x=$CancelButton.Text;$SVCForm.Close()})
$SVCForm.Controls.Add($CancelButton)
$ServerListGroup = New-Object System.Windows.Forms.GroupBox
$ServerListGroup.Location = New-Object System.Drawing.Size(5,10)
$ServerListGroup.size = New-Object System.Drawing.Size(780,300)
$ServerListGroup.text = "Enter list of servers you want to check:"
$SVCForm.Controls.Add($ServerListGroup)
$ServerList = New-object System.Windows.Forms.TextBox
$ServerList.Location = New-object System.Drawing.Size(5,25)
$ServerList.Size = New-Object System.Drawing.Size(280,270)
$ServerList.Multiline = $True
$ServerList.ScrollBars = "Vertical"
#$ServerList.add_TextChanged({ONValButton})
$ServerListGroup.Controls.Add($ServerList)
$SVCButton = New-Object System.Windows.Forms.Button
$SVCButton.Location = New-Object System.Drawing.Size(505,140)
$SVCButton.Size = New-Object System.Drawing.Size(180,22)
$SVCButton.Text = "SVC Check"
$SVCButton.Enabled = $True
$SVCButton.Add_Click({SvcCheckCount})
$ServerListGroup.Controls.Add($SVCButton)
$SvcListGroup = New-Object System.Windows.Forms.GroupBox
$SvcListGroup.Location = New-Object System.Drawing.Size(5,330)
$SvcListGroup.size = New-Object System.Drawing.Size(780,380)
$SvcListGroup.text = "Automatic Running/Not-Running Services are listed below:"
$SVCForm.Controls.Add($SvcListGroup)
#$SvcList = New-object System.Windows.Forms.TextBox
#$SvcList.Location = New-object System.Drawing.Size(5,25)
#$SvcList.Size = New-Object System.Drawing.Size(765,350)
#$SvcList.Multiline = $True
#$SvcList.ScrollBars = "Vertical"
#$SvcList.Readonly= $True
#$SvcListGroup.Controls.Add($SvcList)
$SvcGrid = New-Object System.Windows.Forms.DataGridView
$SvcGrid.Location = New-Object System.Drawing.Size(5,15)
$SvcGrid.Size = New-Object System.Drawing.Size(760,360)
$SvcGrid.ColumnHeadersBorderStyle = [System.Windows.Forms.DataGridViewHeaderBorderStyle]::Single
$SvcGrid.CellBorderStyle = [System.Windows.Forms.DataGridViewCellBorderStyle]::Single
$SvcGrid.ColumnHeadersHeightSizeMode = [System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode]::DisableResizing
$SvcGrid.GridColor = [System.Drawing.Color]::Black
$SvcGrid.RowHeadersVisible = $false
$SvcGrid.AllowUserToAddRows = $false
$SvcGrid.AllowUserToResizeColumns = $False
$SvcGrid.AllowUserToResizeRows = $false
$SvcGrid.ColumnHeadersHeight = 23
$SvcGrid.SelectionMode = [System.Windows.Forms.DataGridViewSelectionMode]::FullRowSelect
$Scroll = New-Object System.Windows.Forms.VScrollBar
$Scroll.Dock = [System.Windows.Forms.DockStyle]::Right
$Scroll.width = 18
$Scroll.isAccessible = $false
$SvcGrid.Controls.Add($Scroll)
$SvcGrid.Columns.Add("Name","Service Name") > $null
$SvcGrid.Columns["Name"].Width = 200
$SvcGrid.Columns["Name"].HeaderCell.Style.Alignment = [System.Windows.Forms.DataGridViewContentAlignment]::MiddleLeft
$SvcGrid.Columns["Name"].DefaultCellStyle.Alignment = [System.Windows.Forms.DataGridViewContentAlignment]::MiddleLeft
$SvcGrid.Columns["Name"].ReadOnly = $False
$SvcGrid.Columns.Add("StartMode", "Start Mode") > $null
$SvcGrid.Columns["StartMode"].Width = 180
$SvcGrid.Columns["StartMode"].HeaderCell.Style.Alignment = [System.Windows.Forms.DataGridViewContentAlignment]::MiddleLeft
$SvcGrid.Columns["StartMode"].DefaultCellStyle.Alignment = [System.Windows.Forms.DataGridViewContentAlignment]::MiddleLeft
$SvcGrid.Columns["StartMode"].ReadOnly = $False
$SvcGrid.Columns.Add("Running","Running") > $null
$SvcGrid.Columns["Running"].Width = 180
$SvcGrid.Columns["Running"].HeaderCell.Style.Alignment = [System.Windows.Forms.DataGridViewContentAlignment]::MiddleCenter
$SvcGrid.Columns["Running"].DefaultCellStyle.Alignment = [System.Windows.Forms.DataGridViewContentAlignment]::MiddleCenter
$SvcGrid.Columns["Running"].ReadOnly = $true
$SvcGrid.Columns.Add("NotRunng","Not Running")>$null
$SvcGrid.Columns["NotRunng"].Width = 180
$SvcGrid.Columns["NotRunng"].HeaderCell.Style.Alignment = [System.Windows.Forms.DataGridViewContentAlignment]::MiddleCenter
$SvcGrid.Columns["NotRunng"].DefaultCellStyle.Alignment = [System.Windows.Forms.DataGridViewContentAlignment]::MiddleCenter
$SvcGrid.Columns["NotRunng"].ReadOnly = $true
$SvcListGroup.Controls.Add($SvcGrid)
Function SvcCheckCount
{
$SvcGrid.Rows.Clear()
$Servername = $ServerList.Text.Split("`n")|%{$_.trim()}
foreach($Server in $Servername)
{
$Server = $Server.ToUpper()
$svctest = Get-WmiObject Win32_Service | Where-Object {$_.StartMode -eq 'Auto'} | Select-Object Name, Startmode, State
Foreach ($svc in $svctest)
{
$name = $svc.Name
$startmode = $svc.StartMode
$state = $svc.State
If($state-eq"Running"){$SvcGrid.Rows.add($name,$startmode,$state)}
If($state-eq"Stopped"){$SvcGrid.Rows.add($name,$startmode,$null,$state)}
}
}
}
$SVCForm.Topmost = $True
$SVCForm.Add_Shown({$SVCForm.Activate()})
[void] $SVCForm.ShowDialog()
Since you already have the GUI portion of this functioning I am going to focus us the grouping of the data you are looking for. Going into this the one thing I am fuzzy on is why you have the
if
statements are for but we can work on that if need be. The following is meant to be in place of yourforeach
loopFirst thing: you were not using the
$server
variable in your wmi call so all the results would have been from the one machine you were running this from. Also, I moved theWhere
into a-Filter
so that should speed up processing on remote machines.Collect all of this information into an array (adding the computer name in case it becomes useful later). Then, using the results from that use
Group-Object
to get the counts you were looking for. Pipe that into anotherForEach-Object
to get the results in your grid ( which i have not tested.)Side note: If you just want the info in a grid you can use
Out-GridView