PI Services

Le blog des collaborateurs de PI Services

Convertir une boîte aux Lettres utilisateur en Boite aux Lettres Partagée dans un environnement hybride

Dans un environnement hybride, la conversion d’une boîte aux lettres utilisateur en une boîte aux lettres standard n'est pas prise en charge, même s'il existe un lien pour le faire depuis le Centre d'administration Exchange Online. Cela semble fonctionner, mais les modifications apportées dans Exchange online ne seront pas nécessairement synchronisées. Pour convertir une boîte aux lettres Utilisateur en boîte partagée, nous devons suivre trois étapes ci-dessous :

  1. Convertir la boîte aux lettres Utilisateur en BAL partagée dans Exchange Online
  2. Modifier les attributs AD Onpremise
  3. Retirer la licence Exchange Online.

Etape 1 :Conversion de la boîte aux lettres Utilisateur en BAL partagée dans Exchange Online :

  • Ouvrir Windows PowerShell et exécuter la commande suivante:

$UserCredential = Get-Credential

  • Dans la boîte de dialogue Demande d’informations d’identification Windows PowerShell, saisir le nom d’utilisateur et mot de passe, puis cliquer sur OK
  • Exécuter les commandes suivantes :

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection

Import-PSSession $Session -DisableNameChecking

  • Une fois connecté sur Exchange Online, saisir la commande ci-dessous pour convertir la BAL utilisateur en BAL partagée :

Set-Mailbox MyuserMailbox -Type Shared

Etape 2 : Modification des attributs AD Onpremise

Avant d’apporter des modifications aux objets Active Directory, noter les valeurs avant ou encore sauvegarder tous les attributs AD et leurs valeurs dans un fichier texte: Get-ADUser MyUserMailbox -Properties *> BeforeAttributeModification.txt

 Dans la console Utilisateurs et ordinateurs Active Directory, s’assurer d'avoir activé les fonctionnalités avancées dans l'option de menu Affichage. Ensuite, accéder à l’objet AD (utilisateur), ouvrir ses Propriétés et accéder à l’onglet Editeur d’attribut puis mettre à jour les attributs suivants avec ces valeurs :

  • msExchRemoteRecipientType: 100
  • msExchRecipientTypeDetails: 34359738368

 

 

  Etape 3: Suppression de la licence Exchange Online

Vu que la boîte aux lettres partagée ne nécessite pas de licence, cette dernière est à supprimer : Utiliser tout simplement le portail Office 365, rechercher l'utilisateur sous Utilisateurs actifs et retirer la licence Exchange Online. Après la révocation de la licence, il est important de valider son statut dans Azure AD.

  • Se connecter au Module Microsoft Azure Active Directory pour Windows PowerShell
  • Installer la version 64 bits de l’Assistant de connexion Microsoft Online Services : Assistant de connexion Microsoft Online Services pour les professionnels des technologies de l’information RTW
  • Télécharger et installer le Module Microsoft Azure Active Directory pour Windows PowerShell via l'exécution de la commande Install-Module MSOnline 
  • Taper la commande Connect-MsolService, dans la boîte de dialogue Connectez-vous à votre compte, taper le nom d’utilisateur et le mot de passe du compte d’administration Office 365, puis cliquer sur OK.
  • Ouvrir une invite de commandes Windows PowerShell avec élévation de privilèges (exécuter Windows PowerShell en tant qu’administrateur).

Note : Si l’authentification multifacteur est activée, il est à suivre les instructions des boîtes de dialogue suivantes pour fournir des informations d’authentification supplémentaires telles qu’un code de vérification.

  • Pour vérifier que la licence a été correctement retirée, exécuter la commande :

Get-MSOLUser -UserPrincipalName MyUserMailbox@mylab.com | fl * lic *

L'attribut LicenseReconciliationNeeded devrait être False. Si LicenseReconciliationNeeded retourne True, Exchange Online voit que cette boîte aux lettres nécessite une licence et l’a marque pour suppression avec une période de grâce de 30 jours.

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 : créer une découverte de registre pour la valeur Default

Dans SCOM, les découvertes basées sur une clé de registre sont les plus communes. Il existe des dizaines de guides et tutoriaux qui détaillent la marche à suivre, je ne reviendrai donc pas sur les fondamentaux mais je me contenterai du rappel suivant : comme le montre l’extrait de code suivant, cette découverte nécessite la définition du chemin de la clé de registre à récupérer et il est possible de définir différents PathTypes et AttributeTypes :

<RegistryAttributeDefinition>

<AttributeName>##UniqueID##RegValueData</AttributeName>

<Path>##RegValuePath##</Path>

<PathType>1</PathType> <!-- 0=RegKey 1=RegValue -->

<AttributeType>2</AttributeType> <!-- 0=CheckIfExists (Boolean) 1=treat data as (String) 2=treat data as (Integer) -->

</RegistryAttributeDefinition>

PathType permet de préciser s’il faut récupérer un Clé ou une Valeur, et AttributeType permet de de préciser si le module doit se contenter de vérifier l’existence de l’entrée, de récupérer sa valeur sous forme de String (chaine de caractères) ou de la récupérer sous forme d’Integer (entier numérique).

Jusqu’ici, rien de bien particulier pour qui est habitué à travailler avec ces découvertes…

