Approvazioni dei report WSUS per un gruppo


9

Sto cercando di trovare un modo per creare un rapporto WSUS degli aggiornamenti che sono stati approvati per il gruppo di computer A che non sono stati approvati per uno o più altri gruppi. In alternativa, un rapporto tabulare che elenca lo stato di approvazione per ciascun aggiornamento e ciascun gruppo, in modo che possa essere elaborato per estrarre ciò di cui ho bisogno. Non sembra esserci un tale rapporto nello stesso WSUS, o almeno non uno che riesco a trovare, quindi uno script per produrre un tale rapporto sarebbe il benvenuto.


Su quale versione di Windows è in esecuzione WSUS?
Nate,

@Nate, è WSUS 3.2.7600.226 in esecuzione su una macchina a 64 bit standard di Server 2008 R2.
John Gardeniers,

Penso di avere una soluzione per te, dammi alcuni e lo confermerò
Nate

Risposte:


8

Questo script PowerShell fa esattamente ciò che è stata la tua richiesta iniziale. Esamina un gruppo di computer e trova gli aggiornamenti non approvati per uno o più altri gruppi di computer.

Nota È necessario eseguirlo su un server WSUS o su un computer su cui sono installati gli strumenti di amministrazione WSUS.

Configurazione

Impostare $targetComputerGroupsul gruppo di computer che si desidera utilizzare come base Impostare $CheckForMissingi nomi del gruppo o dei gruppi per i quali si desidera vedere se sono stati approvati. Nota: per fare multipli solo in coma separato ("Gruppo1, Gruppo2")

$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
            }
        }
    }
}

Una volta completato avrai un output come: inserisci qui la descrizione dell'immagine

Se anziché esportare sullo schermo si desidera esportare l'elenco in un CSV, sostituire la parte inferiore con il seguente codice:

   $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"

Funziona! Sai come fermare il troncamento dell'uscita? A proposito, non posso assegnare la taglia per altre 9 ore.
John Gardeniers,

1
Il troncamento è una funzione di come si formatta PowerShell per lo schermo. Ho aggiornato la risposta con un esempio di invio al file CSV in modo da poter avere i valori completi.
Nate,

Eccellente, in quanto CSV è molto adatto alle mie esigenze. Da qui posso dargli da mangiare a Perl, dove almeno so cosa sto facendo. Molto apprezzato.
John Gardeniers,

7

È possibile "semplicemente" connettersi al database WSUS ed eseguire query su di esso:

  1. Avviare SQL Management Studio con privilegi elevati.
  2. Connettiti \\.\pipe\MSSQL$MICROSOFT##SSEE\sql\queryutilizzando l' autenticazione di Windows .

Queste tabelle sembrano essere di interesse riguardo alla tua domanda:

  • tbUpdate
    Contiene informazioni su singoli aggiornamenti

  • tbTargetGroup
    Contiene informazioni su tutti i gruppi di computer

  • tbDeployment
    Contiene informazioni su quali aggiornamenti sono stati approvati per quali gruppi di computer

Tuttavia, sembra utile utilizzare la vista già esistente vUpdateApprovalper recuperare la maggior parte delle informazioni che stai cercando, poiché questa vista traduce già la ActionIDcolonna tbDeploymenttra le altre cose.

La vUpdateApprovalvista, tuttavia, non include titoli facilmente leggibili per gli aggiornamenti. I titoli vengono solitamente letti da tbLocalizedProperty. Per rendere più facile per noi, c'è un'altra vista: vUpdate.

Non ho davvero i dati corretti nel nostro database WSUS per costruire la query corretta che si adatterebbe alla tua prima richiesta (e non sono abbastanza sicuro da costruirlo ciecamente). Quindi ecco un approccio per la tua richiesta secondaria. Se non ho sbagliato, produce un elenco di tutti gli aggiornamenti e lo stato di approvazione per tutti i gruppi.

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
;

Che produce questo output sul nostro SBS tedesco:

inserisci qui la descrizione dell'immagine

Per il nostro SBS con i suoi 5 gruppi predefiniti, questo produce 121558 righe di risultati in ~ 26 secondi. Pertanto, se si desidera giocare con la query, potrebbe essere consigliabile modificare la prima riga SELECT TOP 1000durante il test.

Mi sono anche preso il tempo di avvolgere tutto in uno script di 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

Si noti che questo script include la SELECT TOP 10limitazione per evitare di inondare la shell durante il test.


È certamente qualcosa da indagare. Forse c'è un modulo Perl per interagire con MS SQL Server.
John Gardeniers,

@ JohnGardeniers: ho aggiunto uno script PowerShell che esegue la query. Purtroppo, la mia conoscenza del Perl è ancora peggio :)
Der Hochstapler,

È un buon punto di partenza, ma dovrò scoprire come interrompere il troncamento dell'output.
John Gardeniers,

@JohnGardeniers: è così che PowerShell visualizza gli oggetti restituiti per impostazione predefinita. È possibile eseguire lo script come myscript.ps1 | flper ottenere un output diverso (non troncato).
Der Hochstapler,

Ho deciso di premiarti per i tuoi sforzi, ma dovrai aspettare 24 ore. Il sistema non mi consente di assegnare immediatamente una taglia.
John Gardeniers,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.