miércoles, 1 de diciembre de 2010

Exchange 2010: creación rápida de usuario y buzón

Con un único formulario, crea un usuario con buzón de correo en Exchange 2010 desde cualquier host conectado al dominio del Directorio Activo. Sólo es necesario tener instalado PowerShell 2 y .NET 3.5 en adelante.

Características:
  • Un sólo formulario.
  • Nombre de dirección de correo igual al nombre de inicio de sesión.
  • Inserción única de la contraseña.
  • Visualización del tamaño de las bases de datos de Exchange 2010 antes de elegirla.
  • Distinción entre cuenta personal y de servicio.
  • Inserción en grupos del Directorio Activo.
  • Inserción de los atributos más utilizados.
  • Visualización en la barra de estado del servidor Exchange 2010 conectado.
  • Gratuito.

Modo de empleo:
  • Ejecuta la herramienta "alta_usuario_mailbox_2010.exe" con un usuario que tenga privilegios para crear buzones en Exchange 2010.
  • Elige en el árbol de la izquierda la Unidad Organizativa donde quieres ubicar la nueva cuenta.
  • Rellena los campos que necesites (algunos son obligatorios).
  • Clica en "Dar de Alta" y si todo es correcto, el usuario (con todas las opciones indicadas en el formulario) y su buzón de correo aparecerán en su sitio.

Pantallazo:


sábado, 27 de noviembre de 2010

Directorio Activo: Informes de usuarios

Toca realizar consultas al Directorio Activo en busca de patrones que guardan los usuarios. Sólo vamos a utilizar PowerShell y .NET (sin más).

Un usuario de un dominio de un Directorio Activo es un objeto y tiene una serie de propiedades (también conocidas como atributos) que le hacen único para unas cosas y común para otras. Entre otras, las propiedades más conocidas de un usuario son: name, displayname, samaccountname, company, department, division, memberof y mail.

Como ejemplo a ilustrar, vamos a obtener un informe de todos los usuarios del grupo G_ADMON y cuya oficina (atributo physicalDeliveryOfficeName) sea Madrid. Primero pongo el código PowerShell y después lo explico:

----comienzo de script.ps1-------------

$rootdse = New-Object DirectoryServices.DirectoryEntry("LDAP://RootDSE")
$dominio = $rootdse.Properties["defaultNamingContext"]
$raiz_dominio = New-Object DirectoryServices.DirectoryEntry("LDAP://$dominio")

$busca = New-Object DirectoryServices.DirectorySearcher $raiz_dominio
$busca.Filter = "(&(objectClass=user)(objectCategory=person))"
$usuarios = $busca.findall()

$c=0

foreach ($usuario in $usuarios)
{
if (($usuario.properties.memberof -like '*G_ADMON*') -and
($usuario.properties.physicaldeliveryofficename -eq 'Madrid'))
{
$usuario.properties.name
$usuario.properties.mail
"-----------------------"
$c++
}
}
"$c usuarios encontrados."

----fin de script.ps1-------------

En las tres primeras líneas se crean tres objetos consecutivamente:

$rootdse: localiza la configuración principal del Directorio Activo.
$dominio: extrae el valor del dominio de la configuración de $rootdse.
$raiz_dominio: partiendo de $dominio, se ubica en su elemento raíz para realizar búsquedas.

Las tres siguientes líneas preparan y ejecutan la búsqueda de usuarios:

$busca: objeto que busca en $raiz_dominio.
$busca.Filter: es un filtro para que sólo busque usuarios y no otro tipo de objetos.
$usuarios = $busca.findall(): busca y encuentra a todos los usuarios que cumplan con el filtro y los deja en $usuarios.

Después se inicializa un contador a 0 y luego hay un bucle foreach que recorre todos los usuarios encontrados. Por cada usuario ($usuario) en $usuarios se busca con if a los usuarios cuyo campo memberof (grupos a los que pertenece el usuario) contenga lo que estamos buscando (el grupo G_ADMON) y cuyo campo physicaldeliveryofficename (oficina) sea Madrid. Si las dos condiciones anteriores se cumplen, mostramos el nombre y el email del usuario en cuestión; además se incrementa el contador. El informe finaliza con el número de usuarios encontrados que cumplen las condiciones.

