Назад | Перейти на главную страницу

Утверждение отчетов WSUS для группы

Я пытаюсь найти способ создать отчет WSUS об обновлениях, одобренных для группы компьютеров A, но не одобренных для одной или нескольких других групп. Как вариант, табличный отчет, в котором перечислены статусы утверждения для каждого обновления и каждой группы, чтобы его можно было обработать для извлечения того, что мне нужно. Похоже, что в самом WSUS такого отчета нет, или, по крайней мере, я не могу его найти, поэтому сценарий для создания такого отчета был бы весьма кстати.

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

Примечание. Вам нужно будет запустить это либо на сервере WSUS, либо на машине, на которой установлены инструменты администрирования WSUS.

Конфигурация

Устанавливать $targetComputerGroup в группу компьютеров, которую вы хотите использовать в качестве базового набора $CheckForMissing к именам группы или групп, для которых вы хотите узнать, утверждены ли они. Примечание. Чтобы выполнить кратное повторение, просто разделите запятую ("Группа1, Группа2")

$serverName="localhost"
$targetComputerGroup="BaselineGroup"
$checkForMissing="MissingGroup1,MissingGroup2"

[void][reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration")
$wsus=[Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer($serverName,$false)
$computerGroup=$wsus.GetComputerTargetGroups()|ForEach-Object -Process {if ($_.Name -eq $targetComputerGroup) {$_}}
$UpdateScope=New-Object Microsoft.UpdateServices.Administration.UpdateScope
$UpdateScope.ApprovedStates="Any"
$updateScope.ApprovedComputerTargetGroups.Add($computerGroup)
$Approvals = $wsus.GetUpdateApprovals($UpdateScope)

#At this point we have all of the updates assigned to the $targetComputerGroup

$report= @()
write-host "Querying for all Updates approved for $targetComputerGroup"

foreach ($Approval in $approvals) {
   $record=""|Select-Object ComputerGroup,UpdateName, UpdateID
   $record.ComputerGroup=$wsus.GetComputerTargetGroup($Approval.ComputerTargetGroupID).Name
   $record.UpdateName=$wsus.GetUpdate($Approval.UpdateID).Title
   $record.UpdateID=$wsus.GetUpdate($Approval.UpdateID).ID.UpdateID
   $report +=$record
   }

#Now group the results by UpdateName
$GR=$report|group -Property UpdateName

$CheckForMissing=$CheckForMissing.Split(",")

 foreach ($entry in $gr) {
    $groups=@()
    foreach ($g in $entry.Group) {
        $groups += $g.ComputerGroup
        }
    foreach ($missing in $checkForMissing) {
        if ($groups -Contains $missing) {}
        else{
            New-Object PSObject -Property @{
            Name = $entry.Name
            UpdateID = $entry.Group[0].UpdateID
            GroupMissing = $missing
            }
        }
    }
}

По завершении вы получите следующий результат:

Если вместо вывода на экран вы хотите экспортировать список в CSV, замените нижнюю часть следующим кодом:

   $CheckForMissing=$CheckForMissing.Split(",")
   $CSVdata=@()
     foreach ($entry in $gr) {
        $groups=@()
        foreach ($g in $entry.Group) {
            $groups += $g.ComputerGroup
            }
        foreach ($missing in $checkForMissing) {
            if ($groups -Contains $missing) {}
            else{
                $CSVdata += New-Object PSObject -Property @{
                Name = $entry.Name
                UpdateID = $entry.Group[0].UpdateID
                GroupMissing = $missing
                }
            }
        }
    }
 $CSVdata|Export-Csv "FILENAME.CSV"

Можно "просто" подключиться к базе данных WSUS и запустим к нему запросы:

  1. Запустите SQL Management Studio с повышенными привилегиями.
  2. Присоединиться \\.\pipe\MSSQL$MICROSOFT##SSEE\sql\query с помощью Проверка подлинности Windows.

Эти таблицы представляются интересными в отношении вашего вопроса:

  • tbUpdate
    Содержит информацию об отдельных обновлениях

  • tbTargetGroup
    Содержит информацию обо всех группах компьютеров

  • tbDeployment
    Содержит информацию о том, какие обновления были утверждены для каких групп компьютеров.

Однако кажется полезным использовать уже существующее представление vUpdateApproval для получения большей части информации, которая вам нужна, поскольку это представление уже переводит ActionID столбец из tbDeployment среди прочего.

В vUpdateApproval view, однако, не содержит легко читаемых заголовков обновлений. Заголовки обычно читаются из tbLocalizedProperty. Чтобы нам было проще, есть другой вид: vUpdate.

На самом деле у меня нет данных в нашей базе данных WSUS, чтобы построить правильный запрос, который подошел бы вашему первому запросу (и я недостаточно уверен, чтобы строить его вслепую). Итак, вот подход для вашего вторичного запроса. Если я не напортачил, он выдает список всех обновлений и состояние утверждения для всех групп.

SELECT
    aUpdate.UpdateId,
    aUpdate.DefaultTitle,
    aGroup.Name as GroupName,
    aApproval.Action as Action
FROM
    PUBLIC_VIEWS.vUpdate AS aUpdate INNER JOIN
    PUBLIC_VIEWS.vUpdateApproval AS aApproval ON aUpdate.UpdateId = aApproval.UpdateId LEFT JOIN
    dbo.tbTargetGroup as aGroup ON aGroup.TargetGroupID = aApproval.ComputerTargetGroupId
;

Что производит этот вывод на нашем немецком SBS:

Для нашего SBS с его 5 группами по умолчанию это дает 121558 строк результатов за ~ 26 секунд. Итак, если вы хотите поэкспериментировать с запросом, может быть целесообразно изменить первую строку на SELECT TOP 1000 во время тестирования.

Я также нашел время, чтобы обернуть все это в сценарий PowerShell:

# Where to connect to
$dataSource        = "\\.\pipe\MSSQL`$MICROSOFT##SSEE\sql\query"
$connectionTimeout = 30

# The query we want to perform against the WSUS database
$query = @"
    SELECT TOP 10
        aUpdate.UpdateId,
        aUpdate.DefaultTitle,
        aGroup.Name as GroupName,
        aApproval.Action as Action
    FROM
        PUBLIC_VIEWS.vUpdate AS aUpdate INNER JOIN
        PUBLIC_VIEWS.vUpdateApproval AS aApproval ON aUpdate.UpdateId = aApproval.UpdateId LEFT JOIN
        dbo.tbTargetGroup as aGroup ON aGroup.TargetGroupID = aApproval.ComputerTargetGroupId
"@
$queryTimeout = 120

# Construct the connection string
$connectionString = "Data Source={0};Integrated Security=True;Connect Timeout={1};Database=SUSDB" -f $dataSource,$connectionTimeout

# Open the connection to the SQL server
$connection = New-Object System.Data.SqlClient.SQLConnection
$connection.ConnectionString = $connectionString
$connection.Open()

# Construct our SQL command
$sqlCommand = New-Object system.Data.SqlClient.SqlCommand( $query, $connection )
$sqlCommand.CommandTimeout = $queryTimeout

# Retrieve the data from the server
$dataSet     = New-Object system.Data.DataSet
$dataAdapter = New-Object system.Data.SqlClient.SqlDataAdapter( $sqlCommand )
[void]$dataAdapter.fill( $dataSet )

# Clean up
$connection.Close()

# Output result
$dataSet.Tables

Обратите внимание, что этот сценарий включает SELECT TOP 10 ограничение, чтобы избежать переполнения вашей оболочки во время тестирования.