Powershell: Cambiar la contraseña de cuenta Active Directory

Partiendo de la sintaxis aprendida en el post “PowerShell: Ejemplos básicos” vamos a crear un script que permita modificar la contraseñade una cuenta basada en el nombre que introduzca el usuario por teclado, el usuario debe introducir los siguientes datos:

  • Nombre de la cuenta que
  • Nueva contraseña
  • Confirmación de la nueva contraseña
  • ¿El usuario debe cambiar la contraseña el próximo inicio de sesión? Pregunta Sí / No.

Configuración

Importa modulo con utilidades para Active Directory y establece una variable de solo lectura global (una constante) para depurar script.

Función para depuración por consola, así podemos desactivar los mensajes informativos que usamos para testear el script.

Funciones de propósito general

Función para leer una cadena introducida por el usuario

Evitamos con un pequeño control que el usuario introduzca una cadena vacía.

Función específica para preguntas donde el usuario debe seleccionar entre dos opciones:

Función de entrada principal

Nuestro script sólo tendrá una línea de código fuera de las funciones (sin contar la cabecera con la importación del modulo y la variable global) y será la llamada a la función “SetAccountPwdMain“:

Función cambio contraseña

Anuncios

PowerShell: Ejemplos básicos

Lógica condicional (IF)

Si la condición condition se evalua como $true PS ejecuta el bloque de sentencias encerradas entre la apertura y cierre de llaves { … }. Lógicamente si se cumple una condición no se evalúa el resto y no se ejecuta.

if(condition)
{
    # statement block
}
elseif(condition)
{
    # statement block
}
else
{
    # statement block
}

En este caso recibimos como argumento al script una variable y mediante un operador de comparación, -eq compara si son iguales la variable $number y el número 5, proviene de equal en ingles.

Un ejemplo un poco más avanzado donde leemos dos variables introducidas por teclado durante la ejecución del script, en este caso usamos el operador de comparación –ne (se cumple la condición cuando las variables comparadas no son iguales, “not equals“).

Bucles repetitivos

Los bucles permiten ejecutar un bloque de código múltiples veces.

do … while Statement/do … until Statement

En un bucle do…While el código del interior como mínimo se ejecuta una vez antes de evaluar la condición while(condition) al final.

En el siguiente ejemplo se repite la misma sentencia mientras el usuario no introduzca una opción valida , como mínimo se mostrara una vez la pregunta al usuario:

Funciones

Las funciones permiten agrupar bloques de código con un propósito y ejecutarlo desde cualquier parte de nuestro programa invocándola por su nombre.  El script anterior podemos meterlo en una función y así no reescribir todo el código cada vez que el usuario deba seleccionar una opción.

Ayuda de la función basada en comentarios

Es una buena práctica ofrecer ayuda y documentación sobre el código para facilitar la reutilización del mismo. Por fortuna PowerShell contempla esta necesidad mediante la funcionalidad “comment_based_help“. Siguiendo una sintaxis concreta vamos a documentar la función anterior

Este es un ejemplo de una función que recibe una cadena de texto y crea una carpeta con este nombre. El comando Get-Help interpreta los comentarios del código fuente y los muestra formateados por la salida.

Enlaces:

Funciones con parámetros

Como los scripts las funciones pueden aceptar parámetros, en el ejemplo anterior lo ideal hubiese sido pasar como parámetro la ruta del directorio a crear, si siempre crease el mismo directorio no resultaría de gran utilidad, con las variables como parámetros de entrada la función condicionamos su comportamiento.

La función acepta una variable de tipo cadena de texto (string), definimos un valor por defecto, cuando se invoca la función sin parámetros crea siempre una carpeta con nombre “testDirDefault” como en la tercera llamada.

Funciones con retorno

Otro ejemplo muy típico es una función que convierte de grados Farenheit a grados Celsius.

El retorno de la función (como la variable $celsius en este caso) es cualquier cosa que escribamos. Podemos usar la palabra clave return $celsius pero no es necesario.

Comentarios de múltiples líneas

Usando “here-string” podemos crear comentarios de varias líneas sin preocuparnos de caracteres especiales como caracteres de escape o de formato de línea, la ventaja es que podemos usarlo internamente también para imprimir la ayuda de un script.

 

Usar parámetros obligatorios

Enlaces:

 

Variables globales de sólo lectura

 

 

 

 

 

 

C# HTTPRequestServer: Tratamiento de llamadas HTTP del cliente

En el siguiente post voy a describir un mecanismo para definir recursos que capturen cada tipo de llamada del cliente HTTP. Este diseño es muy flexible y se pueden añadir nuevas llamadas en forma de clases bien aisladas.

Ejemplos de llamada:

  • http://localhost:8080/Client?name=Iker.  Esta llamada será redirigida por el localizador de recursos al capturador adecuado para su tratamiento ClientHttpRequestHandler.
  • Lo mismo pasa para consultar la información de un producto ficticio llamando a http://localhost:8080/Product se asocia al manejador ProductHttpRequestHandler.
  • Una llamada especial InvalidHttpRequestHandler se ocupa de las llamadas de clientes a recursos que no existen http://localhost:8080/Sales.

Interface HttpRequestHandler

Una interfaz contiene solo las firmas de los métodos, más adelante veremos que cada clase que captura una llamada (por ejemplo ProductHttpRequestHandler) hereda de la interfaz pública HttpRequestHandler y define estos métodos:

  • Handle: Función capturadora de cada recurso que realiza un tratamiento especifico de la llamada del cliente.
  • GetName: Retorna una cadena con el nombre del recurso (“Product”, “Client”…) para que HttpResourceLocator pueda localizar el manejador adecuado para cada llamada.

 

Implementaciones de interface HttpRequestHandler

