CREATE PROCEDURE [dbo].[spSRMCountComputersNeedingUpdates] AS /* Created by: Steven Manross Created: 9/14/2005 Modified: 12/12/2005 Version: v1.01 Description: SQL Query to determine if computers currently show as needing updates. This script is used in conjunction with the WSUSReport.vbs (or WSUSReport.pl) scripts to automatically notify an admin via email that there are computers needing Windows Security-related updates. Some code was taken verbatim from a SQL Profiler trace of the database (and left as-is -- this includes the Index hints) while certain actions were being performed in WSUS. Notes on version requirements: This works on WSUS 2.0, and 2.0 SP1. I have not tested this code using WSUS 3.0 and have no knowledge whether or not it will work. Notes on usage for MSDE instances.. You need to run "sp_configure" to "Allow Updates" in the SUSDB as it is by default restricted from allowing user changes. Please consult Microsoft Support websites on the correct syntax for this procedure. Steven Manross takes no responsibility for mistakes made using sp_configure (although, it would be very unlikely that you messed something up if you followed MS support docs to "Allow Updates" in this database). P.S. Generally you will find this documentation trying to allow updates on the MASTER database. The same procedure applies for the SUSDB while substituting SUSDB for master. Modification notes: v1.01 -- 12/12/2005 Modified the base inner query to look for the TargetGroup named "All Computers" instead of a static guid since the GUID is not the same on ALL WSUS installations. v1.0 -- 9/14/2005 Looks good so far. declare @computersNeedingUpdates int declare @updatesNeededByComputers int SELECT @computersNeedingUpdates = COUNT(DISTINCT(C.TargetID)), @updatesNeededByComputers = COUNT(DISTINCT(U.LocalUpdateID)) FROM tbUpdate AS U INNER JOIN dbo.tbUpdateStatusPerComputer AS S WITH (INDEX (nc3UpdateStatusPerComputer)) ON U.UpdateID=S.UpdateID INNER JOIN dbo.tbComputerTarget AS C ON C.TargetID = S.TargetID WHERE S.SummarizationState IN (2,3,6) AND EXISTS (SELECT * FROM dbo.tbDeployment AS D INNER JOIN dbo.tbRevision AS Re ON Re.RevisionID=D.RevisionID INNER JOIN dbo.tbTargetGroup AS tg ON tg.TargetGroupID = D.TargetGroupID WHERE Re.LocalUpdateID=U.LocalUpdateID AND D.ActionID IN (0,2) AND tg.Name <> 'All Computers' ) */ select @computersNeedingUpdates as computersNeedingUpdates,@updatesNeededByComputers as updatesNeededByComputers IF @computersNeedingUpdates > 0 BEGIN SELECT U.LocalUpdateID, C.FullDomainName as FullDomainName FROM tbUpdate AS U INNER JOIN dbo.tbPreComputedLocalizedProperty AS PCLP ON PCLP.UpdateID=U.UpdateID INNER JOIN dbo.tbLanguage as L on L.ShortLanguage = PCLP.ShortLanguage INNER JOIN dbo.tbLanguageInSubscription as LIS on LIS.LanguageID = L.LanguageID INNER JOIN dbo.tbUpdateType AS UT ON UT.UpdateTypeID=U.UpdateTypeID INNER JOIN dbo.tbUpdateStatusPerComputer AS S ON U.UpdateID=S.UpdateID INNER JOIN dbo.tbComputerTarget AS C ON C.TargetID = S.TargetID INNER JOIN dbo.tbTargetInTargetGroup AS TITG ON TITG.TargetID = C.TargetID INNER JOIN dbo.tbTargetGroup AS TG ON TG.TargetGroupID = TITG.TargetGroupID INNER JOIN dbo.tbRevision AS Re ON Re.LocalUpdateID = U.LocalUpdateID LEFT JOIN dbo.tbKBArticleForRevision AS KB ON KB.RevisionID = RE.RevisionID LEFT JOIN dbo.tbSecurityBulletinForRevision AS SB ON SB.RevisionID = RE.RevisionID INNER JOIN dbo.tbMoreInfoURLForRevision AS MI ON MI.RevisionID = RE.RevisionID and MI.ShortLanguage = L.ShortLanguage WHERE S.SummarizationState IN (2,3,6) AND EXISTS (SELECT * FROM dbo.tbDeployment AS D INNER JOIN dbo.tbRevision AS Re ON Re.RevisionID=D.RevisionID INNER JOIN dbo.tbTargetGroup AS tg ON tg.TargetGroupID = D.TargetGroupID WHERE Re.LocalUpdateID=U.LocalUpdateID AND D.ActionID IN (0,2) AND tg.Name <> 'All Computers' ) SELECT U.LocalUpdateID, UT.Name as UpdateTypeName, KB.KBArticleID, case when SB.SecurityBulletinID IS NULL Then 'None' Else convert(varchar(15),SB.SecurityBulletinID) End as SecurityBulletinID, MI.MoreInfoURL as MoreInfoURL, PCLP.Title as UpdateTitle, PCLP.Description as UpdateDescription FROM tbUpdate AS U INNER JOIN dbo.tbPreComputedLocalizedProperty AS PCLP ON PCLP.UpdateID=U.UpdateID INNER JOIN dbo.tbLanguage as L on L.ShortLanguage = PCLP.ShortLanguage INNER JOIN dbo.tbLanguageInSubscription as LIS on LIS.LanguageID = L.LanguageID INNER JOIN dbo.tbUpdateType AS UT ON UT.UpdateTypeID=U.UpdateTypeID INNER JOIN dbo.tbUpdateStatusPerComputer AS S ON U.UpdateID=S.UpdateID INNER JOIN dbo.tbComputerTarget AS C ON C.TargetID = S.TargetID INNER JOIN dbo.tbTargetInTargetGroup AS TITG ON TITG.TargetID = C.TargetID INNER JOIN dbo.tbTargetGroup AS TG ON TG.TargetGroupID = TITG.TargetGroupID INNER JOIN dbo.tbRevision AS Re ON Re.LocalUpdateID = U.LocalUpdateID LEFT JOIN dbo.tbKBArticleForRevision AS KB ON KB.RevisionID = RE.RevisionID LEFT JOIN dbo.tbSecurityBulletinForRevision AS SB ON SB.RevisionID = RE.RevisionID INNER JOIN dbo.tbMoreInfoURLForRevision AS MI ON MI.RevisionID = RE.RevisionID and MI.ShortLanguage = L.ShortLanguage WHERE S.SummarizationState IN (2,3,6) AND EXISTS (SELECT * FROM dbo.tbDeployment AS D INNER JOIN dbo.tbRevision AS Re ON Re.RevisionID=D.RevisionID INNER JOIN dbo.tbTargetGroup AS tg ON tg.TargetGroupID = D.TargetGroupID WHERE Re.LocalUpdateID=U.LocalUpdateID AND D.ActionID IN (0,2) AND tg.Name <> 'All Computers' ) GROUP BY U.LocalUpdateID,UT.Name,KB.KBArticleID,SB.SecurityBulletinID,MI.MoreInfoURL,PCLP.Title,PCLP.Description END --ENDIF RETURN 1 GO