Le blog technique

Toutes les astuces #tech des collaborateurs de PI Services.

#openblogPI

Retrouvez les articles à la une

SCOM – Requête des heartbeat failure pour les membres d’un groupe spécifique

La requête ci-dessous, a exécuter sur la base de reporting, liste les alertes “Health Service Heartbeat Failure” pour les membres d’un groupe donné (@computergroup1) sur une plage de temps donnée.

-- QUERY TO GET 'Health Service Heartbeat Failure' ALERTS FOR COMPUTERS THAT ARE MEMBERS OF A SPECIFIC GROUP (@computergroup1)

-- MODIFY @computergroup1 AND @startdate/@enddate

-- BEWARE THAT @computergroup1 NAME CHARACTERS NUMBER CAN BE HOLD BY VARCHAR(N) VARIABLE

 

Use OperationsManagerDW

 

DECLARE @startdate    datetime

DECLARE @enddate    datetime

DECLARE @computergroup1    VARCHAR(100)

 

SET @startdate = '2017-09-01 00:00:00'

SET @enddate = '2017-09-30 00:00:00'

SET @computergroup1 = 'MyGroup'

 

 

SELECT 

av.AlertGuid

 

,apv.ParameterValue as SystemName

,av.AlertName

,adv.TicketId

,(DATEADD(hh,DATEDIFF(hh,getutcdate(),getdate()),av.RaisedDateTime)) as DownDateTime 

,(DATEADD(hh,DATEDIFF(hh,getutcdate(),getdate()),arsv.StateSetDateTime)) as RestoredDateTime

,adv.CustomField2 as OutageType 

,adv.CustomField3 as RootCause 

,Alert_ResolutionState = CASE

    WHEN arsv.ResolutionState = '255' THEN 'Closed'

    END

,adv.DBLastModifiedByUserId as UserID

FROM Alert.vAlert av

JOIN Alert.vAlertDetail adv on av.AlertGuid = adv.AlertGuid

JOIN Alert.vAlertResolutionState arsv on av.AlertGuid = arsv.AlertGuid

JOIN Alert.vAlertParameter apv on av.AlertGuid = apv.AlertGuid

 

 

-- JOIN ON TEMPORARY TABLE THAT RETRIEVE MAX OF StateSetDateTime (restoretime)

JOIN    (

        select av.AlertGuid 

        ,(DATEADD(hh,DATEDIFF(hh,getutcdate(),getdate()),av.RaisedDateTime)) as DownDateTime 

        ,MAX(arsv.StateSetDateTime) as restoretime

        from Alert.vAlert av

        JOIN Alert.vAlertDetail adv on av.AlertGuid = adv.AlertGuid

        JOIN Alert.vAlertResolutionState arsv on av.AlertGuid = arsv.AlertGuid

        JOIN Alert.vAlertParameter apv on av.AlertGuid = apv.AlertGuid

        GROUP BY av.AlertGuid,av.RaisedDateTime

        ) temp on temp.AlertGuid = av.AlertGuid

 

 

 

WHERE AlertName = 'Health Service Heartbeat Failure'

AND arsv.ResolutionState = '255'

AND (DATEADD(hh,DATEDIFF(hh,getutcdate(),getdate()),av.RaisedDateTime)) between @startdate and @enddate

 

 

 

and apv.ParameterValue IN (

SELECT vManagedEntity.DisplayName

FROM  vManagedEntity 

INNER JOIN vRelationship ON vManagedEntity.ManagedEntityRowId = vRelationship.TargetManagedEntityRowId 

INNER JOIN vManagedEntity AS ManagedEntity_1 ON vRelationship.SourceManagedEntityRowId = ManagedEntity_1.ManagedEntityRowId

    WHERE (ManagedEntity_1.DisplayName = @computergroup1)

)

 

 

AND arsv.StateSetDateTime = temp.restoretime

AND adv.TicketId is not null

 

GROUP BY apv.ParameterValue,adv.TicketId,av.AlertGuid,av.AlertName,av.RaisedDateTime,arsv.StateSetDateTime,adv.CustomField2,adv.CustomField3,/*adv.CustomField4,*/arsv.ResolutionState,adv.DBLastModifiedByUserId

ORDER BY apv.ParameterValue

 

 

Gestion de WSUS en Powershell – Partie 3

Dans cette partie nous allons voir comment utiliser la fonction Cleanup via Powershell

