Mostrando entradas con la etiqueta Colecciones. Mostrar todas las entradas
Mostrando entradas con la etiqueta Colecciones. Mostrar todas las entradas

jueves, 19 de abril de 2012

Colección de computadoras que no se reportan hace 30 días

El escaneo de hardware o Hardware Inventory es sin lugar a dudas una de las funciones más importantes del SCCM. En la mayoría de los casos, suele ser este inventario el que se realiza con mayor frecuencia, y el que nos marca la pauta de un cliente funcionando correctamente o no.
Existen reportes en el SCCM con los que fácilmente podremos buscar todos los equipos que no hayan enviado un inventario de hardware en los últimos días ¿pero que tal si nos interesa tener esos equipos en una colección?
De este modo podríamos tomar acciones de remediación en forma conjunta, o podemos hacerlo por el simple hecho de tener siempre a mano la lista de esos clientes problemáticos que nos veremos obligados a reparar.

Para armar una colección de este tipo no podremos utilizar el asistente de SCCM, sino que necesitaremos escribir la query en WQL dentro del cuadro de diálogo correspondiente. La consulta para esta colección quedaría así entonces:

select

SMS_R_SYSTEM.ResourceID,

SMS_R_SYSTEM.ResourceType,

SMS_R_SYSTEM.Name,

SMS_R_SYSTEM.SMSUniqueIdentifier,

SMS_R_SYSTEM.ResourceDomainORWorkgroup,

SMS_R_SYSTEM.Client

from SMS_R_System  inner join

SMS_G_System_WORKSTATION_STATUS

on SMS_G_System_WORKSTATION_STATUS.ResourceID = SMS_R_System.ResourceId

where SMS_G_System_WORKSTATION_STATUS.LastHardwareScan <=  DateAdd(dd,-30,GetDate())


Para modificar el tiempo mínimo desde el último reporte deben cambiar el valor al final de al consulta, dentro de  DateAdd(dd,-30,GetDate()). En este caso está configurado en 30 días, pero es posible asignar cualquier otro valor según sea necesario.

El resultado es una colección con clientes a los que deberemos echar una mirada.

Saludos
Franco

Colección para maquinas virtuales

Hoy una query sencillita, pero que puede resultar bastante útil. En este caso armaremos una colección dinámica poblada exclusivamente por maquinas virtuales.

La query para la colección sería esta:

select 
SMS_R_SYSTEM.ResourceID,
SMS_R_SYSTEM.ResourceType,
SMS_R_SYSTEM.Name,
SMS_R_SYSTEM.SMSUniqueIdentifier,
SMS_R_SYSTEM.ResourceDomainORWorkgroup,
SMS_R_SYSTEM.Client 
from SMS_R_System inner join 
SMS_G_System_COMPUTER_SYSTEM 
on SMS_G_System_COMPUTER_SYSTEM.ResourceId = SMS_R_System.ResourceId 
where SMS_G_System_COMPUTER_SYSTEM.Model in 
("Virtual Machine","VMware Virtual Platform")

En este caso agrupamos en la misma colección las maquinas virtuales creadas con software de Microsoft ("Virtual Machine") y aquellas que utilizan VMWare ("VMWare Virtual Platform").

Esta consulta puede armarse usando el asistente del SCCM, y no reviste mayor complejidad.



Del mismo modo, puede usarse una query similar, pero negando el operador "IN" para encontrar todas las computadoras que no son virtuales, las "físicas", por llamarlas de algún modo.

select 
SMS_R_SYSTEM.ResourceID,
SMS_R_SYSTEM.ResourceType,
SMS_R_SYSTEM.Name,
SMS_R_SYSTEM.SMSUniqueIdentifier,
SMS_R_SYSTEM.ResourceDomainORWorkgroup,
SMS_R_SYSTEM.Client 
from SMS_R_System inner join 
SMS_G_System_COMPUTER_SYSTEM 
on SMS_G_System_COMPUTER_SYSTEM.ResourceId = SMS_R_System.ResourceId 
where SMS_G_System_COMPUTER_SYSTEM.Model NOT IN 
("Virtual Machine","VMware Virtual Platform")

Como siempre que armamos colecciones dinámicas, es importante no olvidar crear un schedule para la actualización de los recursos, y en el caso de SCCM 2007 R3, tildar la opción para agregar recursos dinámicamente.

