Deux, trois, de nombreux Compute Clusters : Rechercher des clusters dans Active Directory

La langue française est étonnante. Vous pensez peut-être que tous les chemins mènent à Rome (mais ils ne mènent pas tous à un Scripting Guy : vous vous y perdrez). Et bien, de nombreux chemins mènent également à la configuration d'un compute cluster. Et il existe plus de configurations de compute cluster que de façons de lancer une batte de base-ball (ne dites pas ça à un certain Scripting Guy, fan de base-ball : il vous dira de garder le coude arrière bien haut pendant que vous faites tourner votre batte). Vous pensez peut-être que trop de sysadmins nuisent au compute cluster, mais l'inverse est plus probablement vrai : Plus on est de sysadmins, plus on rit. Ne vous en prenez pas aux Scripting Guys : nous n'avons pas créé cette langue étrange ; nous nous contentons de la déformer.

Quel que soit le proverbe que vous leur appliquiez, les compute clusters peuvent prendre de nombreuses formes. Certaines organisations peuvent prendre un cluster pour un gros tas de ferraille, un super-ordinateur géant avec des centaines de noeuds utilisés par tous à travers une organisation pour de la manutention informatique. D'autres peuvent déployer de petits morceaux de ferraille en des ensembles plus petits à travers de nombreux bureaux ou de nombreux services.. Dans ce dernier scénario, de nombreux compute clusters plus petits vont certainement être déployés sur le même segment de réseau et le même domaine Active Directory. Si vous avez l'impression de vivre comme un administrateur de compute cluster, nous espérons que cet article et ce script seront votre tasse de thé, la prunelle de vos yeux et l'objet de toute votre attention (à vous de choisir).

Dr. Scripto : Chaque chose à sa place, chaque compute cluster à son bureau.

The Microsoft Scripting Guys

Sommaire,Sur cette page

À propos des clusters
Cscript ou pas cscript ?
Contenu d'un script ?
Regroupement de clusters
Ressources

À propos des clusters

Lorsque vous installez Compute Cluster Server (CCS) sur Windows Server 2003, vous entrez dans un monde d'infrastructure qui va bien au delà du système d'exploitation. CCS s'intègre notamment à Active Directory pour la gestion du domaine et de l'identité.

Pour gérer les principaux aspects d'autorisation et d'authentification d'utilisateurs et de groupes sur votre compute clusters dans vos scripts et applications, vous pouvez utiliser Active Directory Service Interfaces (ADSI), la principale bibliothèque de scripts de Windows pour Active Directory.

Cependant, vous ne ignorez sans doute qu'il existe une autre bibliothèque de scripts qui peut également permettre d'automatiser la gestion de votre répertoire. ActiveX Data Objects (ADO) est tout d'abord un script de base de données et une technologie de programmation. Il fournit une interface de programmation cohérente à travers une large gamme de sources d'informations provenant de fichiers de texte, de feuilles de calcul et de différents types de bases de données. Puisqu'un répertoire est également une sorte de base de données, ADO peut être utilisé comme un outil flexible pour les scripteurs et les programmeurs qui travaillent avec Active Directory. Sur ce point, ADO présente selon nous un avantage particulier par rapport à ADSI : c'est souvent le meilleur moyen pour rechercher de manière récursive des ressources dans un conteneur de répertoire à plusieurs niveaux..

Dans le cas présent, nous nous intéressons à la recherche d'un type particulier de ressource : les compute clusters. Si vous devez administrer de nombreux clusters dans le type d'environnement dont nous parlons, ADO peut être un complément utile à vos scripts qui gèrent les utilisateurs, les groupes et les ordinateurs sur ces clusters répartis.

Cscript ou pas cscript ?

Avant de regarder le code de script, assurons-nous que notre environnement de script est opérationnel. Pour la plupart des scripts, vous devez avoir des privilèges d'administrateurs sur les machines où vous les exécutez.

Dans ce cas, cependant, chaque personne avec des informations d'identification de l'utilisateur du domaine devrait pouvoir voir les compute clusters du domaine. Par ailleurs, chaque personne ayant des autorisations en tant qu'utilisateur de cluster devrait être en mesure de récupérer des informations d'état à partir du cluster et de ses nœuds. Comme pour tous les scripts Windows, toutefois, les informations d'identification sous lesquelles les scripts sont exécutés ne permettront pas au script d'effectuer une opération que ces informations d'identification ne pourraient pas faire dans l'interface d'utilisateur graphique ou avec d'autres outils de ligne de commande.

