lunes, 7 de diciembre de 2015

diresp v3 - Tamaños de directorios más rápido

Después de ver cómo funciona la creación y gestión de múltiples hilos (multithreading) en la API de Windows, decidí aplicarlo a la herramienta diresp, de forma que calcule el espacio de cada directorio actual en su propio hilo. El resultado es significativamente más rápido.

Puedes descargar la versión 3 de diresp (diresp3.exe) desde este enlace.

miércoles, 8 de abril de 2015

diresp v2 - Tamaños de directorios

Hablamos de la versión 2 de diresp.exe, la herramienta presentada en el post anterior que muestra los tamaños de los directorios que se encuentran en el directorio actual.

La versión 2 está reescrita completamente en C y en su ejecución incorpora un texto de estado mostrando los directorios detectados e informando por cual va.

Otra de las novedades es la ordenación del listado de directorios por tamaños de menor a mayor, así podemos ver antes el directorio más nutrido.

La herramienta es bastante útil en unidades NTFS cortas de espacio, para detectar rápidamente dónde se concentran los archivos más pesados y eliminarlos o moverlos para liberar espacio, o simplemente averiguar qué directorios son los más pesados.

Actualmente solo está disponible la versión 3 clicando aquí.

lunes, 20 de octubre de 2014

diresp - Tamaños de directorios

Una de las situaciones más comunes en el ámbito de los sistemas operativos donde es necesaria una intervención rápida es la falta de espacio en disco. En estos casos, los administradores de sistemas tenemos que averiguar cómo está distribuido el espacio en disco y determinar qué archivos se pueden eliminar o mover.

La forma más rápida de diagnosticar estas situaciones es averiguar el tamaño de los directorios que cuelgan de un directorio dado. De esta forma podemos comprobar si los tamaños de estos directorios son razonables o no.

Para facilitar la tarea y conseguir esta información lo antes posible, he creado la herramienta diresp.exe. La versión actualmente disponible es la 3 y puedes descargarla en éste enlace.

Para mayor comodidad, conviene copiar esta herramienta en un directorio con Path, como C:\Windows\System32, después abrir la línea de comandos cmd, ubicarse en el directorio padre donde queremos comprobar los tamaños de sus directorios y ejecutar diresp3.exe.

Es posible que tarde un poco en listar los resultados dependiendo del número de subdirectorios y archivos, pero éstos aparecen ordenados por tamaño indicando el nombre del directorio hijo correspondiente. Una vez ubicado el directorio con tamaño sospechoso, podemos acceder a él y ejecutar de nuevo la herramienta (esta vez te aseguro que irá más rápido) hasta confirmar el directorio problemático.

lunes, 16 de junio de 2014

Consultas a SQLServer desde Powershell

Si necesitas lanzar una consulta a una base de datos de SQLServer y que además permita cambiarla rápidamente, puedes utilizar Powershell y la clase System.Data.SqlClient.SqlConnection de .NET de la siguiente manera:

$consulta = "SELECT Name FROM sys.databases"
$srv = "nombreServidor"
$db = "master"

$conex = New-Object System.Data.SqlClient.SqlConnection
$conex.ConnectionString = "Server=$srv;Database=$db;Integrated Security=True"
$conex.Open()
$adaptadorSQL = New-Object System.Data.SqlClient.SqlDataAdapter
$resultado = New-Object System.Data.DataTable
$cmdSQL = New-Object System.Data.SqlClient.SqlCommand
$cmdSQL.CommandText = $consulta
$cmdSQL.Connection = $conex
$adaptadorSQL.SelectCommand = $cmdSQL
$contador = $adaptadorSQL.Fill($resultado)

$resultado

  • La variable $consulta contiene la cadena con la consulta que queramos realizar.
  • La variable $srv indica el nombre del servidor SQLServer en cuestión donde se realizará la consulta.
  • La variable $db es el nombre de la base de datos a consultar en el servidor indicado.
  • La variable $resultado contiene el resultado de la consulta en formato DataTable.

