Cómo crear un informe de inventario de Windows Server de forma gratuita con PowerShell

Contenidos

Logotipo de Powershell

Muchos administradores de servidores usan PowerShell. Naturalmente, una de las tareas más utilizadas es la capacidad de crear scripts y funciones para realizar un inventario de sus servidores y comprender lo que tiene su entorno.

Aún cuando hay muchas alternativas para lograr esto, con diferentes niveles de complejidad, vamos a crear un Reporte de Inventario de Windows Server bastante simple pero efectivo en este post.

Prerrequisitos

Este post será práctico. Si tiene la intención de seguir adelante, primero asegúrese de cumplir con los siguientes requerimientos previos:

  • Trabajar en una PC con Windows 10 unida a un dominio de Active Directory (AD)
  • Tener el módulo ActiveDirectory PowerShell instalado desde el Kit de herramientas RSAT.
  • Tener permiso para consultar cuentas de computadora de AD
  • Puede ejecutar consultas WMI / CIM remotas en equipos remotos
  • Tengo Comunicación remota de PowerShell disponible en computadoras remotas

Recuperando servidores

Fundamental para el script que estamos construyendo son los servidores mismos. Puede escribirlos individualmente en un archivo de texto que se lee, o en una matriz dentro del propio script, pero con PowerShell podemos hacerlo mejor. Para hacer el script más dinámico y no requerir que lo modifiquemos cada vez que se agrega un nuevo servidor, podemos utilizar Active Directory (AD) para extraer la lista de objetos de computadora en una unidad organizativa (OU) determinada.

A continuación, estamos usando el ActiveDirectory módulo, disponible en el Kit de herramientas RSAT, para consultar el Servers OU y recupere todos los objetos de la computadora allí a través de Get-ADComputer.

Import-Module ActiveDirectory

$OU = 'OU=Servers,DC=domain,DC=local'

$Params = @{
    "SearchBase" = $OU
    "Filter"     = '*'
}

$Servers = Get-ADComputer @Params

En este punto, podríamos haber filtrado solo la propiedad de nombre para completar el $servers variable, pero a menudo es muy útil tener todo el objeto devuelto para utilizarlo más tarde.

Determinación de los datos a recolectar

Ahora que tenemos nuestros servidores, debemos averiguar qué debemos recolectar exactamente de cada servidor. Una razón por la que puede ser importante mantener el objeto de AD completo es combinar esos datos con los datos de forma directa del servidor para obtener una imagen más extensa de su entorno.

En la práctica, ¿cómo se ve algo como esto? Vamos a enumerar algunas de las propiedades que sería muy útil conocer.

Valores del servidor

  • Nombre de host del servidor
  • Espacio libre en disco
  • Memoria
  • Conexiones de red

Valores AD

  • Última configuración de contraseña
  • Último inicio de sesión
  • Nombre de host DNS

Recuperando información del servidor

¿Cómo hacemos para recolectar esta información en nuestra lista de servidores devueltos? Dado que tenemos una lista de servidores, tendremos que iterar sobre el $Servers objeto y consulta. Comenzando con un simple Foreach-Object bucle a continuación, podemos crear un objeto personalizado para mantener nuestros valores.

$Servers | Foreach-Object {
    [PSCustomObject]@{
        "ServerHostName"     = $_.Name
        "Description"        = $_.Description
        "FreeDiskSpace"      = $Null
        "TotalMemory"        = $Null
        "NetworkConnections" = $Null
        "PasswordLastSet"    = $_.pwdLastSet
        "LastLogon"          = $_.lastLogon
        "DNSHostName"        = $_.DNSHostName
        "CreationDate"       = $_.WhenCreated
    }
}

Como puede ver, al guardar el objeto completo de Active Directory cuando recuperamos las computadoras por primera vez, nos posibilita completar una amplia gama de información. Desafortunadamente, esta no es toda la información que necesitamos.

Para obtener la información de cada servidor, utilizaremos una interfaz familiar para muchos administradores de servidores, que es la interfaz de Instrumental de administración de Windows (WMI). Puede observar que los cmdlets que se usan a continuación son de la interfaz del Modelo de información común (CIM), de la cual WMI es la implementación de Microsoft de este estándar.

Obtenga el espacio libre en disco

