Todas las entradas de: amarquez

DiskSpd, el sucesor de SQLIO

A la hora de medir el rendimiento de una unidad de almacenamiento, una de las herramientas más útiles y fiables (en entornos Windows) era SQLIO. A pesar de lo que su nombre pueda indicar, esta herramienta no servía para medir la E/S generada por una consulta SQL, sino para obtener medidas de rendimiento de disco. Sin embargo, después de algunos años entre nosotros, se podían apreciar señales de que poco a poco se estaba quedando fuera de su tiempo.

Entra DiskSpd

Finalmente, y tras su última actualización a finales del 2015, SQLIO fue retirado, y reemplazado por una nueva herramienta: DiskSPD. Al igual que su predecesor, se utiliza para obtener métricas de rendimiento de unidades de almacenamiento, pero con un conjunto de utilidades adicionales que lo convierten en algo mucho más útil. Además, y para los aficionados al Software Libre, su código fuente está disponible para descarga en GitHub, con una licencia MIT.

Ahora bien, entre todas las funciones, hay una característica particularmente interesante para los que desarrollamos scripts PowerShell: DiskSPD puede volcar la salida en formato XML. Esto es importante, porque facilita enormemente el procesado masivo de datos obtenidos mediante la ejecución de tests de diskspd.

Dentro de la carpeta de GitHub, hay un conjunto de scripts denominados VMFleet, que permite hacer operaciones y tests de forma masiva en máquinas virtuales, pero para aquellas personas menos ambiciosas que se conforman con testear el rendimiento de una única unidad, acompaño el artículo con un par de pequeños scripts para ejecutar baterías de tests. Obviamente, se pueden personalizar los parámetros de DiskSpd para simular lo más fielmente posible la carga de trabajo del servidor destino, pero como ejemplo ilustrativo basta.

El primero, lanza n ejecuciones de diskspd, bajo un cierto set de parámetros y recopila la salida en una serie de archivos XML en una carpeta especificada. Con $iteraciones podemos especificar el número de repeticiones del experimento, que se guarda en la carpeta especificada con $tag (que además personaliza el nombre del fichero xml generado). El parámetro $threads se usa para especificar cuántos hilos de trabajo deseamos lanzar simultáneamente, con lo que podemos poner, por ejemplo, un hilo por core del sistema.

El segundo script toma los XML de dicha carpeta, y calcula la velocidad media (en MB/s) de rendimiento del disco en base a los datos recopilados. Teniendo en cuenta que el rendimiento de un sistema puede variar a lo largo del tiempo por múltiples circunstancias, lo más realista es realizar varios experimentos idénticos, y promediarlos.

Process-SpeedData se encarga de promediar la velocidad de lectura/escritura y mostrar en pantalla el resultado, a partir de los archivos XML generados por el script anterior, para ello simplemente se le pasa como parámetro la carpeta que se desea escanear, y el script leerá y promediará la información de todos los XML que encuentre en la misma.

Resumiendo…

Aunque SQLio nos ha acompañado durante años y sigue siendo igual de funcional que antes, ahora disponemos de una herramienta igual de potente, más flexible y que además es Open Source. La capacidad de generar la salida en formato XML aquí es una característica diferenciadora que permite incorporar muy fácilmente la salida de información en scripts PowerShell que procesen los datos de rendimiento generados (latencia de acceso, velocidades medias, etc).

Configurar un ILB con PowerShell en Azure Resource Manager

De acuerdo con la documentación de azure, tenemos no una ni dos, sino cuatro formas distintas de definir un balanceador interno de carga en Azure Resource Manager desde cero. Ahora bien, ¿qué sucede cuando ya se tiene infraestructura desplegada y se desea balancear?

Antes de nada… ¿qué es un balanceador interno?

Un ILB (siglas en inglés) proporciona balanceo de carga de red entre máquinas virtuales que residan en la misma red virtual de Azure. Este servicio permite la creación de servicios configurados en alta disponibilidad, de forma que, ante picos elevados de carga, el trabajo se distribuye equitativamente entre los miembros del grupo balanceado. Igualmente, en caso de que alguna máquina del grupo balanceado deje de funcionar, ya sea por tareas de mantenimiento, error de configuración, o fallo de la máquina virtual, el balanceador detecta que la máquina afectada ya no está disponible, y de forma dinámica redistribuye la carga entre el resto de máquinas virtuales del grupo balanceado.

Un escenario básico se correspondería con el siguiente diagrama:

ilb

Se tienen dos máquinas que actúan como servidor Web, dos interfaces de red, el balanceador de carga, y una IP privada que es donde se van a recibir todas las peticiones de servicio.

Descripción del escenario propuesto:

Se tiene un servidor web linux, que está proporcionando un servicio, pero se desea cambiar la configuración “servidor único” por una configuración balanceada, para obtener los beneficios de reducir la carga del servicio en la máquina original, así como conseguir tener una infraestructura más resistente a fallos.

En este caso, una opción sencilla es desplegar una máquina idéntica a la máquina original, y configurar el balanceo de carga a posteriori.

Para asegurarse de que la segunda máquina es una copia idéntica de la primera, es posible utilizar un software como rsync.

Así pues, en este escenario tenemos ya dos máquinas virtuales, con sus correspondientes interfaces de red, y todo está ya funcionando. Sólo falta balancear el sistema.

Paso a paso

En primer lugar, toca iniciar sesión en Azure. En el ejemplo, mi cuenta sólo está adscrita a una suscripción de Azure. En caso de que estuviese dado de alta en más de una, habría que usar los cmdlets “Get-Azure-RmSubscription” y“Select-AzureRmSubscription” para determinar el ID de la subscripción que se desea utilizar, y así poder seleccionarla.

login_vm

Como las máquinas virtuales ya existen, pertenecen a una red virtual de Azure. En este caso, tendremos que averiguar en qué red están con el cmdlet “get-AzureRmVirtualNetwork”. Este cmdlet nos permite seleccionar la red virtual en la que están las máquinas virtuales, y así poder trabajar con sus subredes.

De esta forma, se puede crear la IP de frontend que va a definir el punto de entrada de las solicitudes del servicio balanceado. A continuación, se crea el backend que recibe el tráfico del frontend.

 

createFrontEndBackEnd

Una vez se ha creado todo lo necesario, se puede proceder a crear el balanceador de carga:

ilb-ps

Ahora es cuando empieza lo interesante: Se tienen las máquinas virtuales, las interfaces de red, y el balanceador de carga. Toca ir juntando las piezas para formar el puzzle.

