PI Services

Le blog des collaborateurs de PI Services

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>


 

 

 

 

Sharepoint Online : Script de Restauration d'éléments dans la corbeille.

Restaurer des milliers d'éléments supprimés par une personne sur un site Sharepoint peut être une opération fastidieuse, voici donc un script Powershell pour le faire à votre place et vous bénéficierez aussi d'un rapport d'état ("Success", "Failure") pour chacun des éléments.

1 - Prérequis Powershell

Dans un premier temps nous allons avoir besoin d’installer le module Powershell nécessaire à la gestion de Sharepoint, pour ce faire utilisez la commande suivante :

# Installation du Module Powershell
Install-Module SharePointPnPPowerShellOnline

Une fois le module Powershell installé nous allons pouvoir nous connecter au site et atteindre sa corbeille de là nous pourrons faire le filtrage et l’export des éléments.

2 - Script Powershell

# Script to Restore RecycleBin elements
# By : Mathieu ADELAÏDE
# Date : 06/09/2019
# Version : V0

#######################
# Step 0 : Management #
#######################
#region - Step 0
# Folder Definition
# Get Current Path
$currentPath = (Get-Location).Path


$RootFolder = "C:\Temp\Sharepoint"
$LogFolder = "$RootFolder\Log"

#Folder Creation
$AllFolder = $RootFolder, $LogFolder
$AllFolder | foreach {
    $FolderName = $_
    If (!(Test-Path $FolderName)) {
        New-Item $FolderName -ItemType Directory
        }
    }

# Files Definition
$ResultState = "$LogFolder\RestaurationReport.csv"
Add-Content $ResultState -Value "Title;ItemType;Size;ItemState;DirName;DeletedByName;DeletedDate;ID;State"
$logFilePath = "$logFolder\SP_Restauration.log"

#Define Array
$Array = @()

#Config Variables
$SiteURL = "https://MySite.sharepoint.com/sites/Recrutement"
#endregion - Step 0

#######################
# Step 1 : Connection #
#######################
#region - Step 1
#Connect to Sharepoint Online
Try {
    Connect-PnPOnline -Url $SiteURL -Credentials (Get-Credential)
    }
Catch {
    $tmpError = $_.Exception.message
	Write-Output "The following error occurred: $tmpError" | Add-Content $logFilePath
	Write-Output "The error occurred while we trying to Connect to Sharepoint Online" | Add-Content $logFilePath
    }
#endregion - Step 1

#######################################
# Step 2 : Collection and Restoration #
#######################################
#region - Step 2
# List all Items
$RecycleBin = Get-PnPRecycleBinItem

# Filter result
$FilteredRecycleBin = $RecycleBin.Where({$_.DeletedByName -eq "DUPONT Jean"})
$FilteredRecycleBin | foreach {
    $Title = $_.Title
    $ItemType = $_.ItemType
    $Size = $_.Size
    $ItemState = $_.ItemState
    $DirName = $_.DirName
    $DeletedByName = $_.DeletedByName
    $DeletedDate = $_.DeletedDate
    $ID = $_.id
    $Guid = $ID.Guid
    
    # Restore
    Try {
        Restore-PnPRecycleBinItem -Identity $Guid -Force -ErrorAction Stop
        Write-Output "Successfully Restored File $Title" | Add-Content $logFilePath
        $State = "Succes"
        }
    Catch {
        $tmpError = $_.Exception.message
	    Write-Output "The following error occurred: $tmpError" | Add-Content $logFilePath
	    Write-Output "The error occurred while we trying to Restore $Title" | Add-Content $logFilePath
        $State = "Failed"
        }
    $Array += New-Object psobject -Property @{
        Title = $Title
        ItemType = $ItemType
        Size = $Size
        ItemState = $ItemState
        DirName = $DirName
        DeletedByName = $DeletedByName
        DeletedDate = $DeletedDate
        State = $State
        Id = $id
        }

    # Release variable
    $Title = $null
    $ItemType = $null
    $Size = $null
    $ItemState = $null
    $DirName = $null
    $DeletedByName = $null
    $DeletedDate = $null
    $ID = $null
    $State = $null
    $Guid = $null
    }
#endregion - Step 2

###################
# Step 3 : Export #
###################
#region - Step 3
Try {
    $Array | Export-Csv $ResultState -Encoding UTF8 -NoTypeInformation -Delimiter ";"
    Write-Output "Successfully Export Data" | Add-Content $logFilePath
    }
Catch {
    $tmpError = $_.Exception.message
	Write-Output "The following error occurred: $tmpError" | Add-Content $logFilePath
	Write-Output "The error occurred while we trying to Export Data" | Add-Content $logFilePath
    }
#endregion - Step 3

 

Sharepoint Online : Comment faire un export des éléments dans la corbeille d’un site.