Este es el armazón básico para realizar consultas a objetos de un Directorio Activo, en este caso han sido consultas a dos atributos de todos los usuarios, pero podemos consultar cualquier atributo de cualquier usuario u otro objeto. Sólo necesitamos saber cómo se llaman los atributos de los objetos para buscarlos. Para averiguar estos nombres de atributos aconsejo utilizar la herramienta AD Explorer de Mark Russinovich para ver el Directorio Activo por dentro, localizar los objetos y ver sus atributos.

Además, escribir código para estos menesteres es mucho más corto y rápido con PowerShell que con cualquier otro lenguaje que utilice .NET como VBasic o C#.


martes, 2 de noviembre de 2010

Acceso rápido a herramientas de Windows

El Panel de control de Windows tiene varias herramientas, pero hay otras importantes como los servicios y el visor de sucesos que no aparecen ahí.

Por otro lado, dependiendo de la versión de Windows, los nombres de algunas herramientas cambian, por ej. en Windows XP, Windows 2000 y Windows 2003 tenemos "Agregar o quitar programas", en Windows Vista, tenemos "Programas y características", y en Windows 7 tenemos "Desinstalar un programa" pero en este caso la barra de direcciones sigue haciendo referencia a "Programas y características", todo esto con la misma función recurrente: desinstalar programas.

Por estos motivos y por muchos otros, y porque un click es más rápido que dos, se me ocurrió hacer un menú (herramientas.exe) con categorías y botones donde cada uno inicializa una herramienta:


Este menú ha funcionado correctamente en:
  • Windows XP
  • Windows 2003
  • Windows 7
Y el ordenador que lo utiliza necesita el Framework 3.5 instalado (Windows 7 ya lo lleva puesto).

sábado, 30 de octubre de 2010

Nueva contraseña en tres pasos


Una de las tareas más recurrentes en la administración de un Directorio Activo es el cambio de contraseña de los usuarios.

Utilizar las típicas consolas de administración implican varios pasos para encontrar el usuario y cambiar su contraseña.

Para dejarlo sólo en tres pasos, he creado cambiapass.exe, y una vez abierto ...
  1. Introduce el nombre de la cuenta del usuario (sAMAccountName) y pulsa ENTER.
  2. Si existe, aparece la información suficiente para identificar al usuario.
  3. Introduce la nueva contraseña y pulsa ENTER.

Un vistazo:


Requisitos: Framework 3.5 en un ordenador miembro del dominio.


martes, 28 de septiembre de 2010

Altas rápidas de usuario con Exchange 2007

Cuando se da de alta un usuario en un Directorio Activo Win2003, normalmente también se necesita:
  • Buzón de correo
  • Atributos (organización, departamento, etc.)
  • Pertenencia a grupos
Y para esto son necesarias la consola de Exchange 2007 (creación del usuario y el buzón en este caso) y la consola de Administración de Usuarios y grupos del Directorio Activo (inserción de atributos y grupos).

Para no perder tanto tiempo utilizando dos consolas, he desarrollado una herramienta llamada alta_usuario.exe que ofrece un único formulario para crear un usuario+buzón, indicar toda la información mencionada y alguna cosa más:


Lo primero que debemos hacer es asegurarnos de que cumplimos los requisitos mínimos, que son tener instalado el siguiente software en el host donde ejecutemos alta_usuarios.exe:
Lo segundo es ejecutar alta_usuarios.exe con un usuario que tenga permisos suficientes para crear usuarios en el dominio y buzones en Exchange 2007.

Aparece el formulario, indicamos el nombre del dominio (por defecto DOMINIO) y le damos a Conectar. Esperamos un poco y si todo es correcto, aparecerá en la columna izquierda el árbol de OU's del dominio. Elegimos la OU correspondiente para el nuevo usuario, y ésta aparecerá arriba en el apartado Unidad Organizativa.

Después indicamos la información común de alta del usuario donde es obligatorio el nombre, el nombre de inicio de sesión, la contraseña y el grupo de almacenamiento de correo (los atributos son opcionales).

En el apartado Tipo de cuenta podemos elegir entre:
  • Cuenta personal: el usuario es una persona e indicamos sus apellidos.
  • Cuenta de servicio: el usuario no es una persona e indicamos el atributo Nombre para mostrar que queramos.