Se obtiene la configuración de cada interfaz de red de las VM, y se le asigna el backend del balanceador de carga. A continuación, se guarda la configuración de la interfaz de red, y con esto se asigna dicha interfaz al balanceador de carga interno:

setInterface

Una vez asignadas ambas interfaces, el balanceador de carga interno estará listo para su uso.

Desde el portal de Azure se puede examinar la configuración del balanceador.

backend

Y finalmente llega la prueba de fuego: testear el servicio balanceado. Como las máquinas son servidores linux, la forma más sencilla de hacerlo es editar la página de inicio de Apache con versiones diferentes de la web, de forma que la respuesta que devuelve cada servidor sea diferente. En este caso, se ha optado por hacer que cada máquina devuelva “server1” o “server2” dependiendo de cuál de ellos está sirviendo la respuesta.

balanceado

En esta prueba, primero se hace una conexión en local al servidor, a ver de qué máquina se trata, y a continuación se hace una petición al ILB, para ver qué máquina nos está respondiendo. Se puede ver que, en cada caso, la respuesta la devuelve una máquina distinta, así que el balanceador funciona correctamente.

Al ser un servicio balanceado, en caso de que uno de los servidores deje de funcionar, la sonda se encargará de determinar en un intervalo máximo de 45 segundos que la máquina afectada no debe de seguir dando servicio (en el caso de que la máquina falle justo después de una sonda, ésta ha de fallar dos veces consecutivas para que el ILB deje de usarla para servir respuestas, en un intervalo de 15 segundos entre cada sondeo).

Conclusiones

De esta forma, se puede configurar un servicio balanceado usando PowerShell. Hay documentación que automatiza el proceso incluyendo la creación de servidores e interfaces de red. Actualmente, ése es un proceso muy interesante si tenemos en cuenta que actualmente hay una limitación muy importante en la configuración de los balanceadores de carga, y que se describe en la siguiente sección.

A continuación, se adjunta un script que resume los pasos llevados a cabo para montar el servicio.

script

Limitaciones actuales

Ambas máquinas deben estar en el mismo grupo de disponibilidad. En el modo clásico, se pueden añadir o quitar libremente máquinas virtuales de un grupo, pero en modo Resource Manager, aún no hay soporte para ello. En caso de que ambas máquinas no estén en el mismo grupo de disponibilidad (Availability Set), aparecerá un mensaje de error similar a este:

different-availabilitySet

En el modo Service Manager de Azure, sí que es posible asignar una VM a un Availability Set sin ningún tipo de problema. Cabe esperar que en un futuro próximo esta funcionalidad también esté disponible en el modo Resource Manager.

Monitorizar eventos con PowerShell

En una entrada anterior de este blog, se describía un sencillo sistema con el que monitorizar el espacio libre en los discos de un sistema. Esto ayuda a prevenir problemas como que un servidor de máquinas virtuales se quede sin espacio prematuramente, lo que provoca un bloqueo total de todos los sistemas virtualizados.

Montar un sistema de notificaciones push para un sencillo script que vigila el espacio libre en disco puede parecer un poco overkill para la situación, así que… ¿Por qué no intentar exprimirlo un poco mas? Siguiendo en la línea de monitorizar de un servidor hay una parte que es especialmente útil, sobre todo para diagnosticar problemas: El visor de eventos.

Se abre el telón: Get-EventLog

Este pequeño cmdlet se encarga de leer los eventos del sistema, permitiendo además capacidades de filtrado para poder obtener aquellos que sean de interés para el usuario. La forma más básica de usarlo es invocándolo con el parámetro “-list” ,  que devuelve un listado de todos los logs que se pueden consultar.

Para consultar un log en concreto, se usa “Get-EventLog –LogName <nombreLog>”, donde nombreLog puede ser, por ejemplo “Application” o cualquier otro valor devuelto por la opción “-list”. Además de consultar un log determinado, se puede filtrar de varias formas diferentes, como por ejemplo con el parámetro “-newest <cifra>”, para recoger los últimos cifra eventos registrados en el sistema, o el parámetro “-entrytype <tipo>” para filtrar la respuesta por los siguientes tipos: Error, FailureAudit, Information, SuccessAudit o Warning. Cada uno de estos tipos se corresponde con los tipos que se pueden encontrar en el Visor de Eventos.

Juntando las piezas

Se tiene un sistema para enviar notificaciones, se tiene algo que se desea monitorizar, se tiene una forma de acceder a lo que se quiere vigilar, y se tiene un temporizador con el que invocar todo automáticamente. Con estas cuatro piezas, ya es posible montar un sistema que vigile los eventos generados en el sistema. En este caso, el script solicita los eventos de error guardados en el log “Application”, que se hayan generado en la última hora.

El resultado

Ejecutar este script, genera la siguiente salida en PowerShell (el resultado obviamente cambiará en función del momento y del equipo utilizado).

resultShell

Y como no podía ser de otra forma, slack recibe la notificación directamente desde el script PowerShell. En entornos en los que sea necesario vigilar específicamente una aplicación se pueden hacer filtrados adicionales, no ya a nivel de consulta de Get-EventLog, sino utilizando el famoso Where-Object para filtrar, por ejemplo, por una subcadena del mensaje de error que resulte de especial interés.

slack

Finalmente, y al igual que el script de monitorización de discos del que ya hablamos antes, se puede crear una tarea programada periódica que compruebe el registro de eventos en busca de errores.

Conclusiones

Como se ha visto en el código, se pueden pedir los eventos para la última hora, o para cualquier intervalo de tiempo. Teniendo en cuenta que consultar el registro de eventos puede ser una operación costosa (dependiendo del número de eventos se esté consultando), sería deseable que el intervalo mínimo de consulta de eventos sea una hora, en vez de unos pocos minutos, cuando se está consultando un log que tenga un tamaño apreciable.

Una alternativa interesante consiste en programar un trigger de la tarea programada para que se dispare con un evento, en vez de a un intervalo prefijado. De esta forma, si se tiene conocimiento sobre el tipo de evento que se quiere vigilar, se puede obtener la notificación push prácticamente en el momento en el que se lanza el evento. Esto se puede ver más claramente en la siguiente captura de pantalla. Aunque en este caso, cabe la posibilidad de usar un script mucho más específico, que mande la notificación push adecuada, sin tener que entrar a leer los eventos del registro, filtrarlos, y generar el mensaje automatizado.

newTrigger

PowerShell: Disco duro libre y notificaciones PUSH

Un nuevo año, una nueva semana, y un nuevo artículo sobre PowerShell. En el artículo anterior se hablaba sobre un sistema que enviaba mensajes de email cuando un website de una lista no estaba online. Eso está bien para casos en los que se necesita un informe de estado periódico. Pero si lo que interesa es actuar sobre una emergencia… que está ocurriendo en este mismo instante, tal vez sea necesario tomar una aproximación más inmediata.