Si vous n'avez pas exécuté de scripts d'administration depuis le poste de travail ou le nœud principal sur lequel votre script est exécuté, assurez-vous que l'hôte de script par défaut de Windows Script Host est défini sur Cscript.exe, c'est à dire l'hôte de la ligne de commande, plutôt que sur Wscript.exe, l'hôte GUI (à moins que vous n'aimiez cliquer sur OK de manière répétée).

Pour programmer Cscript.exe par défaut dans l'invite, tapez :

        cscript //h:cscript //nologo //s
      

le commutateur //h définit l'hôte de script par défaut, le commutateur //nologo évite qu'un couple de lignes avec un verbiage inapproprié ne soit exécuté chaque fois que vous exécutez un script, et le commutateur //s enregistre les paramètres comme paramètres par défaut.

Contenu d'un script ?

Passons aux choses sérieuses. Ce script effectue le suivi de tous les compute clusters dans un conteneur Active Directory et vérifie la capacité et l'état de chaque cluster et de ses nœuds. Il a recours à deux technologies de script principales. ADO, pour localiser les compute clusters dans le conteneur Active Directory spécifié ; et l'API de script de Compute Cluster Pack (CCP), pour renvoyer des informations à propos des clusters et des nœuds. Ce script tire également profit de certaines capacités VBScript intégrées en matière d'analyse de chaîne et de traitement des erreurs .

Comme la plupart des scripts de taille plus importante dans Script pour Compute Cluster Server, celui-ci commence par une section qui définit les constantes et les variables. Avant d'exécuter ce script, vous devez attribuer la valeur de strContainer à un conteneur réel dans votre structure Active Directory.

        Const ADS_SCOPE_SUBTREE = 2
        strContainer = "CN=computers,DC=fabrikam,DC=com" 'Accessible AD container.
        strObjectCategory = "ServiceConnectionPoint" 'For CCS
        strServiceClassName = "MicrosoftComputeCluster"
      

Les 20 lignes suivantes définissent l'infrastructure ADO afin de rechercher le conteneur ADO. La majorité de cette section "passe-partout" peut être utilisée avec la plupart des requêtes ADO d'Active Directory. Vous commencez par créer deux références d'objets : l'une à un objet Connection qui indique à ADO le type de fournisseur de données auquel vous souhaitez vous connecter, et l'autre à un objet Command qui définit la requête que vous souhaitez exécuter, le conteneur pour lequel vous souhaitez l'exécuter et le type d'ensemble de données que la requête doit renvoyer.

        Set objConnection = CreateObject("ADODB.Connection")
        Set objCommand = CreateObject("ADODB.Command")
      

Une fois que le fournisseur a été affecté et que l'objet Connection a été ouvert, cet objet Connection est affecté à la propriété ActiveConnection de la commande :

        objConnection.Provider = ("ADsDSOObject")
        objConnection.Open "Active Directory Provider"
        objCommand.ActiveConnection = objConnection
      

le travail commence alors sur l'objet Command. Il est nécessaire de définir la taille de la page si vous voulez récupérer toutes les informations que vous recherchez. (Pour plus d'informations sur la taille de la page, voir Puzzle de script). La constante ADS_SCOPE_SUBTREE, qui représente l'entier 2 est affecté à la propriété Searchscope pour indiquer à ADO de parcourir de manière récursive le conteneur spécifié et tous les sous-conteneurs. Par ailleurs, l'attribut "cn" (pour "common name") est affecté à la propriété Sort On pour demander à ADO de trier les données en fonction du nom de compute cluster.

        objCommand.Properties("Page Size") = 1000
        objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
        objCommand.Properties("Sort On") = "cn"
      

Le code le plus complexe de cette section définit la requête et l'affecte à la propriété CommandText de l'objet Command. Avec ADO, vous pouvez utiliser la syntaxe SQL ou LDAP pour interroger le répertoire. Nous utilisons ici SQL :

        objCommand.CommandText = _
        "SELECT serviceClassName,servicednsname FROM 'LDAP://" & _
        strContainer & "' " & _
        "WHERE objectCategory = '" & strObjectCategory & "' " & _
        "AND serviceClassName = '" & strServiceClassName & "'"
      

