Windows PowerShellCréer votre propre outil d'inventaire logiciel

Don Jones

Contenu

Trouver les informations
Prototypage
Lire des noms d'ordinateur
Modularizing
Fonctions d'opportunités

Dans cet article de la colonne de Windows PowerShell, je vais présenter une utilisation très pratique : je va créer un outil qui répertorie le numéro de version du système d'exploitation (une des meilleures façons pour déterminer la version du système d'exploitation) et service pack numéro de version à partir d'une liste de comput­ers.Mais je vais non seulement pour vous offrir la solution eux-mêmes.Je vais vous guidons tout au long du processus que me permet de développer un script comme celui-ci.

Bien que ce soit à l'évidence un outil utile, je pense que le processus par lequel je développer l'outil est encore plus important.Une fois que vous avez comprendre et pouvez réutiliser ce processus de développement pour vos propres tâches, vous serez également sur votre manière pour résoudre pratiquement n'importe quel problème d'administration utilisant Windows PowerShell.(En tant que l'ancienne indiquant atteint, si vous enseigne un homme pour créer un outil …) Ainsi, nous allons commencer.

Trouver les informations

Le premier et souvent plus difficile, tâche consiste à savoir dans lequel vous pouvez réellement trouver le système d'exploitation et numéros de version service pack.Vous pourriez être tenté pour aller spelunking dans le Registre.Le Registre est parfois la réponse des informations telles que, mais il est généralement la mon option de dernier recours, car le Registre peut être un peu difficile fonctionner avec.

Les mots « récupération » et « informations » immédiatement déclenchent une réponse possible à mon avis : WMI (Windows Management Instrumentation).Un autre mot clé qui permet de me considérer WMI est « distant », car dans version 1 de Windows PowerShell, WMI est sur votre seule option pour effectuer n'importe quel type d'opération Stocks ou Gestion des informations à distance.

Malheureusement, il existe des dizaines de milliers de classes WMI dans la plupart des systèmes, et ce qui peut rendre difficile la trouver celui qui contient les informations souhaitées.J'AI généralement commencent par un moteur de recherche Web et perforation dans une expression comme « wmi service pack version numéro ». Notez que vous allez peut-être une expression de recherche relativement long souhaitez qu'afin de générer des résultats plus précis.

Vous devrez même essayer certaines des variables conditions de recherche, mais ne pas être tenté d'abréger (« version wmi sp » n'est pas assure la résultats très utiles).Envisagez d'autres conditions.Par exemple, ce que l'on peut appeler « correctifs, » d'autres personnes appellent "correctifs", et toujours d'autres appeler » rapide fix Ingénierie » ou « correctifs qfe ». Essayez tous ces termes peut être nécessaire pour rechercher les résultats de la droite.

Le si vous recherchez sur autre chose liées à matériel ou le noyau du système d'exploitation Windows, Ajout « Win32 » à votre expression de recherche peut vous aider, étant donné que la plupart des classes WMI appropriés commencent par un préfixe « Win32_ ».Ajout de « Win32 » à ma recherche en cours sans aucun doute génère les meilleurs résultats.Je vois plusieurs résultats avec « Win32_OperatingSystem » dans les titres, c'est un nom de classe WMI.

Maintenant, la chose importante est pour éviter de cliquer sur tous les résultats de recherche.(De cette façon réside madness.) Tout d'abord, je voudrais trouver les pages documentation disponible pour la classe, afin que je recommencer avec une nouvelle recherche en utilisant uniquement le nom de classe que J'AI découvert.Cela va produire généralement un lien vers leMSDN.Microsoft.comPermettent site Web dans les première deux des résultats et qui doivent d'accéder à un peu directement à la page de documentation de classe.

La figure 1 illustre une partie de cette page.J'ai défile à une table particulièrement importante sur cette page, qui répertorie les versions du système d'exploitation fonctionne avec lequel la classe.Je ne peut pas indiquer combien de fois que j'ai labored sur quelque chose, essayant d'obtenir pour travailler, seulement à découvrir que ce que j'a essaie de faire n'a pas réellement existent dans la version de Windows que j'utilisais.Maintenant, j'ai l'habitude de première vérification cette table.

fig01.gif

La figure 1, recherchez des informations sur la classe WMI (cliquez sur l'image pour l'agrandir)

JE faire défiler la page un peu voir de qu'il existe deux propriétés je suis intéressé : BuildNumber et ServicePack­MajorVersion.En fait, ServicePackMinorVersion peut être utile, aussi, bien que j'ai jamais vu un numéro de 2.1 service pack de Microsoft.Néanmoins, il probablement mérite à vérifier si uniquement à être détaillée.

Cmdlet du mois : CliXML d'exporter et importer-CliXML

Windows PowerShell dispose la capacité de stocker un instantané statique des objets dans un format XML spécial, permettant les informations à ces objets être conservées dans un fichier et chargé en mémoire pour examen ultérieure.Vous pouvez simplement copier objets à exporter-CliXML pour enregistrer ces objets dans un fichier :

Get-Process | Export-CliXML c:\processes.xml

Lorsque vous importez ensuite ces objets dans l'interpréteur de commandes, vous pouvez examiner les comme tout autre objet. Elles ne sont pas réel objets, mais elles permettent autres options de rapports. Supposons que vous avez planifié un script qui exporte tous les processus sur un serveur donné à 03 : 00. Lorsque certaines tâches de maintenance exécute. Lorsque vous accédez à utiliser, vous pouvez charger ces processus et examinez les leur tri éventuellement sur leur consommation de mémoire virtuelle, comme suit :

Import-CliXML c:\processes.xml | Sort VM -descending

Prototypage

Je ne souhaite pas les autres sans faire respecter ces propriétés j'attends accéder. Windows PowerShell permet très facilement faire. Je démarre en vérifiant ces informations sur mon ordinateur local :

Get-WmiObject Win32_OperatingSystem | Select
BuildNumber,ServicePackMajorVersion,ServicePack­MinorVersion

OK, la version mineure soit à zéro, ce qui était que prévu, donc je vais oublier qu'il. Les autres informations sont également que prévu, un numéro de version de 6001 pour mon ordinateur Windows Server 2008 et une version service pack 1.

Maintenant va faire un test similaire sur un ordinateur distant, qui je sais que je suis un administrateur :

Get-WmiObject Win32_OperatingSystem –computer Server2 | 
Select BuildNumber,ServicePackMajorVersion

Si ce test ne fonctionne pas, je dois arrêter et de déterminer pourquoi avant peut se les autres. Les problèmes sont probables liées à connectivité, les pare-feux ou les autorisations, en dehors de l'étendue de Windows PowerShell lui-même. Une fois que j'ai tout fonctionne correctement, je peut passer à l'étape suivante dans mon problème : comment obtenir un ensemble de noms d'ordinateur d'un fichier.

Lire des noms d'ordinateur

En supposant que ma liste de noms d'ordinateur se trouve dans un fichier texte et s'il existe un nom de l'ordinateur figurant sur chaque ligne, la plus simple pour cela consiste à utiliser la cmdlet Get-Content. (Ne vous inquiétez pas si vos noms d'ordinateur sont pas dans un fichier texte ou liste une par ligne, j'aborderai techniques permettant de traiter différents cas dans une colonne suivie.)

Chaque nom est renvoyé en tant qu'objet chaîne indépendants. Et une fonctionnalité pratique de la Get-WmiObjectcmdlet est que son paramètre –computerName accepte une collection de noms d'ordinateur, donc il doit faire l'astuce :

$names = Get-Content c:\computernames.txt
Get-WmiObject Win32_OperatingSystem –comp $names | Select
BuildNumber,ServicePackMajorVersion

Le problème est maintenant que mon résultat est une liste de nombres, avec aucune indication de quel nombre atteint avec l'ordinateur. Heureusement, la classe Win32_OperatingSystem se produit pour une autre propriété, CSName, qui inclut le nom de l'ordinateur. Pour que je puisse l'ajouter cette propriété à mon sortie et j'obtiens un inventaire intéressant :

$names = Get-Content c:\computernames.txt
Get-WmiObject Win32_OperatingSystem –comp $names | Select
CSName,BuildNumber,ServicePackMajorVersion

Modularizing

Tout cela peut-être un peu trop importante pour un technicien moins expérimenté à utiliser, l'étape finale est à modulariser tout cela dans une fonction. Une façon est d'écrire une fonction qui accepte un nom de fichier et avoir la fonction faire tout le travail :

Function Get-SPInventory ([string]$filename) {
  $names = Get-Content $filename
  Get-WmiObject Win32_OperatingSystem –comp  $names | Select   CSName,BuildNumber,ServicePackMajorVersion
}

Comme vous pouvez le voir, j'ai simplement encapsulé mon code de travail dans une fonction appelée Get-SPInventory. J'ai défini il avec un paramètre d'entrée nommé $ filename, afin qu'il puisse être appelée uniquement comme suit :

Get-SPInventory c:\computernames.txt

Les résultats peuvent toujours être transmis dans un fichier CSV, converti en HTML ou formatée différemment, avec les commandes de Windows PowerShell normales, comme suit :

Get-SPInventory c:\computernames.txt | 
Export-CSV SPInventory.csv

Ce n'est toujours pas parfait, cependant. Que se passe-t-il si J'AI également souhaité des informations qui n'a pas été incluses dans la classe Win32_OperatingSystem, telles que le numéro de série du BIOS pour chaque ordinateur de stock ? Qui peut être utile puisque les bases de configuration Gestion des données (CMDBs) utilise le numéro de série du BIOS comme l'identificateur unique pour les ordinateurs.

J'AI peut également le résultat de la fonction pour être un peu plus flexible, peut-être autoriser à trier ou filtrer les résultats plus facilement. Ensuite, je peut par exemple, choisir d'inclure uniquement les ordinateurs Windows Server 2003 avec une ancienne version pack service dans le résultat final pour créer une liste d'ordinateurs que mise à jour est nécessaire.

Fonctions d'opportunités

Maintenant je veux récrire ma fonction à un lecteur mieux dans le pipeline Windows PowerShell. En particulier, J'AI que la fonction directement accepter des noms d'ordinateur à partir du pipeline, de cette façon, je pouvez choisir où j'obtenir les noms d'ordinateur dans chaque fois que J'AI utilisez la fonction. Les noms d'ordinateur peuvent peut-être dans un fichier ou ils peuvent figurer dans Active Directory et je la fonction puisse fonctionner bien les deux cas. Par conséquent, voici la fonction réécrite pour la canalisation :

Function Get-SPInventory {
  PROCESS {
    $wmi = Get-WmiObject Win32_OperatingSystem       –comp $_ | Select     CSName,BuildNumber,ServicePackMajorVersion
    Write-Output $wmi
  }
}

Ce type spécial de fonction utilise un bloc de script PROCESS, qui exécute une fois pour chaque objet pipeline je canal dans la fonction. (Lecteurs dédiés sont rappelez-vous que je L'AI indiqué le bloc de script PROCESS dans l'article de juillet 2008 de cet article, disponible à technet.microsoft.com/Magazine/cc644947.aspx.) La variable spéciale $ _ remplira automatiquement avec le pipeline d'entrée, tant que je suis transférant dans les noms d'ordinateur, il vous fonctionne correctement. La nouvelle fonction est utilisée comme suit :

Get-Content c:\computernames.txt | Get-SPInventory

Comme vous pouvez le voir, il offre davantage de flexibilité pour obtenir des noms d'ordinateur de différentes sources. Je simplement remplacez la partie Get-Content de la commande que commande est nécessaire pour récupérer les noms d'ordinateur. Noter que j'ai également paramétré il afin que je puisse créer plus robuste de sortie en interrogeant différentes classes WMI (ou autres sources de données) avant de construction de mon résultat.

Mais qui n'est pas la fin de la discussion. Mois suivant je vais développer cette fonction pour inclure le numéro de série BIOS dans la sortie.

Don Jones est co-fondateur de technologie concentrés et auteur de nombreux livres D'INFORMATIQUE. Lire ses conseils Windows PowerShell hebdomadaires ou contactez-le à www.ConcentratedTech.com.