1 – Les Variables

La fonction « Cleanup » permet de nettoyer la base du serveur WSUS.

Il est possible de supprimer :

  • Les Superseded Updates  ou mises à jour remplacées en Français
  • Les Expired Updates ou mises à jour expirées en Français
  • Les Obsolete Updates ou mises à jour obsolètes en Français
  • Les Compress Updates ou mises à jour inutiles en Français
  • Les Obsolete Computers ou les ordinateurs obsolètes en Français
  • Les Unneeded ContentFiles ou Fichiers de mise jour inutiles en Français

Dans l’exemple ci-dessous les variables seront par défaut à « $False » il suffit de mettre « $True » pour valider la fonction.

    # Variables de Cleanup: 
# Decline updates that have not been approved for 30 days or more, are not currently needed by any clients, and are superseded by an aproved update. 
[Boolean]$SupersededUpdates = $false 
# Decline updates that aren't approved and have been expired my Microsoft. 
[Boolean]$ExpiredUpdates = $false 
# Delete updates that are expired and have not been approved for 30 days or more. 
[Boolean]$ObsoleteUpdates = $false 
# Delete older update revisions that have not been approved for 30 days or more. 
[Boolean]$CompressUpdates = $false 
# Delete computers that have not contacted the server in 30 days or more. 
[Boolean]$ObsoleteComputers = $True 
# Delete update files that aren't needed by updates or downstream servers. 
[Boolean]$UnneededContentFiles = $false 

 

2 – La commande

Une fois les variables définies, il faut indiquer le « Cleanup Scope » qui permet d’établir quels paramètres seront nettoyer, pour cela nous utiliserons la commande suivante :

$CleanupScope = New-Object Microsoft.UpdateServices.Administration.CleanupScope($supersededUpdates,$expiredUpdates,$obsoleteUpdates,$compressUpdates,$obsoleteComputers,$unneededContentFiles)

Une fois le « Cleanup Scope » définit, il ne reste plus qu’a exécuter la commande de nettoyage ci-dessous : 

($Wsus.GetCleanupManager()).PerformCleanup($CleanupScope)

Ou

$Cleanup = $Wsus.GetCleanupManager()
$Cleanup.PerformCleanup($CleanupScope)

 

3 – Bonus

Si vous possédez plusieurs serveurs WSUS, il est possible d’exécuter ce script (dans cet exemple nous ciblons uniquement les Ordinateurs obsolètes, remplacez les « $False » par « $True » pour valider les autres paramètres) :

<pre class="wp-block-syntaxhighlighter-code"># Script de Cleanup

$LogCatch = "$env:USERPROFILE\Desktop\LogCatch.txt"

# Détection des WSUS
Get-ADComputer -Filter { (Name -like "*WSUS*") -and (Enabled -eq $true)} | Select-Object -Property DNSHostName | Sort-Object -Property DNSHostName | ForEach-Object {
    $DNSHostName = $_."DNSHostName"
    
#region - Connexion au WSUS
        # Varibles de connexions
            $WsusServer = $DNSHostName
            $WsusPort = "8530"
        # Valeur max de prise en compte d'une machine (ici 30 jours sans connexion au serveur WSUS)
            $thirtydaysago = (get-date).adddays(-30)
            $DaysComputerStale = "30"

        #region - Ouverture de la connexion au serveur 
        $ErrorActionPreference = 'SilentlyContinue'
        Try {
            [void][reflection.assembly]::loadwithpartialname("microsoft.updateservices.administration")
            $Wsus = [microsoft.updateservices.administration.adminproxy]::getupdateserver($WsusServer,$false,$WsusPort)
            $Wsus.Name
            $Log = $Wsus.Name
            }
        Catch {
            Write-Warning "$($WsusServer)<$($WsusPort)>: $($_)" | Add-Content -Path $LogCatch
            $Connection = "Failed"
            $finalWorkSheet.Cells.Item($FinalExcelRow,9) = $Connection
            }
            If ($Log -eq $null){
                Try {
                    $WsusPort2 = "80"
                    [void][reflection.assembly]::loadwithpartialname("microsoft.updateservices.administration")
                    $Wsus = [microsoft.updateservices.administration.adminproxy]::getupdateserver($WsusServer,$false,$WsusPort2)
                    $Wsus.Name
                    }
                Catch {
            Write-Warning "$($WsusServer)<$($WsusPort2)>: $($_)" | Add-Content -Path $LogCatch
                        }
                }
        $ErrorActionPreference = 'SilentlyContinue'
        #endregion - Ouverture de la connexion au serveur
#endregion - Connexion au WSUS

#region - Cleanup
    # Variables de Cleanup: 
    # Decline updates that have not been approved for 30 days or more, are not currently needed by any clients, and are superseded by an aproved update. 
    [Boolean]$supersededUpdates = $false 
    # Decline updates that aren't approved and have been expired my Microsoft. 
    [Boolean]$expiredUpdates = $false 
    # Delete updates that are expired and have not been approved for 30 days or more. 
    [Boolean]$obsoleteUpdates = $false 
    # Delete older update revisions that have not been approved for 30 days or more. 
    [Boolean]$compressUpdates = $false 
    # Delete computers that have not contacted the server in 30 days or more. 
    [Boolean]$obsoleteComputers = $True 
    # Delete update files that aren't needed by updates or downstream servers. 
    [Boolean]$unneededContentFiles = $false 

    $CleanupScope = New-Object Microsoft.UpdateServices.Administration.CleanupScope($supersededUpdates,$expiredUpdates,$obsoleteUpdates,$compressUpdates,$obsoleteComputers,$unneededContentFiles) 

    ($Wsus.GetCleanupManager()).PerformCleanup($CleanupScope)

#endregion - Cleanup

#region - Release des Variables
$Name = $null
$WsusPort = $null
$Wsus = $null
$Log = $null
#endregion - Release des Variables
}</pre>

