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.
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.