Подсчет сервисов на нескольких серверах

Я все еще начинающий с PowerShell, но люблю учиться и исследовать все, что он может сделать.

Итак, я собираюсь создать сценарий, который будет выводить в таблицу таблицы данных. Я создал достаточно простую форму с многострочным текстовым полем, в котором вы можете ввести список серверов, а затем просто простую кнопку "проверить", которая вызывает мою функцию, чтобы фактически запрашивать у каждого сервера свои услуги и выводить эту информацию в datagridview ниже этого.

Эту часть мне было достаточно легко создать. Дело в том, что я хочу сделать следующее ":

  • запросить каждый сервер и получить список всех служб на этом сервере
  • затем в представлении данных я хочу, чтобы в столбце 1 было показано имя службы, а затем в столбце 2 указано количество серверов, на которых эта служба имеется.

Надеюсь, что это сделать с тех пор. Не могу предоставить какой-либо код, потому что я не знаю, как правильно его написать! Я думаю, что есть какой-то способ сгенерировать полный список, затем сделать цикл и подсчитать тип, но не уверен.

Я благодарю вас за любую помощь с этим. Погуглил и читал как сумасшедший. Либо не правильный критерий поиска, либо что-то не подходит для меня.

Обновление - добавление в текущий скрипт у меня:

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

1 ответ

Решение

Поскольку у вас уже есть часть GUI этой функции, я собираюсь сфокусировать нас на группировке данных, которые вы ищете. Занимаясь этим, я не совсем понимаю, почему у вас есть if заявления для, но мы можем работать над этим, если это будет необходимо. Следующее должно быть вместо вашего foreach петля

$services = @()
foreach($Server in $Servername){
    $Server = $Server.ToUpper()
    $services += Get-WmiObject Win32_Service -ComputerName $Server -Filter 'StartMode="Auto"' |
            Select-Object Name, Startmode, State | 
            Add-Member -MemberType NoteProperty -Value $Server -Name "Server" -PassThru
}  
$services | Group-Object Name | ForEach-Object{
    $SvcGrid.Rows.add($_.Name,$_.Count)
}

Первое: вы не использовали $server переменная в вашем вызове wmi, поэтому все результаты были бы получены с той машины, с которой вы ее выполняли. Кроме того, я переместил Where в -Filter так что это должно ускорить обработку на удаленных машинах.

Соберите всю эту информацию в массив (добавив имя компьютера на случай, если оно станет полезным позже). Затем, используя результаты этого использования Group-Object чтобы получить счета, которые вы искали. Труба это в другое ForEach-Object чтобы получить результаты в вашей сетке (которую я не проверял.)

Примечание: если вы просто хотите получить информацию в сетке, вы можете использовать Out-GridView

$services | Group-Object Name | Select name,count | Out-GridView
Другие вопросы по тегам