José Miguel's profileLa sala de máquinasPhotosBlogListsMore Tools Help

La sala de máquinas

October 17

PowerShell: Grabar eventos en el registro de eventos

 

Creo que fue Trajano el que dijo "Lo que no está en los archivos del imperio, no ha ocurrido nunca" y es cierto, porque aunque haya podido ocurrir, a todos los efectos es como si no.

Me acuerdo muchas veces de esta frase cuando ocurren errores en cualquiera de los programas y sistemas que me toca controlar. Lees el mensaje de error, no dice nada más que lo obvio, miras los posibles registros de la aplicación y tampoco, miras el registro de eventos de Windows y nada.

Que esto nos lo hagan los demás, molesta. Si nos lo hacemos nosotros, no tiene perdón.

PowerShell es un potente lenguaje basado en objetos que nos permite acceder a casi cualquier cosa de nuestro sistema, hardware o software.
Viene de fábrica con decenas de commandlets que nos facilitan muchísimo la creación de scripts. Tiene un buen sistema de control de errores y con todo eso lo primero que haremos será crear tareas de monitorización y control que programaremos para ejecutarse automáticamente.

Hasta aquí todo bien. Hasta tenemos un commandlet que nos permite leer el registro de eventos fácilmente (Get-Eventlog).
¿Pero qué pasa si nuestro script debe dejar registros de su ejecución? Bien, siempre podemos grabarlos en un fichero de texto mediante Out-File pero eso nos obliga a tener varios ficheros, tal vez diseminados por todo el sistema de archivos, y difíciles de gestionar.

¿Si tenemos un registro de eventos, por qué no podemos escribir en él desde PowerShell? La respuesta es que sí podemos pero nadie pensó en hacer un commandlet para ello.

Veamos cómo hacerlo:

Para empezar instanciamos un objeto de la clase Eventlog

$EventLog = New-Object System.Diagnostics.EventLog

Este objeto tiene múltiples miembros pero para escribir nuestra entrada bastarán tres de ellos que explico a continuación.

Lo primero es especificar quien o qué va a grabar el evento en el registro. Normalmente es el nombre de la aplicación, subsistema o driver y debe estar asociado a uno de los registros (Aplicación, Seguridad, Sistema, etc) para poder usarse. En nuestro caso el origen de eventos será PowerShell y ya se halla asociado a su propio registro, así que especificar el origen del evento será tan fácil como asignar el valor PowerShell a la propiedad Source.

$EventLog.Source = "PowerShell"

Lo siguiente es indicar en cual de los registros se ha de grabar el evento. Tradicionalmente los registros eran Aplicación, Seguridad y Sistema pero pueden haber más creados por aplicaciones o servicios. PowerShell no es una excepción y al instalarse crea su propio registro llamado Windows PowerShell al cual se asocia como origen de eventos. Esto es importante ya que impedirá a PowerShell escribir en otro registro a no ser que lo reasociemos pero eso se escapa al alcance de este artículo.

La manera de indicar que vamos a grabar nuestro evento en el registro Windows PowerShell es usando la propiedad Log:

$EventLog.Log = "Windows PowerShell"

Finalmente grabaremos el evento usando el método WriteEntry. 

Este método admite cuatro parámetros:

  • message: indica el mensaje a incluir en el evento 
  • type: el tipo de evento a escoger de entre los cinco posibles (Error, Warning, Information, SuccessAudit y FailureAudit)
  • eventID: un número, de nuestra elección, que identifique el evento y que se halle comprendido entre 0 y 65535. Aquí nos encontramos con la duda de qué número usar ya que PowerShell usa ya algunos y no es cuestión de usarlos para no crear confusión. No he encontrado documentación sobre los que están en uso pero todos los que he visto llegan como máximo al 600, por lo que yo empleo del 65000 en adelante.
  • category: un número propio de la aplicación que identifica más concretamente el evento. En este caso también PowerShell tiene sus propias categorías que comprenden de la 0 a la 8 por lo que podemos usar a partir de la 9 a la 32767. Las categorías "oficiales" se traducen a textos descriptivos y localizados, las nuestras aparecerán como el número entre paréntesis. La categoría 0 es ninguna. 

Así pues, después de esto la instrucción para grabar nuestra entrada en el registro podría quedar así:

$EventLog.WriteEntry("La ejecución terminó correctamente", "Information", 65000, 0)

Si alguien quiere saber más sobre los miembros de la clase Eventlog, puede hacerlo desde PowerShell con:

get-member -inputobject $Eventlog | Format-List

Si lo que queremos ya es crear nuestras propias categorías, registrar PowerShell en otro registro o complicarnos la vida de mil maneras no debemos dejar de pasarnos por el siguiente enlace.

http://msdn.microsoft.com/en-us/library/system.diagnostics.eventlog.aspx

Hasta la próxima.

July 10

Propiedades de la clase User en Active Directory: I - la pestaña "General" y las propiedades identificativas

 

Active Directory no sólo se limita a almacenar cuentas de usuario y máquinas, además constituye un completo repositorio donde guardar datos de nuestra organización. No sólo cuenta con múltiples clases con decenas de propiedades cada una sino que su estructura interna (esquema) se puede extender para adaptarse a nuestras necesidades.