Saludos
Franco

lunes, 16 de abril de 2012

Colección con computadoras que NO tienen un software instalado

Una solicitud común, pero con cierta dificultad de resolver, es la de buscar todos los equipos que NO tengan determinado software instalado. Podemos realizar esta búsqueda a través de un reporte, de una query, o todavía mejor, de una colección dinámica.
La ventaja de usar la colección, es que una de las razones para solicitar el listado de equipos que NO tengan X software instalado, es, justamente, para instalarselo. Y el deploy debemos hacerlo sobre una colección.

La complejidad de la query en este caso reside en dos puntos. El primero es que se trata de una consulta anidada. Para quienes no están muy acostumbrados a los lenguajes de consulta (en este caso WQL), esto puede complicar un poco las cosas. El segundo inconveniente es que tenemos dos "Add/Remove Programs". El de los equipos con sistema operativo de 32 bits y el de los X64. Así que tendremos que buscar en ambas tablas y encontrar a quienes no aparezcan en ninguna de ellas.

Sin más rodeos, he aquí la query para obtener todas las computadoras que no cuenten con determinado software:

select SMS_R_SYSTEM.ResourceID,
SMS_R_SYSTEM.ResourceType,
SMS_R_SYSTEM.Name,
SMS_R_SYSTEM.SMSUniqueIdentifier,
SMS_R_SYSTEM.ResourceDomainORWorkgroup,
SMS_R_SYSTEM.Client
 from SMS_R_System inner join
 SMS_G_System_COMPUTER_SYSTEM
 on SMS_G_System_COMPUTER_SYSTEM.ResourceID = SMS_R_System.ResourceId
 where SMS_G_System_COMPUTER_SYSTEM.Name not in
 (select distinct SMS_G_System_COMPUTER_SYSTEM.Name from  SMS_R_System inner join SMS_G_System_COMPUTER_SYSTEM on SMS_G_System_COMPUTER_SYSTEM.ResourceID = SMS_R_System.ResourceId inner join SMS_G_System_ADD_REMOVE_PROGRAMS on SMS_G_System_ADD_REMOVE_PROGRAMS.ResourceID = SMS_R_System.ResourceId left join SMS_G_System_ADD_REMOVE_PROGRAMS_64 on SMS_G_System_ADD_REMOVE_PROGRAMS_64.ResourceID = SMS_R_System.ResourceId where SMS_G_System_ADD_REMOVE_PROGRAMS.DisplayName like
 "%NOMBRE DEL SOFTWARE%"
 or SMS_G_System_ADD_REMOVE_PROGRAMS_64.DisplayName like
 "%NOMBRE DEL SOFTWARE%")

Como podrán adivinar, deben reemplazar "NOMBRE DEL SOFTWARE" por el nombre del programa a buscar.

Esta query no puede armarse completamente en el diseñador de querys de SCCM, pero si les resulta más sencillo, pueden usarlo de este modo:

Tipo de criterio: Subselected values.
Donde: Computer System - Name
Operador: Is not in
Subselect: Y aquí pegan toda la subconsulta que aparece entre paréntesis en la consulta original:

select distinct SMS_G_System_COMPUTER_SYSTEM.Name from  SMS_R_System inner join SMS_G_System_COMPUTER_SYSTEM on SMS_G_System_COMPUTER_SYSTEM.ResourceID = SMS_R_System.ResourceId inner join SMS_G_System_ADD_REMOVE_PROGRAMS on SMS_G_System_ADD_REMOVE_PROGRAMS.ResourceID = SMS_R_System.ResourceId left join SMS_G_System_ADD_REMOVE_PROGRAMS_64 on SMS_G_System_ADD_REMOVE_PROGRAMS_64.ResourceID = SMS_R_System.ResourceId where SMS_G_System_ADD_REMOVE_PROGRAMS.DisplayName like
 "%NOMBRE DEL SOFTWARE%"
 or SMS_G_System_ADD_REMOVE_PROGRAMS_64.DisplayName like
 "%NOMBRE DEL SOFTWARE%"

El asistente nos dice que hay un error en la subconsulta, pero en realidad es una falla en el análisis, podemos obviar esta advertencia.

No olvidemos, que para que la coleccione funcione correctamente debemos actualizarla periódicamente y permitir el agregado dinámico de recursos:


Saludos
Franco