En el script de hoy, el objetivo es saber si una máquina de la granja de servidores de la empresa se está quedando sin espacio libre en disco. Para ello se hará uso de una consulta WMI, el programador de tareas de Windows y un servicio PUSH de notificaciones a teléfonos móviles.

El código

Paso a Paso

Acceso a información de discos locales

Desde powershell, esto se puede ver fácilmente con el siguiente comando: “gwmi win32_volume -Filter ‘drivetype = 3’”, que devuelve una lista detallada de parámetros para cada uno de los discos del sistema. Esto constituye la primera pieza del puzzle que toca resolver.

get-drives

El DriveType indica el tipo de disco que se desea consultar. En este caso, el DriveType = 3 hace un filtrado para mostrar únicamente los discos duros locales. Para cada uno de los discos que devuelve, se quiere procesar los que tengan una capacidad superior a 0 para descartar cualquier unidad de CD/DVD que pudiera haber pasado el filtro.

Entran en escena los servicios PUSH

Hay multitud de proveedores de servicios PUSH, como PushOver, Slack, PushBullet, NotifyMyAndroid… Cada uno tiene sus ventajas e inconvenientes: Los hay con diferentes modelos de licenciamiento, desde licencia por plataforma en la que se instale, hasta la compra de paquetes de mensajes cuando se llega al límite máximo de mensajes mensuales.

De todos los nombrados anteriormente, hay uno que tiene cliente móvil para las tres grandes plataformas (Android, IOS y Windows Phone) y que además tiene la segunda pieza necesaria: una API REST con la que poder enviar notificaciones: Slack

De la API, que incluye funciones para infinidad de tareas, la parte interesante es la que envía un mensaje al chat. Por limpieza y reusabilidad del código, esta parte se ha separado en una función aparte llamada “Send-SlackMessage” que acepta como parámetros el canal al que se desea enviar el mensaje, el nombre de usuario que aparece como “agente publicador”, y el mensaje en sí. Esta función se puede sacar del código y utilizar como notificador en cualquier otro script PowerShell, como procesos que tardan horas en completar, o cualquier otra situación en la que se considere que sea necesario recibir notificaciones.

La parte más importante, y de la que depende que todo esto pueda funcionar, es el token de cliente. En este caso, desde la web de Slack se puede solicitar un token de usuario desde el que enviar notificaciones de una forma muy sencilla y automatizada, sin necesidad de tener que implementar ningún tipo de esquema de autenticación.

¿Por algún motivo el token queda expuesto y empiezan a llegar mensajes de spam? Simplemente se genera un nuevo token, y listo.

get-token

Programando tareas

Nada de esto tendría sentido si no hay una forma de hacer una comprobación periódica del estado del disco. Esto se puede lograr muy fácilmente con el Task Scheduler de Windows. En primer lugar se programa el trigger para que se ejecute diariamente cada 10 minutos.

new-task

Y en segundo lugar se especifica la acción a realizar. En este caso, lanzar una PowerShell –file “nombreFichero.ps1”, que es donde está guardado el script que acompaña a este artículo.

new-task2

Comprobación y Conclusiones

Finalmente, toca comprobar que todo ha funcionado correctamente, y que la notificación se ha recibido en los diferentes medios (Android, Windows Phone, PC,…)

message

Screenshot_Android   Screenshot_WP

Como se puede ver, aunque Slack proporciona clientes para todas las plataformas la interfaz de usuario y la organización de los mensajes cambia dependiendo de la plataforma.

En conclusión, mediante el uso de sistemas de mensajería Push, se pueden enviar notificaciones a canales específicos lo que permite avisar a un equipo completo de trabajo de que algo está pasando con los servidores, al tiempo que la bandeja de entrada de correo electrónico se puede mantener algo más limpia de mensajes. Esto puede permitir una interacción más ágil entre los miembros de un equipo para coordinarse en la resolución del problema.

Comprobar disponibilidad de websites con PowerShell

En ocasiones, para un administrador de sistemas, resulta imprescindible saber si un determinado sitio web está levantado o no. Esta necesidad aumenta aún más, si cabe, si el administrador tiene a su cargo una elevada cantidad de sitios que monitorizar. Una solución rápida puede ser, por ejemplo, lanzar un comando ping para saber si un servidor responde a una cierta dirección. Pero esto no nos da información sobre si una cierta URL está activa o funcionando correctamente.

Para este tipo de situaciones, hace falta hacer procesamiento a un nivel más alto que simplemente “comprobar que la máquina responde”. Y aquí es donde PowerShell viene a ayudar, automatizando el proceso y proporcionando acceso a funciones de alto nivel que proporcionan información adicional.

El Código

Paso a paso…

En primer lugar, nos pide las credenciales de nuestra cuenta de correo. En este caso, las de un servidor de correo ficticio llamado “unsmtp.plainconcepts.com”. Para los que tengan Office365, también funciona con estas credenciales.

credentials

A continuación, se crea un array vacío en el que se van a guardar una serie de objetos a partir del cual se generará un informe. Justo después se define un array de URLs en el que se tiene una serie de sitios web a consultar. Importar la lista de URLs desde un archivo CSV es mucho más conveniente, pero a efectos de script demo, se decidió prescindir de esa parte para que el script funcione “tal cual” sin dependencia de otros archivos.

Para cada elemento de la lista de URIs, se hace una llamada al sitio web con invoke-webRequest. Esto hace que PowerShell conecte con el sitio web, en caso de éxito, nos muestra en pantalla un mensaje “el host está online”, y guarda un objeto en el listado con el que se va a generar el informe. En caso de error se captura la excepción correspondiente y se discrimina por código de error, siendo los más interesantes son el 404 y el 500. Si se desea completar el script, se puede consultar la lista completa de códigos de estado HTTP y añadir los manejadores que se considere necesarios.

psOutput

En penúltimo lugar, una vez procesados todos los elementos de la lista de sitios, toca procesar el listado de objetos para generar un informe de estado en formato CSV. Este informe se guarda en la carpeta temporal del usuario, donde no moleste.

Finalmente, se envía por correo con send-mailMessage. Se puede enviar al propio usuario, o adjuntar una copia a otra persona.

email

informePreview

Conclusión

Como se puede ver, las partes más importantes de este script son la consulta a cada URL, que posibilita obtener información detallada del estado de cada una, y el envío del informe de estado en formato CSV por correo electrónico. Este script se puede añadir a una tarea programada que se ejecute diariamente (en caso de necesitar un informe diario), o modificarlo para que la tarea programada se pueda ejecutar con mayor frecuencia, pero modificando la parte de envío de informe por correo electrónico, para que el informe sólo se genere con los hosts que tengan problemas, y el email sólo se envíe cuando se genere el archivo CSV de informe.