La requête extrait deux attributs (serviceClassName et servicednsname) du conteneur, filtrés par une clause WHERE. Cette clause déclare que la requête souhaite uniquement des objets satisfaisant aux deux critères suivants : leur catégorie doit être ServiceConnectionPoint et leur serviceClassName doit être MicrosoftComputeCluster. Tous les objets qui satisfont à ces critères devraient être des compute clusters, suivant le schéma Active Directory.

Une fois l'objet Command chargé pour les compute clusters, le script appuie sur la gâchette en appelant la méthode Execute. Cette méthode exécute la requête pour le conteneur. Lorsque la fumée disparaît, Execute lance l'interception dans un objet représentant le groupe d'enregistrements qui satisfait aux critères de la requête. Nous affectons une référence à cet objet à une variable nommée objRecordSet. Qui a dit que le nommage des variables n'était pas un art ?

        Set objRecordSet = objCommand.Execute
      

À ce stade crucial, avec notre jeu d'enregistrements tout frais en poche, il existe un moment de scriptus interruptus pour détecter une erreur éventuelle à l'aide de l'objet Err intégré à VBScript (qui travaille en tandem avec l'instruction On Error Resume Next au début du script). Que faire en cas de ratés de la commande Execute ? Cela signifie généralement que le conteneur n'est pas atteignable. Le script appelle donc la fonction HandleError, lui transmet un message approprié et affiche l'information d'erreur VBScript. Puis il rentre à la maison avec sa requête, en raison de l'absence de jeu d'enregistrements avec lequel continuer.

        On Error Resume Next
        ...
        If Err Then
        HandleError "ERROR: Unable to find container: " & strContainer
        WScript.Quit
        End If
      

Si la commande ne renvoie pas d'erreur, le script affiche un message indiquant que le conteneur est recherché et plonge dans le jeu d'enregistrements. En fait, si nous voulions seulement connaître les noms des compute clusters, nous pourrions simplement boucler dans le jeu d'enregistrements pour les obtenir. Mais dans ce script, tant que nous connaissons les problèmes liés au suivi, nous allons également saisir des informations sur chaque cluster et ses nœuds. Pour ce faire, nous devons utiliser l'API de script de Compute Cluster Pack.

Donc, avant de boucler dans le jeu d'enregistrements, nous saisons cette occasion pour créer une référence à l'objet API CCP, à l'aide de l'identificateur programmatique "Microsoft.ComputeCluster.Cluster", qui devrait être la référence incontestée pour tous les fans de script Compute Cluster Server. Nous recherchons à nouveau la présence éventuelle d'erreur, mais cette fois-ci, nous n'abandonnons pas si nous en voyons une. Nous transmettons simplement un message à HandleError déclarant que nous ne pourrons pas tirer d'informations sur les clusters et les nœuds à partir de chaque compute cluster trouvé. Le script peut tout de même continuer et répertorier au moins les noms des clusters qu'il a obtenus avec ADO.

        Set objComputeCluster = CreateObject("Microsoft.ComputeCluster.Cluster")
        If Err Then
        HandleError "ERROR: Unable to find Compute Cluster Pack API " & _
        "on this computer. Cluster and node settings not available."
        End If
      

Oui, c'est vrai, il est grand temps de commencer à boucler dans le jeu d'enregistrements et à rechercher ces compute clusters, mais il existe quelques étapes préliminaires. Nous ne voulons pas perdre notre temps à boucler dans un jeu d'enregistrements qui contient 0 enregistrement, ce qui signifierait qu'aucun compute cluster n'a été trouvé. Nous nous assurons donc que la propriété EOF (End Of File) de l'objet jeu d'enregistrements n'est pas vraie, ce qui est simplement une manière doublement négative de dire qu'il existe au moins un enregistrement.

        If Not objRecordSet.EOF Then
      

