Le blog technique

Toutes les astuces #tech des collaborateurs de PI Services.

#openblogPI

Retrouvez les articles à la une

SCOM – Script de mode maintenance depuis une liste

Le script ci-dessous est une version un peu avancée avec des fonctions de log et de vérification.

SetInstanceFromFileInMM.txt (5,99 kb)

 

# SET MULTIPLE CLASS INSTANCE FROM LIST, IN MAINTENANCE MODE.

#Parametres
Param(
$ClassName="Microsoft.Windows.Computer", # Name of Class (Not DisplayName to avoid system language differences) 
$MS= "MyMS.Mydomain.com", # Target Management Server
$cred = $(Get-Credential),
$HostFilePath="C:\HostMM.txt", # List of Host to put in Maintenance Mode
$Duration="10", # Duration in minutes (min: 5 minutes)
$LogPath = "C:\MMlog.txt" # Path of Log file
)



function Write-Log 
{ 
    [CmdletBinding()] 
    Param 
    ( 
        [Parameter(Mandatory=$true, 
                   ValueFromPipelineByPropertyName=$true)] 
        [ValidateNotNullOrEmpty()] 
        [Alias("LogContent")] 
        [string]$Message, 
 
        [Parameter(Mandatory=$false)] 
        [Alias('LogPath')] 
        [string]$Path=$LogPath, 
         
        [Parameter(Mandatory=$false)] 
        [ValidateSet("Error","Warn","Info")] 
        [string]$Level="Info", 
         
        [Parameter(Mandatory=$false)] 
        [switch]$NoClobber 
    ) 
 
    Begin 
    { 
        # Set VerbosePreference to Continue so that verbose messages are displayed. 
        $VerbosePreference = 'Continue' 
    } 
    Process 
    { 
         
        # If the file already exists and NoClobber was specified, do not write to the log. 
        if ((Test-Path $Path) -AND $NoClobber) { 
            Write-Error "Log file $Path already exists, and you specified NoClobber. Either delete the file or specify a different name." 
            Return 
            } 
 
        # If attempting to write to a log file in a folder/path that doesn't exist create the file including the path. 
        elseif (!(Test-Path $Path)) { 
            Write-Verbose "Creating $Path." 
            $NewLogFile = New-Item $Path -Force -ItemType File 
            } 
 
        else { 
            # Nothing to see here yet. 
            } 
 
        # Format Date for our Log File 
        $FormattedDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss" 
 
        # Write message to error, warning, or verbose pipeline and specify $LevelText 
        switch ($Level) { 
            'Error' { 
                Write-Error $Message 
                $LevelText = 'ERROR:' 
                } 
            'Warn' { 
                Write-Warning $Message 
                $LevelText = 'WARNING:' 
                } 
            'Info' { 
                Write-Verbose $Message 
                $LevelText = 'INFO:' 
                } 
            } 
         
        # Write log entry to $Path 
        "$FormattedDate $LevelText $Message" | Out-File -FilePath $Path -Append 
    } 
    End 
    { 
    } 
}


# Initiate Log File
$message = "------ START OF MAINTENANCE MODE LOG ------`n`n"
Write-Log -Message $message -Path $LogPath -Level Info -ErrorAction SilentlyContinue


#Check that Host list file exist
if (!(Test-Path -Path $HostFilePath))
    {
    $message = "Unable to find Host list file`n"
    write-host -ForegroundColor red $message
    Write-Log -Message $message -Path $LogPath -Level Error -ErrorAction SilentlyContinue
    exit 1
    }


# Store content of file
$HostList = Get-Content -Path $HostFilePath


#Import of SCOM module
try
{
Import-Module -Name OperationsManager -ErrorAction stop
}
catch
{
$message = "Error during import of SCOM PS module`n"
write-host -ForegroundColor red $message
Write-Log -Message $message -Path $LogPath -Level Error -ErrorAction SilentlyContinue
exit 1
}