¡Las posibilidades son ilimitadas!

Borrado de objetos fantasma del metaverso

Como ya hemos visto en una introducción a FIM/MIM, este producto es un poderoso sistema de sincronización de identidades. Para hacer su misión, guarda información de objetos de diversos tipos en el Metaverso, que actúa a la vez como origen y destino de información.

Para traer la información al Connector Space de un Management Agent (MA), se dispone de dos operaciones: full import y delta import. Estas operaciones, como su nombre indica, están pensadas para jugar dos roles en el proceso: En primer lugar traer todos los objetos, y luego detectar cambios en los mismos. Una vez finaliza cualquiera de estas operaciones, se hace una operación de sincronización (full sync/delta sync) y los cambios se escriben en el metaverso al tiempo que se reciben actualizaciones desde el metaverso, que luego haya que exportar.

En la mayoría de ocasiones, los MA que se configuran, disponen para la operación delta import de mecanismos que permiten detectar no sólo los cambios en el valor de los atributos, sino también si algún objeto se ha eliminado. Por otro lado, dada la naturaleza de los sistemas a los que se conectan los Management Agents, hay ocasiones en las que la eliminación de un objeto no se puede detectar porque el objeto ha desaparecido por completo del sistema origen, lo que impide la trazabilidad del evento. Esto implica, que existe un objeto en el metaverso que no debería existir : Un objeto fantasma.

Happy-Haunting-Ghost-Banner

Una forma de solucionar esta situación consiste en ejecutar una operación Full Import, lo que permite al Connector Space detectar todas las eliminaciones “fantasma”, y propagar los cambios al metaverso. Sin embargo, es posible encontrarse en una situación en la que el connector space tiene un tamaño de cientos de miles, o millones de registros, y completar una operación de Full import bajo dichas condiciones puede suponer varios días de trabajo. Dependiendo de la situación, esto no es una estrategia viable, ya que requiere una planificación cuidadosa, y una parada de servicio del sistema de sincronización, que durante varios días no va a actualizar la información de los sistemas conectados dentro de los intervalos habituales de tiempo.

Otra forma de resolver esta situación… es actuar de forma proactiva, y prohibir en los sistemas origen que se produzca el borrado físico de objetos, de forma que el problema nunca se produce, y por tanto, no hay que hacer nada más al respecto.

Afortunadamente, aunque ya sea porque no se puede cambiar la forma de trabajo o porque una operación de Full Import se prolongaría demasiado en el tiempo, se dispone de una tercera alternativa. Usar un Management Agent adicional que se encargue de hacer la limpieza. En esencia, lo que se hace es añadir los objetos a eliminar a este management agent, usando algún atributo que los identifique de forma unívoca, se les hace un JOIN, configurar una regla de eliminación, provocar una desconexión, y la desconexión lanzará un delete.

Creación de un Management Agent de CSV: “Delimited Text File”

El conector más sencillo que se puede usar para este propósito es el conector de CSV. Principalmente porque es posible alimentarlo con datos extraídos directamente del metaverso, además de por la sencillez con la que se puede configurar.

Lo primero es determinar qué objetos son los que se desea eliminar. En este caso, se acude a la pestaña “Metaverse Search”, y por motivos didácticos, se ordenan los objetos devueltos por el campo ObjectID para seleccionar algunos de ellos (los primeros). Hay que tener en cuenta que el ObjectID de los objetos existentes en el Metaverso es diferente del ObjectID de los objetos existentes en el Connector Space de cada MA, así que es importante coger el del Metaverso. Es importante en este paso fijarse en el número de objetos que pueblan el Metaverso: 4683.

MVCapture2

Lo más destacable de esta fase, es que se pueden elegir los campos que se desea obtener en la búsqueda del metaverso, seleccionar los objetos con el ratón, y copiarlos con Ctrl+C. Esto genera una copia en CSV en el portapapeles que se puede pegar a voluntad en el archivo de texto que se va a utilizar para el MA.

cleanupCSV

Ahora que ya se tiene el archivo CSV, y está definido el formato de los datos que se van a utilizar, es hora de pasar a crear y configurar el Management Agent de CSV. Como indica el título de esta sección, es el MA “Delimited Text File”. En las siguientes capturas de pantalla se van a especificar las principales opciones que hay que tener en cuenta a la hora de especificar los parámetros del MA, para que pueda ser usado con la finalidad deseada.

En primer lugar, seleccionar un archivo CSV que contiene el formato de los datos que el MA va a importar. Se puede definir el mismo archivo que se ha creado previamente.

template

A continuación, toca configurar algunos parámetros del CSV para asegurarse de que el MA lo lee correctamente: Separadores de atributos, cómo definir los nombres de atributos…

format

En esta pantalla se define el anchor y el tipo de dato de los atributos, además de indicar si son multivaluados (array) o no. El anchor es equivalente a la clave primaria, indentificando de forma inequívoca e irrepetible al objeto. De esta forma todos los atributos de los objetos quedan perfectamente definidos.

attributes

Toca definir las reglas de JOIN. En este caso, el join se hace en base al ObjectID. Este atributo es siempre único para cada objeto creado, tanto en el connector space como en el metaverso. Dado que lo que se desea es unir los objetos del Connector Space del MA de CSV con su equivalente en el metaverso, este ObjectID es el mismo existente en el metaverso. Así, se establece el enlace correcto entre objetos, y no es necesario crear un CSV grande con multitud de campos que permitan hacer el Join.

joinRule

Es de vital importancia especificar que el comportamiento de deprovisionamiento sea “Make them disconnectors”. Esta parte juega un papel importantísimo, a posteriori, porque se especifica en las reglas de borrado de los objetos del metaverso que un elemento se borre cuando uno de sus enlaces en el Connector Space del MA de CSV pase al estado “disconnector”.

DeprovisioningCSV

A continuación, se guarda la configuración del Management Agent, y se procede a modificar la política de eliminación de objetos tipo “Person” del Metaverso. En esta pantalla, hay dos opciones: O se elimina el objeto cuando el último conector se desconecta (ignorando los conectores de ciertos Management Agents), o bien eliminar cuando un conector de alguno de los Management Agents elegidos se desconecta. Se elige esta última opción y se marca el conector de limpieza (llamado CleanUp) en este caso. Se han ocultado los nombres de los otros MAs que hay desplegados en esta implementación de MIM porque no son relevantes para el caso que nos ocupa.