El resultado de esta consulta lista todas las bases de datos del servidor indicado.

Si la base de datos en cuestión está contenida en una instancia nombrada, la variable $servidor debe incluir el nombre de la instancia de la siguiente manera: nombreServidor\nombreInstancia.

Este tipo de scripts es especialmente útil para incluirlos en alguna tarea programada y recibir información con un intervalo determinado.

sábado, 1 de marzo de 2014

miniServidor Web en Windows

Mirando un poco cómo hacer una pequeña aplicación en lenguaje C para probar Sockets y comunicar programas a través de TCP/IP, encontré que el compilador LCC-Win trae una biblioteca llamada netutils.h dejando el asunto fácil y muy interesante.

Adaptando un poco el ejemplo de la aplicación servidor que trae la documentación, decidí dar un repaso al protocolo HTTP y crear un pequeño servidor Web.

El funcionamiento de este miniServidor Web sería muy sencillo y no cumpliría mucho con el estándar, pero para ver cómo funciona por dentro está bien. Lo que hace es lo siguiente:

  • Leer un archivo HTML dado como parámetro.
  • Iniciar una sesión de conexión a un Socket en la IP 127.0.01 en el puerto 10000.
  • Esperar una conexión de un navegador web.
  • Cuando reciba una conexión, visualiza la información recibida (las cabeceras HTTP del navegador).
  • Preparar las cabeceras HTTP de respuesta.
  • Leer el archivo HTML dado y agregarlo a las cabeceras anteriores.
  • Enviar la respuesta al navegador (cabeceras HTTP y el HTML).
  • Visualizar los datos enviados.

El código fuente sería el siguiente (servidor.c):

#include <stdio .h>
#include "netutils.h"

int main(int argc,char *argv[])
{
  while (1)
  {
    FILE* pf;
    if ((pf = fopen(argv[1],"rt")) == NULL)
    {
      puts("Error abriendo html.");
      return 1;
    }
    
    Session session; 
    char buf[8192];
    memset(&session,0,sizeof(session));
    session.port = 10000;
    session.Host = "127.0.0.1";
    
    if (ServerConnect(&session)){ return 0; }

    printf("Conectado...\n");
    memset(buf,0,sizeof(buf));
    
    if (Receive(&session,sizeof(buf)-1,buf)){ return 0; }
    
    printf("Datos recibidos:\n\n %s\n",buf);

    char texto[1000000] = "HTTP/1.1 200 OK\nContent-Type: text/html\n\n";

    int c, i = strlen(texto);

    while ( (c=getc(pf) ) != EOF){ texto[i] = c; i++; }
    texto[i] = '\0';

    fclose(pf);    
    
    if (Send(&session,strlen(texto),texto)){ return 0; }

    printf("Datos enviados:\n\n %s\n", texto);

    CloseSession(&session);

    printf("\nConexion cerrada.\n");
  }
}

Una vez creado servidor.c, en la misma carpeta creamos el archivo HTML que queremos publicar en nuestro miniServidorWeb (holamundo.html), cuyo código sería el siguiente:

<html>
<head>
  <title>Titulo>/title>
</head>
<body>
  <p><h1>Hola Mundo</h1></p>
</body>
</html>

Asumiendo que  LCC-Win está instalado en c:\lcc y que tenemos la ruta de los binarios del compilador (c:\lcc\bin) incluida en la variable PATH del sistema, ya podemos compilar y enlazar:

    lcc servidor.c
    lcclnk servidor.obj c:\lcc\lib\netutils.lib

Con esto tendremos el ejecutable servidor.exe creado, que es nuestro miniServidor Web. Lo ejecutamos dándole como parámetro el nombre del archivo HTML a publicar:

    servidor.exe holamundo.html

Y el miniServidor Web quedará a la escucha en el puerto 10000 de la IP 127.0.0.1, datos proporcionados en el código fuente. Ahora le toca al cliente, vamos al navegador Web y tecleamos la URL:

    http://127.0.0.1:10000

Con esto el navegador Web conecta con la IP indicada en el puerto 10000 y recupera nuestro HTML.