Récemment j’ai été confronté à un sujet délicat, une synchronisation entre Sharepoint Online et un poste client s’est terminée par la suppression de la majorité des dossiers et fichiers du site en question.

Pour pouvoir connaitre l’étendue des dégâts il a fallu faire un audit de ce qui avait été supprimés par erreur.

On pourrait le faire graphiquement via le portail, mais lorsque le nombre d’éléments s’élève à plusieurs milliers ce n’est pas pratique.

Voici une petite astuce pour faire un export au format CSV des éléments dans la corbeille et en option comment les filtrer sur un utilisateur en particulier.

 

1 - Prérequis Powershell

Dans un premier temps nous allons avoir besoin d’installer le module Powershell nécessaire à la gestion de Sharepoint, pour ce faire utilisez la commande suivante :

# Installation du Module Powershell
Install-Module SharePointPnPPowerShellOnline

Une fois le module Powershell installé nous allons pouvoir nous connecter au site et atteindre sa corbeille de là nous pourrons faire le filtrage et l’export des éléments.

2 - Script Powershell

2.1 Version avec tous les éléments de la corbeille.

#Config Variables
$SiteURL = "https://Monsite.sharepoint.com/sites/Recrutement"
$Items = "C:\temp\RecycleBinItems.csv"
Add-Content $Items -Value "Title;ItemType;Size;ItemState;DirName;DeletedByName;DeletedDate"
$Array = @()
 

#Connect to PnP Online
Connect-PnPOnline -Url $SiteURL -Credentials (Get-Credential)

# List and export all Items in Recycle bin
$RecycleBin = Get-PnPRecycleBinItem
$RecycleBin | foreach {
    $Title = $_.Title
    $ItemType = $_.ItemType
    $Size = $_.Size
    $ItemState = $_.ItemState
    $DirName = $_.DirName
    $DeletedByName = $_.DeletedByName
    $DeletedDate = $_.DeletedDate

    $Array += New-Object psobject -Property @{
        Title = $Title
        ItemType = $ItemType
        Size = $Size
        ItemState = $ItemState
        DirName = $DirName
        DeletedByName = $DeletedByName
        DeletedDate = $DeletedDate
        }
    }

$Array | Export-Csv $Items -Encoding UTF8 -NoTypeInformation 

2.2 Version avec option de filtrage.

Dans cette version nous faisons la même requête, en ajoutant un filtrage sur un utilisateur bien précis.

#Config Variables
$SiteURL = "https://Monsite.sharepoint.com/sites/Recrutement"
$Items = "C:\temp\RecycleBinItems.csv"
Add-Content $Items -Value "Title;ItemType;Size;ItemState;DirName;DeletedByName;DeletedDate"
$Array = @()
 

#Connect to PnP Online
Connect-PnPOnline -Url $SiteURL -Credentials (Get-Credential)

# List and export all Items in Recycle bin
$RecycleBin = Get-PnPRecycleBinItem
$FilteredRecycleBin = $RecycleBin.Where({$_.DeletedByName -eq "DUPONT Jean"})
$FilteredRecycleBin | foreach {
    $Title = $_.Title
    $ItemType = $_.ItemType
    $Size = $_.Size
    $ItemState = $_.ItemState
    $DirName = $_.DirName
    $DeletedByName = $_.DeletedByName
    $DeletedDate = $_.DeletedDate

    $Array += New-Object psobject -Property @{
        Title = $Title
        ItemType = $ItemType
        Size = $Size
        ItemState = $ItemState
        DirName = $DirName
        DeletedByName = $DeletedByName
        DeletedDate = $DeletedDate
        }
    }

$Array | Export-Csv $Items -Encoding UTF8 -NoTypeInformation 

 

SCOM - Script - Fonction de suppression d'agent a distance

La fonction ci-dessous permet de supprimer un agent scom en se connectant a distance a un management server donné.