DeletionRule2

Con esto, ya se está listo para empezar el proceso de eliminación. Lo primero que hay que hacer es poblar el Connector Space con los objetos necesarios. Para ello, hay que configurar los perfiles de ejecución de “Full Import” y “Full Sync” para el MA de limpieza. A la hora de configurar el Full Import, se pide la localización física del archivo CSV que contiene los datos a importar. Este CSV debe residir en una carpeta específica, creada dentro de la estructura de carpetas del MIM en el momento de guardar el Management Agent.

ConfigureFullImportCSV

Una vez creados los perfiles de Full Import y Full Sync, toca ejecutarlos:

Se puede observar que como resultado del Full Import, se han añadido 15 objetos, que son los que se habían añadido al CSV originalmente. Esto se puede comprobar haciendo una búsqueda en el Connector Space, o simplemente clicando sobre el enlace “Adds” que aparece en la ventana de resultados.

FullImportCSV2

La consecuencia del Full Sync, con la regla de JOIN especificada anteriormente, es que se ejecuta la operación JOIN sobre los objetos del Connector Space, que pasan a su vez a estar enlazados con los objetos que ya residían en el metaverso y que se desean eliminar.

FullSyncCSV2

Ahora llega la parte interesante. Para eliminar los objetos del metaverso hay que convertir en desconectores los que tenemos en el Connector Space del MA de limpieza. La forma más sencilla de conseguirlo es borrando el Connector Space del MA de limpieza y haciendo un Full Sync. Al hacerlo, automáticamente los objetos desconectados eliminarán los correspondientes objetos del Metaverso, limpiando de forma efectiva los datos basura que no se habían eliminado de forma adecuada.

 

Conclusión

Como se puede ver en la siguiente captura, en el Metaverso quedan 4668 objetos, de los 4683 que había originalmente. Los 15 objetos que han sido gestionados con el MA de CSV para la operación de limpieza han desaparecido por completo del Metaverso, y ya no aparecerán en subsecuentes operaciones de sincronización en los otros MA que habían contribuido estos datos. Una operación sencilla, que ha permitido eliminar objetos que de otra forma no hubiesen desaparecido del Metaverso si no se realizan las operaciones de Full Import/Full Sync en el MA que creó los objetos.

endResult

Bonus

Una alternativa diferente de conseguir la limpieza pasa por utilizar el conector de SQL, esto se puede consultar en la url https://konab.com/using-cleanup-ma-fim-2010/

Análisis de Paquetes con PowerShell

A veces, la única opción para localizar problemas en una aplicación o servicio consiste en analizar el tráfico de red, para comprobar que todo está funcionando correctamente.Una pequeña joya disponible para los aficionados a la Shell son los cmdlets de Captura de Paquetes de Eventos de Red (Network Event Packet Capture cmdlets). Están disponibles para Windows Server 2012R2 y Windows 8.1.

Captura de Paquetes

Con esos cmdlets es posible registrar todos los eventos de red que se producen en la máquina. Tan sólo hace falta alguna forma de guardarlos. Aquí entra en juego el “ETL Logging” (ETL por Event Trace Log), que viene a ser la tecnología que permite a Windows guardar todos los eventos del sistema, para luego poder consultarlos con el Visor de Eventos (tip: para abrirlo de la forma más rápida posible, usa el cuadro de diálogo “ejecutar”, y se escribe el nombre de la aplicación del visor de eventos: Win+R –> eventvwr).

¿Cómo lo hago?

En resumidas cuentas, para capturar los eventos de red, hay que crear una sesión del capturador, establecer un proveedor de logs, iniciar la sesión, hacer lo que haya que hacer con la red, parar la sesión, y finalmente… eliminar la sesión. El proceso paso a paso queda así:

  • En primer lugar es necesario abrir una sesión de Administrador de PowerShell. El motivo es que la captura de paquetes requiere de privilegios elevados. Puede parecer una molestia, pero es una buena práctica de seguridad.
  • Crear la sesión de captura de paquetes: new-neteventsession -name “sesion1”image
  • Hasta aquí todo fácil. Toca elegir un proveedor de logs, para guardar un registro del tráfico. Una manera sencilla de obtener una lista de proveedores de logs relacionados con la red es con el comando logman query providers | select-string tcp
    image Se obtienen tres proveedores, para elegir el primero se escribe: Add-NetEventProvider -Name “Microsoft-Windows-TCPIP” -SessionName “sesion1”
    image
  • Ya está todo listo, se puede empezar a capturar los paquetes. Para ello, se inicia la sesión de captura. Start-NetEventSession –Name “sesion1”
    image
  • Se puede obtener información sobre la sesión de captura de paquetes con el cmdlet Get-NetEventSession
    image
  • Una vez obtenida la información deseada, se detiene la captura con Stop-NetEventSession -Name sesion1
    image
  • Finalmente, una vez detenida la sesión, se puede eliminar de la Shell. Para variar, usaremos un pipe con el cmdlet Remove-NetEventSession. Como se ha visto en artículos anteriores, la primera parte del pipe/tubería obtiene todas las sesiones, y las pasa una a una a la segunda parte del pipe, que en este caso, se encarga de eliminar las sesiones.
    image

Una vez se han completado todos estos pasos, se tiene un archivo de log con la información de red capturada, pero falta por responder una pregunta esencial: ¿Cómo visualizar/analizar estos datos? Como se comentó al principio es posible emplear el visor de Eventos de Windows para leerlos.

image

Para ello, se usa el menú Acción, Abrir Log guardado, y se abre el archivo de log que se ha creado durante la sesión de captura de paquetes. En este caso, el archivo en cuestión es C:Windowssystem32configsystemprofileAppDataLocalNetEventTrace.etl

image

Una vez abierto, nos aparece una nueva sección en la aplicación llamada “Saved Logs”, en la que se encuentra el archivo que se acaba de abrir

Capture

Conclusión

PowerShell ofrece herramientas de monitorización de red, que se pueden integrar en un script, por ejemplo, para analizar si una determinada aplicación se está comportando de la forma debida, o incluirlo dentro de rutinas de mantenimiento para detectar tráfico a direcciones o puertos sospechosos.

Bonus

La Shell también ofrece un cmdlet para leer archivos de log ETL, Get-WinEvent. Esto proporciona capacidades de filtrado de cadenas adicional, que no se tiene en la aplicación del visor de Eventos.

image

Por ejemplo, y sin ir más lejos, una vez que se tiene la variable $log con la ejecución de la línea mostrada en la captura anterior, se puede lanzar el siguiente comando: $log.message | Select-String -SimpleMatch ‘fail’ , lo que mostraría una lista de errores de conexión.