Una cuenta de servicio es aquella que utilizan uno o más usuarios, y la cual carece de apellidos. En el caso del atributo Nombre para mostrar de la cuenta personal será: apellido1 apellido2, nombre.

El penúltimo paso es añadir al nuevo usuario en los grupos que queramos del Directorio Activo, y si nos equivocamos también podemos quitarlos (tampoco es obligatorio).

Por último, le damos al botón Dar de Alta y el resultado lo tendremos más abajo.

Nota: esta herramienta está muy probada en producción, en el entorno indicado y funciona estupendamente, no obstante, si la pruebas y ves algún fallo o sugerencia, agradeceré me lo comuniques.

lunes, 13 de septiembre de 2010

Directorio Activo: grupos y miembros

Cuando un Directorio Activo alcanza su madurez, también alcanza un buen número de grupos que se utilizan para que sus miembros (usuarios y otros grupos) dispongan de otros recursos del Directorio Activo como carpetas compartidas, listas de distribución de email, permisos para realizar ciertas operaciones, etc.

En cualquier caso y a medida que pasa el tiempo, la creación de grupos disminuye y aumenta la necesidad de agregar/eliminar miembros de estos grupos.

Para que esta tarea sea más rápida y amena, he creado una herramienta llamada Gestión de miembros en grupos (gestion_grupos.exe) que hace lo siguiente:
  • Conecta con el dominio deseado previa indicación de su nombre.
  • Crea una lista desplegable con todos los grupos encontrados en el dominio indicado.
  • Elegido un grupo de la lista desplegable, aparecen sus miembros.
  • Para eliminar un miembro, lo seleccionamos de la lista y clicamos en "Eliminar".
  • Para agregar un miembro, escribimos su nombre de cuenta (samAccount) en el campo a la izquierda del botón "Agregar" y clicamos en él.
  • Los miembros pueden ser usuarios y/o grupos.
  • Requiere .NET Framework 3.5

Un pantallazo:

lunes, 19 de julio de 2010

Monitorizando colas de Exchange 2007


Get-Queue -server nombre_servidor_exchange2007

es el comando PowerShell que muestra una instantánea del número de mensajes de las colas del servidor de correo Exchange 2007.

Una buena mejora en la visualización de resultados de este comando sería que éstos aparecieran en una ventanita de Windows y se actualizara con cierta frecuencia:

Para conseguirlo, escribiremos una aplicación en C# que internamente ejecute nuestro comando en PowerShell y envíe su salida a un Listview con los resultados, todo en una ventanita.

Para que esto funcione, tanto en el desarrollo de la aplicación como en la ejecución posterior del .exe, es necesario utilizar un usuario que tenga permisos para visualizar las colas, por ej. el administrador de dominio.





Requisitos de software en el host de desarrollo:

- SharpDevelop
- Powershell 2
- Consola de administración de Exchange 2007
- .NET Framework 3.5

Instalado todo esto, abrimos SharpDevelop con el usuario que tenga permisos para ver las colas de Exchange 2007 y creamos en un proyecto nuevo una nueva aplicación de Windows que se llame "colas_correo", de esta forma:

Creada la aplicación, tendremos una ventana vacía que es el formulario por defecto "MainForm". A la derecha de la vista de diseño del formulario tenemos la columna de propiedades del elemento que tengamos seleccionado. Seleccionamos la ventana del formulario y en la lista de propiedades buscamos la propiedad "Text", y le ponemos el nombre que queramos para que aparezca como título de la ventana, por ej. "Colas Exchange".

Dentro del formulario creamos una etiqueta cuya propiedad (Name) sea "leyenda_form". La propiedad Text de esta etiqueta la modificaremos dinámicamente para visualizar la fecha/hora de la última consulta a las colas.

Debajo de la etiqueta creamos un ListView con dos columnas, seleccionamos el ListView creado, clicamos en la flechita que está cerca de la esquina superior derecha del ListView, clicamos en "Editar columnas" y agregamos un miembro 0 (columna izquierda) donde su propiedad (Name) debe tener el valor: cola_form, y la propiedad Text debe tener el valor: Cola. Después agregamos otro miembro 1 (columna derecha) donde su propiedad (Name) debe tener el valor: mensajes_form y la propiedad Text debe tener el valor: Mensaje.

