Búsqueda de sitios web

Cómo crear un informe básico de actualizaciones de Windows de PowerShell


Si alguna vez implementó actualizaciones de Windows en clientes de su red, probablemente sus gerentes le habrán preguntado qué KB se implementaron y cuándo surge un problema en una estación de trabajo o servidor. Desafortunadamente, a veces la herramienta integrada de informes del servidor WSUS puede dejarlo frustrado y no tiene una gran funcionalidad para generarlos fuera de la GUI de administración de WSUS. Tienes una alternativa; ¡Un informe de actualización de Windows de PowerShell!

Cómo saber cuándo se necesita un informe de PowerShell

Recientemente, un grupo de administradores que estaban trabajando en la validación de un análisis de vulnerabilidades de seguridad me pidieron ayuda. Este análisis de vulnerabilidad afirmaba que a un conjunto de sistemas les faltaban KB de Microsoft en particular, KB que fueron aprobadas recientemente, vencieron la fecha límite y se muestran como instaladas en la consola de administración de WSUS.

Envié algunas capturas de pantalla del estado de la consola junto con mi respuesta de administrador de sistemas. No le di mucha importancia en ese momento porque estaba ocupada con otros proyectos y ésta era una petición de rutina.

Pasó aproximadamente un día y se ejecutó otro análisis de vulnerabilidades, que produjo los mismos resultados. La gerencia no estaba convencida de que las actualizaciones estuvieran instaladas. Al tener problemas con WSUS de vez en cuando, comencé a desconfiar de los informes integrados y de la consola de administración. ¡No sabía que actualizar Windows fuera tan difícil!

Para ser cauteloso y un poco más diligente, decidí omitir la consola de administración de WSUS e ir directamente a las estaciones de trabajo y servidores que aparecían en el análisis de vulnerabilidades de seguridad.

Lluvia de ideas sobre un informe de actualización de Windows

Afortunadamente, el escaneo de vulnerabilidades de seguridad solo encontró alrededor de 4 estaciones de trabajo y 12 servidores con estos KB supuestamente faltantes. Entonces creé una lista simple en un archivo de texto usando el nombre de dominio completo (FQDN) de cada host. También sabía con certeza que los KB faltantes se habrían instalado en los últimos 30 días, ya que acababa de completar un ciclo de mantenimiento.

Con este conocimiento en mano, anoté un pseudocódigo que me ayudaría a comenzar. Esto es lo que describí:

  • Almacenar mi archivo de texto que contiene la lista de hosts.
  • Para cada uno de los hosts en ese archivo, ejecute un comando.
  • El comando debe recopilar las KB instaladas en los últimos 30 días.
  • El resultado solo debe contener el nombre del host, el ID de KB/HotFix y la fecha de instalación.
  • El resultado debe ser legible y solo debe ser un archivo simple.
  • No se necesita codificación sofisticada, solo comparar visualmente con lo que mostraban los informes de WSUS.

Según mis notas, tenía una buena idea de lo que estaba buscando y qué cmdlets podría necesitar. La atención se centró principalmente en el cmdlet Get-HotFix. Este cmdlet consulta todas las revisiones (más comúnmente conocidas como actualizaciones de seguridad) que se han aplicado a un host de Windows. Puede encontrar todas o actualizaciones específicas en máquinas con Windows. Puede leer más sobre este cmdlet y cómo usarlo aquí.

Get-HotFix no admite comunicación remota implícita, por lo que necesitaba idear un método para ejecutar este cmdlet en los sistemas sobre los que necesitaba informar. Invoke-Command lo hace y usted puede pasar múltiples valores al parámetro ComputerName.

Ya guardé una lista de los hosts a los que me dirijo, así que me ahorraré algo de escritura y almacenaré esos hosts como una variable. Para hacerlo, tendré que asignar un nombre de variable y hacer que el valor sea la lista de hosts.

Get-Content leerá el contenido del archivo de texto línea por línea creando una especie de matriz. Llamemos a esta matriz $Hosts. Ahora tengo un comando, algunos datos para alimentar al siguiente conjunto de comandos, pero necesito que los datos resultantes sean legibles y concisos.

Quiero tomarme un momento para enfatizar “Filtrar primero, formatear al final”. . Recordar esto le ayudará cuando trabaje con este tipo de scripts. Abrir una sesión de PowerShell y ejecutar el cmdlet Get-Hotfix por sí solo generalmente generará una larga lista de actualizaciones que se han aplicado a un host.

