WSUS by powershell part 2 – Reporting des clients WSUS

Bonjour à tous,

dans mon premier article sur WSUS et Powershell Wsus industrialisation du déploiement des mises à jour je vous suggérai un ensemble de script afin de gérer le déploiement de vos mises à jour ainsi que le traitement des indicateurs WSUS.

Je vais maintenant vous montrer comment lister l’ensemble des serveurs:

– en attente de redémarrage
– en erreur suite à l’installation de mise à jours
– n’ayant pas contacté WSUS depuis plusieurs jours

Je ne m’attarderai donc pas sur certaines commandes Powershell que nous pourrions déjà avoir vu ensemble lors de mon premier article lié à WSUS

Clients WSUS en attente de redémarrage

Récupération de la date du jour

$startTime = (get-date -f MM-dd-yyyy)

Récupération des informations du serveur WSUS local et déclaration du chemin d’un fichier csv

$wsus = Get-WsusServer
$file = "\\Fileshare\WSUSTemp\Serveurs-Pending-Reboot-$startTime.csv"

On se crée un scope de recherche avec l’option « ::InstalledPendingReboot »

[reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration") | out-null
$computerScope = new-object Microsoft.UpdateServices.Administration.ComputerTargetScope;
$computerScope.IncludeDownstreamComputerTargets = $true
$computerScope.IncludedInstallationStates = [Microsoft.UpdateServices.Administration.UpdateInstallationStates]::InstalledPendingReboot; 

On vient ensuite utiliser ce scope via $wsus.GetComputerTargets. Si besoin vous pouvez utiliser la fonction Where-Object pour affiner votre recherche, dans notre exemple nous filtrons sur le nom de serveur avec « citrix ». Nous exportons le résultat dans le fichier CSV déclaré en début de script.

$computers = $wsus.GetComputerTargets($computerScope) | select FullDomainName,IPAddress | Export-Csv -Path $file
$computers = $wsus.GetComputerTargets($computerScope) | Where-Object {$_.FullDomainName -like "*Citrix*"} | select FullDomainName,IPAddress | Export-Csv -Path $file
$computers = $wsus.GetComputerTargets($computerScope) | Where-Object {$_.FullDomainName -like "*Citrix*"} | select FullDomainName

On récupère maintenant le nombre de serveur en attente de redémarrage

$count = $computers.count

Je déclare deux fichiers de communication HTM statique, un dans le cas ou il y a des serveurs en attente de redémarrage et un second dans le cas ou il n’y en aurai pas.

$file3 = "C:\Scripts\HTM\PendingReboot0\WSUS.htm"
$file4 = "C:\Scripts\HTM\PendingReboot1\WSUS.htm"

Encoding en UTF8

$encoding=[System.Text.Encoding]::UTF8

On vient maintenant vérifier s’il y a bien une valeur au dessus de zero dans $count, si c’est le cas on envoi un mail avec la pièce jointe dans le cas contraire on envoi tout de même une communication mais évidemment sans pièce jointe

if ($count -eq "0"){
$body = Get-Content -Path $file3 | Out-String
Send-MailMessage -From "wsus@ma-societe.fr" -To "equipe.microsoft@ma-societe.fr" -Subject "Clients WSUS - Pas de redémarrage en attente" -SmtpServer "mail.ma-societe.fr" -bodyashtml -Body $body -Encoding $encoding
 } else{
$body = Get-Content -Path $file4 | Out-String
Send-MailMessage -From "wsus@ma-societe.fr" -To "equipe.microsoft@ma-societe.fr" -Subject "Clients WSUS - Des redémarrages sont en attente" -SmtpServer "mail.ma-societe.fr" -bodyashtml -Body $body -Attachments $file -Encoding $encoding
}

Clients WSUS en erreur

Récupération de la date du jour

$startTime = (get-date -f MM-dd-yyyy)

Récupération des informations du serveur WSUS local et déclaration du chemin d’un fichier csv

$Wsus = Get-WsusServer
$file = "\\Fileshare\WSUSTemp\Serveurs-en-erreur-$startTime.csv"

On déclare comme précédemment notre zone de recherche avec cette fois $updateScope.IncludedInstallationStates = ‘Failed’ et $computerScope.IncludedInstallationStates = ‘Failed’

$updateScope = New-Object Microsoft.UpdateServices.Administration.UpdateScope
$updateScope.IncludedInstallationStates = 'Failed'
$computerScope = New-Object Microsoft.UpdateServices.Administration.ComputerTargetScope
$computerScope.IncludedInstallationStates = 'Failed'
$computerScope.IncludeDownstreamComputerTargets = 'true'
$GroupFailHash=@{}
$ComputerHash = @{}
$UpdateHash = @{}

On vient maintenant rechercher pour l’ensemble des serveurs en erreur, toutes les KB avec le status d’installation en erreur également.
On peut toujours affiner si besoin la recherche via le filtre Where-Object {$_.FullDomainName -like « *citrix* »}

$ComputerFailInstall = $wsus.GetComputerTargets($computerScope) | Where-Object {$_.FullDomainName -like "*citrix*"} | ForEach {
    $Computername = $_.FullDomainName
    $Update = ($_.GetUpdateInstallationInfoPerUpdate($updateScope) | ForEach {
        $Update = $_.GetUpdate()
        $Update.title
        $Update.ProductTitles
        $ComputerHash[$Computername] += ,$Update.title
        $UpdateHash[$Update.title] += ,$Computername
    }) -join ', '
    If ($Update) {
        $TempTargetGroups = ($_.GetComputerTargetGroups() | Select -Expand Name)
           $TempTargetGroups | ForEach {
           $GroupFailHash[$_]++
        }
        [pscustomobject] @{
            Computername = $_.FullDomainName
            TargetGroups = $TempTargetGroups
            IP= $_.IPAddress
            Updates = $Update
        }
    }
}

Comme précédemment on vient récupérer le nombre de client correspondant

$count = $ComputerFailInstall.count

On déclare à nouveau deux fichiers HTM pour la communication

$file3 = "C:\Scripts\HTM\ServeursoenErreur0\WSUS.htm"
$file4 = "C:\Scripts\HTM\ServeursenErreur1\WSUS.htm"

Encoding en UTF8

$encoding=[System.Text.Encoding]::UTF8

On vient maintenant comparer la valeur $count et renouveler l’opération si celle ci est > à zéro mais cette fois à la fin de la boucle nous utilisons « Out-File $file » qui vient remplir notre fichier CSV.

Je n’ai malheureusement pas trouvé l’astuce pour le faire en une seule fois, en effet, l’option « Out-File $file » empêche de réaliser un count derrière de la variable $ComputerFailInstall qui renvoi systématiquement un résultat nul.

if ($count -eq "0"){
$body = Get-Content -Path $file3 | Out-String
Send-MailMessage -From "wsus@ma-societe.fr" -To "equipe.microsoft@ma-societe.fr" -Subject "Serveurs WSUS - Pas de serveur en erreur $startTime" -SmtpServer "mail.ma-societe.fr" -Body $body -bodyashtml -Encoding $encoding
 } else{

 $ComputerFailInstall = $wsus.GetComputerTargets($computerScope) | Where-Object {$_.FullDomainName -like "*CITRIX*"} | ForEach {
    $Computername = $_.FullDomainName
    $Update = ($_.GetUpdateInstallationInfoPerUpdate($updateScope) | ForEach {
        $Update = $_.GetUpdate()
        $Update.title
        $Update.ProductTitles
        $ComputerHash[$Computername] += ,$Update.title
        $UpdateHash[$Update.title] += ,$Computername
    }) -join ', '
    If ($Update) {
        $TempTargetGroups = ($_.GetComputerTargetGroups() | Select -Expand Name)
           $TempTargetGroups | ForEach {
           $GroupFailHash[$_]++
        }
        [pscustomobject] @{
            Computername = $_.FullDomainName
            IP= $_.IPAddress
            TargetGroups = $TempTargetGroups
            Updates = $Update
        }
    }
} | Sort Computername | Out-File $file -append -Width 3000 

# Envoi du mail
$body = Get-Content -Path $file4 | Out-String
Send-MailMessage -From "wsus@ma-societe.fr" -To "equipe.microsoft@ma-societe.fr" -Subject "Serveurs WSUS - Liste des serveurs en erreur $startTime" -SmtpServer "mail.ma-societe.fr" -Body $body -bodyashtml -Encoding $encoding -Attachments $file
}

Clients WSUS n’ayant pas contacté WSUS depuis plusieurs jours

Déclaration de deux dates, celle du jour et celle du jour moins 4 jours
Tout en sachant qu’il doit le faire quotidiennement, on va partir du principe qu’un client qui ne contacte plus son serveur WSUS depuis plus de 4 jours rencontre un problème.

$startTime = (get-date -f yyyy-MM-dd)
$startTime4 = (get-date).AddDays(-4).ToString("yyyy-MM-dd")

Déclaration d’un fichier sur lequel nous allons travailler
Utiliser la variable date dans le nom du fichier nous assure de ne jamais utiliser un doublon

$file = "\\Fileshare\WsusClientStatus-$startTime.csv"

On vient maintenant exporter au format CSV l’ensemble des serveurs dont le paramètre $_.LastReportedStatusTime est plus petit que J moins 4 jours, dans l’export on en profite pour ajouter le nom du client, sa date justement de dernier rapport, son appartenance à un groupe, et son IP. Je réalise de plus un tri sur le groupe des clients WSUS

Get-WsusComputer -IncludeDownstreamComputerTargets | Where-Object {$_.LastReportedStatusTime -le $startTime4} | select FullDomainName,LastReportedStatusTime,RequestedTargetGroupName,IPAddress | sort RequestedTargetGroupName| Export-Csv -Path $file -Delimiter ";"

Gérant plusieurs milliers de serveurs je n’ai jamais rencontré de cas où l’ensemble des clients WSUS contacte leur WSUS, j’ai constamment en moyenne quelques dizaines de serveurs posant problème. Je n’ai donc jamais eu besoin de compter cette valeur afin de pouvoir ensuite jouer sur la communication. Mais rien ne vous empêche de le faire en vous servant des exemples ci-dessus.

Comme toujours j’utilise un fichier HTM pour venir composer mon Email

$file3 = "C:\Scripts\HTM\Clients-WSUS-Pas-synchro\WSUS.htm"
$encoding=[System.Text.Encoding]::UTF8

$body = Get-Content -Path $file3 | Out-String
Send-MailMessage -From "wsus@ma-societe.fr" -To "equipe.microsoft@ma-societe.fr" -Subject "Etat de synchro des serveurs reliés à WSUS" -SmtpServer "mail.ma-societe.fr" -bodyashtml -Body $body -Encoding $encoding -Attachments "$file"

Ces script permettent de rapidement visualiser les serveurs « en souffrance », il y a de très forte chance que vous soyez obligé de vous y connecter afin de les dépanner.

J’espère que ce deuxième article autour de WSUS vous a plu.

Évidemment beaucoup de chose sont modulables et également perfectibles !

Dans un prochain et dernier article autour de WSUS je tâcherai de rentrer cette fois dans la base SQL de WSUS toujours via PowerShell afin de sortir des rapports tels que les client WSUS avec des mises à jours approuvées en « need » ou plus simplement la liste de tous les clients et leur date de dernière synchronisation.

A+

Publicité

Votre commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l’aide de votre compte WordPress.com. Déconnexion /  Changer )

Photo Facebook

Vous commentez à l’aide de votre compte Facebook. Déconnexion /  Changer )

Connexion à %s

Créez un site Web ou un blog gratuitement sur WordPress.com.

Retour en haut ↑

Technopreneurph

Technology Entrepreneurship For the World

Chemist Blogger

All things science, technology, and geek culture

Cambly Blog

Practice English with a Native Speaker

BirdsBeep is a Multiplatform Chat Application

BirdsBeep is the uprising of new chatting features that will satisfy.

Deepak verma

Get Latest updates from Famous Tech Blogs in One Blog.

Le mur d'Adrien

De l'administration système pour tous

%d blogueurs aiment cette page :