martes, 10 de abril de 2012

Obtener todas las actualizaciones requeridas por los equipos en una colección

Otro reporte personalizado para cubrir una necesidad personal. En este caso, necesitaba saber que actualizaciones son requeridas por todos los servidores dentro de una colección. Combinando los resultados de este reporte con datos como ventanas de mantenimiento y deployments es fácil saber que se va a instalar, cuando y dónde.

La query del reporte es la siguiente:
SELECT Name
      ,[Title]
      ,[Description]
      ,[InfoURL]
  FROM [SMS_SVR].[dbo].[v_UpdateComplianceStatus]
 , [SMS_SVR].[dbo].[v_UpdateInfo]
 , [SMS_SVR].[dbo].[v_FullCollectionMembership]
  Where Status=2
  and v_UpdateComplianceStatus.CI_ID=v_UpdateInfo.CI_ID
  and v_UpdateComplianceStatus.ResourceID=v_FullCollectionMembership.ResourceID
  and CollectionID=@ID
  order by Name

Y la query para el parámetro CollectionID es la siguiente:
begin
  if (@__filterwildcard = '')
   SELECT DISTINCT CollectionID, Name FROM v_Collection ORDER BY Name
  else
   SELECT DISTINCT CollectionID, Name FROM v_Collection
   WHERE CollectionID like @__filterwildcard
   ORDER BY Name
 end

El resultado será algo como esto:


Espero que les sirva.
Saludos.

lunes, 9 de abril de 2012

Reporte para ventanas de mantenimiento periódicas (semanales, mensuales, etc.)

En mi organización tengo colecciones con ventanas de mantenimiento mensuales. Las uso para tirar actualizaciones a todos los servidores pero de manera organizada, haciendo el deploy de los updates a distintos servidores según su criticidad, o en el caso de los clusters o NLB, asegurándome que no se reinicien todos los nodos al mismo tiempo.
Una pregunta común de compañeros, e incluso de mi mismo, es ¿y cuándo le tocan actualizaciones a X servidor? o ¿cuándo fue la última vez que se le instalaron actualizaciones a X servidor?

Para poder responder esa pregunta rápidamente me he armado un reporte que, tras pedirnos el nombre del equipo en cuestión, nos informa la última y la próxima ventana de mantenimiento que le corresponde.

Seguramente se puede hacer mejor, pero a mí me funciona así:

La query del reporte es esta:

Declare @Primero as datetime
Declare @Segundo as datetime
Declare @Tercero as datetime
Declare @Cuarto as datetime

Declare @ultPrimero as datetime
Declare @ultSegundo as datetime
Declare @ultTercero as datetime
Declare @ultCuarto as datetime

set @Primero=dateadd(dd,-1,DATEADD(wk, DATEDIFF(wk,0,dateadd(dd,7-datepart(day,getdate()),getdate())), 0))
set @Primero=(
case
 when @Primero<getdate() then
  dateadd(dd,-1,DATEADD(wk, DATEDIFF(wk,0,dateadd(dd,7-datepart(day,dateadd(mm,+1,getdate())),dateadd(mm,+1,getdate()))), 0))
 else @Primero
end)

set @Segundo=dateadd(dd,-1,DATEADD(wk, DATEDIFF(wk,0,dateadd(dd,7-datepart(day,getdate()),getdate())), 0))+7
set @Segundo=(
case
 when @Segundo<getdate() then
  dateadd(dd,-1,DATEADD(wk, DATEDIFF(wk,0,dateadd(dd,7-datepart(day,dateadd(mm,+1,getdate())),dateadd(mm,+1,getdate()))), 0))+7
 else @Segundo
end)

set @Tercero=dateadd(dd,-1,DATEADD(wk, DATEDIFF(wk,0,dateadd(dd,7-datepart(day,getdate()),getdate())), 0))+14
set @Tercero=(
case
 when @Tercero<getdate() then
 dateadd(dd,-1,DATEADD(wk, DATEDIFF(wk,0,dateadd(dd,7-datepart(day,dateadd(mm,+1,getdate())),dateadd(mm,+1,getdate()))), 0))+14
 else @Tercero
end)

