El siguiente procedimiento almacenado permite listar todos los jobs de todos los servidores vinculados a una instancia que hayan fallado en las últimas horas.

Adicionalmente, existe un arreglo para construir un HTML, que sería el cuerpo de un mensaje que podría ser enviado por mail para su seguimiento.

create proc [dbo].[Jobs_Fallidos]
@pOut varchar(max) = null output,
@pDestino varchar(10) = 'Mail',
@pTODO_OK bit = 0 output,
@pFechaHoraDesde smalldatetime = null

as

--Para sólo recuperar los de las últimas x horas
select @pFechaHoraDesde = isnull(@pFechaHoraDesde, dateadd(hh, -14, getdate()))

declare @sql nvarchar(max), @parte_fija nvarchar(max)

select @sql = '', @parte_fija = N'
select ''#NombreLinkedServer#'' as Server, Job, DiaEjecucion,
HoraEjecucion, Duracion, Paso, NombrePaso, Mensaje
from OpenQuery([#NombreLinkedServer#], ''
select g.name as Job, cast(h.run_date as varchar(20)) as DiaEjecucion,
right(''''000000'''' + cast(h.run_time as varchar(20)), 6) as HoraEjecucion,
right(''''000000'''' + cast(h.run_duration as varchar(20)), 6) as Duracion,
h.step_id as Paso,
h.step_name as NombrePaso,
h.message as Mensaje
from (
select j.name,h.instance_id id
from
msdb.dbo.sysjobs j with(nolock) inner join
msdb.dbo.sysjobhistory h with(nolock) on j.job_id = h.job_id
and h.run_status=0
) g inner join msdb.dbo.sysjobhistory h with(nolock)on g.id = h.instance_id
where h.step_id > 0 and
h.run_date >= cast(CONVERT(char(8),dateadd(dd,-1,getdate()),112) as int)'') T'


if object_id ('tempdb..#fjobs') > 0
drop table #fjobs

create table #fjobs
(Server varchar(15) not null,
Job varchar(100) not null,
DiaEjecucion char(8) not null,
HoraEjecucion char(6) not null,
Duracion char(6) not null,
Paso int null,
NombrePaso varchar(100) null,
Mensaje varchar(max) null
)


select @sql = @sql + replace(@parte_fija, '#NombreLinkedServer#', name) + ' union all
'
from sys.servers where provider = 'SQLNCLI'

select @sql = left(@sql, len(@sql) - 12)

insert #fjobs
exec sp_executesql @sql

delete from #fjobs
where DiaEjecucion + ' ' +
left(HoraEjecucion,2)+':'+substring(HoraEjecucion,3,2) < @pFechaHoraDesde

--Listado de jobs que han fallado
select cast(h.Server as nvarchar(15)) Server,
cast(h.Job as nvarchar(100)) as Job,
cast(h.DiaEjecucion as nvarchar(8)) as DiaEjecucion,
cast(HoraEjecucion as nvarchar(6)) as HoraEjecucion,
cast(Duracion as nvarchar(8)) as Duracion,
cast(Paso as nvarchar(10)) as Paso,
cast(NombrePaso as nvarchar(100)) as NombrePaso,
cast(Mensaje as nvarchar(500)) as Mensaje
from #fjobs h
order by Server, Job, DiaEjecucion, HoraEjecucion, Paso


--Apartir de aquí, es un divertimento para enviar un mail con este listado
if @pDestino = 'Mail' and exists(select top 1 h.Server from #fjobs h)
begin
select @pOut = '<html>
<head>
<STYLE TYPE="text/css">
<!--
body{font-family: Segoe UI; font-size: 9pt;}
TH{font-family: Segoe UI; font-size: 9pt; color: 000099}
TD{font-family: Segoe UI; font-size: 9pt;}
--->
</STYLE>
</head>
<body><p>'+
'Jobs Fallidos en las últimas horas:</p>' +
'<table border=1 cellspacing=0 cellpadding=3>
<tr><th>Servidor</th><th>Job</th><th>Dia</th><th>Hora</th><th>Duracion</th>
<th>Step</th><th>Nombre</th><th>Mensaje</th>
</tr>'

select @pOut = @pOut + '
<tr>' +
'<td>' + h.Server + '</td>' +
'<td>' + rtrim(h.Job) + ' </td>' +
'<td>' + h.DiaEjecucion + ' </td>' +
'<td>' + left(h.HoraEjecucion,2)+':'+substring(h.HoraEjecucion,3,2) + ' </td>' +
'<td>' + left(h.Duracion,2)+':'+substring(h.Duracion,3,2)+':'+right(h.Duracion,2)+''' </td>'+
'<td>' + cast(h.Paso as varchar(10)) + ' </td>' +
'<td>' + h.NombrePaso + ' </td>' +
'<td>' + left(h.Mensaje, 200) + ' </td>' +
+ '</tr>'
from #fjobs h
order by Server, Job, DiaEjecucion, HoraEjecucion, Paso

select @pOut = @pOut + '</table>' +
'<p>No responda a este mensaje</p>' +
'<p>Sistemas de Información.<BR>
Plus Ultra Seguros.</p>' +
'</body>
</html>'

end

if not exists(select top 1 h.Server from #fjobs h)
select @pTODO_OK = 1
else
select @pTODO_OK = 0

if object_id ('tempdb..#fjobs') > 0
drop table #fjobs

set nocount off

return 0