En entornos corporativos donde la gestión de Políticas de Grupo (GPOs) es esencial para el control de seguridad y configuración de equipos, automatizar auditorías puede ahorrar tiempo y reducir errores. El siguiente script de PowerShell permite procesar múltiples archivos XML de GPOs generados desde la consola de administración, extrayendo información clave y exportándola a un archivo CSV legible.
¿Qué hace este script?
Este script recorre de forma recursiva todos los archivos XML dentro de un directorio (y subdirectorios) especificado, lee su contenido, extrae datos importantes de cada GPO y los guarda en un archivo CSV para su posterior análisis.
# Ruta del directorio con los archivos XML de GPO
$directorio = "C:\Datos\Reportes_xml"
# Salida del CSV
$salidaCSV = "$directorio\gpos_exportadas.csv"
# Crear lista para guardar resultados
$resultados = @()
# Procesar cada archivo XML en el directorio (con subcarpetas)
Get-ChildItem -Path $directorio -Filter *.xml -Recurse | ForEach-Object {
$archivo = $_.FullName
try {
[xml]$xml = Get-Content $archivo
$dominio = $xml.GPO.Identifier.Domain.'#text'
$nombreGPO = $xml.GPO.Name
# --- Corrección para obtener Owner con namespaces ---
$nsManager = New-Object System.Xml.XmlNamespaceManager($xml.NameTable)
$nsManager.AddNamespace("gp", "http://www.microsoft.com/GroupPolicy/Types/Security")
$nsManager.AddNamespace("gpTypes", "http://www.microsoft.com/GroupPolicy/Types")
$ownerNameNode = $xml.SelectSingleNode("//gp:Owner/gpTypes:Name", $nsManager)
$owner = if ($ownerNameNode) { $ownerNameNode.InnerText } else { "Desconocido" }
$activoMaquina = $xml.GPO.Computer.Enabled
$activoUsuario = $xml.GPO.User.Enabled
$politicasActivas = @()
if ($xml.GPO.Computer.ExtensionData) {
foreach ($ext in $xml.GPO.Computer.ExtensionData.Extension.Policy) {
if ($ext.State -eq "Enabled") {
$politicasActivas += $ext.Name
}
}
}
if ($xml.GPO.User.ExtensionData) {
foreach ($ext in $xml.GPO.User.ExtensionData.Extension.Policy) {
if ($ext.State -eq "Enabled") {
$politicasActivas += $ext.Name
}
}
}
$activaPolitica = if ($politicasActivas.Count -gt 0) { "Si" } else { "No" }
# --- Extraer info de LinksTo ---
$linkada = "No"
if ($xml.GPO.LinksTo) {
if ($xml.GPO.LinksTo.Enabled -and $xml.GPO.LinksTo.Enabled -eq "true") {
$linkada = "Si"
}
}
# Concatenar políticas activas en una sola cadena
$politicasConcatenadas = $politicasActivas -join ", "
$numeroPoliticas = $politicasActivas.Count
# Guardar resultado como objeto
$resultados += [PSCustomObject]@{
Dominio = $dominio
NombreGPO = $nombreGPO
ActivaLaPolitica = $activaPolitica
ActivoUsuario = $activoUsuario
ActivoMaquina = $activoMaquina
OwnerPolitica = $owner
Linkada = $linkada
PoliticasActivas = $politicasConcatenadas
NumeroPoliticasActivas = $numeroPoliticas
}
}
catch {
Write-Warning "Error procesando ${archivo}: $($_.Exception.Message)"
}
}
# Exportar a CSV
$resultados | Export-Csv -Path $salidaCSV -NoTypeInformation -Encoding UTF8
Write-Output "Exportado a: $salidaCSV"
Desglose del script
1. Definición de rutas
$directorio = "C:\Datos\Reportes_xml"
$salidaCSV = "$directorio\gpos_exportadas.csv"
Se define el directorio que contiene los archivos XML y la ruta de salida para el archivo CSV.
2. Inicialización de la lista de resultados
$resultados = @()
Se crea un array vacío que almacenará los objetos de resultados por cada GPO procesada.
3. Lectura y procesamiento de archivos XML
Get-ChildItem -Path $directorio -Filter *.xml -Recurse | ForEach-Object {
Se buscan todos los archivos XML dentro del directorio, incluyendo subcarpetas.
4. Carga del archivo XML y manejo de excepciones
try {
[xml]$xml = Get-Content $archivo
...
}
catch {
Write-Warning "Error procesando ${archivo}: $($_.Exception.Message)"
}
Cada archivo se carga como un objeto XML y se maneja cualquier error que pueda surgir en el proceso.
5. Extracción de datos básicos
$dominio = $xml.GPO.Identifier.Domain.'#text'
$nombreGPO = $xml.GPO.Name
$activoMaquina = $xml.GPO.Computer.Enabled
$activoUsuario = $xml.GPO.User.Enabled
Se obtienen el dominio, nombre de la GPO, y si está activa para equipos y/o usuarios.
6. Lectura del propietario (Owner) usando namespaces XML
powershellCopiarEditar$nsManager = New-Object System.Xml.XmlNamespaceManager($xml.NameTable)
$nsManager.AddNamespace("gp", "http://www.microsoft.com/GroupPolicy/Types/Security")
$nsManager.AddNamespace("gpTypes", "http://www.microsoft.com/GroupPolicy/Types")
$ownerNameNode = $xml.SelectSingleNode("//gp:Owner/gpTypes:Name", $nsManager)
$owner = if ($ownerNameNode) { $ownerNameNode.InnerText } else { "Desconocido" }
Se definen los espacios de nombres necesarios para localizar correctamente el nodo del propietario de la GPO.
7. Detección de políticas activas
$politicasActivas = @()
if ($xml.GPO.Computer.ExtensionData) {
foreach ($ext in $xml.GPO.Computer.ExtensionData.Extension.Policy) {
if ($ext.State -eq "Enabled") {
$politicasActivas += $ext.Name
}
}
}
Se revisan las políticas tanto de equipo como de usuario, y se almacenan aquellas activas.
8. Verificación si la GPO está enlazada
$linkada = "No"
if ($xml.GPO.LinksTo) {
if ($xml.GPO.LinksTo.Enabled -and $xml.GPO.LinksTo.Enabled -eq "true") {
$linkada = "Si"
}
}
Se determina si la GPO está vinculada a alguna Unidad Organizativa (OU).
9. Registro del resultado
$resultados += [PSCustomObject]@{
Dominio = $dominio
NombreGPO = $nombreGPO
ActivaLaPolitica = $activaPolitica
ActivoUsuario = $activoUsuario
ActivoMaquina = $activoMaquina
OwnerPolitica = $owner
Linkada = $linkada
PoliticasActivas = $politicasConcatenadas
NumeroPoliticasActivas = $numeroPoliticas
}
Se crea un objeto con toda la información recolectada para cada archivo XML.
10. Exportación a CSV
$resultados | Export-Csv -Path $salidaCSV -NoTypeInformation -Encoding UTF8
Write-Output "Exportado a: $salidaCSV"
Finalmente, se exporta toda la información a un archivo CSV con codificación UTF-8.
Resultado
El archivo CSV generado incluirá columnas como:
- Dominio
- NombreGPO
- ActivaLaPolitica
- ActivoUsuario
- ActivoMaquina
- OwnerPolitica
- Linkada
- PoliticasActivas
- NumeroPoliticasActivas
Esto facilita la visualización y análisis de configuraciones GPO de forma centralizada, ideal para auditorías de cumplimiento, revisión de configuración o migraciones de políticas.
Conclusión
Este script es una herramienta poderosa para administradores de sistemas que gestionan grandes volúmenes de GPOs. Automatiza la extracción de información útil de archivos XML y la convierte en datos estructurados listos para análisis en Excel u otras herramientas.