viernes, 13 de abril de 2012

Comparar actualizaciones entre dos servidores

En forma predeterminada, el SCCM 2007 trae un reporte, el 97, que compara el inventario de software de dos computadoras. Esto puede ser muy útil en algunos casos, pero no lo es si lo que nos interesa saber es que actualizaciones fueron instaladas en un equipo y en otro no.
La idea de este reporte es, justamente, comparar las actualizaciones en dos computadoras, y devolvernos aquellas que están instaladas en uno de esos equipos y en el otro no.

Es una consulta compleja, pero que puede entenderse con un poco de análisis, y que fácilmente puede modificarse para cualquier otra comparación de inventario que les interese.

La query del reporte es la siguiente:

select
(case when inv1.Description0 is not null then @pc1 else @pc2 end) as Servidor,
  (case when inv1.Description0 is not null then inv1.User_Domain0 else inv2.User_Domain0 end) as Dominio,
  (case when inv1.Description0 is not null then inv1.User_Name0 else inv2.User_Name0 end) as Usuario,
  (case when inv1.Description0 is not null then inv1.Operating_System_Name_and0 else inv2.Operating_System_Name_and0 end) as SO,
  (case when inv1.Description0 is not null then inv1.InstalledOn else inv2.InstalledOn end) as Fecha,
  (case when inv1.Description0 is not null then inv1.InstalledBy0 else inv2.InstalledBy0 end) as [Instalado por],
  (case when inv1.Description0 is not null then inv1.ServicePackInEffect0 else inv2.ServicePackInEffect0 end) as [Service Pack],
  (case when inv1.Description0 is not null then inv1.Caption0 else inv2.Caption0 end) as Identificador,
  (case when inv1.Description0 is not null then inv1.Description0 else inv2.Description0 end) as Descripción
  from
(
Select distinct sys.Netbios_Name0, sys.User_Domain0, sys.User_Name0, sys.Operating_System_Name_and0,
dbo.ConvertirFecha(qfe.InstalledOn0) as InstalledOn,
qfe.InstalledBy0, qfe.ServicePackInEffect0, qfe.Caption0, qfe.Description0
FROM v_R_System sys
JOIN v_GS_QUICK_FIX_ENGINEERING qfe on sys.ResourceID=qfe.ResourceID
WHERE sys.Netbios_Name0=@pc1
union
Select distinct sys.Netbios_Name0,
 sys.User_Domain0,
 sys.User_Name0,
 sys.Operating_System_Name_and0,
dbo.ConvertirFecha(PSE.AgentInstallDate) as InstalledOn,
'NA' as InstalledBy0,
 'NA' as ServicePackInEffect0,
 PSE.ID as Caption0,
 PSE.Title as Description0
FROM v_R_System sys
JOIN v_GS_PatchStatusEx PSE on sys.ResourceID=PSE.ResourceID
WHERE sys.Netbios_Name0=@pc1
) as inv1
full outer join
(
Select distinct sys.Netbios_Name0, sys.User_Domain0, sys.User_Name0, sys.Operating_System_Name_and0,
dbo.ConvertirFecha(qfe.InstalledOn0) as InstalledOn,
qfe.InstalledBy0, qfe.ServicePackInEffect0, qfe.Caption0, qfe.Description0
FROM v_R_System sys
JOIN v_GS_QUICK_FIX_ENGINEERING qfe on sys.ResourceID=qfe.ResourceID
WHERE sys.Netbios_Name0=@pc2
union
Select distinct sys.Netbios_Name0,
 sys.User_Domain0,
 sys.User_Name0,
 sys.Operating_System_Name_and0,
dbo.ConvertirFecha(PSE.AgentInstallDate) as InstalledOn,
'NA' as InstalledBy0,
 'NA' as ServicePackInEffect0,
 PSE.ID as Caption0,
 PSE.Title as Description0
FROM v_R_System sys
JOIN v_GS_PatchStatusEx PSE on sys.ResourceID=PSE.ResourceID
WHERE sys.Netbios_Name0=@pc2
) as inv2
on inv1.Description0=inv2.Description0
where (inv1.Description0 is NULL) or (inv2.Description0 is NULL)
order by Servidor


Como pueden ver, es bastante extensa, pero no hay que asustarse. Es un gigantesco JOIN de dos "Select" que ya habíamos usado antes. El join es un full outer, es decir compara y obtiene solo los registros que no están en ninguna de las dos subconsultas. Además, utilizando un CASE para cada columna, mostramos solo los valores del equipo que tiene datos, en este caso, el equipo que tiene instalado el update que no se encuentra en el otro equipo.

Los parámetros de la consulta son el nombres de las PCs a comparar (@pc1 y @pc2). Para ambos podemos utilizar esta query:

begin

 if (@__filterwildcard = '')
  SELECT DISTINCT SYS.Netbios_Name0 from v_R_System SYS WHERE SYS.Client0=1 ORDER By SYS.Netbios_Name0
 else
  SELECT DISTINCT SYS.Netbios_Name0 from v_R_System SYS WHERE SYS.Client0=1
  and SYS.Netbios_Name0 like @__filterwildcard
  ORDER By SYS.Netbios_Name0
end

En las subconsultas para obtener las actualizaciones instaladas en cualquier servidor utilice una vez más la función ConvertirFecha, cuya query de creación ya dí en el post anterior.

El resultado del reporte debería verse más o menos así:



Espero que les sirva.
Saludos
Franco

No hay comentarios:

Publicar un comentario