OK, nous allons maintenant pouvoir nous amuser. Nous devons tout d'abord nous assurer que nous sommes au début du jeu d'enregistrements en appelant la méthode MoveFirst. Ensuite, nous démarrons une boucle Do Until, qui indique au moteur VBScript d'effectuer les opérations entre "Do Until" et "Loop" jusqu'à ce qu'il les ait réalisées sur chaque enregistrement du jeu. Chaque boucle démarre en vérifiant s'il a atteint EOF, auquel cas le script se termine et se déplace. Si nous ne sommes pas à EOF, nous continuons à parcourir la boucle. Chaque fois que le script atteint la fin de la boucle, il appelle la méthode MoveNext pour passer à l'enregistrement suivant du le jeu d'enregistrements, puis vérifie à nouveau s'il a atteint la fin du jeu d'enregistrements avant une nouvelle itération.

        objRecordSet.MoveFirst
        Do Until objRecordSet.EOF
        ...
        objRecordSet.MoveNext
        Loop
      

Dans cette boucle, nous vidons pour chaque enregistrement la valeur du champ "servicednsname" dans une variable et affichons le nom DNS en entier. Cela ressemblera à "srv-ccs-1.computers.fabrikam.com".

        strClusterDnsName = objRecordSet.Fields("servicednsname").Value
        Wscript.Echo vbCrLf & "Cluster DNS Name: " & strClusterDnsName
      

Ensuite, nous extrairons nos fonctions d'analyse de chaîne VBScript, Left et InStr, puis commencerons le découpage. Nous utilisons InStr pour rechercher la première période de la chaîne, et Left pour couper la partie de la chaîne à gauche de cette période. Cela nous donne le nom de l'hôte, qui devrait correspondre au nom du compute cluster.

        strClusterName = Left(strClusterDnsName, _
        (InStr(strClusterDnsName, ".") - 1))
      

Bien sûr, ce n'est pas aussi élégant qu'une expression régulière, mais ça marche. Et si vous préférez vraiment utiliser une expression régulière à la place, VBScript fournit un objet RegExp pour assouvir votre soif d'analyse.

À ce stade, nous avons notre jeu d'enregistrements de compute clusters dans ce conteneur, le nom de chaque cluster ainsi que notre référence d'objet Cluster. Donc, nous utilisons la méthode Cluster.Connect dans chaque boucle pour nous connecter au cluster et obtenir ses propriétés, en recherchant à nouveau la présence éventuelle d'une erreur au cas où le cluster n'est pas accessible.

        objComputeCluster.Connect(strClusterName)
        If Err Then
        HandleError "ERROR: Unable to connect to this compute cluster."
        Else
      

Après avoir obtenu et renvoyé les propriétés du cluster, nous utilisons la méthode Cluster.ComputeNodes pour obtenir un ensemble des nœuds de ce cluster.

        Set colNodes = objComputeCluster.ComputeNodes
      

Nous bouclons dans l'ensemble de nœuds, en utilisant cette fois une boucle For Each, qui intervient pour l'ensemble comme Do Until le faisait pour le jeu d'enregistrements. Nous obtenons pour chaque nœud ses propriétés et son état.

        For Each objNode In colNodes
        WScript.Echo "  Node: " & objNode.Name
        WScript.Echo "    Number of Processors: " & objNode.NumberOfProcessors
        WScript.Echo "    Processor Architecture: " & _
        objNode.ProcessorArchitecture
        WScript.Echo "    Processor Speed: " & objNode.ProcessorSpeed & " MHz"
        WScript.Echo "    Memory: " & objNode.Memory & " MB"
        strStatus = ""
        Select Case objNode.Status
        Case 0 strStatus = "Ready"
        Case 1 strStatus = "Paused"
        Case 2 strStatus = "Unreachable"
        Case 3 strStatus = "Pending Approval"
        Case Else strStatus = "Status unobtainable"
        End Select
        WScript.Echo "    Status: " & strStatus
        Next
      

Pour plus d'explications sur le fonctionnement de cette partie API CCP du script, voir Le tour des nœuds en 80 scripts : tour d'horizon de la bibliothèque de scripts Compute Cluster Server.

La structure de ce script ressemble légèrement à celle du système solaire. Nous avons un gros objet cluster looping qui tourne autour du jeu d'enregistrements et de plus petits objets de nœuds qui tournent autour de chaque cluster. Et pourtant il bouge. Si Galilée voyait le script, il n'en croirait pas ses yeux ...

