Analice netlogon.log usando PowerShell para encontrar subredes faltantes
Active Directory utiliza Sitios para definir en qué parte de la topología reside una computadora y, por lo tanto, determinar qué servidor debe usarse para ciertos servicios. Por ejemplo, los sitios se utilizan para determinar qué controlador de dominio debe usar un cliente como servidor de inicio de sesión y si uno de mis clientes inicia sesión en un sitio en algún lugar de Australia, probablemente no quiero que procese políticas de grupo desde un controlador de dominio en los EE. UU. .
Por esta razón definimos sitios en Active Directory donde cada sitio está asociado con una o más subredes y la vida es buena. Pero, ¿qué sucede si nos olvidamos de definir una determinada subred o de repente se utiliza una nueva subred? Si una computadora se conecta a Active Directory sin que se le haya asignado un sitio, podría producirse un comportamiento inesperado.
Para obtener más detalles sobre este proceso, hay una excelente publicación de blog al respecto en este enlace: http://jorgequestforknowledge.wordpress.com/2011/01/27/dc-locator-what-does-quot-no-client-site- quot-mean-in-netlogon-log/
Una excelente manera de hacer que las computadoras de cualquier subred no definida usen un sitio predeterminado es usar subredes "generales". Si la dirección IP de una computadora coincide con más de una subred, la coincidencia más específica gana, lo que significa que puedo asignar 10.1.1.0/24 al Sitio1 y 10.1.2.0/24 al Sitio2 y luego asignar 10.1.0.0/16 al Sitio1 creando cualquier dirección. dentro de este alcance que no coincida con ninguna otra subred definida se asociará con el Sitio1.
Sin embargo, esta publicación no trata sobre por qué, si o cómo se deben definir las subredes. Se trata de encontrar qué subredes utilizan los clientes sin estar definidas en Active Directory. Para encontrar estas subredes (de ahora en adelante denominadas “subredes faltantes”) debemos examinar netlogon.log en cada controlador de dominio y buscar el mensaje de error NO_CLIENT_SITE.
La primera parte de la fila será una marca de tiempo (si no, la marca de tiempo está deshabilitada) y el nombre y la dirección IP de la computadora cliente aparecerán al final de la fila. Esta puede ser una tarea bastante engorrosa en entornos grandes, por lo que escribí un script para recopilar la última parte de los registros de netlogon.log de varios controladores de dominio y buscar NO_CLIENT_SITE. También extraerá la marca de tiempo, el nombre de la computadora y la dirección IP de cada fila y los devolverá como un PSObject personalizado para clasificarlo y/o filtrarlo fácilmente. Si la marca de tiempo de netlogon.log por algún motivo está deshabilitada en cualquiera de sus controladores de dominio, establezca el parámetro -IncludeTimestamp en $false). El script es bastante simple, enumero todos los controladores de dominio en el dominio actual como valor predeterminado para -DomainControllers con el siguiente código:
([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()).DomainControllers.NameLuego escribí dos funciones, la primera usa Get-Content con el parámetro -Tail para recuperar el último (n) número de filas del archivo de registro netlogon.log de cada controlador de dominio y envía cada fila a la canalización.
La segunda función acepta picaduras del oleoducto. En esta función, primero definí una expresión regular en el bloque Begin{} dependiendo del parámetro IncludeTimestamp. Luego, este patrón se compara con cada fila analizada. Para extraer la información que me interesa de cada fila que coincide con mi patrón, uso algo llamado Grupos con nombre. En resumen, todo lo que esté entre paréntesis en una expresión regular se considera un grupo y se completará en la variable automática $matches cuando se use el operador -match en PowerShell.
Luego se puede acceder a cada grupo usando $matches[index] donde índice es el número de índice del grupo que comienza en 1. $Matches[0] siempre contendrá la cadena coincidente completa. Sin embargo, rápidamente resulta bastante frustrante realizar un seguimiento del índice de cada grupo, especialmente si tiene grupos anidados. Existe una gran solución para ese problema llamada Grupos con nombre.
Simplemente ingrese '?
A un grupo de personas se le asigna la tarea de presentarse en cinco frases. Suponemos que todos escribirán su nombre y probablemente con el prefijo “nombre es”. Hagamos coincidir cada oración con un patrón para eso.
$Pattern = “name is (?<name>w+)”Esto buscará "el nombre es" seguido de w, que es una expresión regular para cualquier carácter alfanumérico o guión bajo, y +, lo que significa que el carácter alfanumérico (o guión bajo) aparecerá una o más veces. La parte de nuestra coincidencia entre paréntesis es un grupo llamado "nombre".
Ahora hacer coincidir una oración podría verse así:
”My name is Simon” -match $PatternEsto devolverá True y completará la variable automática $matches. Examinar $matches conectándolo a Get-Member mostrará que $matches es una tabla hash. Para extraer el grupo nombrado de la oración coincidente, simplemente podemos obtener el valor de la clave 'nombre' de la tabla hash:
$Matches[“name”]Una vez realizada la coincidencia, la devolución del resultado se realiza mediante la creación de un PSCustomObject que se escribe en la salida.