Usando la clase WMI disponible de Win32_LogicalDisk, podemos obtener todos los discos disponibles y su espacio libre. Cuando ejecutamos el comando por primera vez, Get-CimInstance -ClassName Win32_LogicalDisk, puede notar que no es exactamente legible en su salida predeterminada.

El segundo problema aquí es que tenemos más de una unidad devuelta. Me agradaría saber sobre cada una de esas unidades y cuánto espacio libre hay disponible en GB. Modifiquemos el código para hacer algunas transformaciones y mejorarlo.

$Disks = Get-CimInstance -ClassName Win32_LogicalDisk

$DisksResult = $Disks | Foreach-Object {
    [PSCustomObject]@{
        "Drive"     = $_.DeviceID
        "FreeSpace" = [Math]::Round(($_.FreeSpace / 1GB),2)
    }
}

$DisksResult

Después de ejecutar los comandos, nuestra salida es mucho más limpia y ahora se puede utilizar en nuestro script.

Pero, ¿y si quisiéramos alertar sobre una condición de poco espacio en disco? Sería bueno expandir esto solo un poco para determinar una bandera en cada unidad que cumpla con esa condición. Comparando el espacio libre con el espacio total disponible, podemos ver si está por debajo del 10% o 10 GB. El motivo de la -or La condición es que en discos muy grandes, el 10% aún puede ser muy generoso, por lo que determinar un límite absoluto ayuda.

$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

Como puede ver ahora, tenemos un gran conjunto de información para guardar en nuestros servidores.

How% 20to% 20Build% 20a% 20Windows% 20Server% 20Inventory% 20Report% 20for / Untitled% 202.png? Trim = 1,1 & bg-color = 000 & pad = 1,1

Obtenga la memoria disponible

Es útil saber cuánta RAM se asigna a cada servidor, especialmente en un entorno de máquina virtual. Si encuentra que algunos están sobreaprovisionados, puede ahorrar valiosos recursos ajustando el tamaño correcto de los servidores. Por suerte, esto es mucho más sencillo de recuperar.

Usando el Win32_PhysicalMemory Clase WMI, podemos sumar todos los devueltos Capacity propiedades para obtener la memoria total.

(Get-CimInstance -ClassName Win32_PhysicalMemory | Measure-Object -Property Capacity -Sum).Sum / 1GB

Obtenga todas las conexiones de red

En conclusión, queremos recuperar todas las conexiones de red juntas. Esto es útil para saber si un determinado servidor tiene varias interfaces de las que preocuparse. Usando un mecanismo ligeramente distinto esta vez, estamos usando el Get-NetAdapter cmdlet, pero como éste no tiene un ComputerName , usaremos PS Remoting para invocarlo localmente en el servidor de destino y devolver los resultados a nuestro script.

$NetworkConnections = Invoke-Command -ComputerName $_.DnsHostName -ScriptBlock  Select-Object Name, Status, LinkSpeed

Nuestra salida se verá semejante a la de abajo y después podemos guardar esto en nuestro script.

Tenga en cuenta que para Invoke-Command para que funcione, será necesario configurar PS Remoting en los servidores de destino.

Poniendolo todo junto

Ahora que tenemos todas las piezas, juntemos todo esto. El script final está debajo y combina todo el código para crear un objeto de salida personalizado con lo que queremos informar.

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  Select-Object Name, Status, LinkSpeed
  

    [PSCustomObject]@ Measure-Object -Property Capacity -Sum).Sum / 1GB)
        "NetworkConnections" = $NetworkConnections
        "PasswordLastSet"    = $_.pwdLastSet
        "LastLogon"          = $_.lastLogon
        "DNSHostName"        = $_.DNSHostName
        "CreationDate"       = $_.WhenCreated
    
}

Conclusión

Lo que hemos demostrado aquí es solo la punta del iceberg en términos de lo que se puede construir para un reporte de inventario. Hay muchas más propiedades útiles que puede agregar a este reporte. Llevando esto más allá, puede construirlo en una página HTML, programar una tarea para que se ejecute semanalmente o inclusive incorporarlo en otras herramientas como Ansible.

PowerShell hace que sea trivialmente fácil obtener toda la información que necesita para reunir en un solo lugar. Una vez que analice su entorno y determine lo que necesita saber, cree el reporte en PowerShell para ayudarlo a preparar su capacidad para auditar su entorno en el futuro.

Suscribite a nuestro Newsletter

No te enviaremos correo SPAM. Lo odiamos tanto como tú.