PI Services

Le blog des collaborateurs de PI Services

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

ZABBIX - Script - Tout les hosts, leur status et leurs templates liés

Le script ci-dessous affiche tout les hosts avec leur status et les templates associés

 

GetZabbixAlIHostsAndTemplates(Native_API).ps1 (2,46 kb)

 

### GET ALL ZABBIX HOSTS WITH THEIR STATUS AND TEMPLATES LINKED


Param(
[Parameter(Mandatory=$false)] $baseurl='https://MyZabbixSrv.My.domain/zabbix',
$credential = (Get-Credential -Credential "MyAccount"),
)

 
$global:JsonParams = @{}
     
# 
Function ConnectZabbix($cred,$baseurl)
{
$JsonParams.body =  @{
        "jsonrpc"= "2.0"
        "method"= "user.login"
        "params"= @{
            "user"= $cred.UserName
            "password"= $cred.GetNetworkCredential().Password
        }
        "id"= 1
        "auth"= $null
    } | ConvertTo-Json
    $JsonParams.uri = "$baseurl/api_jsonrpc.php"
    $JsonParams.headers = @{"Content-Type" = "application/json"}
    $JsonParams.method = "Post"
 
 
[System.Net.ServicePointManager]::SecurityProtocol = 'tls12'
[Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
 
$global:Connresult = Invoke-WebRequest @JsonParams -UseBasicParsing
 
}
 
# Invoke ConnectZabbix
ConnectZabbix -cred $credential -baseurl $baseurl
 
 
 
## GET HOSTS ##
$JsonParams.body = @{
    "jsonrpc"= "2.0"
    "method"= "host.get"
    "params"= @{
        output = "hostid","name","available","status"
        selectParentTemplates = "templateid","name"
        }

    auth = ($Connresult.Content | ConvertFrom-Json).result
    id = 2
} | ConvertTo-Json

$ZabbixHosts = Invoke-WebRequest @JsonParams -UseBasicParsing
$ZabbixHosts = $ZabbixHosts.Content | ConvertFrom-Json



## CREATE EMPTY TABLEAU THAT WILL STORE HOSTS AND TEMPLATES
$HostsAndTemp = @()

foreach ($Zabbhost in $ZabbixHosts.result)
{

$obj = New-Object psobject

$obj | Add-Member -Name "HOSTNAME" -membertype Noteproperty -Value $Zabbhost.name
$obj | Add-Member -Name "ZBX AGENT STATUS" -membertype Noteproperty -Value `
    $( 
      switch ($Zabbhost.status)
      {
      0 {"ENABLED"}
      1 {"DISABLED"}
      }
     )

$obj | Add-Member -Name "ZBX AGENT AVAILABLE" -membertype Noteproperty -Value `
    $( 
      switch ($Zabbhost.available)
      {
      1 {"AVAILABLE"}
      2 {"UNAVAILABLE"}
      0 {"UNKNOWN"}
      }
     )

$obj | Add-Member -Name "ZABBIX TEMPLATES LINKED" -membertype Noteproperty -Value $Zabbhost.parentTemplates.name


$HostsAndTemp += $obj

}


# TABLEAU FINAL
write-host "`n---- $($ZabbixHosts.result.Count) HOSTS ---`n"
write-host "HOSTNAME - ZBX AGENT STATUS - ZBX AGENT AVAILABLE - ZABBIX TEMPLATES LINKED`n"


$HostsAndTemp | sort hostname | ft -AutoSize

 

Zabbix – Supervision basique d’une URL


Zabbix propose plusieurs manière de superviser des URL. L’exemple ci-dessous propose d’utiliser un ‘Web Scenario’ pour la supervision d’une URL simple (ici www.google.fr).

on commence par créer un template vide qui contiendra la configuration:

image


image


image

NB: Le nom du Host group associé est arbitraire.

Cliquer Add.

image

Le template vide est crée.


image

Cliquer “Create Web Scenario”


image

Name: Check Google

Agent: On positionne Zabbix. ce champs permet de selectionner plusieurs type de client http/navigateur.

Cliquer Steps.


image

Dans la zone Steps, cliquer sur Add.


image

name: Google base page

URL: http://www.google.fr

Required Status codes: 200


image

image

Cliquer Add

image

Le Web scenario est crée.


image

On applique (Link) le template au host devant effectuer le check de supervision.


image


image

Apres quelques minutes les données remonte dans la liste des “Latest data” du host concerné. on voit ici que le code HTTP renvoyé est bien 200 (OK)

On crée a présent un trigger (alerte) en charge declencher une alerte sur le cas ou le code HTTP serait different de 200.

image

image

Dans les propriétés du template, cliquer Triggers


image

cliquer en haut a droite Create Trigger


image

Name: Google Site KO

Clquer sur Add a coté de la zone Expression pour construire la condition de declenchement.


image

Cliquer sur Select pour aller rechercher l’item crée precedemment.


image

Selectionner “Response code for step “Google base page”…”


image

Laisser selectionné la fonction “last()”.

Result: <> 200

cliquer Insert.


image

A titre d’indication ajouter le nom de l’url surveillée dans le champ URL.

Cliquer Add.


image

Le trigger est maintenant actif.

SCOM - Script - Supprimer ou Mettre en mode maintenance un/des agent selon la valeur d'une propriété (Nouvelle version)

Le script suivant est une nouvelle version d'un script récemment proposé. Ont été rajouté le choix entre suppression et mode maintenance (on verifie aussi que la machine est déjà en mode maintenance)

 

DeleteOrMaintenanceAgentUponPropertyValue.ps1 (14,85 kb)

 

## DeleteOrMaintenanceAgentUponPropertyValue.ps1
## SCOM - REMOVE FROM CONSOLE OR PUT IN MAINTENANCE MODE, AGENT(S) THAT HAVE SPECIFIC VALUES IN ONE OR MORE CLASS PROPERTY.
## AUTHOR: C.JOURDAN
## Version: 1.1

##  PARAMETERS
##  $MS: Target Management Server
##  $ObjectClass: Display Name of Target Class
##  $FirstProperty: name of class property
##  $FirstPropVal: multi value possible of $FirstProperty
##  $Action: DELETE or MAINTENANCE
##  $MaintenanceDuration: Nb of minutes for Maintenance Mode
##  $ThreshNotDelete: Nb of found computers to delete over which we only warn (NO AUTOMATIC DELETE)

## NOTES: $ThreshNotDelete PARAMETER IS A SECURITY OPTION TO AVOID DELETION OF TWO MANY AGENTS. BE SURE OF THE APPLIED CRITERIAS BEFORE UNLOCK THAT! 


#PARAMETERS
Param(
[Parameter(Mandatory=$false)]
$MGroup,
[Parameter(Mandatory=$false)]
$MS="MyMS",
[Parameter(Mandatory=$false)]
$ObjectClass="MyClass",
[Parameter(Mandatory=$false)]
$FirstProperty='MyProperty',
[Parameter(Mandatory=$false)]
$FirstPropVal="^.*(AZERTY|QWERTY).*$",
<# -- ADDITIONAL PROPERTIES FROM $ObjectClass INSTANCE -- SEE CLASS INSTANCE RETRIEVE SECTION
[Parameter(Mandatory=$false)]
$SecondProperty='Prop2',
[Parameter(Mandatory=$false)]
$SecondPropVal='Value2'
#>
[Parameter(Mandatory=$false)]
$Action = "Maintenance",
[Parameter(Mandatory=$false)]
$MaintenanceDuration = 30,
[Parameter(Mandatory=$false)]
$ThreshNotDelete = 10
)

#ScriptName
$ScriptName = "DeleteOrMaintenanceAgentUponPropertyValue.ps1"



#FUNCTIONS

# NewEventSource
# Check of a source existance  in the 'operation manager' eventlog that match the script name, to log some events.
         Function NewEventSource 
         { 
         if(!(Test-Path "HKLM:\SYSTEM\CurrentControlSet\services\eventlog\Operations Manager\$ScriptName")) 
         { 
         New-EventLog -LogName "Operations Manager" -Source $ScriptName 
         }
         } 


# DeleteSCOMAgent
# Remove agent from SCOM Console.
Function DeleteSCOMAgent 
{
Param(
  [string[]]$AgentComputerName,
  [string]$MSServer
)

[System.Reflection.Assembly]::Load("Microsoft.EnterpriseManagement.Core, Version=7.0.5000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")
[System.Reflection.Assembly]::Load("Microsoft.EnterpriseManagement.OperationsManager, Version=7.0.5000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")



function New-Collection ( [type] $type ) 
{
	$typeAssemblyName = $type.AssemblyQualifiedName;
	$collection = new-object "System.Collections.ObjectModel.Collection``1[[$typeAssemblyName]]";
	return ,($collection);
}




# Connect to management group
Write-output "Connecting to management group "$ConnectionSetting.name""

$ConnectionSetting = New-Object Microsoft.EnterpriseManagement.ManagementGroup($MSServer)
$admin = $ConnectionSetting.GetAdministration()


Write-output "Getting agent managed computers"
$agentManagedComputers = $admin.GetAllAgentManagedComputers()

# Get list of agents to delete
foreach ($name in $AgentComputerName) 
{
    Write-output "Checking for $name"
    foreach ($agent in $agentManagedComputers)
    {
        if ($deleteCollection -eq $null) 
        {
            $deleteCollection = new-collection $agent.GetType()
        }

        
        if (@($agent.PrincipalName -eq $name))
        {
	    Write-output "Matched $name"
            $deleteCollection.Add($agent)
            break
        }
    }
}

if ($deleteCollection.Count -gt 0) 
{
    Write-output "Deleting agents"
    $admin.DeleteAgentManagedComputers($deleteCollection)
    if($?){
           $Script:result="Agents deleted"
           Write-Output $result
          }
    Else  {
           $result="Error during deletion of one ore more agent"
           Write-Output $result
          }
}

Else
    {
    $result="No Agent found to delete"
    Write-Output $result
    }


}


Function SetMM
{
# Function SetMM 
########################################################################
# 
#
[CmdletBinding()]

param(
  [string]$HostToMM,
  [string]$Duration
)

$startTime = [DateTime]::Now
$endTime = $startTime.AddMinutes($Duration)

    # Get "Microsoft.Windows.Computer" Class
    $Class = get-SCOMclass | where-object {$_.Name -eq "Microsoft.Windows.Computer"};

    $Instance = Get-SCOMClassInstance -Class $Class | Where-Object {$_.Displayname -like "$HostToMM*"};
    
    Start-SCOMMaintenanceMode -Instance $Instance -Reason "PlannedOther" -EndTime $endTime -Comment "PLANNED BY SCOM AGENT REMOVER" -ErrorAction Stop
    
    
}



#END FUNCTIONS



#Log of script execution 
NewEventSource
$message =  "Execution du script $ScriptName"
$message
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 999 -Message $message -EntryType Information 


# Check if $Action is valid
if ($Action -notmatch "^delete|maintenance$")
    {
    $message = "NO VALID ACTION HAS BEEN CHOOSED - POSSIBLE VALUE: `"DELETE`" OR `"MAINTENANCE`""
    write-host -ForegroundColor Yellow $message
    NewEventSource 
    write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1000 -Message $message -EntryType Warning
    exit 1
    }



#Import of SCOM Powershell module
try
{
Import-Module -Name OperationsManager -ErrorAction stop
}
catch
{
$message = "ERROR DURING IMPORT OF SCOM PS MODULE"
write-host -ForegroundColor red $message
NewEventSource 
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1001 -Message $message -EntryType Error 
exit 1 
}



#Connection to management group $MGroup
try
{
New-SCOMManagementGroupConnection -ComputerName $MS
}
catch
{
$message = "ERROR DURING CONNECTION TO $MS"
write-host -ForegroundColor red $message
NewEventSource 
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1002 -Message $message -EntryType Error 
exit 1 
}


# Get $ObjectClass Class
$Class = Get-SCOMClass -displayname $ObjectClass | Where-Object {$_.PropertyCollection -match "^.*($FirstProperty|$SecondProperty).*$"} -ErrorAction stop    ## -- WE CHECK THAT THE TARGET CLASS REALLY HOLD THE WANTED PROPERTIES
if (!($Class))
{
$message = "ERROR DURING RETRIEVE OF '$ObjectClass' CLASS. (CRITERIAS: Class=`"$ObjectClass`" - Property=`"$FirstProperty`" - Value=`"$FirstPropVal`")"
write-host -ForegroundColor red $message
NewEventSource 
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1003 -Message $message -EntryType Error 
exit 1 
}




# Get Computers that have $FirstProperty value as: $FirstPropVal 
try
{
$TargetComp = $Class | Get-SCOMClassInstance | Where-Object {
$_."[$($Class.Name)].$FirstProperty".value -match $FirstPropVal -OR $_.$FirstProperty -match $FirstPropVal`               ##-- DIFFERENT COMBINATION (THE "[$($Class.Name)]" SYNTAX IS TO INCLUDE CASE OF A NOTE PROPERTY
#-AND $_."[$($Class.Name)].$SecondProperty".value -eq $SecondPropVal -OR $_.$SecondProperty -eq $SecondPropVal`     ##-- ADDITIONAL POTENTIAL PROPERTIES (SEE SCRIPT PARAMS)
} -ErrorAction Stop

#$TargetComp = $Class | Get-SCOMClassInstance | Where-Object {                                                       ## -- TO TEST UNFOUND COMPUTER SCENARIO
#$_."[$($Class.Name)].$FirstProperty".value -eq "azerty" -OR $_.$FirstProperty -eq "azerty"`                        ## -- TO TEST UNFOUND COMPUTER SCENARIO
#} -ErrorAction Stop                                                                                                ## -- TO TEST UNFOUND COMPUTER SCENARIO

}
catch
{
$message = "ERROR DURING RETRIEVE OF CLASS INSTANCES (CRITERIAS: Class=`"$ObjectClass`" - Property=`"$FirstProperty`" - Value=`"$FirstPropVal`")"
write-host -ForegroundColor red $message
NewEventSource 
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1004 -Message $message -EntryType Error 
exit 1 
}




switch($Action)
{
"Delete" {


# Analyse the content of $TargetComp
switch($TargetComp.Count)
{
{$_ -lt 1}                  {            
                            $message = "NO AGENT TO REMOVE (CRITERIAS: Class=`"$ObjectClass`" - Property=`"$FirstProperty`" - Value=`"$FirstPropVal`")"
                            Write-Host -F Blue -B White $message
                            NewEventSource 
                            write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1005 -Message $message -EntryType Information 
                            }


{$_ -ge 1 -AND $_ -le $ThreshNotDelete} ## -- SECURITY OPTION TO AVOID DELETION OF TWO MANY AGENTS. BE SURE OF THE APPLIED CRITERIAS BEFORE UNLOCK THAT!
                            {
                            $message = "FOLLOWING AGENTS WILL BE REMOVED:"
                            Write-Host -F Yellow $message
                            $TargetComp.displayname
                                                            
                                DeleteSCOMAgent -AgentComputerName $TargetComp.displayname -MSServer $MS
                                #$result
                                switch($result)
                                    {
                                    "Agents deleted" 
                                                                                        {
                                                                                            $message = "FOLLOWING AGENTS HAS BEEN REMOVED FROM SCOM CONSOLE (CRITERIAS: Class=`"$ObjectClass`" - Property=`"$FirstProperty`" - Value=`"$FirstPropVal`") :`n "
                                                                                            $message += $TargetComp | foreach {$_.DisplayName ;"`n"}
                                                                                            write-host $message
                                                                                            NewEventSource 
                                                                                            write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1006 -Message $message -EntryType Information 
                                                                                        }
                                    
                                    "Error during deletion of one ore more agent" 
                                                                                        {
                                                                                            $message = "ERROR DURING DELETION OF ONE OR MORE AGENT! MANUAL CHECK REQUIRED (CRITERIAS: Class=`"$ObjectClass`" - Property=`"$FirstProperty`" - Value=`"$FirstPropVal`") "
                                                                                            write-host $message
                                                                                            NewEventSource 
                                                                                            write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1007 -Message $message -EntryType Warning
                                                                                        } 

                                    "No Agent found to delete" 
                                                                                        {
                                                                                            $message = "NO AGENT FOUND TO DELETE - MANUAL CHECK REQUIRED (CRITERIAS: Class=`"$ObjectClass`" - Property=`"$FirstProperty`" - Value=`"$FirstPropVal`")"
                                                                                            write-host $message
                                                                                            NewEventSource 
                                                                                            write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1008 -Message $message -EntryType Warning
                                                                                        } 


                                    
                                
                                    
                                
                            
                                }

                            }

{$_ -gt $ThreshNotDelete}                 {
                            $message = "WARNING: NUMBER OF AGENTS TO REMOVE IS GREATER THAN 10 ! MANUAL CHECK REQUIRED"  ## -- SECURITY OPTION TO AVOID DELETION OF TWO MANY AGENTS. BE SURE OF THE APPLIED CRITERIAS BEFORE UNLOCK THAT!
                            Write-Host -F red $message
                            $TargetComp.displayname
                            NewEventSource 
                            write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1009 -Message $message -EntryType Warning
                            }


}


         }


"Maintenance" {

#Clear-Variable message

    If ($TargetComp.Count -ge 1)
        {

        foreach ($target in $TargetComp)
            {
            If (Get-SCOMMaintenanceMode -Instance $target)
                {
                #$message += "`n$target IS ALREADY IN MAINTENANCE MODE"
                $AlreadyInMM += "$target`n"
                }
            Else
                {
                SetMM -HostToMM $target -Duration $MaintenanceDuration
                $PutInMM += "$target`n" 
                }
            }
                       

            $message = "`nFOLLOWING AGENTS HAS BEEN SET IN MAINTENANCE MODE (CRITERIAS: Class=`"$ObjectClass`" - Property=`"$FirstProperty`" - Value=`"$FirstPropVal`") :`n"
            $message += $PutInMM
            $message += "`n`nFOLLOWING AGENTS ARE ALREADY IN MAINTENANCE MODE (CRITERIAS: Class=`"$ObjectClass`" - Property=`"$FirstProperty`" - Value=`"$FirstPropVal`") :`n"
            $message += $AlreadyInMM
            write-host $message
            NewEventSource 
            write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1010 -Message $message -EntryType Information 
         }
        
    Else
        {
        $message = "NO AGENT TO PUT IN MAINTENANCE MODE HAS BEEN FOUND. (CRITERIAS: Class=`"$ObjectClass`" - Property=`"$FirstProperty`" - Value=`"$FirstPropVal`")"
        write-host $message
        NewEventSource 
        write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1011 -Message $message -EntryType Information
        }
    }


default {

        $message = "No action has been choosed. Possible value: `"Delete`" (Delete Agent from console) or `"Maintenance`" (Put corresponding computer in Maintenance Mode)"
        write-host -ForegroundColor red $message
        NewEventSource 
        write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1012 -Message $message -EntryType Error 
        exit 1 
        }

}

 

SCOM - Script - Comparaison Agents et Liste Machines

Le script ci-dessous propose de comparer un extract des agents scom avec une liste de machine, pour un suivi de déploiement par exemple.

Compare_SCOMAgent_ComputerList.ps1 (1,67 kb)

 

### COMPARE SCOM AGENTS AND COMPUTER LIST IN TXT FILE

#Parameters
Param(
[Parameter(Mandatory=$false)]
$MS="MyMS.MyDomain",
[Parameter(Mandatory=$false)]
$Cred = $(Get-Credential "MyDomain\Me"),
[Parameter(Mandatory=$false)]
$FilePath = "C:\ServerList.txt "
)


#Import du module SCOM
try
{
Import-Module -Name OperationsManager -ErrorAction stop
}
catch
{
write-host -ForegroundColor red "Erreur lors de l'import du module SCOM"
}

#Connection au management group $MGroup
New-SCOMManagementGroupConnection -ComputerName $MS -Credential $Cred


# Recuperation de la liste des agents (netbios name
$agents = Get-SCOMAgent | select computername -ExpandProperty computername


# Import du fichier $FilePath
try
{
$ComputerList = Get-Content -Path $FilePath
}
catch
{
write-host -ForegroundColor red "Error during import of `"$FilePath`""
}




# Machines dans Scom ET dans la liste
$Both = $(Compare-Object -ReferenceObject $agents -DifferenceObject $ComputerList -IncludeEqual -ExcludeDifferent).inputobject

# Machines uniquement dans SCOM
$InScom = $(Compare-Object -ReferenceObject $agents -DifferenceObject $ComputerList | Where-Object {$_.sideindicator -eq "<="}).inputobject

# Machines uniquement dans la liste
$InFile = $(Compare-Object -ReferenceObject $agents -DifferenceObject $ComputerList | Where-Object {$_.sideindicator -eq "=>"}).inputobject




write-host -B White -F Blue "`n $($both.Count) COMPUTERS THAT ARE IN SCOM AND IN FILE:"
$Both

write-host -B White -F Blue "`n $($InScom.Count) COMPUTERS THAT ARE ONLY IN SCOM:"
$InScom

write-host -B White -F Blue "`n $($InList.Count) COMPUTERS THAT ARE ONLY IN FILE:"
$InFile



 

SCOM - Script - Supprimer un agent de la console en fonction de la valeur d'une ou plusieurs propriété d'une classe

Le script ci-dessous propose le scenario ou l'on doit automatiser la suppression d'un agent de la console (pas une desinstallation) en fonction de la valeur d'une ou plusieurs propriétés de l'instance d'une classe pour ce/ces agents.

Ceci peut permettre par exemple dans la cas de la présence d'une classe étendue (avec vos propres propriétés issues par exemple d'un outil tiers) de decommissionner un ou plusieurs agents automatiquement, selon la valeur de ces propriétés (Dans l'exemple inscrit par defaut dans les paramètres, on cherche la valeur 'Useless' ou 'Deprecated' de la propriété 'Usage' de la classe 'MyClass')

 

RemoveAgentUponPropertyVal.ps1 (10,67 kb)

 

## RemoveAgentUponPropertyVal.ps1
## SCOM - REMOVE AGENT(S) FROM CONSOLE THAT HAVE SPECIFIC VALUES IN ONE OR MORE CLASS PROPERTY.
## AUTHOR: C.JOURDAN
## Version: 1.0

##  PARAMETERS
##  $MS: Target Management Server
##  $ObjectClass: Display Name of Target Class
##  $FirstProperty: name of class property
##  $FirstPropVal: multi value possible of $FirstProperty
##  $ThreshNotDelete: Nb of found computers to delete over which we only warn (NO AUTOMATIC DELETE)

## NOTES: $ThreshNotDelete PARAMETER IS A SECURITY OPTION TO AVOID DELETION OF TWO MANY AGENTS. BE SURE OF THE APPLIED CRITERIAS BEFORE UNLOCK THAT! 


#PARAMETERS
Param(
[Parameter(Mandatory=$false)]
$MGroup,
[Parameter(Mandatory=$false)]
$MS='localhost',
[Parameter(Mandatory=$false)]
$ObjectClass = 'MyClass',
[Parameter(Mandatory=$false)]
$FirstProperty='Usage',
[Parameter(Mandatory=$false)]
$FirstPropVal="^.*(Useless|Deprecated).*$",
<# -- ADDITIONAL PROPERTIES FROM $ObjectClass INSTANCE -- SEE CLASS INSTANCE RETRIEVE SECTION
[Parameter(Mandatory=$false)]
$SecondProperty='Prop2',
[Parameter(Mandatory=$false)]
$SecondPropVal='Value2'
#>
[Parameter(Mandatory=$false)]
$ThreshNotDelete = 10
)

#ScriptName
$ScriptName = "RemoveAgentUponPropertyVal.ps1"


#FUNCTIONS

# NewEventSource
# Check of a source existance  in the 'operation manager' eventlog that match the script name, to log some events.
         Function NewEventSource 
         { 
         if(!(Test-Path "HKLM:\SYSTEM\CurrentControlSet\services\eventlog\Operations Manager\$ScriptName")) 
         { 
         New-EventLog -LogName "Operations Manager" -Source $ScriptName 
         }
         } 


# DeleteSCOMAgent
# Remove agent from SCOM Console.
Function DeleteSCOMAgent 
{
Param(
  [string[]]$AgentComputerName,
  [string]$MSServer
)

[System.Reflection.Assembly]::Load("Microsoft.EnterpriseManagement.Core, Version=7.0.5000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")
[System.Reflection.Assembly]::Load("Microsoft.EnterpriseManagement.OperationsManager, Version=7.0.5000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")



function New-Collection ( [type] $type ) 
{
	$typeAssemblyName = $type.AssemblyQualifiedName;
	$collection = new-object "System.Collections.ObjectModel.Collection``1[[$typeAssemblyName]]";
	return ,($collection);
}




# Connect to management group
Write-output "Connecting to management group"

$ConnectionSetting = New-Object Microsoft.EnterpriseManagement.ManagementGroup($MSServer)
$admin = $ConnectionSetting.GetAdministration()


Write-output "Getting agent managed computers"
$agentManagedComputers = $admin.GetAllAgentManagedComputers()

# Get list of agents to delete
foreach ($name in $AgentComputerName) 
{
    Write-output "Checking for $name"
    foreach ($agent in $agentManagedComputers)
    {
        if ($deleteCollection -eq $null) 
        {
            $deleteCollection = new-collection $agent.GetType()
        }

        
        if (@($agent.PrincipalName -eq $name))
        {
	    Write-output "Matched $name"
            $deleteCollection.Add($agent)
            break
        }
    }
}

if ($deleteCollection.Count -gt 0) 
{
    Write-output "Deleting agents"
    $admin.DeleteAgentManagedComputers($deleteCollection)
    if($?){
           $Script:result="Agents deleted"
           Write-Output $result
          }
    Else  {
           $result="Error during deletion of one ore more agent"
           Write-Output $result
          }
}

Else
    {
    $result="No Agent found to delete"
    Write-Output $result
    }


}




#END FUNCTIONS


#Log of script execution 
NewEventSource 
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1000 -Message "Execution du script $ScriptName" -EntryType Information 



#Import of SCOM Powershell module
try
{
Import-Module -Name OperationsManager -ErrorAction stop
}
catch
{
write-host -ForegroundColor red "Error during import of SCOM PS Module"
NewEventSource 
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1001 -Message "Error during import of SCOM PS Module" -EntryType Error 
exit 1 
}



#Connection to management group $MGroup
try
{
New-SCOMManagementGroupConnection -ComputerName $MS
}
catch
{
write-host -ForegroundColor red "Error during connection to MS $MS"
NewEventSource 
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1002 -Message "Error during connection to MS $MS" -EntryType Error 
exit 1 
}


# Get $ObjectClass Class
$Class = Get-SCOMClass -displayname $ObjectClass | Where-Object {$_.PropertyCollection -match "^.*($FirstProperty|$SecondProperty).*$"} -ErrorAction stop    ## -- WE CHECK THAT THE TARGET CLASS REALLY HOLD THE WANTED PROPERTIES
if (!($Class))
{
$message = "ERROR DURING RETRIEVE OF '$ObjectClass' CLASS. CHECK THAT CLASS EXIST OR THAT THE PROPERTIES YOU WANT EXIST IN THIS CLASS"
write-host -ForegroundColor red $message
NewEventSource 
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1003 -Message $message -EntryType Error 
exit 1 
}




# Get Computers that have $FirstProperty value as: $FirstPropVal 
try
{
$TargetComp = $Class | Get-SCOMClassInstance | Where-Object {
$_."[$($Class.Name)].$FirstProperty".value -match $FirstPropVal -OR $_.$FirstProperty -match $FirstPropVal`               ##-- DIFFERENT COMBINATION (THE "[$($Class.Name)]" SYNTAX IS TO INCLUDE CASE OF A NOTE PROPERTY
#-AND $_."[$($Class.Name)].$SecondProperty".value -eq $SecondPropVal -OR $_.$SecondProperty -eq $SecondPropVal`     ##-- ADDITIONAL POTENTIAL PROPERTIES (SEE SCRIPT PARAMS)
} -ErrorAction Stop

#$TargetComp = $Class | Get-SCOMClassInstance | Where-Object {                                                       ## -- TO TEST UNFOUND COMPUTER SCENARIO
#$_."[$($Class.Name)].$FirstProperty".value -eq "azerty" -OR $_.$FirstProperty -eq "azerty"`                        ## -- TO TEST UNFOUND COMPUTER SCENARIO
#} -ErrorAction Stop                                                                                                ## -- TO TEST UNFOUND COMPUTER SCENARIO

}
catch
{
$message = "Error during retrieve of '$ObjectClass' instances that have $FirstProperty : $FirstPropVal"
write-host -ForegroundColor red $message
NewEventSource 
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1004 -Message $message -EntryType Error 
exit 1 
}


# Analyse the content of $TargetComp
switch($TargetComp.Count)
{
{$_ -lt 1}                  {            
                            $message = "NO AGENT TO REMOVE"
                            Write-Host -F Blue -B White $message
                            NewEventSource 
                            write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1005 -Message $message -EntryType Information 
                            }


{$_ -ge 1 -AND $_ -le $ThreshNotDelete} ## -- SECURITY OPTION TO AVOID DELETION OF TWO MANY AGENTS. BE SURE OF THE APPLIED CRITERIAS BEFORE UNLOCK THAT!
                            {
                            $message = "FOLLOWING AGENTS WILL BE REMOVED:"
                            Write-Host -F Yellow $message
                            $TargetComp.displayname
                                                            
                                DeleteSCOMAgent -AgentComputerName $TargetComp.displayname -MSServer $MS
                                #$result
                                switch($result)
                                    {
                                    "Agents deleted" 
                                                                                        {
                                                                                            $message = "FOLLOWING AGENTS HAS BEEN REMOVED FROM SCOM CONSOLE SINCE THEIR $FirstProperty IS EQUAL: $FirstPropVal . $($TargetComp.displayname)"
                                                                                            NewEventSource 
                                                                                            write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1006 -Message $message -EntryType Information 
                                                                                        }
                                    
                                    "Error during deletion of one ore more agent" 
                                                                                        {
                                                                                            $message = "ERROR DURING DELETION OF ONE OR MORE AGENT! MANUAL CHECK REQUIRED"
                                                                                            NewEventSource 
                                                                                            write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1007 -Message $message -EntryType Warning
                                                                                        } 

                                    "No Agent found to delete" 
                                                                                        {
                                                                                            $message = "NO AGENT FOUND TO DELETE BY DeleteSCOMAgent FUNCTION! MANUAL CHECK REQUIRED"
                                                                                            NewEventSource 
                                                                                            write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1008 -Message $message -EntryType Warning
                                                                                        } 


                                    
                                
                                    
                                
                            
                                }

                            }

{$_ -gt $ThreshNotDelete}                 {
                            $message = "WARNING: NUMBER OF AGENTS TO REMOVE IS GREATER THAN 10 ! MANUAL CHECK REQUIRED"  ## -- SECURITY OPTION TO AVOID DELETION OF TWO MANY AGENTS. BE SURE OF THE APPLIED CRITERIAS BEFORE UNLOCK THAT!
                            Write-Host -F red $message
                            $TargetComp.displayname
                            NewEventSource 
                            write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1009 -Message $message -EntryType Warning
                            }


}



 

 

 

 

Zabbix - Script Bash de sauvegarde de la base

Ci-dessous, un script bash de sauvegarde complète de la base Zabbix.

BackupZabbixDBFull.sh (1,17 kb)

 

#! /bin/bash
#Def de variables
user="<user>" #Utilisateur de la base de donnees
passwd="<password>" #Mot de passe de l'utilisateur de la base
db="zabbixdb" #Nom de la base
dest="/etc/backup/mysql-full-backup" #Chemin de destination de la sauvegarde (Attention, pas de slash a la fin)
nbsav=5 #Nombre de sauvegardes a conserver

#On fabrique les variables systeme
dte=$(date +"%Y-%m-%d--%H-%M-%S")
fic="$db/$db-$dte.sql"

#### SCRIPT ####
if [ -d $dest/$db ]
then
echo "On sauvegarde dans $db"
else
echo "On cree le dossier de sauvegarde $dest/$db"
mkdir $dest/$db
fi
echo "sauvegarde de la base $db dans $dest/$fic"
ionice -c3 nice -n19 mysqldump -u $user -p$passwd $db > "$dest/$fic"
echo "On compresse "$dest/$fic" avec gzip : $fic.gz"
ionice -c3 nice -n19 gzip "$dest/$fic"

nbfic=$(ls -C1X $dest/$db/$db* | wc -l)
diff=$(echo $(($nbfic-$nbsav)))
echo "On calcule le nombre de fichiers a supprimer pour ne garder que les $nbsav derniers : $diff"
i=1 #Compteur du for
for f in $(ls -C1X "$dest/$db")
do
if [ $i -le $diff ]
then
oldsav="$dest/$db/$f"
echo "On supprime $dest/$db/$f"
rm -f "$dest/$db/$f"
let i++
fi
done
 

 

 

Script - Suivi des machines ayant l'agent Scom et l'agent Zabbix

Pour faire suite a l'article recent "SCOM - Zabbix - Management Pack pour l'agent Zabbix sur Windows" qui propose de créer et decouvrir une classe 'ZabbixAgent', voici un script permettant de faire un suivi des machines ayant l'agent Scom et l'agent Zabbix.

 

ScomAndZabbix.ps1 (1,20 kb)

 

## RETRIEVE COMPUTERS THAT HAVE SCOM AGENT AND ZABBIX AGENT


#Variables
$MGroup = "MyMG"
$MS= "MyMGServer.mydomain"
$cred = Get-Credential "ME\Myself"


#Import du module SCOM
try
{
Import-Module -Name OperationsManager -ErrorAction stop
}
catch
{
write-host -ForegroundColor red "Erreur lors de l'import du module SCOM"
}

#Connection au management group $MGroup
New-SCOMManagementGroupConnection -ComputerName $MS -Credential $cred



# Classe des "Health Service"
$AgentClass = Get-SCOMClass -DisplayName "Health Service"

# Classe des "Zabbix Agent"
$ZabbAgClass = Get-SCOMClass -DisplayName "ZabbixAgent"

# Instances de la classe $AgentClass
$AgentInst = $AgentClass | Get-SCOMClassInstance | select -Property *

# Instances de la classe $ZabbAgClass
$ZabbAgInst = $ZabbAgClass | Get-SCOMClassInstance | select -Property *


# COMPARAISON (MACHINE AYANT L'AGENT ZABBIX ET L'AGENT SCOM)
$ScomAndZab =  Compare-Object -ReferenceObject $AgentInst.displayname -DifferenceObject $ZabbAgInst.path -IncludeEqual -ExcludeDifferent
Write-Host "--- MANAGEMENT GROUP SCOM: $MS ---"
write-host "--- "$ScomAndZab.count" COMPUTERS THAT HAVE SCOM AND ZABBIX ---"
$ScomAndZab.inputobject | sort

 

SCOM - Zabbix - Management Pack pour l'agent Zabbix sur Windows

 Dans le cadre de la supervision et/ou du suivi du déploiement de l'agent Zabbix avec Scom, voici un management pack qui:

- Decouvre l'agent zabbix, sa version, ses propriétés "ZabbixPassiveServer" et "ZabbixActiveServer"

- Monitor le service ZabbixAgent

- propose deux console tasks:

       - Restart Zabbix Agent Service

       - Display Agent Configuration File (Chemin du fichier de config overridable)

NB: Les Discovery rules et Monitors sont désactivées par defaut.

 

ZabbixAgent.MP.xml (23,35 kb)

 

<?xml version="1.0" encoding="utf-8"?><ManagementPack ContentReadable="true" SchemaVersion="2.0" OriginalSchemaVersion="1.1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <Manifest>
    <Identity>
      <ID>ZabbixAgent.MP</ID>
      <Version>1.0.0.3</Version>
    </Identity>
    <Name>ZabbixAgent MP</Name>
    <References>
      <Reference Alias="SCInternal">
        <ID>Microsoft.SystemCenter.Internal</ID>
        <Version>7.0.8433.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="Windows">
        <ID>Microsoft.Windows.Library</ID>
        <Version>7.5.8501.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="Performance">
        <ID>System.Performance.Library</ID>
        <Version>7.0.8433.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="System">
        <ID>System.Library</ID>
        <Version>7.5.8501.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="SC">
        <ID>Microsoft.SystemCenter.Library</ID>
        <Version>7.0.8433.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="Health">
        <ID>System.Health.Library</ID>
        <Version>7.0.8433.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
    </References>
  </Manifest>
  <TypeDefinitions>
    <EntityTypes>
      <ClassTypes>
        <ClassType ID="ZabbixAgent" Accessibility="Public" Abstract="false" Base="Windows!Microsoft.Windows.LocalApplication" Hosted="true" Singleton="false" Extension="false">
          <Property ID="Name" Type="string" AutoIncrement="false" Key="false" CaseSensitive="false" MaxLength="256" MinLength="0" Required="false" Scale="0" />
          <Property ID="Version" Type="string" AutoIncrement="false" Key="false" CaseSensitive="false" MaxLength="256" MinLength="0" Required="false" Scale="0" />
          <Property ID="ZabbixPassiveServer" Type="string" AutoIncrement="false" Key="false" CaseSensitive="false" MaxLength="256" MinLength="0" Required="false" Scale="0" />
          <Property ID="ZabbixActiveServer" Type="string" AutoIncrement="false" Key="false" CaseSensitive="false" MaxLength="256" MinLength="0" Required="false" Scale="0" />


        </ClassType>
        <ClassType ID="ZabbixAgent.MP.Application.Rollup" Accessibility="Public" Abstract="false" Base="System!System.Service" Hosted="false" Singleton="false" Extension="false">
          <Property ID="ApplicationName" Type="string" AutoIncrement="false" Key="true" CaseSensitive="false" MaxLength="256" MinLength="0" Required="false" Scale="0" />
        </ClassType>
      </ClassTypes>
      <RelationshipTypes>
        <RelationshipType ID="ZabbixAgent.MP.Application.Contains.ZabbixAgent" Accessibility="Public" Abstract="false" Base="System!System.Containment">
          <Source ID="Source" MinCardinality="0" MaxCardinality="2147483647" Type="ZabbixAgent.MP.Application.Rollup" />
          <Target ID="Target" MinCardinality="0" MaxCardinality="2147483647" Type="ZabbixAgent" />
        </RelationshipType>
      </RelationshipTypes>
    </EntityTypes>
	<ModuleTypes>
	
		<WriteActionModuleType ID="ZabbixAgent.DisplayAgentConfig.WA" Accessibility="Internal" Batching="false">
        <Configuration>
          <xsd:element minOccurs="1" name="ConfigFilePath" type="xsd:string" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
          <xsd:element minOccurs="1" name="TimeoutSeconds" type="xsd:integer" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
        </Configuration>
        <OverrideableParameters>
          <OverrideableParameter ID="ConfigFilePath" Selector="$Config/ConfigFilePath$" ParameterType="string" />
          <OverrideableParameter ID="TimeoutSeconds" Selector="$Config/TimeoutSeconds$" ParameterType="int" />
        </OverrideableParameters>
        <ModuleImplementation Isolation="Any">
          <Composite>
            <MemberModules>
              <WriteAction ID="PSWA" TypeID="Windows!Microsoft.Windows.PowerShellWriteAction">
                <ScriptName>ZabbixAgent.DisplayAgentConfig.WA.ps1</ScriptName>
                <ScriptBody>
#=================================================================================
#  Script to display Zabbix Agent Configuration File
#=================================================================================

param($ConfigFilePath)

#=================================================================================
# Constants section - modify stuff here:

# Assign script name variable for use in event logging
$ScriptName = "ZabbixAgent.DisplayAgentConfig.Task.ps1"
#=================================================================================


# Gather who the script is running as
$whoami = whoami


# Begin Main Script
#=================================================================================
Write-Host "Task Starting.  Running as $whoami"
#Load agent scripting object
Write-Host "Display Zabbix Agent Config File"
try
	{
	Get-Content -Path $ConfigFilePath
	}
	catch
	{
	write-host "Error during access to $ConfigFilePath file"
	}

#=================================================================================
                </ScriptBody>
                <Parameters>
                  <Parameter>
                    <Name>ConfigFilePath</Name>
                    <Value>$Config/ConfigFilePath$</Value>
                  </Parameter>
                </Parameters>
                <TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
              </WriteAction>
            </MemberModules>
            <Composition>
              <Node ID="PSWA" />
            </Composition>
          </Composite>
        </ModuleImplementation>
        <OutputType>System!System.BaseData</OutputType>
        <InputType>System!System.BaseData</InputType>
      </WriteActionModuleType>
	
	</ModuleTypes>
  </TypeDefinitions>
  <Monitoring>
    <Discoveries>
      <Discovery ID="ZabbixAgent.Discovery" Enabled="false" Target="Windows!Microsoft.Windows.Computer" ConfirmDelivery="false" Remotable="true" Priority="Normal">
        <Category>Discovery</Category>
        <DiscoveryTypes>
          <DiscoveryClass TypeID="ZabbixAgent">
            <Property PropertyID="Name" />
            <Property TypeID="System!System.ConfigItem" PropertyID="ObjectStatus" />
            <Property TypeID="System!System.ConfigItem" PropertyID="AssetStatus" />
            <Property TypeID="System!System.ConfigItem" PropertyID="Notes" />
            <Property TypeID="System!System.Entity" PropertyID="DisplayName" />
          </DiscoveryClass>
        </DiscoveryTypes>
        <DataSource ID="DS" TypeID="Windows!Microsoft.Windows.WmiProviderWithClassSnapshotDataMapper">
          <NameSpace>\\$Target/Property[Type="Windows!Microsoft.Windows.Computer"]/NetworkName$\root\cimv2</NameSpace>
          <Query>SELECT Name, DisplayName, PathName FROM Win32_Service WHERE Name like '%zabbix%'</Query>
          <Frequency>86400</Frequency>
          <ClassId>$MPElement[Name="ZabbixAgent"]$</ClassId>
          <InstanceSettings>
            <Settings>
              <Setting>
                <Name>$MPElement[Name="Windows!Microsoft.Windows.Computer"]/PrincipalName$</Name>
                <Value>$Target/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</Value>
              </Setting>
              <Setting>
                <Name>$MPElement[Name="ZabbixAgent"]/Name$</Name>
                <Value>$Data/Property[@Name='Name']$</Value>
              </Setting>
            </Settings>
          </InstanceSettings>
        </DataSource>
      </Discovery>
	     
	  
	 <Discovery ID="ZabbixAgent.Discovery.PowerShell.Properties.Discovery" Enabled="false" Target="ZabbixAgent" ConfirmDelivery="false" Remotable="true" Priority="Normal">
        <Category>Discovery</Category>
        <DiscoveryTypes>
          <DiscoveryClass TypeID="ZabbixAgent">
            <Property PropertyID="Version" />
            <Property PropertyID="ZabbixPassiveServer" />
            <Property PropertyID="ZabbixActiveServer" />
          </DiscoveryClass>
        </DiscoveryTypes>
        <DataSource ID="DS" TypeID="Windows!Microsoft.Windows.TimedPowerShell.DiscoveryProvider">
          <IntervalSeconds>86393</IntervalSeconds>
          <SyncTime />
          <ScriptName>ZabbixAgent.PowerShell.Properties.Discovery.ps1</ScriptName>
          <ScriptBody>
#=================================================================================
#  Script to gather additional properties of zabbix agent via PowerShell
#
#  Author: CJOURDAN
#  v1
#=================================================================================
param($SourceId,$ManagedEntityId,$ComputerName)


# Manual Testing section - put stuff here for manually testing script - typically parameters:
#=================================================================================
# $SourceId = '{00000000-0000-0000-0000-000000000000}'
# $ManagedEntityId = '{00000000-0000-0000-0000-000000000000}'
# $Computername = 'server.domain.com'
# $MGName = ''
# $IP = ''
#=================================================================================


# Constants section - modify stuff here:
#=================================================================================
# Assign script name variable for use in event logging
$ScriptName = "ZabbixAgent.PowerShell.Properties.Discovery.ps1"

#=================================================================================


# Starting Script section - All scripts get this
#=================================================================================
# Gather the start time of the script
$StartTime = Get-Date
#Set variable to be used in logging events
$whoami = whoami
# Load MOMScript API
$momapi = New-Object -comObject MOM.ScriptAPI
#Log script event that we are starting task
$momapi.LogScriptEvent($ScriptName,1006,0,"`nScript is starting.")
#=================================================================================


# Discovery Script section
#=================================================================================
# Load SCOM Discovery module
$DiscoveryData = $momapi.CreateDiscoveryData(0, $SourceId, $ManagedEntityId)
#=================================================================================


# Begin MAIN script section
#=================================================================================


# Get Infos from Zabbix Agent Configuration File
#=======================================================================			
$ZabbixConfFile = "C:\Program Files\zabbix_agents\conf\zabbix_agentd.win.conf"
#=======================================================================

try
{
$FileContent = Get-Content -Path $ZabbixConfFile -ErrorAction Stop
}
catch
{
$momapi.LogScriptEvent($ScriptName,1007,2,"`Error during retrieve of Zabbix Conf File Content")
exit 1
}


$ActiveServer =  $FileContent | Where-Object {$_ -like "ServerActive=*"}

$PassiveServer = $FileContent | Where-Object {$_ -like "Server=*"} 

If (!($ActiveServer) -or $ActiveServer.Length -eq 0)
	{
    #Write-Host "`Error during retrieve of Active Server data"
    $momapi.LogScriptEvent($ScriptName,1007,2,"`Error during retrieve of Active Server data or Active Server is not configured")
	$ActiveServer = "NULL"
	}
    Else
	{
	$ActiveServer = $ActiveServer.Replace('ServerActive=','')
	}


If (!($PassiveServer) -or $PassiveServer.Length -eq 0)
	{
    #write-host "`Error during retrieve of PassiveServer data"
    $momapi.LogScriptEvent($ScriptName,1007,2,"`Error during retrieve of PassiveServer data or Passive Server is not configured")
	$PassiveServer = "NULL"
	}
Else
	{
	$PassiveServer = $PassiveServer.Replace('Server=','')
	}


# Get Infos from Zabbix Agent exe (zabbix_agentd.exe)
#=======================================================================
try
	{
	$Version = $(Get-ChildItem -Path "C:\Program Files\zabbix_agents\bin\win64\zabbix_agentd.exe").VersionInfo.productversion
	}
catch
	{
	#write-host "`Error during retrieve of agent version"
    $momapi.LogScriptEvent($ScriptName,1007,2,"`Error during retrieve of agent version")
	$Version = "NULL"
	}



# Discovery Script section - Discovery scripts get this
#=================================================================================
$instance = $DiscoveryData.CreateClassInstance("$MPElement[Name='ZabbixAgent']$")
$instance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $Computername)
$instance.AddProperty("$MPElement[Name='ZabbixAgent']/Version$", $Version)
$instance.AddProperty("$MPElement[Name='ZabbixAgent']/ZabbixPassiveServer$", $PassiveServer)
$instance.AddProperty("$MPElement[Name='ZabbixAgent']/ZabbixActiveServer$", $ActiveServer)


$DiscoveryData.AddInstance($instance)

# Return Discovery Items Normally           
$DiscoveryData
# Return Discovery Bag to the command line for testing (does not work from ISE)
# $momapi.Return($DiscoveryData)
#=================================================================================


# End of script section
#=================================================================================
#Log an event for script ending and total execution time.
$EndTime = Get-Date
$ScriptTime = ($EndTime - $StartTime).TotalSeconds
$momapi.LogScriptEvent($ScriptName,1008,0,"`nScript has completed.") 
#=================================================================================
# End of script	  
		  </ScriptBody>
          <Parameters>
            <Parameter>
              <Name>SourceId</Name>
              <Value>$MPElement$</Value>
            </Parameter>
            <Parameter>
              <Name>ManagedEntityId</Name>
              <Value>$Target/Id$</Value>
            </Parameter>
            <Parameter>
              <Name>ComputerName</Name>
              <Value>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</Value>
            </Parameter>
            
          </Parameters>
          <TimeoutSeconds>600</TimeoutSeconds>
        </DataSource>
      </Discovery>
    </Discoveries>
   <Tasks>
	<Task ID="ZabbixAgent.RestartZabbixAgent.Task" Accessibility="Public" Enabled="true" Target="ZabbixAgent" Timeout="120" Remotable="true">
        <Category>Custom</Category>
        <WriteAction ID="WA" TypeID="Windows!Microsoft.Windows.ScriptWriteAction">
          <ScriptName>ZabbixAgent.RestartZabbixAgent.Task.vbs</ScriptName>
          <Arguments />
          <ScriptBody>
            Option Explicit
            On Error Resume Next
            Dim ScriptName, oAPI, objWMIService, oShell, oShellEnv, computerName, strCommand, objProcess, objProgram, strShell

            ScriptName = "ZabbixAgent.RestartZabbixAgent.Task.vbs"

            'Load momscript API
            Set oAPI = CreateObject("MOM.ScriptAPI")
            'Log script event that we are starting
            Call oAPI.LogScriptEvent(ScriptName, 1313, 2, "A command to restart the zabbix agent was sent.  We will attempt to stop and then restart the ZabbixAgent now.")

            'Begin Healthservice Restart
            Set oShell = WScript.CreateObject("WScript.Shell")
            set oShellEnv = oShell.Environment("Process")
            computerName = oShellEnv("ComputerName")
            'Echo that we are about to start for task output
            WScript.echo "Beginning Restart attempt for ZabbixAgent on " & computerName
            strCommand = "cmd /c net stop ZabbixAgent & cmd /c net start ZabbixAgent"
            Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
            Set objProcess = objWMIService.Get("Win32_Process")
            Set objProgram = objProcess.Methods_( _
            "Create").InParameters.SpawnInstance_
            objProgram.CommandLine = strCommand
            Set strShell = objWMIService.ExecMethod( _
            "Win32_Process", "Create", objProgram)
            'Echo that we are restarting for task output
            WScript.echo "Restarting ZabbixAgent on " & computerName
            'End ZabbixAgent Restart
          </ScriptBody>
          <TimeoutSeconds>60</TimeoutSeconds>
        </WriteAction>
      </Task>
	  
	  
	  <Task ID="ZabbixAgent.DisplayAgentConfig.Task" Accessibility="Public" Enabled="true" Target="ZabbixAgent" Timeout="120" Remotable="true">
        <Category>Custom</Category>
        <WriteAction ID="PSWA" TypeID="ZabbixAgent.DisplayAgentConfig.WA">
          <ConfigFilePath>C:\Program Files\zabbix_agents\conf\zabbix_agentd.win.conf</ConfigFilePath>
          <TimeoutSeconds>60</TimeoutSeconds>
        </WriteAction>

		
      </Task>
</Tasks>
	<Monitors>
      <UnitMonitor ID="ZabbixAgent.ZabbixAgentService.Monitor" Accessibility="Public" Enabled="false" Target="ZabbixAgent" ParentMonitorID="Health!System.Health.AvailabilityState" Remotable="true" Priority="Normal" TypeID="Windows!Microsoft.Windows.CheckNTServiceStateMonitorType" ConfirmDelivery="false">
        <Category>Custom</Category>
        <OperationalStates>
          <OperationalState ID="ZabbixAgent.ZabbixAgentService.Monitor.OK" MonitorTypeStateID="Running" HealthState="Success" />
          <OperationalState ID="ZabbixAgent.ZabbixAgentService.Monitor.KO" MonitorTypeStateID="NotRunning" HealthState="Error" />
        </OperationalStates>
        <Configuration>
          <ComputerName>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetworkName$</ComputerName>
          <ServiceName>ZabbixAgent</ServiceName>
          <CheckStartupType>true</CheckStartupType>
        </Configuration>
      </UnitMonitor>
    </Monitors>

  

  </Monitoring>
 
  <LanguagePacks>
    <LanguagePack ID="FRA" IsDefault="true">
      <DisplayStrings>
        <DisplayString ElementID="ZabbixAgent.MP">
          <Name>ZabbixAgent MP</Name>
        </DisplayString>
        <DisplayString ElementID="ZabbixAgent.MP.Application.Contains.ZabbixAgent">
          <Name>ZabbixAgent MP Application Contains ZabbixAgent</Name>
          <Description>Defines a System.Containment relationship between ZabbixAgent.MP.Application.Rollup and ZabbixAgent.</Description>
        </DisplayString>
        <DisplayString ElementID="ZabbixAgent.MP.Application.Rollup">
          <Name>ZabbixAgent MP Application Rollup</Name>
        </DisplayString>
        <DisplayString ElementID="ZabbixAgent.MP.Application.Rollup" SubElementID="ApplicationName">
          <Name>Application Name</Name>
          <Description>Application Name</Description>
        </DisplayString>
        <DisplayString ElementID="ZabbixAgent">
          <Name>ZabbixAgent</Name>
        </DisplayString>
        <DisplayString ElementID="ZabbixAgent.Discovery">
          <Name>ZabbixAgent Discovery</Name>
        </DisplayString>
        <DisplayString ElementID="ZabbixAgent.Discovery.PowerShell.Properties.Discovery">
          <Name>ZabbixAgent PowerShell Properties Discovery</Name>
        </DisplayString>

        <DisplayString ElementID="ZabbixAgent" SubElementID="Name">
          <Name>Name</Name>
        </DisplayString>
		<DisplayString ElementID="ZabbixAgent" SubElementID="Version">
          <Name>Version</Name>
        </DisplayString>
		<DisplayString ElementID="ZabbixAgent" SubElementID="ZabbixPassiveServer">
          <Name>ZabbixPassiveServer</Name>
        </DisplayString>
		<DisplayString ElementID="ZabbixAgent" SubElementID="ZabbixActiveServer">
          <Name>ZabbixActiveServer</Name>
        </DisplayString>
		<DisplayString ElementID="ZabbixAgent.ZabbixAgentService.Monitor">
          <Name>Zabbix Agent Service</Name>
        </DisplayString>
        <DisplayString ElementID="ZabbixAgent.ZabbixAgentService.Monitor" SubElementID="ZabbixAgent.ZabbixAgentService.Monitor.OK">
          <Name>Service is running</Name>
        </DisplayString>
        <DisplayString ElementID="ZabbixAgent.ZabbixAgentService.Monitor" SubElementID="ZabbixAgent.ZabbixAgentService.Monitor.KO">
          <Name>Service is not running</Name>
        </DisplayString>
        <DisplayString ElementID="ZabbixAgent.RestartZabbixAgent.Task">
          <Name>Restart Zabbix Agent Service</Name>
        </DisplayString>
        <DisplayString ElementID="ZabbixAgent.DisplayAgentConfig.Task">
          <Name>Display Agent Configuration File</Name>
        </DisplayString>


      </DisplayStrings>

    </LanguagePack>
  
  <LanguagePack ID="ENU" IsDefault="false">
      <DisplayStrings>
        <DisplayString ElementID="ZabbixAgent.MP">
          <Name>ZabbixAgent MP</Name>
        </DisplayString>
        <DisplayString ElementID="ZabbixAgent.MP.Application.Contains.ZabbixAgent">
          <Name>ZabbixAgent MP Application Contains ZabbixAgent</Name>
          <Description>Defines a System.Containment relationship between ZabbixAgent.MP.Application.Rollup and ZabbixAgent.</Description>
        </DisplayString>
        <DisplayString ElementID="ZabbixAgent.MP.Application.Rollup">
          <Name>ZabbixAgent MP Application Rollup</Name>
        </DisplayString>
        <DisplayString ElementID="ZabbixAgent.MP.Application.Rollup" SubElementID="ApplicationName">
          <Name>Application Name</Name>
          <Description>Application Name</Description>
        </DisplayString>
        <DisplayString ElementID="ZabbixAgent">
          <Name>ZabbixAgent</Name>
        </DisplayString>
        <DisplayString ElementID="ZabbixAgent.Discovery">
          <Name>ZabbixAgent Server Discovery</Name>
        </DisplayString>
        <DisplayString ElementID="ZabbixAgent.Discovery.PowerShell.Properties.Discovery">
          <Name>ZabbixAgent PowerShell Properties Discovery</Name>
        </DisplayString>
        <DisplayString ElementID="ZabbixAgent" SubElementID="Name">
          <Name>Name</Name>
        </DisplayString>
		<DisplayString ElementID="ZabbixAgent" SubElementID="Version">
          <Name>Version</Name>
        </DisplayString>
		<DisplayString ElementID="ZabbixAgent" SubElementID="ZabbixPassiveServer">
          <Name>ZabbixPassiveServer</Name>
        </DisplayString>
		<DisplayString ElementID="ZabbixAgent" SubElementID="ZabbixActiveServer">
          <Name>ZabbixActiveServer</Name>
        </DisplayString>
		<DisplayString ElementID="ZabbixAgent.ZabbixAgentService.Monitor">
          <Name>Zabbix Agent Service</Name>
        </DisplayString>
        <DisplayString ElementID="ZabbixAgent.ZabbixAgentService.Monitor" SubElementID="ZabbixAgent.ZabbixAgentService.Monitor.OK">
          <Name>Service is running</Name>
        </DisplayString>
        <DisplayString ElementID="ZabbixAgent.ZabbixAgentService.Monitor" SubElementID="ZabbixAgent.ZabbixAgentService.Monitor.KO">
          <Name>Service is not running</Name>
        </DisplayString>
        <DisplayString ElementID="ZabbixAgent.RestartZabbixAgent.Task">
          <Name>Restart Zabbix Agent Service</Name>
        </DisplayString>
	    <DisplayString ElementID="ZabbixAgent.DisplayAgentConfig.Task">
          <Name>Display Agent Configuration File</Name>
        </DisplayString>


      </DisplayStrings>
    </LanguagePack>
  </LanguagePacks>
</ManagementPack>