Envio de correo desde FIM (Conector de WebServices)

Hola a todos, hoy vamos a tratar un tema radicalmente distinto a mi habitual post de PowerShell. En este caso, vamos a hablar del conector de Web Services para FIM, y cómo se puede añadir un flujo para que envíe correo. En primer lugar, y a grosso modo, hablemos de FIM:

 Brevísima introducción a FIM

Forefront Identity Manager, FIM para los amigos,  es un gestor de Identidad. Su última versión ha sido renombrada como Microsoft Identity Manager (MIM), que en el futuro recibirá nuevos artículos en este blog. La parte más importante del producto es el Synchronization Service (FIM Sync), aunque también dispone de una funcionalidad llamada FIM Portal (basado en Sharepoint) que ayuda a simplificar algunas tareas de gestión. Su función consiste en sincronizar la identidad de los usuarios a través de muy diversos entornos. Dicho así suena a que es algo muy fácil, pero en realidad, la gestión de identidad puede suponer un dolor de cabeza muy serio en cuanto tenemos más de una única fuente de datos en la que se encuentre la identidad de los usuarios.

Vamos por partes: Entendemos por identidad como la esencia que identifica de forma inequívoca a una persona. En el caso de Active Directory, la identidad de una persona coincide con su cuenta de usuario. Pero ¿Qué sucede si lo que se tiene de esa persona es una tabla en una base de datos de Recursos Humanos? En muchos casos, lo que se hace es enviar un correo electrónico con los datos de dicha persona (su identidad) al administrador de Active Directory, quien procede al alta de dicha persona. En ocasiones, se ha automatizado el proceso, de forma que dar de alta a una persona en la BBDD de Recursos Humanos automáticamente crea una cuenta en Active Directory.

Ahora bien, ¿Qué sucede si con el paso del tiempo, el usuario notifica al administrador de Active Directory que ha cambiado su domicilio, pero no lo notifica a Recursos Humanos? O bien el administrador se encarga de decirle al responsable de RRHH que hay que cambiar el domicilio, o bien… siempre cabe la posibilidad de que el domicilio se quede sin cambiar.
La situación se complica, si además hay que gestionar la identidad del usuario en más de uno o dos sistemas diferentes. Máxime si uno de los sistemas es además un sistema personalizado propio y exclusivo de la empresa.

Forefront Identity Manager entra para poner un poco de orden en todo este caos de identidad. FIM, como herramienta, posee una base de datos llamada “Metaverso”, en la que va a guardar metadatos de todas las fuentes de identidad configuradas, y se encarga de poner en orden todo ello, asignando los datos correctos a la identidad (única e irrepetible) de una persona. Pero no sólo actúa de repositorio y almacén central de datos, adquiridos mediante conectores de muy diversa naturaleza. Sino que además, actúa como sincronizador, y se encarga de distribuir los cambios que se realicen a la entidad “usuario” a todos los sistemas afectados, de forma que los datos de dicho usuario Siempre estén en sincronía.

Para poder hacer esto, FIM proporciona una serie muy amplia de conectores, llamados Management Agents, que se pueden conectar a infinidad de orígenes de identidad, como puede ser Active Directory, Microsoft SQL Server, tablas en una Base de Datos, líneas en un archivo CSV…. la variedad es inmensa. Pero pese a la gran variedad de conectores disponibles, siempre queda la posibilidad de que una empresa esté usando un sistema de gestión de identidad propio… que debe ser sincronizado con otros sistemas. Un ejemplo, puede ser una aplicación personalizada de gestión de recursos humanos.

Para este tipo de sistemas, FIM proporciona herramientas que permiten la creación/desarrollo de nuevos Management Agent, ya sea el conector ECMA 2.0, o el conector basado en WebServices.

De los dos, a priori, el que parece más sencillo de usar, pero al mismo tiempo aparenta ser el más limitado, es el conector de WebServices. Pero eso es sólo en la superficie. Ya que al profundizar en él, no es tan sencillo de utilizar ni tampoco es tan limitado como parece. Así pues, y tras esta larga introducción ¿qué mejor forma de mostrar su potencia, que mostrando un pequeño snippet que nos permite enviar un correo desde FIM?

 Prerrequisitos

Para poder replicar el contenido de este post, es necesario más trabajo del habitual. La versión de FIM sobre la que se ha trabajado es FIM 2010 R2. Como requisito base, se va a necesitar un Active Directory, así que es necesario tener un laboratorio de AD con al menos un DC. También es necesario tener un Microsoft SQL Server instalado y configurado (aunque puede estar funcionando en la misma máquina donde se despliegue FIM Sync). La buena noticia, es que en ambos casos, tanto SQL Server (2008/2012) como FIM 2010R2 tienen una trial de 180 días, así que es posible desplegarlos sin preocupaciones, que nos van a durar casi 6 meses. Finalmente, y dado que se usa el conector de web services, es buena idea tener una máquina adicional con IIS en la que se despliegue un web service. Y ya puestos a pedir, también viene bien tener un Visual Studio con el que desarrollar el web service (por simplicidad), aunque es perfectamente posible implementar un web Service SOAP que se pueda usar en Apache y PHP.

Pregunta del millón: Si se va a utilizar FIM y el conector de Web Services para enviar correo, ¿realmente es necesario montar un servidor con un webservice (por muy simple que sea) para que todo esto funcione? La respuesta es . FIM va a comprobar que el conector tiene definido un web service y un tipo de objeto que va a leer en sus operaciones. Así que si no existen ni el objeto ni el servidor del que lo va a leer… no se va a poder crear el conector en el cliente de FIM Sync.

EstructuraServidoresEn definitiva, se necesita tener al menos tres máquinas virtuales en un laboratorio de AD: Domain Controller, un Servidor Web, y la máquina de FIM (que simultáneamente hospeda SQL Server). Esta configuración FIM-SQL_Server no es la aconsejada para despliegues físicos, pero en cambio, ésta es la configuración recomendada si se va a desplegar un servicio de FIM Sync en Azure

Conector de WebServices

Este conector está basado en Windows Workflow Foundation (WWF). Bueno, en un subconjunto de WWF, para ser más precisos. Esto de entrada ya parece un limitante, pero con suficientes dosis de creatividad, es posible hacer casi de todo.

Para poder trabajar con este conector, se utiliza un editor llamado “Web Service Configuration Tool“, absolutamente minimalista, pero que cumple con su cometido a la perfección. De entrada, se puede ver que hay tres secciones bien diferenciadas: Discovery, Object Types y Test Connection.