Aceptamos ventanas y pasamos a picar código. Clicamos en la pestaña "Fuente" de abajo y podremos editar el código de este formulario que es el que utilizaremos. El archivo que contendrá este código es MainForm.cs y estará ubicado en la carpeta del proyecto.

También tienes disponible el código de MainForm.cs en este enlace.

En el comienzo del archivo MainForm.cs aparece por defecto una lista de directivas using que tenemos que completar dejándolas así:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Host;
using System.Management.Automation.Runspaces;
using System.Text;

Para evitar errores en la compilación relacionados con la falta de referencias, seguramente sea necesario agregar las referencias correspondientes para alguno de estos using. Lo puedes hacer desde el menú Proyecto, Agregar Referencia, pestaña GAC, buscar la referencia correspondiente, seleccionarla y OK.

Después de la lista de los using, hay un namespace cuyo nombre da igual para nuestro propósito. Dentro de tal, tendremos un public partial class MainForm: Form que es la clase de nuestro formulario y dentro de ella hay métodos (funciones), entre ellos, el punto de entrada es el método public MainForm() que se encarga de iniciar el formulario.

Dentro de public MainForm(), lo primero es el método InitializeComponent() que se encarga de inicializar el formulario con las propiedades por defecto, y justo después crearemos un Timer para que nuestra aplicación saque datos cada minuto:

Timer timer1 = new Timer();
timer1.Interval = 60000; // un minuto
timer1.Enabled = true;
timer1.Tick += new System.EventHandler (OnTimerEvent);

Además, necesitamos un método
OnTimerEvent()
que tiene que ir al mismo nivel que public MainForm(), así:

public void OnTimerEvent(object source, EventArgs e)
{
saca_datos();
leyenda_form.Text = "Última actualización: " + DateTime.Now.ToLongTimeString();
}

leyenda_form
es el nombre de una etiqueta dentro del formulario que indica la última fecha/hora que se hizo la consulta a las colas (no olvides tenerla ubicada visualmente en el formulario con la propiedad (Name) adecuada).

saca_datos()
es el método que hará la invocación a PowerShell y sacará los datos de la cola. También debe ir al mismo nivel que public MainForm().

Importante:
el método saca_datos() debes editarlo para definir la variable "servidor" con el nombre DNS de tu servidor Exchange 2007.

El código del método saca_datos() es el siguiente:

private void saca_datos()
{
lista_form.Items.Clear();
// edita la siguiente línea con el nombre DNS de tu servidor de correo
string servidor = "el_nombre_de_tu_servidor_exchange";

RunspaceConfiguration rsConfig = RunspaceConfiguration.Create();
PSSnapInException snapInException = null;
PSSnapInInfo info = rsConfig.AddPSSnapIn
("Microsoft.Exchange.Management.PowerShell.Admin", out snapInException);
Runspace myRunSpace = RunspaceFactory.CreateRunspace(rsConfig);
myRunSpace.Open();
Pipeline pipeLine = myRunSpace.CreatePipeline();

// comando powershell
Command myCommand = new Command("Get-Queue");

//parámetros powershell
CommandParameter param_server = new CommandParameter("server", servidor);
myCommand.Parameters.Add(param_server);

//mete en la tubería de ejecución
pipeLine.Commands.Add(myCommand);

//ejecución
Collection commandResults = pipeLine.Invoke();

//resultados
string cola = "";
string mensajes = "";

foreach (PSObject cmdlet in commandResults)
{
cola = cmdlet.Properties["NextHopDomain"].Value.ToString();
mensajes = cmdlet.Properties["MessageCount"].Value.ToString();

//saca datos en lista
ListViewItem i = new ListViewItem();
i.Text = cola;
i.SubItems.Add(mensajes);
lista_form.Items.Add(i);
}
}


Y listo, con esto sólo queda darle a F5 para compilar y ejecutar la solución.

Si todo es correcto, el ejecutable colas_correo.exe lo encontrarás en la carpeta debug o release dentro de la carpeta bin del proyecto, el cual podrás utilizar directamente.