viernes, 8 de octubre de 2010

Gráfico evolutivo del espacio en unidades en disco (I)


En los siguientes artículos voy a tratar cómo crear un sencillo sistema que permita almacenar en una BB.DD. la evolución del espacio en disco en los distintos servidores existentes en nuestra red. La idea es hacer uso de powershell y SQL Server para crearnos este sistema. Aprovecharemos Reporting Services de SQL Server para mostrar gráficamente los resultados obtenidos.
En primer lugar necesitaremos un servidor de BB.DD. con un SQL Server instalado, preferiblemente con una versión 2005 o superior (aunque también es posible instalar Reporting Services en SQL Server 2000). Crearemos en una base de datos, que en mi caso he denominado ServerFreeSpace. Vamos a crear 4 tablas y un procedimiento almacenado:

El procedimiento almacenado, RegSpaceImport, nos servirá para coger un fichero de texto plano (un .txt) que va a contener un conjunto de líneas que recogen, cada una de ellas:
  • el nombre del servidor,
  • la unidad de disco,
  • el espacio total de la unidad de disco,
  • el espacio usado de esa unidad y
  • el espacio libre.
Este fichero txt es el resultado de un script en powershell que veremos más adelante.
El código de este procedimiento almacenado es el siguiente:
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go

ALTER PROCEDURE [dbo].[sp_RegSpaceImport]
@PathFileName varchar(100),
@FechaHoy datetime

AS

--Paso 1: Construir una clausula BULK INSERT valida
DECLARE @SQL varchar(2000)

-- Formato valido (ejemplo): NombreServidor,C:,33.91,6.59,27.32
SET @SQL = "BULK INSERT TmpRegSpace FROM '"+@PathFileName+"' WITH (FIELDTERMINATOR = ',') "

--Paso 2: Ejecutar la clausula BULK INSERT
EXEC (@SQL)

--Paso 3: INSERT datos al final de la tabla REGSPACE
INSERT RegSpace (NServ,NUnidad,TotalEspacio,EspacioUsado,EspacioLibre,FechReg)
SELECT NServ,NUnidad,TotalEspacio,EspacioUsado,EspacioLibre,@FechaHoy
FROM TmpRegSpace

--Paso 4: Vaciar la tabla temporal
TRUNCATE TABLE TmpRegSpace

Este procedimiento almacenado deberemos utilizarlo en un trabajo del Agente de SQL Server, para que sea ejecutado a diario:

Lo que haremos en este trabajo es lanzar el procedimiento almacenado descrito, la ruta en la que queremos que se almacene el fichero .txt resultante y la fecha de ejecución:





Por otra parte, las cuatro tablas que deberemos crear en nuestra BB.DD. son las siguientes:
  • Tabla RegSpace: es la tabla principal en la que se almacenaran los datos obtenidos junto a la fecha.
  • Tabla TDiscosServ: tabla en la que se almacena las unidades de disco que tiene cada servidor. La emplearemos en un dropdownlist del Reporting Services.
  • Tabla TmpRegSpace: se trata de una tabla intermedia que utilizará el procedimiento almacenado para insertar los datos obtenidos del fichero txt. Si nos fijamos en el procedimiento almacenado, primero hacemos una inserción masiva (BULK INSERT, paso 2) en TmpRegSpace, y posteriormente utilizamos estos datos para insertar en la tabla RegSpace (paso 3) añadiendo la fecha.
  • Tabla TServidores: tabla que almacena los distintos servidores existentes. La emplearemos para llenar un dropdownlist del Reporting Services. 
Una vez que hemos visto la BB.DD. que vamos a emplear, pasamos a ver el script en powershell. Este script será ejecutado a través de una tarea programada en una máquina donde tengamos instalado Powershell (sólo en W2008 R2 ya viene incluido). Si no lo tenemos instalado, podemos obtenerlo desde aquí . Yo he empleado la versión 1.0 que era la que tenía instalada en un W2003.