interface

  • Discovery es la sección donde se puede editar y añadir nuevos Web Services, en este caso basados en SOAP, aunque instalando una actualización también es posible usar servicios REST.
  • Object Types es la sección donde se definen los objetos que se van a sincronizar con FIM. Cuando se configura, aparecen las opciones para añadir el código WWF que va a gestionar las operaciones de Full Import, Delta Import, y Export (delete-add-replace) relacionadas con ese objeto. Estos objetos, se proyectan directamente en el metaverso de FIM a la hora de crear el Management Agent, así que es seguro decir que hay total libertad a la hora de definir los Object Type.
  • Finalmente, la sección Test Connection es la que vamos a usar en este post.

Obviamente, las cosas no son tan sencillas como decir “vamos a hacer un test de envío de correo” y listo. En este caso, para poder hacer el test, FIM hace comprobaciones sobre los archivos de configuración creados con la herramienta. Se fija en detalles tan insignificantes como que la herramienta se va a conectar a un Web Service SOAP existente, o que los datos que devuelve el Web Service son compatibles con un Object Type detallado previamente, etc. Por eso es necesario contar con una máquina adicional que

Cómo crear un Web Service en Visual Studio, e instalarlo en un servidor IIS adicional para que FIM pueda leerlo, es un tema aparte que merece un mini-post para detallarlo. Simplemente decir, que para que todo esto pueda funcionar con el Web Service Configuration Tool en modo SOAP, es necesario tener un web service accesible, y que haya sido configurado en la herramienta, de forma que pueda pasar las validaciones de FIM Sync. Para ello, simplemente acudimos a la sección de Discovery, y añadimos un nuevo servicio, con tipo de tipo de credencial none y con modo de seguridad none. Al fin y al cabo, es un servicio de pruebas, y no es necesario complicarse aún más con modelos de autenticación.

nuevoServicioSOAP

A continuación añadimos un objeto, para que las validaciones de FIM no se quejen y nos digan que el conector no es válido. Sumamente sencillo y rápido, que lo importante no es crear el objeto en el configurador

objetoMetaverso

Ahora que ya está todo preparado (Active directory, despliegue de máquinas, servicio web…) vamos a lo importante: cómo enviar correo.

Envío de Correo: Uso de la sección Test Connection

Con todo ya preparado, ¡toca ponerse manos a la obra! Tenemos el Web Service Configuration Tool, así que toca empezar a mover componentes. Como estamos trabajando con Windows Workflow Foundation, todo va a ser bastante visual, y sobre todo, hay que tener en cuenta que el código se incrusta dentro de bloques denominados secuencias.

Lo primero: Definir las variables que necesitamos para desarrollar el proyecto.

vars

El editor de configuración, dispone de tres secciones interesantes en la parte inferior de la ventana de edición de código: Variables, Arguments, Imports. Para el uso que importa en este artículo, sólo se va a hacer uso de la sección “Variables”, en la que definimos las variables que se van a utilizar. Es importante señalar dos apartados de esta sección: Scope que indica el ámbito de la variable, dentro de una secuencia, y Variable Type, que es donde definimos el tipo de las variables. En Variable Type, se muestra una serie de tipos predefinidos aunque, y aquí entra la magia, es posible buscar cualquier clase presente en el .NET framework para utilizarla como tipo de variable.

advancedTypes_WSConnectorEstablecer que las variables estén en el scope “sequence” (el top-level) es el equivalente a definirlas como variables globales que estarán disponibles para todas las secuencias que se creen dentro de la secuencia padre.

A continuación, es necesario definir la estructura de lo que es necesario para enviar un correo. Los pasos básicos. Esto lo vemos en la siguiente captura de pantalla:

overView Tenemos una Secuencia, que es el cuerpo principal del programa en WWF que se va a “escribir” en la sección de “Test Connection”. En esta secuencia, se añade una nueva secuencia, y se la llama “SendMail”. Una secuencia equivale conceptualmente a una función. Es una agrupación de elementos, que se puede plegar y desplegar a voluntad para ocultar sus contenidos. En este caso, la secuencia SendMail tiene tres partes: Una que es el cuerpo del Mensaje, que se define asignando un valor a una variable, otra sección que es “configurar Servidor SMTP”, y una última sección que es “Enviar Mail”. Estas secciones se despliegan a continuación para mostrar sus contenidos.

configurarSMTP

En la secuencia de “Configurar Servidor SMTP”, lo que se hace es configurar el objeto del tipo SMTPClient que se definió al principio del proceso. Para mejorar la claridad de lo que se hace, hemos renombrado las acciones del tipo “assign” para que su descripción muestre la ruta completa de variables que se está asignando. Convenientemente, las credenciales para conectar al servidor SMTP quedan oscurecidas dentro del textbox en el que están escritas, pero para que lo tengamos claro, son un objeto del tipo Net.NetworkCredentials. Para simplificar aún más, indicamos que el cuerpo del mensaje no es HTML.

A continuación, desplegamos la segunda secuencia “Enviar Mail”

enviarMail

 

En este caso, se establece la dirección de envío (mailMessage.From = New System.Net.MailAddress(fromMailAddress)), y aquí viene lo potente: El componente de WWF “InvokeMethod”, que permite ejecutar un método de una clase que haya sido instanciada en un objeto. En este caso, se añade la dirección a la que se quiere enviar a la lista de destinatarios. Es necesario usarlo, ya que internamente es una lista, y los correos destino se deben añadir uno a uno. Se define el Subject del mensaje, se define el Body del mensaje, y se vuelve a usar un InvokeMethod para, esta vez sí, hacer que el objeto SMTPClient (instanciado como smtpService) se encargue de enviar el correo electrónico que hemos definido.

anadirDestinatario

Finalmente, si queremos que FIM se entere de que todo ha terminado con éxito, toca añadir al final de la secuencia la siguiente asignación:

resultTrue

Con esto, hemos definido la configuración del conector de Web Services. Pero todo esto, por sí solo, no hace absolutamente nada. Es necesario Crear un Management Agent del conector de Web Services en FIM Sync, e indicarle que use este archivo de configuración. Para ello, lo más importante es copiar el archivo de configuración a una carpeta muy concreta, de lo contrario, FIM Sync no será consciente de su existencia.

url

 

Finalmente, con el archivo de configuración copiado en la carpeta de Extensiones, se puede proceder a crear el Management Agent. Para ello, se abre el Synchronization Service Manager on FIM, y se acude a la sección “Management Agents”, seleccionamos “Create”, y nos encontramos con esto:

creandoMA

Se selecciona que el Management Agent que se desea crear es el de “Web Service (Microsoft)”, se le pone un nombre, y se pulsa “Next”, esto nos lleva a la pantalla de configuración de conexión del MA.