La nomenclature de mes serveurs comporte « WSUS » dans le nom, je passe donc par un « Get-Adcomputer », mais vous pouvez très bien remplacer cela par un « Import-CSV ».

Gestion de WSUS en Powershell – Partie 2

Dans l’article précédent nous avons vu comment nous connecter au serveur WSUS en Powershell, voyons maintenant ce que l’on peut récupérer informations.

1 – Etat de la configuration du serveur WSUS

Pour obtenir la configuration du serveur WSUS faites :

$Wsus.GetConfiguration()

Cette commande vous permet d’obtenir l’ensemble de la configuration du serveur.

Nous pouvons par exemple définir cette commande comme variable afin de pouvoir récupérer des informations de manière plus précise (car la commande retourne beaucoup d’informations).

Dans notre exemple nous allons récupérer les informations ci-dessous (pour information mon infrastructure possède un UpstreamServer) :

  • Le nom de l’UpstreamServer
  • Le port de connexion à l’UpstreamServer
  • Le serveur est il autorisé à synchroniser avec Windows Update
  • Le chemin d’accès au stockage des mise à jours
  • L’emplacement du fichier de log

J’ai variabilisé les requêtes car elles me servent plusieurs fois dans le script.

$Config = $Wsus.GetConfiguration()
$UpstreamServer = $Config.UpstreamWsusServerName
$UpstreamPort = $Config.UpstreamWsusServerPortNumber
$SyncFromMU = $Config.SyncFromMicrosoftUpdate
$StoragePath = $config.LocalContentCachePath
$LogPath = $Config.LogFilePath

$Config | Select-Object -Property UpstreamWsusServerName,UpstreamWsusServerPortNumber,SyncFromMicrosoftUpdate,LocalContentCachePath,LogFilePath

Si le serveur WSUS n’est pas le serveur en Amont (Upstream Server), donc en aval (Downstream Server) il est possible de connaitre ses paramètres via la commande :

$Wsus.GetSubscription()

Comme vous le voyez une information n’est pas retournée, ce n’est rien d’autre que les paramètre du serveur auquel vous êtes connecté, afin de connaitre ces informations rien de plus simple:

($Wsus.GetSubscription()).UpdateServer

Ou

$Subscription = $Wsus.GetSubscription()
$Subscription.UpdateServer


 

Pour obtenir des informations relatives aux mises à jour (Updates) comme : le nombre de mise à jour, combien sont approuvées, combien sont déclinées, combien sont nécessaires… utilisez la commande:

  $Wsus.GetStatus()

Après ces quelques petits exemples, vous me direz c’est bien mais pour l’instant ce n’est que de la collecte d’informations, comment puis je exploiter le serveurs alors? 

Dans la prochaine partie nous verrons comment interagir avec le serveur WSUS et lancer le nettoyage (Cleanup) du serveur.