Le blog technique

Toutes les astuces #tech des collaborateurs de PI Services.

#openblogPI

Retrouvez les articles à la une

SCOM – : Commandes Powershell pour positionner en masse un Failover Management Server

 

Il existe une méthode de l’objet powershell scom get-scomagent permettant de positionnez la failover management server vers lequel basculera vos agent en cas de crash de leur Primary Management Server.

Les commandes suivantes présentent la logique d’execution de ce positionnement:

On attribue a deux variables le Primary Management Server et le Failover Management Server

$primaryms=Get-SCOMManagementServer -Name "MyPrimaryServer1.home.com"

$failoverms=Get-SCOMManagementServer -Name "MyFailoverServer1.home.com"

On attribue a une variable tout les agents qui ont comme Primary Management Server le serveur "MyPrimaryServer1.home.com”

$agentstomove=Get-SCOMAgent | where-object {$_.primarymanagementservername -eq "MyPrimaryServer1.home.com”}

Vous pouvez vous assurez qu’aucun des agents ne possede un failover server érroné avec la commande suivante qui positionne cette valeur a Null

$agentstomove | foreach {Set-SCOMParentManagementServer -agent $_ -Failoverserver $null}

Enfin pour positionner le Failover Management Server.  Je vous conseille dans ce cas la de mettre l’option Verbose, surtout si le nombre d’agent a traiter est important afin de voir le résultat

$agentstomove | foreach {Set-SCOMParentManagementServer -agent $_ -Failoverserver $failoverms –verbose}

SCOM : Debug des échecs d’exécution de process et de requêtes wmi.

 

Les alertes “Workflow Runtime: Failed to run a process or script” ou “Workflow Runtime: Failed to run a WMI query” révèle un problème d’exécution d’une règle ou d’un moniteur.

1er cas: ce problème est ponctuel. Le champ repeat count de l’alerte est peu élevé et la dernière occurrence (champ Last Modified) n’est pas très récent:

Dans la plupart de ces cas, le workflow exécuté a l’origine de cette erreur n’a pas pu aboutir pour des problèmes ponctuels de performance ou de disponibilité de la machine cible. Vous pouvez essayez de faire le parallèle entre l’heure de l’alerte et les éventements présent dans les eventlog Application et Systeme de la machine cible.

2nd cas: Ce problème est récurrent. Le champ repeat count de l’alerte est élevé et la dernière occurrence (champ Last Modified) est récente: Cela signifie que le workflow concerné échoue systématiquement pour cette la machine cible.

Action:

Il est important de lire le champ Description de l’alerte pour voir plus de détail sur la commande ou la requête exécutée, le workflow impacté et la machine cible.

Exemples:

*************************************************************

Command executed: "C:\Windows\system32\cscript.exe" /nologo "IsHostingMSCS.vbs" {1C0CCF64-D32D-B64C-A66A-792E7F0934D6} {6E52A2D1-E55F-7E00-A150-D4CFAB747EFE} (…) (…)

Working Directory: C:\Program Files\System Center Operations Manager\Agent\Health Service State\Monitoring Host Temporary Files 2960\58276\

One or more workflows were affected by this.

Workflow name: System.Mom.BackwardCompatibility.Computer.IsHostingMSCS.Discovery

Instance name: Machine1.home.com

*************************************************************

***************************************************************

Object enumeration failed

Query: ‘SELECT ServiceName, StartName, DisplayName FROM SqlService WHERE ServiceName="SQLAgent$REC_FR_CI_AS"’

HRESULT: 0x800706be

Details: The remote procedure call failed.

One or more workflows were affected by this.

Workflow name: Microsoft.SQLServer.2008.AgentDiscovery

Instance name: MSSQLSERVER

Instance ID: {6AD519E3-D3C0-7B1B-EE4A-92367A4CDCEC}

***************************************************************

 

Connectez vous sur la machine concernée par l’alerte

Pour les alertes concernant une erreur d’exécution d’un script, tentez d’exécutez dans une fenêtre de commande le script et les argument associés tel que la commande apparait dans le champ Description de l’alerte (Command Executed:…)

Les scripts de supervision des règles/moniteurs retourne dans la plupart des cas leurs données au format XML, ce qui signifie que le script a abouti a une transmission des données récoltées. Dans la cas contraire, le retour affiché par l’exécution de ce script peut être une erreur vbscript ou powershell lié au contenu du script lui-même.

 

Pour les alertes concernant une erreur d’exécution d’une requête wmi, vérifiez sur la machine que la requête wmi précisée dans le champ description de l’alerte (Query:…) peut être effectuée.

=> Utilisez wbemtest.exe présent nativement sur tout les OS Windows pour exécutez la requête wmi.

image

image

image

image

De plus le code situé apres “HRESULT” dans la description de l’alerte indique le type d’erreur wmi. ces types sont disponible sur le lien http://msdn.microsoft.com/en-us/library/aa394559%28v=vs.85%29.aspx

Quelques astuces Powershell

Introduction

Lorsque l’on développe des scripts Powershell, il y a un certain nombres de commandes génériques que l’on réutilise très souvent. Nous verrons aussi quelques astuces qui peuvent être utiles dans de nombreux scripts.

Astuces

Retrouver le dossier d’exécution du script :

Souvent, il arrive que l’on crée une bibliothèque de scripts. Un script peut en appeler un autre parce qu’il contient des fonctions. On peut aussi vouloir faire appel à un fichier de configuration. Beaucoup de scripts contiennent alors le chemin d’exécution via une variable qu’il convient de changer manuellement dès que le répertoire est modifié. Cela n’est cependant pas très portatif. Il est nettement plus intéressant de retrouver ce chemin dynamiquement.

La commande ci-dessous permet de retourner le dossier où se situe le script qui est en train de s’exécuter.

001
002
$RootFolder = Split-Path -Path $MyInvocation.MyCommand.Path 

On peut ensuite retrouver nos fichiers additionnels via des chemins relatifs calculés depuis celui que l’on vient de récupérer.

"$MyInvocation.MyCommand.Path" retourne le chemin du fichier.
A partir de ce dernier la commande "Split-Path" nous retourne uniquement le dossier dans lequel est contenu le script.

Connaître le contexte d’exécution (32 ou 64 bits) :

Il peut arriver que l’on souhaite lancer un exécutable spécifiquement depuis une instance Powershell x86 ou x64 car celui-ci n’existe pas dans un autre contexte.

Pour cela, il existe une astuce permettant de savoir quelle édition de Powershell (x86 ou x64) est lancée :

001
002
[System.IntPtr]::Size 

Cette commande nous donne la taille d’un pointeur sous la forme d’un entier. Lorsque l’invite de commande Powershell est en x64, cette valeur vaut 8. Dans le cas contraire il s’agit de 4. On peut facilement imaginer une structure conditionnel permettant de relancer un script automatiquement en Powershell x86 qui intègre un exécutable ne tournant que sur cette version.

001
002
003
004
005
006
if( [System.IntPtr]::Size -ne 4) { 
    #Chemin du script
    $Path = $myInvocation.InvocationName 
    #Invocation de Powershell x86 avec le même script à exécuter comme paramètre
    $Return = &"$env:windir\syswow64\windowspowershell\v1.0\powershell.exe" $Path 
}

Le script est-il exécuté en mode administrateur :

Dans le même esprit, il est possible de savoir si un script a été lancé en mode administrateur. En effet, certaines opérations peuvent exiger ce mode de fonctionnement :

001
002
([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")

Bien évidemment il n’existe pas de commande pour relancer le script dans ce mode. On peut cependant inviter l’utilisateur à le faire.

Tester son script pour une autre version de Powershell :

Il peut arriver que l’on développe son script Powershell sur son poste client qui est en version 3 alors que le serveur qui le lance est lui en version 2. Afin d’être certain que ce script est compatible, il est possible d’indiquer la version de Powershell à utiliser. En voici un exemple ci-dessous :

test version

En version 3 il n’est plus nécessaire de faire d’Import-Module pour utiliser les cmdlets Active Directory, ce qui n’est pas le cas en Powershell 2. Nous voyons donc clairement la différence entre les 2 exécutions.

Appeler une librairie .NET :

Il existe de nombreuses méthodes pour charger une librairie .NET (sous forme de dll ou directement de code C# par exemple). Ici, nous en verrons une qui utilise la commande Powershell Add-Type :

Pour utiliser les Windows forms pour les interfaces graphiques.

001
002
Add-Type -AssemblyName "System.Windows.Forms"

Pour administrer IIS, on charge une dll depuis son emplacement sur le disque

001
002
Add-Type -Path "c:\windows\system32\inetsrv\microsoft.web.administration.dll"

Intégrer directement du code C# (il est aussi possible de le faire avec du code VBScript)

001
002
003
004
005
006
007
008
009
010
011
012
Main; Add-Type -TypeDefinition @"
public class Test
{
    public string Name {get;set;}
    public int Size {get;set;}
    public Test(string Name, int Size){
        this.Name = Name;
        this.Size = Size;
    }
}
"@

Toutefois lorsque la commande Add-Type sera exécutée il n’est pas possible de recharger une librairie qui aurait été modifiée (Cela est dû à .NET). En effet une librairie ne peut être déchargée. Il faut alors changer de session Powershell (c’est à dire lancer une nouvelle instance de Powershell).