Si vous voulez décrocher la lune, copiez ce script dans le presse-papiers et collez-le dans un fichier texte, en donnant une extension ".vbs" au fichier. Veillez à bien le coller dans le nom de votre domaine ou conteneur actuel à la place de "CN=computers,DC=fabrikam,DC=com". Ouvrez ensuite une invite de commande et c'est parti ! Et rappelez-vous, si vous n'avez pas encore changé votre hôte de script par défaut en Cscript.exe, vous pouvez exécuter le script en mode batch en faisant précéder le nom du script de la mention "cscript" :

        cscript findclusters.vbs
      

Voici le code complet :

Liste : Rechercher des clusters dans un conteneur Active Directory et obtenir des informations.

        'List all computers in container running Compute Cluster Server and get
        'information on nodes of each.

        On Error Resume Next

        'Initialize constants and variables.
        Const ADS_SCOPE_SUBTREE = 2
        strContainer = "CN=computers,DC=fabrikam,DC=com" 'Accessible AD container.
        strObjectCategory = "ServiceConnectionPoint" 'For CCS
        strServiceClassName = "MicrosoftComputeCluster"

        'Search ADsPath recursively for compute clusters with ADO.
        Set objConnection = CreateObject("ADODB.Connection")
        Set objCommand = CreateObject("ADODB.Command")
        objConnection.Provider = ("ADsDSOObject")
        objConnection.Open "Active Directory Provider"
        objCommand.ActiveConnection = objConnection
        objCommand.Properties("Page Size") = 1000
        objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
        objCommand.Properties("Sort On") = "cn"
        'Construct SQL query.
        objCommand.CommandText = _
        "SELECT serviceClassName,servicednsname FROM 'LDAP://" & _
        strContainer & "' " & _
        "WHERE objectCategory = '" & strObjectCategory & "' " & _
        "AND serviceClassName = '" & strServiceClassName & "'"
        'Perform search of container.
        Set objRecordSet = objCommand.Execute
        If Err Then
        HandleError "ERROR: Unable to find container: " & strContainer
        WScript.Quit
        End If
        WScript.Echo "Searching AD container: " & strContainer & " ..."

        'Create object reference to CCP API.
        Set objComputeCluster = CreateObject("Microsoft.ComputeCluster.Cluster")
        If Err Then
        HandleError "ERROR: Unable to find Compute Cluster Pack API " & _
        "on this computer. Cluster and node settings not available."
        End If

        'Check if returned record set is empty.
        If Not objRecordSet.EOF Then
        objRecordSet.MoveFirst
        'Loop through compute clusters returned by query.
        Do Until objRecordSet.EOF
        strClusterDnsName = objRecordSet.Fields("servicednsname").Value
        Wscript.Echo vbCrLf & "Cluster DNS Name: " & strClusterDnsName
        'Parse cluster name from DNS name.
        strClusterName = Left(strClusterDnsName, _
        (InStr(strClusterDnsName, ".") - 1))
        Wscript.Echo "Cluster Host Name: " & strClusterName

        'Connect to cluster head node and get cluster properties.
        objComputeCluster.Connect(strClusterName)
        If Err Then
        HandleError "ERROR: Unable to connect to this compute cluster."
        Else
        WScript.Echo "Compute Cluster Name: " & objComputeCluster.Name
        WScript.Echo "Server calls asynchronous: " & _
        objComputeCluster.IsAsynchronous
        WScript.Echo "Compute Cluster Environment Variables:"
        Set colEnvVars = objComputeCluster.EnvironmentVariables
        For Each objEnvVar In colEnvVars
        WScript.Echo "  " & objEnvVar.Name & " = " & objEnvVar.Value
        Next
        WScript.Echo "Compute Cluster Parameters:"
        Set colParams = objComputeCluster.Parameters
        For Each objParam In colParams
        WScript.Echo "  " & objParam.Name & " = " & objParam.Value
        Next
        WScript.Echo "Compute Cluster Nodes:"
        Set colNodes = objComputeCluster.ComputeNodes
        'Loop through nodes and get node properties.
        For Each objNode In colNodes
        WScript.Echo "  Node: " & objNode.Name
        WScript.Echo "    Number of Processors: " & objNode.NumberOfProcessors
        WScript.Echo "    Processor Architecture: " & _
        objNode.ProcessorArchitecture
        WScript.Echo "    Processor Speed: " & objNode.ProcessorSpeed & " MHz"
        WScript.Echo "    Memory: " & objNode.Memory & " MB"
        strStatus = ""
        Select Case objNode.Status
        Case 0 strStatus = "Ready"
        Case 1 strStatus = "Paused"
        Case 2 strStatus = "Unreachable"
        Case 3 strStatus = "Pending Approval"
        Case Else strStatus = "Status unobtainable"
        End Select
        WScript.Echo "    Status: " & strStatus
        Next
        End If

        objRecordSet.MoveNext
        Loop

        Else
        Wscript.Echo "No records found."
        End If

        '******************************************************************************

        Sub HandleError(strMessage)
        'Handle errors passed from other parts of script.

        strError = VbCrLf & VbCrLf & strMessage & _
        VbCrLf & "Number (dec) : " & Err.Number & _
        VbCrLf & "Number (hex) : &H" & Hex(Err.Number) & _
        VbCrLf & "Description  : " & Err.Description & _
        VbCrLf & "Source       : " & Err.Source
        WScript.Echo strError
        Err.Clear

        End Sub
      