Las clases heredadas del interface HttpRequestHandler son las encargadas del tratamiento de cada mensaje. Cada clase tratará un tipo de mensaje, las clases implementan la definición de los dos métodos del interface:

  • GetName: Retorna el atributo de la clase con el nombre del recurso para facilitar su identificación por parte del localizador de recursos.
  • Handle: Contiene el tratamiento de la llamada, recibe como parámetro una instancia de la clase HttpListenerContext que proporciona acceso a todos los datos de la llamada (por ejemplo el nombre del cliente en la URL) y la respuesta.

ProductHttpRequestHandler

Esta clase permite obtener información de un producto pasando el nombre como parámetro en la URL.

InvalidHttpRequestHandler: Manejador para recursos no encontrados

Esta clase es algo especial, informa al cliente de que un recurso no existe con el código HTTP 404 (Not Found).

HttpResourceLocator: Localizador de recursos

La clase HttpResourceLocator registra los capturadores de cada llamada HttpRequestHandler dentro de su atributo privado _httpRequestHandlers en forma de diccionario, la clase Dictionary representa una colección de elementos clave-valor. La clave está representada con una cadena que contiene el nombre del recurso (“Product”, “Client”) para poder localizarlo, el valor es el interface HttpRequestHandler.

El constructor de la clase HttpResourceLocator instancia la clase Dictionary y registra el manejador InvalidHttpRequestHandler para retornar 404 cuando no encuentra un recurso.

El método público AddHttpRequestHandler  registra las clases de tratamiento de las llamadas basadas en el interface HttpRequestHandler pasados como entrada al método.

HttpServer: Servidor Web principal

 

 

Ejecución

Post relacionados

Enlaces externos

POSH GUI: Aplicación Web para diseñar formularios para scripts PowerShell

Código en GitHub.

POSH GUI es una simpática herramienta que me he encontrado en la Web, solo requiere un registro previo gratuito de una cuenta de usuario para acceder a un entorno de trabajo en línea para crear formularios para PowerShell.

Yo me he creado este formulario de login de prueba y le he añadido algo de código para realizar las comprobaciones de los datos introducidos, a modo de ejemplo.



 

C# WinServiceBasic1 v1.1.0: Servicio con servidor HTTP

El servicio que he programado hasta ahora no ofrece ninguna funcionalidad, uno de los usos más habituales es ofrecer un puerto abierto a la escucha para comunicarse con otras aplicaciones en red que ejercen de clientes. En vez de inventar un nuevo protocolo vamos a usar uno reconocido, usando la clase HttpListener vamos a crear un servidor HTTP muy sencillo (espacio de nombres “using System.Net”);

Proyecto en GitHub (v1.1.0)

Clase WebServer

Vamos a crear una clase WebServer que agrupa todas las funcionalidades de nuestro servidor Web. Solo contiene dos atributos privados:

  • _listener: Una instancia de la clase HttpListener.
  • _responderMethod: El capturador de evento cuando un cliente se conecta.

Los métodos que ofrece son tres:

  • WebServer: El constructor de la clase, recibe la URL donde se pondrá a la escucha (por ejemplo “http://localhost:8080/test/” y la función externa a la clase que genera la respuesta al cliente (_responderMethod).  La parte más interesante del constructor es la llamada a _listener.Start().
  • Run: Este método no acepta parámetros. Emplea el método IsListening de HttpListener para determinar si se ha iniciado. La clase  HttpListenerContext proporciona acceso a los objetos de solicitud y respuesta utilizados por la clase HttpListener.  Llama al método interno que apunta a la función que captura la solicitud cliente “_responderMethod(ctx.Request);” y con la respuesta la redirecciona al cliente HTTP.
  • Stop: Este método es muy simple, llama a la Stop y Close de HttpListener.

Ejecución

Ejecutamos e introducimos la siguiente URL en nuestro navegador para ver el resultado: http://localhost:8080/test/.

Posts relacionados

Referencias Externas

 

 

C# WinServiceBasic1 v1.0.1: Añadimos algunas mejoras al servicio

Después de experimentar un poco con el servicio (C# WinServiceBasic1: Crear un servicio básico en Windows) he prescindido del control de VS que permite instalar el servicio y hacerlo yo mismo a mano con scripts PS (PowerShell), los he guardado en la carpeta Debug y permiten instalar / desinstalar / arrancar / parar / ver estado del servicio.

Proyecto WinServiceBasic1 en GitHub.

WinServiceBasic1_install.ps1

Utilizo el comando New-Service para instalar el servicio, el script previamente copia el ejecutable en C:\bin y borra el servicio si ya existiese previamente.

WinServiceBasic1_delete.ps1

WinServiceBasic1_start.ps1

Start-Service -Name "MyNewService"

WinServiceBasic1_stop.ps1

Stop-Service -Name "MyNewService"

WinServiceBasic1_view.ps1

Get-WmiObject win32_service -Filter "name='MyNewService'"

También he realizado modificaciones en las propiedades del objeto eventLog1 (clase EventLog para escribir logs que se visualizan en el visor de eventos de Windows), es necesario especificar la propiedad Source, normalmente se define como el nombre de la aplicación (“MyNewService” en este caso).

Ajusto algunos parámetros del objeto “MyNewService” (heredado de la clase ServiceBase) para modificar el comportamiento del servicio. La propiedad AutoLog a “False” para que la aplicación no genere eventos por su cuenta.

Además he sobrecargado el método WriteEntry para ilustrar como generar diferentes tipos de eventos (información, error,…):

Ahora los eventos del visor de eventos de Windows proporcionan más información:

Después de probar un rato con EventLog he instalado NLog para generar logs con más flexibilidad (ver “NLog: Sistema de logging gratuito y de código abierto para .Net“)

Referencias externas