Sin embargo pocas veces se emplea para poco más que guardar los datos que en él graban las aplicaciones de Microsoft. No conozco encuestas al respecto pero me atrevería a decir que entre las razones figuran el desconocimiento de su esquema, su distancia del modelo relacional al que muchos estamos habituados y la falta de herramientas "amigables" para la manipulación masiva de valores.

En esta serie de  artículos intentaré documentar una de las clases más familiares al administrador; la clase User. Empezaremos por la pestaña "General" y sus propiedades identificativas.

Las utilidades de conocer estas propiedades pueden ser múltiples pero se resumen en tres

  • Rellenar datos masivamente mediante scripts para hacer de Active Directory una completa fuente de información.
  • Poder realizar copias de estos datos para su traspaso a otras bases de datos.
  • Realizar modificaciones masivas de propiedades en Active Directory.

Para ello es necesario tener nociones de algún lenguaje de scripting. Aquí emplearemos VBScript.

Si queréis información sobre VBScript podéis encontrarla en:

http://www.microsoft.com/technet/scriptcenter/guide/sas_ads_overview.mspx?mfr=true (inglés)

De momento crearemos un nuevo usuario, repasaremos sus propiedades y lo verificaremos con un pequeño script que, de paso, nos servirá como punto de partida para ir complicándolo o para ir creando otros.

¡Vamos allá!   

CREANDO UN NUEVO USUARIO

Cuando creamos un nuevo usuario, se nos solicitan valores para tan sólo unas pocas de las muchísimas propiedades que posee la clase User. Son los que llamaremos propiedades identificativas.

Las únicas obligatorias son "Nombre completo", "Nombre de inicio de sesión de usuario" y "Contraseña".  El "Nombre completo" puede rellenarse directamente o rellenarse automáticamente a partir de los valores "Nombre", "Iniciales" y "Apellidos". Igualmente la propiedad "Nombre de inicio de sesión de usuario (anterior a Windows 2000)" puede rellenarse directamente o tomar el valor de "Nombre de inicio de sesión de usuario". Hasta aquí todo va bien, pero a partir de ahora empezamos a notar cosas curiosas que llevan a confusiones.

Para empezar, vemos una columna llamada "Nombre para mostrar" de la que no sabíamos nada hasta ahora. Con todo esto, nuestro usuario tiene ya cinco propiedades llamadas "Nombre algo". Además si seleccionamos el contenedor "Users" en "Usuarios y equipos de Active Directory" veremos que el valor que nos muestra la columna "Nombre" no se corresponde con el que habíamos introducido en el campo "Nombre" al crear el usuario.  Lamentablemente y resumiendo, los nombres de las propiedades de la clase User, los de las cajas de texto que muestran sus valores y los de las columnas de "Usuarios y equipos de Active Directory" no coinciden. Para acabarlo de arreglar, los que trabajamos en castellano tenemos una traducción por el medio. Vamos a ver cómo se relacionan.

Para empezar diremos que aún hay otra propiedad "Nombre algo" que es la que identifica unívocamente al usuario. Afortunadamente Active Directory se ha encargado de generarla por nosotros y no la muestra, desafortunadamente una propiedad así es demasiado útil como para no conocerla. Hablo de la propiedad "cn", abreviatura de "common name". Más adelante, cuando conectemos con Active Directory, usaremos esta propiedad para seleccionar a nuestro usuario.

¿Pero que valor ha dado Active Directory a esta propiedad? El valor que adopta esta propiedad es el valor final de la caja de texto "Nombre completo".

PROPIEDADES DE LA CAJA DE DIALOGO "Nuevo objeto - Usuario"

image

 

INGLES CASTELLANO PROPIEDAD NOTAS
Common name Nombre común cn Propiedad oculta. Identifica unívocamente a un usuario en AD.
First name Nombre givenName

No aparece en la MMC. La columna Nombre corresponde a la propiedad name y al campo Nombre completo de la ficha de nuevo usuario

Initials Iniciales Initials  
Last name Apellidos sn  
Full name Nombre completo name  
User logon name Nombre de inicio de sesión de usuario userPrincipalName  
User logon name (pre-Windows 2000) Nombre de inicio de sesión de usuario (anterior a Windows 2000)

samAccountName

 

Si ahora echamos un ojo a la pestaña "General" veríamos que quedan varias propiedades por rellenar y de las que tampoco se nos ha dicho nada al crear el usuario. Sus correspondencias son las que muestro a continuación.

PROPIEDADES DE LA PESTAÑA "General"

image

INGLES CASTELLANO PROPIEDAD NOTAS
First name Nombre givenName

No aparece en la MMC. La columna Nombre corresponde a la propiedad name y al campo Nombre completo de la ficha de nuevo usuario

Initials Iniciales Initials  
Last name Apellidos sn  
Display name Nombre para mostrar displayName  
Description Descripción description  
Office Oficina

physicalDeliveryOfficeName

 
Telephone number Número de teléfono telephoneNumber  
E-Mail Correo electrónico mail Múltiple
Web page Página web wWWHomePage Múltiple
 