Au passage, si souhaitez que vos scripts soient le plus simple possible, une version dépouillée de ce script sans le traitement des erreurs ou les commentaires est disponible dans la section Nœuds de la zone Compute Cluster Server du Référentiel de scripts.

Regroupement de clusters

Si vous deviez gérer un grand nombre de compute clusters, vous pourriez utiliser un script comme celui que nous venons de voir afin d'établir une liste de référence des clusters et nœuds, en modifiant le script pour enregistrer la liste dans un fichier texte, une feuille de calcul ou une base de données dans "Il vous faut une bonne mémoire : préparation au déploiement de Compute Cluster Server avec scripts – Partie 2"). Ensuite, vous pourriez exécuter périodiquement le script comme une tâche planifiée et générer la liste actuelle de clusters et nœuds encours d'exécution. Il serait assez simple d'écrire un script séparé qui compare les deux listes, en le consignant et en indiquant aux administrateurs les écarts constatés. Cela pourrait englober les clusters et les nœuds qui sont désactivés ou hors ligne ainsi que les clusters et nœuds non autorisés qui ont été ajoutés sans respecter la procédure.

Dr. Scripto : Si c'est aussi simple, pourquoi est-ce que vous ne l'avez pas écrit ?

Réfléchissez bien. Pendant que vous vérifiez vos compute clusters, cela ne vous prendrait pas longtemps de développer le script afin de contrôler les conditions de chaque cluster et nœud avec l'API CCP et d'autres technologies de script telles que Windows Management Instrumentation (WMI). Mais c'est une autre histoire.

Si vous êtes développeur (ou scripteur chevronné) et maîtrisez .NET Framework (ou que vous aimeriez maîtriser cet outil), vous pouvez chercher le code C# équivalent pour trouver les compute clusters dans un répertoire du blog du developer blog de Dennis Crain "Lire des noms de noeuds principaux compute cluster à partir de Directory Services", sur le site Windows HPC Community.

Ressources

Compute Cluster Server et Active Directory

Déploiement et gestion de Microsoft Windows Compute Cluster 2003

Configuration réseau de Compute Cluster

ActiveX Data Objects ( ADO )

Script pour bases de données

Microsoft Windows 2000 Scripting Guide : travailler avec les bases de données

Microsoft ActiveX Data Objects (ADO) SDK

Eh, où est mon imprimante : utiliser des scripts pour une recherche dans Active Directory.

Active Directory Service Interfaces (ADSI)

Script pour Active Directory

Microsoft Windows 2000 Scripting Guide : notions fondamentales de script ADSI

Active Directory Service Interfaces SDK

API du Compute Cluster Pack

Le tour des nœuds en 80 scripts : tour d'horizon de la bibliothèque de scripts Compute Cluster Server.

Référentiel de scripts : Compute Cluster Server

SDK du Microsoft Compute Cluster Pack