creandoMA.2

En esta sección, es importante elegir el proyecto del configurador del conector que hemos creado, y el Host y el puerto que hemos definido en el proyecto, así como la misma configuración en el modo de seguridad y el tipo de credencial de cliente. FIM va a validar todo esto, y en caso de que haya algún error no va a dejar que continuemos bajo ningún concepto.

Una vez  todo está validado, FIM pasa a la siguiente pantalla “Global Parameters”, en la que aparece un único checkbox disponible:

creandoMA.3¡¡¡¡ “Test Connection” !!!! Marcando este checkbox, FIM va a ejecutar el código que hemos creado anteriormente en el apartado “Test Connection”, que existe única y específicamente para ser ejecutado en este instante. Esto es muy útil para probar partes del código del conector de Web Services, ya que se pueden ejecutar sin ningún tipo de compromiso, y en caso de que todo haya funcionado bien, lo sabremos gracias a la sección “Result = true” que añadimos al final del código. Para pruebas más complejas, es muy útil no devolver ningún valor de Result (por defecto es false), o cambiarlo a False en caso de que algún tipo de validación no se haya ejecutado como se espera.

Es la hora de la verdad: En cuanto se pulse “Next”, teniendo el checkbox marcado, FIM va a compilar el conector de Web Service, y va a ejecutar la sección de “Test Connection”. En caso de que todo salga bien, se enviará un correo electrónico a la dirección deseada, y el cuadro de diálogo para crear un Management Agent pasará a la siguiente sección “Configure Partitions and Hierarchies”. Pero todo ello ya no pertenece al ámbito de este post.

En cambio, lo que sí pertenece, es la última captura de pantalla…

correoFIM

Finalmente, ¡los correos han llegado a su destino!

 

Conclusión

En este artículo se ha compartido un fragmento de código para el conector de Web Services, que es muy útil a la hora de diagnosticar problemas en casos de importaciones masivas. Por ejemplo, si hay que sincronizar medio millón de usuarios, eso es un proceso que puede tomar varios días de proceso para el conector. En caso de que hubiese algún tipo de problemas, un sistema de alertas por email que indique que algo está pasando es vital para ayudar a actuar de inmediato, corrigiendo la situación que esté dando problemas en el lado servidor antes de vernos forzados a interrumpir el proceso. Cualquier interrupción de una operación de full Import puede suponer días de espera, ya que es una operación que no puede ser reiniciada.

En definitiva, una herramienta útil para desarrollos más complejos utilizando el conector de Web Services.

¡Hasta la próxima!

Alerta de Seguridad: Ejecución remota de código MS15-078

https://technet.microsoft.com/library/security/MS15-078

Esta semana se ha desplegado un parche de seguridad crítico que corrige una vulnerabilidad de ejecución de código remoto. Esta vulnerabilidad afecta a todas las ediciones de Windows. El vector de ataque se basa en la apertura de documentos diseñados específicamente a tal efecto, o la visita a páginas web que contenga tipografías OpenType incrustadas que hayan sido diseñadas para explotar el fallo.

La vulnerabilidad se produce por la forma en que la “Windows Adobe Type Manager Library” gestiona las fuentes OpenType.

Formas de explotación: Se requiere interacción por parte del usuario objetivo, que ha de abrir un documento con una fuente openType  incrustada que haya sido diseñada a tal efecto, o bien visitar una página web que contenga la tipografía OpenType.

Acciones a realizar: Toda máquina que se haya actualizado y necesite un reinicio debe ser reiniciada lo antes posible para evitar posibles infecciones que sucedan durante la navegación web en sitios de poca confianza. En las máquinas que no tengan configurado Windows Update para que descargue e instale automáticamente las actualizaciones, el sistema debe ser actualizado manualmente y reiniciado para que la actualización tenga efecto.

Powershell Snippets: Obtener la MAC de la tarjeta WIFI de equipos en el AD

Hola a todos,

En ocasiones, hace falta obtener información específica sobre equipos del dominio. Por ejemplo, supongamos que por motivos estadísticos, es necesario sacar un listado de los equipos de una oficina que están encendidos en un momento determinado, y no sólo eso, sino que además se desea obtener la MAC de su interfaz Wi-Fi (para complicar el asunto).

En este caso, está claro que se va a utilizar el módulo de Active Directory de PowerShell, ya que hace falta obtener un listado de equipos. Y por otro lado, es necesario que haya un mecanismo que permita conectarse a las máquinas para acceder a la lista de interfaces de red, y poder leer las que nos interesen.

Afortunadamente, PowerShell dispone de todo lo necesario para llevar a cabo esta tarea. A continuación, un breve desglose con los cmdlets principales:

  • Get-ADComputer -Filter * -SearchBase “OU=Oficina,OU=Empresa,DC=Empresa,DC=com”
    Este cmdlet va a encargarse de obtener todos los equipos del dominio. Además, se especifica
  • get-wmiobject -class “Win32_NetworkAdapter” -computername $comp.DNSHostName -filter “NetConnectionID = ‘Wi-Fi’ ” -ErrorAction “Stop”
    Con este cmdlet se lanza una consulta WMI a los equipos obtenidos previamente, y se le aplica un filtro por el campo “Wi-Fi”. También se puede filtrar por “Ethernet”, o no filtrar en absoluto.
  • New-Object PSObject -prop @{Computer = $comp.DNSHostName; Adapter = $obj.Name; MAC=$obj.MACAddress}
    El último comando importante genera un objeto con los atributos “Computer”, “Adapter” y “MAC”, que se utiliza para crear un archivo CSV al final del script.

Hay una poderosa razón para que este script deba lanzarse desde la PowerShell de un usuario Administrador de Dominio: Se conecta a cada una de las máquinas para consultar su lista de interfaces y quedarnos con aquellas que tienen interfaz Wi-Fi. Si quien lo ejecuta no es administrador de dominio, no va a poder conectar con las máquinas, y por tanto, no podrá generar el listado.

Sin más dilación, aquí tenéis el código de la función.

Se puede pegar tal y como está en una consola de PowerShell e invocarla como un cmdlet cualquiera, o se puede integrar dentro de un módulo, o generar un script (copiando únicamente el código de la función). Las posibilidades son infinitas, sobre todo gracias a que se puede jugar con el cmdlet get-wmiObject para obtener una variedad de información casi ilimitada.

shell

Finalmente, y como un artículo sobre un script nunca queda completo si no incluye capturas de pantalla… aquí está una muestra del CSV resultado de la ejecución del script.

wifiMac

 

Happy Scripting!