Function Remove-SCOMAgent
{

 [CmdletBinding()]
 Param
    (
        [Parameter(Mandatory=$true, Position=0)]
        [string]$MServer,
        [Parameter(Mandatory=$true, Position=1)]
        [string]$AgentName,
        [Parameter(Mandatory=$true, Position=2)]
        [string]$User,
        [Parameter(Mandatory=$true, Position=3)]
        [string]$Domain

    )

$Cred = Get-Credential -Message "password" -Username "$Domain\$User"
	


#Import-Module OperationsManager            
New-SCOMManagementGroupConnection -ComputerName $MServer -Credential $Cred
Start-Sleep -s 3

$administration = (Get-SCOMManagementGroup).GetAdministration();
Start-Sleep -Milliseconds 500
$agentManagedComputerType = [Microsoft.EnterpriseManagement.Administration.AgentManagedComputer];
$genericListType = [System.Collections.Generic.List``1]
$genericList = $genericListType.MakeGenericType($agentManagedComputerType)
$agentList = new-object $genericList.FullName
$agent = Get-SCOMAgent *$AgentName*

If(!($agent))
{
$message = "No agent found with name `"$AgentName`""
$message
exit
}

Start-Sleep -S 5
$agentList.Add($agent);

$genericReadOnlyCollectionType = [System.Collections.ObjectModel.ReadOnlyCollection``1]
$genericReadOnlyCollection = $genericReadOnlyCollectionType.MakeGenericType($agentManagedComputerType)
$agentReadOnlyCollection = new-object $genericReadOnlyCollection.FullName @(,$agentList);    
$administration.DeleteAgentManagedComputers($agentReadOnlyCollection);
}

Remove-SCOMAgent -MServer MyMS -AgentName serv1 -User Myaccount -Domain MyDomain



 

Powershell : Credentials Test Function

 

Une petite fonction Powershell pour vous permettre de vérifier des identifiants.

Function Test-Credential {
    PARAM (
        [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)]
        [STRING]$User,
        [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 1)]
        [STRING]$Pass
        )
    Process {
        # Test Credentials
        Add-Type -AssemblyName system.DirectoryServices.AccountManagement
        $DirectoryService = New-Object System.DirectoryServices.AccountManagement.PrincipalContext('domain')
        $Credentials = $DirectoryService.ValidateCredentials($User,$Pass)

        # Return
        If ($Credentials -eq $true) {
            Write-Host "Credentials are correct" -ForegroundColor Green
            }
        Else {
            Write-Host "Credentials are no good" -ForegroundColor Red
            }
        }
    }

 

WSUS Server : Connection Error

Vous venez de déployer un serveur WSUS, finir sa configuration et rattacher les premières machine à se dernier; mais lorsque vous vous rexonnectez sur le serveur afin d'exécuter la console "Windows Server Update Services" vous avez le droit au message d'erreur suivant :

La cause :

Bien souvent cette erreur est lié à IIS, je vous invite donc à exécuter "Internet Information Services (IIS) Manager" puis déroulez le serveur et sélectionnez "Application Pool", ici vous pourrez constater que le "WsusPool" est arrêté.

La solution :

Sélectionnez le et faite "Advanced Settings..." dans le volet de droite, sélectionnez le "Start Mode" pour le passer de "OnDemand" à "AlwaysRunning" puis validez en faisant "OK".

Démarrez le "WsusPool", puis vous pourrez fermer la console IIS.

NB : Tant que le serveur WSUS n'aura pas redémarrez la configuration du IIS ne sera pas effective (vous devrez relancez le "WsusPool" Manuellement à chaque nouvelle connexion au serveur).

Retournez dans la console "Windows Server Update Services" et faites "Reset Server Node"

Enjoy

 

Sharepoint Online : Problème d'accès

Il m'est arrivé il y a peu de temps un cas un peu spécifique, quelqu'un qui bénéficiait de droit "Full Control" sur Sharepoint online se voyait gratfié d'un "Access Denied" à chaque tentative de connexion sur l'url de son site et ceux même en cliquant sur le lien envoyé par Sharepoint lorsqu'on lui attribuait les droits.

La Cause:

En fait cette personne avait bénéficié de droits divers et variés (en accès direct, via l'appartenance à des groupes, via les demandes, Full Control, Edit, Read Only, Limited Access...) car personne parmis les gestionnaires Shrepoint ne parvenait à lui donner les droits.

Par conséquent nous sommes tombé dans un conflit de droits d'accès qui n'a pu être résolu de manière graphique, mais via Powershell.

 

La Solution: 

Afin de solder le problème il a fallu passer par Powershell et supprimer les dépendances de ce compte via la suppression du compte de la "UserInfo List".

Pour ce faire nous avons utilisé les commandes ci-dessous (Attention le module Sharepoint Online pour Powershell est nécessaire):

# Connexion à Sharepoint Online
Connect-SPOService -Url https://monnorganisation.sharepoint.com -Credential "adm-maade@monorganisation.com"

# Vérification des groupes d'appartenance pour mon Utilisateur
$AllUsers = Get-SPOUser -Site https://monnorganisation.sharepoint.com/sites/Toto
$FilterMonUser = $AllUsers.where({$_.loginname -eq "tartanpion@globule.net"})

# Afficher les groupes de mon Utilisateur
$FilterMonUser.groups

# Suppression de mon utilisateur de la UserInfo List
Remove-SPOUser -Site "https://monnorganisation.sharepoint.com/sites/Toto" -LoginName "tartanpion@globule.net"

 

Une fois la commande terminée, j'ai pu réaffecter les bons droits au travers du bon groupe dans l'interface du site Sharepoint.

Info supplémentaires:

https://docs.microsoft.com/en-us/sharepoint/remove-users