PS51> Get-HotFix

Source        Description      HotFixID      InstalledBy          InstalledOn
------        -----------      --------      -----------          -----------
MACWINVM      Update           KB2693643     MACWINVM\Administ... 3/14/2019 12:00:00 AM
MACWINVM      Update           KB4100347     NT AUTHORITY\SYSTEM  2/17/2019 12:00:00 AM
MACWINVM      Update           KB4230204     NT AUTHORITY\SYSTEM  7/6/2018 12:00:00 AM
MACWINVM      Security Update  KB4287903     NT AUTHORITY\SYSTEM  7/8/2018 12:00:00 AM
MACWINVM      Security Update  KB4338832     NT AUTHORITY\SYSTEM  7/21/2018 12:00:00 AM
MACWINVM      Update           KB4338853     NT AUTHORITY\SYSTEM  7/6/2018 12:00:00 AM
MACWINVM      Update           KB4343669     NT AUTHORITY\SYSTEM  7/19/2018 12:00:00 AM
MACWINVM      Security Update  KB4343902     NT AUTHORITY\SYSTEM  8/15/2018 12:00:00 AM
MACWINVM      Update           KB4346084     NT AUTHORITY\SYSTEM  5/11/2019 12:00:00 AM
MACWINVM      Update           KB4456655     NT AUTHORITY\SYSTEM  9/12/2018 12:00:00 AM
--snip--

El filtrado ayuda a recopilar solo la información que necesita.

Sin datos filtrados, el formateo es inútil en este momento. Piense en el filtrado como sus requisitos de tipo de datos y en el formato como desea que se muestren esos datos. Para mis propósitos ya tenía pensados los requisitos. Necesitaba instalar actualizaciones en los últimos 30 días.

Para filtrar, necesitaré usar el cmdlet Where-Object y luego pasar algunas propiedades de miembros y operadores de comparación con un toque matemático. Para hacer esto, tomaré cada objeto devuelto ($_) de Get-HotFix y los pasaré a Where-Object para encontrar todas las actualizaciones. instalado en una fecha mayor que (-gt) la fecha de hoy (o cada vez que ejecuto el script) menos (-30) hace días. Eso obtendrá los datos iniciales que estoy buscando.

Get-HotFix | Where-Object { $_.InstalledOn -gt ((Get-Date).AddDays(-30)) }

Pero quiero filtrar un poco más los objetos devueltos y sus propiedades. Aquí es donde Select-Object me ayudará, permitiéndome recortar aún más la cantidad de datos que se mostrarán a solo un par de propiedades cruciales.

Get-HotFix | Where-Object { $_.InstalledOn -gt ((Get-Date).AddDays(-30)) } |
Select-Object -Property PSComputerName, Description, HotFixID, InstalledOn

Ahora que tengo los datos filtrados correctamente, puedo pasar a formatear los resultados en un formato utilizable. Para hacerlo, canalizaré ( | ) los resultados de mi filtrado anterior a Format-Table -Autosize y los generaré como un tipo de archivo de mi elección. Necesitaré usar los parámetros Append y -ErrorAction SilentlyContinue para garantizar que cada resultado se escriba en la siguiente línea del archivo de salida y, si se produce un error, no se producirá. No provocar que no se contacte con el resto de hosts.

Format-Table -AutoSize |
Out-File -Encoding utf8 -FilePath '.\Recent_OS_Updates.txt' -Append -ErrorAction SilentlyContinue

Elegí utilizar un archivo de texto porque no necesitaba nada sofisticado. Puede cambiar la salida para satisfacer sus necesidades. Mi salida era algo similar a esto:

Aquí está el guión final ideado y utilizado:

$Hosts = Get-Content -Path '.\hosts.txt'
Invoke-Command -ComputerName $Hosts -ScriptBlock {
    Get-HotFix | Where-Object {
        $_.InstalledOn -gt ((Get-Date).AddDays(-30))
    } | Select-Object -Property PSComputerName, Description, HotFixID, InstalledOn
} | Format-Table -AutoSize |
Out-File -Encoding utf8 -FilePath '.\Recent_OS_Updates.txt' -Append -ErrorAction SilentlyContinue

Para mí, esto fue simple, conciso y ofreció una prueba de que las bases de conocimiento realmente estaban instaladas. El informe fue bien recibido por el equipo directivo y estaba en un formato de fácil lectura.

Artículos relacionados