set @Cuarto=dateadd(dd,-1,DATEADD(wk, DATEDIFF(wk,0,dateadd(dd,7-datepart(day,getdate()),getdate())), 0))+21
set @Cuarto=(
case
 when @Cuarto<getdate() then 
 dateadd(dd,-1,DATEADD(wk, DATEDIFF(wk,0,dateadd(dd,7-datepart(day,dateadd(mm,+1,getdate())),dateadd(mm,+1,getdate()))), 0))+21
 else @Cuarto
end)

set @ultPrimero=dateadd(dd,-1,DATEADD(wk, DATEDIFF(wk,0,dateadd(dd,7-datepart(day,getdate()),getdate())), 0))
set @ultPrimero=(
case
 when @ultPrimero>getdate() then
 dateadd(dd,-1,DATEADD(wk, DATEDIFF(wk,0,dateadd(dd,7-datepart(day,dateadd(mm,-1,getdate())),dateadd(mm,-1,getdate()))), 0))
 else @ultPrimero
end)

set @ultSegundo=dateadd(dd,-1,DATEADD(wk, DATEDIFF(wk,0,dateadd(dd,7-datepart(day,getdate()),getdate())), 0))+7
set @ultSegundo=(
case
 when @ultSegundo>getdate() then
 dateadd(dd,-1,DATEADD(wk, DATEDIFF(wk,0,dateadd(dd,7-datepart(day,dateadd(mm,-1,getdate())),dateadd(mm,-1,getdate()))), 0))+7
 else @ultSegundo
end)

set @ultTercero=dateadd(dd,-1,DATEADD(wk, DATEDIFF(wk,0,dateadd(dd,7-datepart(day,getdate()),getdate())), 0))+14
set @ultTercero=(
case
 when @ultTercero>getdate() then
 dateadd(dd,-1,DATEADD(wk, DATEDIFF(wk,0,dateadd(dd,7-datepart(day,dateadd(mm,-1,getdate())),dateadd(mm,-1,getdate()))), 0))+14
 else @ultTercero
end)

set @ultCuarto=dateadd(dd,-1,DATEADD(wk, DATEDIFF(wk,0,dateadd(dd,7-datepart(day,getdate()),getdate())), 0))+21
set @ultCuarto=(
case
 when @ultCuarto>getdate() then
 dateadd(dd,-1,DATEADD(wk, DATEDIFF(wk,0,dateadd(dd,7-datepart(day,dateadd(mm,-1,getdate())),dateadd(mm,-1,getdate()))), 0))+21
 else @ultCuarto
end)

SELECT dbo.v_R_System.Name0,
v_Collection.Name as 'Colección',
sw.Name AS [Ventana], 
 sw.Description,
  sw.Duration AS 'Duración en minutos',
  sw.IsEnabled AS 'Habilitada',
CASE substring(Description, 12,5)
         WHEN 'First' THEN @Primero
 WHEN 'Secon' THEN @Segundo
         WHEN 'Third' THEN @Tercero
         WHEN 'Fourt' THEN @Cuarto         
      END as [Próxima ejecución],
CASE substring(Description, 12,5)
         WHEN 'First' THEN @ultPrimero
 WHEN 'Secon' THEN @ultSegundo
         WHEN 'Third' THEN @ultTercero
         WHEN 'Fourt' THEN @ultCuarto         
      END as [Última ejecución] 
FROM         
 dbo.v_ServiceWindow AS sw INNER JOIN
    dbo.v_FullCollectionMembership AS fcm ON 
 sw.CollectionID = fcm.CollectionID INNER JOIN 
 v_Collection ON sw.CollectionID=v_Collection.CollectionID INNER JOIN
 dbo.v_R_System ON fcm.ResourceID = dbo.v_R_System.ResourceID 
WHERE (dbo.v_R_System.Operating_System_Name_and0 LIKE '%server%')
 and dbo.v_R_System.Name0=@servidor


La query para el prompt "@servidor" es:
begin
 if (@__filterwildcard = '')
  SELECT DISTINCT SYS.Netbios_Name0 from v_R_System SYS where SYS.Client0=1 and isnull(SYS.Obsolete0, 0) = 0 ORDER By SYS.Netbios_Name0
else
  SELECT DISTINCT SYS.Netbios_Name0 from v_R_System SYS
WHERE SYS.Netbios_Name0 like @__filterwildcard
  and SYS.Client0=1 and isnull(SYS.Obsolete0, 0) = 0
  ORDER By SYS.Netbios_Name0
end


El resultado del reporte se ve así: