Comment créer gratuitement un rapport d'inventaire Windows Server avec PowerShell
PowerShell est utilisé par de nombreux administrateurs de serveur. Naturellement, l'une des tâches les plus utilisées est la capacité de créer des scripts et des fonctions pour inventorier vos serveurs et comprendre ce que possède votre environnement.
Bien qu'il existe de nombreuses façons d'y parvenir, avec des niveaux de complexité variables, nous allons créer un rapport d'inventaire Windows Server assez simple mais efficace dans cet article.
Sommaire
Conditions préalables
Cet article sera pratique. Si vous avez l'intention de suivre, assurez-vous d'abord que les conditions suivantes sont en place:
- Travailler sur un PC Windows 10 joint à un domaine Active Directory (AD)
- Faites installer le module ActiveDirectory PowerShell à partir de la boîte à outils RSAT.
- Avoir l'autorisation d'interroger les comptes d'ordinateur AD
- Peut exécuter des requêtes WMI / CIM distantes sur des ordinateurs distants
- Avoir PowerShell Remoting disponible sur les ordinateurs distants
Récupération des serveurs
Les serveurs eux-mêmes sont à la base du script que nous construisons. Vous pouvez les écrire individuellement dans un fichier texte lu ou dans un tableau dans le script lui-même, mais en utilisant PowerShell, nous pouvons faire mieux. Pour rendre le script plus dynamique et ne pas nous obliger à le modifier chaque fois qu'un nouveau serveur est ajouté, nous pouvons utiliser Active Directory (AD) pour extraire la liste des objets informatiques dans une unité d'organisation (OU) donnée.
Ci-dessous, nous utilisons le ActiveDirectory
module, disponible dans la boîte à outils RSAT, pour interroger le Servers
OU et récupérer tous les objets informatiques là-bas via Get-ADComputer
.
Import-Module ActiveDirectory
$OU = 'OU=Servers,DC=domain,DC=local'
$Params = @{
"SearchBase" = $OU
"Filter" = '*'
}
$Servers = Get-ADComputer @Params
À ce stade, nous aurions pu filtrer uniquement la propriété name pour remplir le $servers
variable, mais il est souvent très utile d'avoir l'intégralité de l'objet renvoyé pour l'utiliser ultérieurement.
Déterminer les données à collecter
Maintenant que nous avons nos serveurs, nous devons déterminer ce que nous devons collecter exactement sur chaque serveur. L'une des raisons pour lesquelles il peut être important de conserver l'objet AD complet est de combiner ces données avec des données directement à partir du serveur lui-même pour obtenir une image plus grande de votre environnement.
En pratique, à quoi ressemble quelque chose comme ça? Énumérons quelques-unes des propriétés qu'il serait très utile de connaître.
Valeurs du serveur
- Nom d'hôte du serveur
- Espace disque libre
- Mémoire
- Les connexions de réseau
Valeurs AD
- Dernier mot de passe défini
- Dernière connexion
- Nom d'hôte DNS
Récupération des informations du serveur
Comment collecter ces informations sur notre liste de serveurs retournés? Comme nous avons une liste de serveurs, nous devrons parcourir le $Servers
objet et requête. Commençant par un simple Foreach-Object
boucle ci-dessous, nous pouvons créer un objet personnalisé pour contenir nos valeurs.
$Servers | Foreach-Object {
(PSCustomObject)@{
"ServerHostName" = $_.Name
"Description" = $_.Description
"FreeDiskSpace" = $Null
"TotalMemory" = $Null
"NetworkConnections" = $Null
"PasswordLastSet" = $_.pwdLastSet
"LastLogon" = $_.lastLogon
"DNSHostName" = $_.DNSHostName
"CreationDate" = $_.WhenCreated
}
}
Comme vous pouvez le constater, en enregistrant l'objet complet d'Active Directory lors de la première récupération des ordinateurs, nous pouvons remplir un large éventail d'informations. Malheureusement, ce ne sont pas toutes les informations dont nous avons besoin.
Pour obtenir les informations de chaque serveur, nous utiliserons une interface familière pour de nombreux administrateurs de serveur, qui est l'interface WMI (Windows Management Instrumentation). Vous pouvez remarquer que les applets de commande utilisées ci-dessous proviennent de l'interface Common Information Model (CIM), dont WMI est l'implémentation de Microsoft de cette norme.
Obtenez l'espace disque libre
Utilisation de la classe WMI disponible Win32_LogicalDisk
, nous pouvons obtenir tous les disques disponibles et leur espace libre. Lorsque nous exécutons la commande pour la première fois, Get-CimInstance -ClassName Win32_LogicalDisk
, vous remarquerez peut-être qu'il n'est pas exactement lisible dans sa sortie par défaut.
Le deuxième problème ici est que nous avons plus d'un lecteur retourné. Je voudrais connaître chacun de ces disques et combien d'espace libre est disponible en Go. Modifions le code pour effectuer des transformations et l'améliorer.
$Disks = Get-CimInstance -ClassName Win32_LogicalDisk
$DisksResult = $Disks | Foreach-Object {
(PSCustomObject)@{
"Drive" = $_.DeviceID
"FreeSpace" = (Math)::Round(($_.FreeSpace / 1GB),2)
}
}
$DisksResult
Après avoir exécuté les commandes, notre sortie est beaucoup plus propre et peut maintenant être utilisée dans notre script.
Mais que se passe-t-il si nous voulons alerter sur une condition d'espace disque faible? Il serait bon de l'étendre légèrement pour définir un indicateur sur chaque lecteur répondant à cette condition. En comparant l'espace libre à l'espace total disponible, nous pouvons voir s'il est inférieur à 10% ou 10 Go. La raison de la -or
condition, c'est que sur de très grands disques, 10% peuvent encore être très généreux, donc fixer une limite absolue aide.
$Disks = Get-CimInstance -ClassName Win32_LogicalDisk
$DisksResult = $Disks | Foreach-Object {
$FreeSpace = (Math)::Round(($_.FreeSpace / 1GB),2)
$TotalSpace = (Math)::Round(($_.Size / 1GB),2)
If ( ($FreeSpace / $TotalSpace -LT 0.10) -Or $FreeSpace -LT 10 ) {
$LowDiskSpace = $True
} Else {
$LowDiskSpace = $False
}
(PSCustomObject)@{
"Drive" = $_.DeviceID
"FreeSpace" = $FreeSpace
"LowDiskSpace" = $LowDiskSpace
}
}
$DisksResult
Comme vous pouvez le voir maintenant, nous avons un grand ensemble d'informations à enregistrer avec nos serveurs.
Obtenez la mémoire disponible
Il est pratique de savoir combien de RAM est allouée à chaque serveur, en particulier dans un environnement de machine virtuelle. Si vous constatez que certains sont surapprovisionnés, vous pouvez économiser des ressources précieuses en dimensionnant correctement les serveurs. Heureusement, c'est beaucoup plus simple à récupérer.
En utilisant le Win32_PhysicalMemory
Classe WMI, nous pouvons résumer tous les retours Capacity
propriétés pour obtenir la mémoire totale.
(Get-CimInstance -ClassName Win32_PhysicalMemory | Measure-Object -Property Capacity -Sum).Sum / 1GB
Obtenez toutes les connexions réseau
Enfin, nous voulons récupérer toutes les connexions réseau ensemble. C'est utile de savoir si un certain serveur a plusieurs interfaces pour s'inquiéter. En utilisant un mécanisme légèrement différent cette fois, nous utilisons le Get-NetAdapter
applet de commande, mais comme celui-ci n'a pas de ComputerName
, nous utiliserons PS Remoting pour l'invoquer localement sur le serveur cible et renvoyer les résultats à notre script.
$NetworkConnections = Invoke-Command -ComputerName $_.DnsHostName -ScriptBlock {
Get-NetAdapter -Physical | Select-Object Name, Status, LinkSpeed
}
Notre sortie ressemblera à celle ci-dessous et nous pouvons ensuite l'enregistrer dans notre script.
Gardez à l'esprit que pour Invoke-Command
pour fonctionner, PS Remoting devra être configuré sur les serveurs cibles.
Mettre tous ensemble
Maintenant que nous avons tous les morceaux, mettons tout cela ensemble. Le script final est ci-dessous et combine tout le code pour créer un objet de sortie personnalisé avec exactement ce que nous voulons rapporter.
Import-Module ActiveDirectory
$OU = 'OU=Servers,DC=domain,DC=local'
$Params = @{
"SearchBase" = $OU
"Filter" = '*'
}
$Servers = Get-ADComputer @Params
$Servers | Foreach-Object {
$Disks = Get-CimInstance -ComputerName $_.DnsHostName -ClassName Win32_LogicalDisk
$DisksResult = $Disks | Foreach-Object {
(PSCustomObject)@{
"Drive" = $_.DeviceID
"FreeSpace" = (Math)::Round(($_.FreeSpace / 1GB),2)
}
}
$NetworkConnections = Invoke-Command -ComputerName $_.DnsHostName -ScriptBlock {
Get-NetAdapter -Physical | Select-Object Name, Status, LinkSpeed
}
(PSCustomObject)@{
"ServerHostName" = $_.Name
"Description" = $_.Description
"FreeDiskSpace" = $DisksResult
"TotalMemory" = ((Get-CimInstance -ComputerName $_.DnsHostName -ClassName Win32_PhysicalMemory | Measure-Object -Property Capacity -Sum).Sum / 1GB)
"NetworkConnections" = $NetworkConnections
"PasswordLastSet" = $_.pwdLastSet
"LastLogon" = $_.lastLogon
"DNSHostName" = $_.DNSHostName
"CreationDate" = $_.WhenCreated
}
}
Conclusion
Ce que nous avons démontré ici n'est que la pointe de l'iceberg en termes de ce qui peut être construit pour un rapport d'inventaire. Il existe de nombreuses autres propriétés utiles que vous pouvez ajouter à ce rapport. En allant plus loin, vous pouvez l'intégrer dans une page HTML, planifier une tâche pour exécuter cette semaine, ou même l'encapsuler dans d'autres outils tels qu'Ansible.
PowerShell permet de rassembler facilement toutes les informations dont vous avez besoin en un seul endroit. Une fois que vous avez analysé votre environnement et déterminé ce que vous devez savoir, créez le rapport dans PowerShell pour aider à pérenniser votre capacité à auditer votre environnement.