Mientras, en la ventana donde ejecutamos el miniServidor Web aparecerán los datos recibidos y los enviados en cada sesión HTTP.

Y ahí lo tienes, el servidor Web más pequeño del mundo.

sábado, 26 de octubre de 2013

Debian | Capacidad de discos y actualizaciones pendientes


Dos de las tareas más importantes para mantener un servidor disponible y seguro son:

  • Comprobar la capacidad de las particiones de los discos duros.
  • Comprobar si existen actualizaciones pendientes de las aplicaciones en servicio.

En el caso de un SO GNU/Linux como Debian, podemos utilizar la salida de los comandos df y apt-get, procesarlos con un script de Perl y enviar el resultado por email con formato HTML.

Para que Perl pueda enviar emails, utilizaremos el módulo MIME::Lite de CPAN. Para instalar este módulo podemos seguir estos pasos:

  • Instalar las librerías básicas de compilación y enlazado: apt-get install build-essential
  • Entrar en CPAN: cpan
  • Instalar el módulo: install MIME::Lite
  • Salir de CPAN: exit

Instalado el módulo, Perl podrá enviar emails.

Ahora el script en Perl. Lo puedes descargar clicando en éste enlace.

Las variables que tienes que personalizar en el script son:

  • $servidor: nombre corto que identifique al servidor en cuestión.
  • $from: dirección de email de origen (puedes inventarte una, aunque no exista).
  • $smtpserver: la ip del servidor de correo (SMTP) a enviar el mensaje (el que gestione el dominio de la direccion de email de entrega).
  • $to: dirección de email de entrega del mensaje (este email debe ser el real para recibir los informes).

Una vez personalizado, puedes crear una tarea programada con CRON para que ejecute el script con la frecuencia adecuada (por ejemplo, una vez al día) y esperar que te lleguen los informes por email en un bonito formato HTML.

viernes, 19 de abril de 2013

Citrix: información de sesiones

En un entorno Citrix a veces es necesario conocer rápidamente las sesiones de usuario iniciadas en un servidor concreto, como por ejemplo, para diagnosticar alguna incidencia con alguna aplicación.

Para no perder tiempo en acceder a la consola de administración y averiguar esta información, he preparado un script con PowerShell que, indicando el nombre de un servidor Citrix en la variable $nombre_host y ejecutándolo en cualquier otro host con los permisos suficientes muestra la información de las sesiones de Citrix activas:

# información de sesiones citrix


# nombre del servidor de Citrix
$nombre_host = hostname


# fecha/hora/minuto/segundo de la toma
$t = get-date
$anio = $t.year
$mes = $t.month
$dia = $t.day
$hora = $t.hour
$minuto = $t.minute
$segundo = $t.second

$tiempo = "$anio $mes $dia $hora $minuto $segundo"

# captura sesiones actuales del servidor de Citrix indicado
$sesiones = qwinsta /SERVER:$nombre_host

# elimina primera línea
$sesiones = $sesiones[1..$sesiones.length]

# inicia variables
$usuario = ""
$sesionid = 0
$total_cpu = 0
$mem = 0

foreach ( $sesion in $sesiones )
{
  # si se trata de una sesión de citrix
  if ( $sesion -match "wdica" )
  {
    $sesion = $sesion -replace “\s+”,” ”
    $t = $sesion.split(" ")

    # captura usuario e id de sesión
    $usuario = $t[2]
    $sesionid = $t[3]

    # inicia total_cpu y mem para esta sesión/usuario
    $total_cpu = 0
    $mem = 0

    # captura la memoria y el total de cpu de los procesos
    # de cada sesión/usuario de citrix
    $procesos = get-process | where {$_.sessionid -eq $sesionid}
    foreach ( $proceso in $procesos )
    {
      $total_cpu += $proceso.cpu
      $mem += $proceso.ws
    }
    $mem = [int]($mem / 1mb)
    write-host $tiempo $nombre_host $usuario $total_cpu $mem
  }
}