Un cas particulier s’est cependant présenté il y a quelques semaines : une application dont le numéro de version était stocké dans la valeur « Default Value » :

clip_image001_thumb

S’il s’agit manifestement d’une valeur plus que d’une clé, elle ne possède pas de nom… comment faire alors pour indiquer son chemin ?

Faut-il indiquer le chemin de la clé parente mais préciser PathType = 1 comme s’il s’agissait d’une valeur ?

Ou bien indiquer le chemin SOFTWARE\Appli\(Default) ?

Un très ancien article du blog de Marius Sutra (https://blogs.msdn.microsoft.com/mariussutara/2008/02/28/howto-registry-attribute-definition-explained/) indique qu’un PathType = 2 existerait pour ce cas précis, mais les tests ne sont pas concluants et aucune autre trace de cette possibilité ne semble exister, même pas dans la définition de la probe Registry sur MSDN.

Après quelques essais infructueux, la bonne réponse a finalement été trouvée directement par le client avec qui je travaillais :

Il suffit en réalité d’indiquer le chemin sous la forme SOFTWARE\Appli\\ (avec deux antislash à la fin, donc), et de conserver le PathType = 1

Encore une astuce à conserver dans un coin… Merci Jérémie !

Outils Azure : récupérer le certificat du proxy transparent

L’utilisation d’Azure et d’outils qui s’appuient dessus (tels que Storage Explorer, Azure Migrate, Azure CLI, Visual Studio et VS Code…) est devenue presque banale et quotidienne pour beaucoup d’entre nous.

Cependant, dans un environnement d’entreprise, un problème récurrent se présente : la connexion d’un de ces outils à Azure échoue avec un message indiquant un certificat racine incorrect ou autosigné ; comme par exemple ici « Self-signed certificate in certificate chain » :

clip_image002

Une vérification dans les journal d’événement CAPI2 de la machine où s’exécute l’outil devrait permettre d’identifier quel certificat empêche la connexion et, bien souvent il s’agit du proxy d’entreprise qui fonctionne en mode « transparent », interceptant ainsi tous les flux sortants.

Deux solutions sont alors possibles : demander à l’administrateur du proxy de mettre en liste d’exclusion les flux nécessaires à l’application, ou récupérer le certificat racine du proxy afin de l’intégrer au magasin des autorités de confiance de votre machine ou dans les certificats de confiance de l’application, si elle le supporte (c’est le cas pour Storage Explorer).

C’est bien entendu le second cas qui nous intéresse ici. Pour récupérer le certificat, il est nécessaire de passer par l’outil OpenSSL qui n’est pas présent nativement sous Windows. Fort heureusement, il est possible de télécharger des binaires déjà compilées et de les exécuter directement depuis l’invite de commande : https://sourceforge.net/projects/openssl/

Une fois l’archive téléchargée et décompressée, la commande suivante permet de récupérer la chaine de certificats réellement reçus par le système lors d’une requête HTTPS :

s_client –showcerts –connect urldeconnexionauservice.test.com:443

clip_image004

On retrouve ici l’erreur « self signed certificate in certificate chain » ainsi que les certificats présents, inclus entre les lignes ----BEGIN CERTIFICATE---- et ----END CERTIFICATE---- :

clip_image006

Il ne reste plus qu’à copier cette chaine de caractères dans un fichier texte, à renommer ce fichier avec une extension .cer et à l’importer dans l’outil ou directement dans le magasin Windows des autorités de certification approuvées.

Orchestrator : récupérer la liste des variables et leurs valeurs

Bien que cela n’arrive pas souvent, il peut se révéler nécessaire d’extraire l’intégralité des variables dans Orchestrator ainsi que leurs valeurs, par exemple dans le cadre de la migration vers un autre outil d’ordonnancement.

Malheureusement, nativement cette extraction n’est possible qu’au format d’export Orchestrator, difficilement lisible.

L’outil communauté « Parse Orchestrator Export Tool » permet d’obtenir une version plus lisible de cet export, mais il ne permet malheureusement aucune sortie dans un format « universel » tels que des tableaux CSV ou Excel.

Nous allons donc nous appuyer directement sur la base de données SQL d’Orchestrator pour obtenir les valeurs qui nous intéressent :

with VariablePath as

(

select 'Variables\' + cast(name as varchar(max)) as [path], uniqueid

from dbo.folders b

where b.ParentID='00000000-0000-0000-0000-000000000005' and disabled = 0 and deleted= 0

union all

select cast(c.[path] + '\' + cast(b.name as varchar(max)) as varchar(max)), b.uniqueid from dbo.FOLDERS b

inner join

VariablePath c on b.ParentID = c.UniqueID

where b.Disabled = 0 and b.Deleted = 0

)

select O.Name,V.Value,VP.[Path]

from dbo.objects AS O

INNER JOIN VariablePath AS VP ON VP.UniqueID = O.ParentID

INNER JOIN Variables AS V ON V.UniqueID = O.UniqueID

Cette requête retourne le nom, la valeur et l’arborescence de la variable :

clip_image002[10]

Notez cependant que la valeur des variables chiffrées (mots de passe…) reste illisible, puisqu’elles ne sont pas disponibles en texte clair dans la base.

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>