La tarea programada lanzará a diario este script en powershell, de la siguiente forma:
C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe C:\InformeEspacioDisco\ReportBBDDEspacio.ps1
Indicando la ruta donde se encuentra instalado Powershell, así como la ruta de nuestro script (en mi caso lo he denominado ReportBBDDEspacio.ps1). El script debe ejecutarse antes que el procedimiento almacenado RegSpaceImport de SQL Server.
El script deberá ejecutarse desde una máquina que tenga acceso a los diferentes servidores que queremos analizar y empleará dos ficheros de texto plano (.txt). Uno de salida (fichero de resultados), que en mi caso he ubicado en una carpeta compartida en el fichero de BBDD, y otro fichero que contiene los nombres de los servidores cuyas unidades de disco queremos analizar.
Una primera opción es no especificar un usuario con privilegios en el código del script (por lo que se empleará el usuario indicado en la tarea programada):
#Fichero de resultados
$freeSpaceFileName = file://nombre_servidor_bbdd/InformeEspacioDisco/EspacioLibre.txt

#Fichero con los servidores analizados (un servidor por linea)
$serverlist = "C:\InformeEspacioDisco\ListaServidores.txt"

New-Item -ItemType file $freeSpaceFileName -Force

Function writeDiskInfo
{
param( $fileName,$servidor,$devId,$frSpace,$totSpace)
$totSpace=[math]::Round(($totSpace/1073741824),2)

if ($totSpace -eq 0)
{
    $totSpace = 1
}

$frSpace=[Math]::Round(($frSpace/1073741824),2)
$usedSpace = $totSpace - $frspace
$usedSpace=[Math]::Round($usedSpace,2)

$linea = $servidor+","+$devid+","+$totSpace+","+$usedSpace+","+$frSpace

Add-Content $fileName $linea

}

foreach ($server in Get-Content $serverlist)
{

$dp = Get-WmiObject win32_logicaldisk -ComputerName $server | Where-Object {$_.drivetype -eq 3}
foreach ($item in $dp)
{
Write-Host $server $item.DeviceID $item.FreeSpace $item.Size
writeDiskInfo $freeSpaceFileName $server $item.DeviceID $item.FreeSpace $item.Size

}
}




Pero también podemos indicar el usuario en el propio código, encriptando el password previamente y almacenándolo en un fichero de texto (Credencial.txt). Esto nos puede ser de utilidad si tenemos varios dominios y no existen relaciones de confianza entre ellos.
#Fichero de resultados
$freeSpaceFileName = file://nombre_servidor_bbdd/InformeEspacioDisco/EspacioLibre.txt

#Fichero con los servidores analizados (un servidor por linea)
$serverlist = "C:\InformeEspacioDisco\ListaServidores.txt"

New-Item -ItemType file $freeSpaceFileName -Force

Function writeDiskInfo
{
param( $fileName,$servidor,$devId,$frSpace,$totSpace)
$totSpace=[math]::Round(($totSpace/1073741824),2)

if ($totSpace -eq 0)
{
    $totSpace = 1
}

$frSpace=[Math]::Round(($frSpace/1073741824),2)
$usedSpace = $totSpace - $frspace
$usedSpace=[Math]::Round($usedSpace,2)

$linea = $servidor+","+$devid+","+$totSpace+","+$usedSpace+","+$frSpace

Add-Content $fileName $linea

}

foreach ($server in Get-Content $serverlist)
{

$pw = Get-Content C:\InformeEspacioDisco\Credencial.txt | ConvertTo-SecureString
$cred = New-Object System.Management.Automation.PsCredential("Dominio\usuario", $pw)

$dp = Get-WmiObject win32_logicaldisk -ComputerName $server -Credential $cred | Where-Object {$_.drivetype -eq 3}
foreach ($item in $dp)
{
Write-Host $server $item.DeviceID $item.FreeSpace $item.Size
writeDiskInfo $freeSpaceFileName $server $item.DeviceID $item.FreeSpace $item.Size
}
}



Con estos pasos ya hemos completado el primer paso del proyecto, la obtención de los datos y su almacenado en una BB.DD. En el próximo artículo veremos cómo mostrar esta información haciendo uso de Reporting Services.

No hay comentarios:

Publicar un comentario