#Connection to management server $MS
try
{
New-SCOMManagementGroupConnection -ComputerName $MS -Credential $cred
}
catch
{
$message = "Error during connection to $MS`n"
write-host -ForegroundColor red $message
Write-Log -Message $message -Path $LogPath -Level Error -ErrorAction SilentlyContinue
exit 1
}
 

# Set Start/End Time upon Duration 
$startTime = [DateTime]::Now
$endTime = $startTime.AddMinutes($Duration)


# Get the class
$Class = Get-SCOMClass | where-object {$_.Name -eq $ClassName} -ErrorAction Stop

If ($Class -eq $null)
    {
    $message = "Unable to find `"$ClassName`" Class`n"
    write-host -ForegroundColor red $message
    Write-Log -Message $message -Path $LogPath -Level Error -ErrorAction SilentlyContinue
    exit 1
    }



# Get the instances where displayname match content of $HostList
$Instances = Get-SCOMClassInstance -Class $Class | Where-Object {`
$_.Displayname -in $HostList 
} -ErrorAction Stop

If ($Instances -eq $null)
    {
    $message = "Unable to find instances of `"$ClassName`" Class`n"
    write-host -ForegroundColor red $message
    Write-Log -Message $message -Path $LogPath -Level Error -ErrorAction SilentlyContinue
    exit 1
    }



# Put in Maintenance Mode
$message = "Putting following instances in Maintenance Mode for $Duration minutes...:`n $($Instances | foreach {"$_;`n"})"
write-host $message
Write-Log -Message $message -Path $LogPath -Level Info -ErrorAction SilentlyContinue

    
$Instances | foreach {`
    try
    {
    $message = "`nSetting Maintenance Mode on `"$_`"..."
    write-host $message
    Write-Log -Message $message -Path $LogPath -Level Info -ErrorAction SilentlyContinue
    Start-SCOMMaintenanceMode -Instance $_ -Reason "PlannedOther" -EndTime $endTime -Comment "MM of $_" -ErrorAction Stop
    }
    catch
    {
    $message = "Error setting Maintenance Mode on `"$_`""
    write-host -ForegroundColor red $message
    Write-Log -Message $message -Path $LogPath -Level Error -ErrorAction SilentlyContinue
    }
}
    

# Check and log Maintenance Mode
$message = "Checking Maintenance Mode..."
Write-Log -Message $message -Path $LogPath -Level Info -ErrorAction SilentlyContinue

$Instances | foreach {`
$message = Get-SCOMMaintenanceMode -Instance $_ | foreach {"COMMENT: $($_.Comments) -- START:$($_.StartTime) -- END:$($_.ScheduledEndTime) -- REASON:$($_.Reason) -- USER:$($_.User)`n" } 
Write-Log -Message $message -Path $LogPath -Level Info -ErrorAction SilentlyContinue

}




    

 

 

Zabbix – Principe des périodes de maintenance

A l’instar de la plupart des outils de supervision, Zabbix propose un système de mise en maintenance de la supervision.

Pour configurer une nouvelle maintenance, Aller dans le menu Configuration / Maintenance:

image

Cliquer Create Maintenance Period

image

Renseigner le nom de la période.

Intéressant, le choix est donné de collecter ou non les données.

Attention: les champs de date Active Since et Active Till ne représente pas la période de maintenance elle même mais le temps au sein duquel nous allons créer une ou plusieurs périodes dans l’onglet correspondant (Periods)

Dans l’exemple ci-dessous on positionne une plage de temps d’un an.

image

Aller dans l’onglet Periods. Cliquer Add

image

4 modes sont disponibles: One Time Only, Daily, Weekly et Monthly.

imageimageimageimageimage

Dans l’onglet Hosts and groups, selectionner le/les hosts ou le/les host groups

image

Une fois la période crée, elle apparait en état Approaching lorsque la date Active Since approche.

image

Lorsque les hosts concernés sont effectivement en période de maintenance, l’icone image apparait a coté, jusqu’a la fin de la période.

image

image

Dans cet exemple, dans un an, la règle de maintenance passera en mode Expired.

image

SCOM 2019 – An Item With The Same Key Has Already Been Added après l’installation de l’UR1

SCOM 2019 UR1 a introduit de nouveaux management packs universels pour Linux. Ils vont permettre de simplifier la supervision des différentes distributions : plus besoin d’un MP différent pour chaque distribution et chaque version de cette distribution, les MP universels pourront gérer toutes les futures versions des distributions supportées.

Cependant, le déploiement de ces MP universels dans un environnement disposant encore du MP RHEL 6 et de serveurs découverts dans cette version provoque un petit souci : la vue Unix/Linux Computers ne se charge plus et l’erreur suivante apparait :

clip_image001

Par ailleurs, l’erreur suivante est visible dans le journal d’événements :

System.ArgumentException: An item with the same key has already been added.
   at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   at Microsoft.SystemCenter.CrossPlatform.UI.OM.Integration.MonitoringObjectPathToMonitoringObjectDictionary..ctor(IEnumerable`1 monitoringObjects)
   at Microsoft.SystemCenter.CrossPlatform.UI.OM.Integration.UnixComputerOperatingSystemHelper.JoinCollections(IEnumerable`1 managementServers, IEnumerable`1 resourcePools, IEnumerable`1 unixcomputers, IEnumerable`1 operatingSystems)
   at Microsoft.SystemCenter.CrossPlatform.UI.OM.Integration.UnixComputerOperatingSystemHelper.GetUnixComputerOperatingSystemInstances(String criteria)
   at Microsoft.SystemCenter.CrossPlatform.UI.OM.Integration.Administration.UnixAgentQuery.DoQuery(String criteria)
   at Microsoft.EnterpriseManagement.Mom.Internal.UI.Cache.Query`1.DoQuery(String criteria, Nullable`1 lastModified)
   at Microsoft.EnterpriseManagement.Mom.Internal.UI.Cache.Query`1.FullUpdateQuery(CacheSession session, IndexTable& indexTable, Boolean forceUpdate, DateTime queryTime)
   at Microsoft.EnterpriseManagement.Mom.Internal.UI.Cache.Query`1.InternalSyncQuery(CacheSession session, IndexTable indexTable, UpdateReason reason, UpdateType updateType)
   at Microsoft.EnterpriseManagement.Mom.Internal.UI.Cache.Query`1.InternalQuery(CacheSession session, UpdateReason reason)
   at Microsoft.EnterpriseManagement.Mom.Internal.UI.Cache.Query`1.TryDoQuery(UpdateReason reason, CacheSession session)
   at Microsoft.EnterpriseManagement.Mom.Internal.UI.Console.ConsoleJobExceptionHandler.ExecuteJob(IComponent component, EventHandler`1 job, Object sender, ConsoleJobEventArgs args)

La raison en est simple : le nouveau MP universel a découvert une nouvelle fois vos serveurs RHEL 6, ce qui crée des doublons dans la base de données et un plantage de la console lorsqu’elle tente de les lister.

Vous disposez maintenant de deux solutions :

– Supprimer le MP RHEL 6 qui, par ailleurs, n’est plus supporté dans SCOM 2019. Vos serveurs RHEL6 seront toujours supervisés par le MP universel, mais ce dernier ne contient pas exactement les même moniteurs, il faudra donc vérifier qu’il répond à vos besoins. Par ailleurs, si vous aviez développé des règles et moniteurs qui ciblent spécifiquement la classe RHEL 6, il faudra les réécrire.
Par ailleurs, vous ne pourrez plus découvrir de nouveaux serveurs RHEL 6 si vous supprimez ce management pack.

– Désactiver la découverte des serveurs RHEL 6 via un override, puis exécuter la commande Remove-SCOMDisabledClassInstance.

Une fois débarrassé de ces doublons, tout devrait rentrer dans l’ordre !