COMPROBANDO QUE ESTO ES ASI

Para verificar todo lo anterior, he creado un pequeño script que consulta esas propiedades y las muestra por pantalla. El resultado es algo parecido a esto pero sin equivocarse de ruta como yo :-):

image 

SCRIPT DE VERIFICACION

'==========================================================================
'* CONSULTORIA CERTIA S.L
'* Titulo: Muestra las propiedades de un objeto user en AD
'* Fichero: MuestraPropsGral.vbs.
'* Propósito: Este script muestra y verifica el contenido de los atributos de la pestaña "general" de un usuario de AD.
'* Uso: cscript.exe MuestraPropsGral.vbs
'* Autor: José Miguel Calzada Lisbona
'==========================================================================

'* Para referencias sobre VBScript ver:
'* http://www.microsoft.com/technet/scriptcenter/guide/sas_ads_overview.mspx?mfr=true (inglés)

Option Explicit
On Error Resume Next

'***************************
'* Definición de Constantes.
'* Podríamos usar los números, pero así quedará más claro el texto
'***************************

Const ERRORS = 1
Const WARNING = 2
Const INFORMATION = 4

'***************************
'* Declarar variables.
'* No es obligatorio pero es cuestión de disciplina
'***************************
Dim objShell
Dim objUser
Dim strValue

Set objShell = WScript.CreateObject("WScript.Shell")
'* Esto tampoco es necesario pero lo usaremos para escribir en el registro de sucesos

Set objUser = GetObject("LDAP://cn=Antonio B.. Martín,cn=Users,dc=certia,dc=net")
'* Esta línea es fundamental. Aquí conecto con el usuario "Antonio B.. Martín"
'* del contenedor Users, del dominio certia del dominio de primer nivel net.
'* El valor "Antonio B.. Martín" es el de la propiedad "Nombre completo" y se muestra
'* en la columna "Nombre" de Usuarios y equipos de Active Directory.
'* Para más información ver http://msdn.microsoft.com/en-us/library/aa772319(VS.85).aspx (inglés) 

If Err.Number <> 0 Then
    ErrorHandle
End If
'* Aquí controlamos los posibles errores

WScript.Echo "Nombre: " & objUser.givenName
WScript.Echo "Iniciales: " & objUser.initials
WScript.Echo "Apellidos: " & objUser.sn
WScript.Echo "Nombre para mostrar: " & objUser.displayName
WScript.Echo "Descripción: " & objUser.description
WScript.Echo "Oficina: " & objUser.physicalDeliveryOfficeName
WScript.Echo "Número de teléfono: " & objUser.telephoneNumber
WScript.Echo "Correo electrónico: " & objUser.mail
WScript.Echo "Página web: " & objUser.wWWHomePage
WScript.Echo "Descripción: " & objUser.description
WScript.Echo "-----------------------------------------------"
For Each strValue in objUser.otherTelephone
    WScript.Echo "Otros teléfonos: " & strValue
Next
WScript.Echo "-----------------------------------------------"
For Each strValue in objUser.url
    WScript.Echo "Otras webs: " & strValue
Next
'* Esto es lo que andábamos buscando. Sacamos por pantalla las propiedades de la pestaña "General"
'* Nótese los dos bucles para las propiedades multivalor "Otros teléfonos" y "Otras webs"

objShell.LogEvent INFORMATION, "La relación de atributos terminó con éxito."
'* Grabamos una entrada en el registro de sucesos si ha ido bien

WScript.Quit
'* Final del script

Sub ErrorHandle
    objShell.LogEvent ERRORS, Err.Number & " - " & Err.Description & "."
    '* Grabamos una entrada en el registro de sucesos si ha habido algún error.
    Err.Clear
    WScript.Quit
End Sub

February 25

Presentación

La sala de máquinas pretende ser un blog donde se hable de asuntos relacionados con los sistemas. Así, en general.

A fin de cuentas todos están relacionados entre sí y el barco sólo llega a puerto con todos ellos funcionando correctamente.

Como en un barco los sufridos maquinistas se ven sometidos a demandas y exigencias a menudo contradictorias y que habrán de saber equilibrar. El capitán, la tripulación, los propietarios de la carga, las propias máquinas y los elementos.

Y el jefe de máquinas en el medio. 

 

José Miguel Calzada Lisbona

There are no categories in use.
No list items have been added yet.
¡Gracias por tu visita!
Please wait...
Sorry, the comment you entered is too long. Please shorten it.
You didn't enter anything. Please try again.
Sorry, we can't add your comment right now. Please try again later.
To add a comment, you need permission from your parent. Ask for permission
Your parent has turned off comments.
Sorry, we can't delete your comment right now. Please try again later.
You've exceeded the maximum number of comments that can be left in one day. Please try again in 24 hours.
Your account has had the ability to leave comments disabled because our systems indicate that you may be spamming other users. If you believe that your account has been disabled in error please contact Windows Live support.
Complete the security check below to finish leaving your comment.
The characters you type in the security check must match the characters in the picture or audio.