Microsoft KB Archive/887404

= How to use Systems Management Server 2003 to deploy the ValidatePath module =

Article ID: 887404

Article Last Modified on 2/23/2007

-

APPLIES TO


 * Microsoft ASP.NET 1.1
 * Microsoft Systems Management Server 2003

-



SUMMARY
''The ValidatePath Module (VPModule.msi) installs an HTTP module that is named Microsoft.Web.ValidatePathModule.dll on target computers. The installation also updates the Machine.config files on all installed versions of the .NET Framework with a new HTTP module entry. For additional information about the VPModule.msi file, click the following article number to view the article in the Microsoft Knowledge Base:''

887289 HTTP module to check for canonicalization issues with ASP.NET



INTRODUCTION
The Microsoft Baseline Security Analyzer (MBSA) cannot detect whether individual systems require the installation of the VPModule.msi file. Therefore, you cannot use the software update management feature of Microsoft Systems Management Server (SMS) 2003 for compliance assessment. Instead, we recommend that customers who are deploying SMS 2003 use standard software distribution for the deployment of the VPModule.msi file.

The VPModule.msi installation detection script has the following modes of operation:
 * Scan only
 * Scan and install

Scan only
In scan only mode, the detection script will execute and assess whether a particular system requires the module. Status return codes are generated that will be used by SMS and that can be used in compliance reports.

Note A set of sample reports is included in the &quot;More Information&quot; section. The content for the Managed Object Format (MOF) files that are required to generate these reports is also included.

The detection script can be deployed to any SMS Advanced Client computer. If the detection script is executed on a client computer that does not require the VPModule.msi file, the script will exit gracefully.

Scan and install
In scan and install mode, the detection script identifies system compliance. If a system does not have the VPModule.msi file, the script starts the execution of an MSI file to install the VPModule.msi file. Status messages are returned by the MSI file that SMS will use. These messages can be used to generate reports that show deployment progress across the enterprise.

Note After you successfully execute a MSI package, a 'Microsoft ASP.NET ValidatePath Module' entry appears in Add and Remove Programs in Control Panel. You do not have to restart a system to execute a MSI package.



Phase 1: Preparation
The compliance detection and installation solution is made up of a VPModuleScanner.js detection script and a VPModule.msi file. You must create an SMS package that contains both files. To help you create the SMS package and program objects for this detection script and http module, this section includes the contents of a Package Definition File (PDF).

The following text should be copied and pasted in a Notepad file and saved with an .SMS extension. For example, use Aspnet.sms. [PDF] Version=2.0 [Package Definition] Publisher=Microsoft Name=ASP .NET Scan and Install Package Version=1.0 Language=ALL Programs=Scan,Install,UnInstall

[Scan] Name=ASP .NET Scan CommandLine=wscript //B vpmodulescanner.JS -o %TEMP%\aspnet.log UserInputRequired=False EstimatedRunTime=5 AdminRightsRequired=True CanRunWhen=AnyUserStatus SupportedClients=Win NT (I386) Win NT (I386) MinVersion1=5.00.0000.0 Win NT (I386) MaxVersion1=5.00.9999.9999 Win NT (I386) MinVersion2=5.10.0000.0 Win NT (I386) MaxVersion2=5.10.9999.9999 Win NT (I386) MinVersion3=5.20.0000.0 Win NT (I386) MaxVersion3=5.20.9999.9999

[Install] Name=ASP .NET Install CommandLine=wscript //B vpmodulescanner.JS -o %TEMP%\aspnet.log -install UserInputRequired=False EstimatedRunTime=5 AdminRightsRequired=True CanRunWhen=AnyUserStatus SupportedClients=Win NT (I386) Win NT (I386) MinVersion1=5.00.0000.0 Win NT (I386) MaxVersion1=5.00.9999.9999 Win NT (I386) MinVersion2=5.10.0000.0 Win NT (I386) MaxVersion2=5.10.9999.9999 Win NT (I386) MinVersion3=5.20.0000.0 Win NT (I386) MaxVersion3=5.20.9999.9999

[UnInstall] Name=ASP .NET UnInstall CommandLine=msiexec /q /x &quot;VPModule.msi&quot; UserInputRequired=False EstimatedRunTime=5 AdminRightsRequired=True CanRunWhen=AnyUserStatus SupportedClients=Win NT (I386) Win NT (I386) MinVersion1=5.00.0000.0 Win NT (I386) MaxVersion1=5.00.9999.9999 Win NT (I386) MinVersion2=5.10.0000.0 Win NT (I386) MaxVersion2=5.10.9999.9999 Win NT (I386) MinVersion3=5.20.0000.0 Win NT (I386) MaxVersion3=5.20.9999.9999

To create the package and program objects, follow these steps:
 * 1) In the SMS Administrator Console, click Packages.
 * 2) Right-click Packages, click New, click Package from Definition.

A Create Package from Definition Wizard starts. Use this wizard to create the package and program objects. You will be prompted to supply the package definition file that you created earlier. You can also select the source files (VPModuleScanner.js and VPModule.msi) to complete the package creation.
 * 1) When you finish the steps in the wizard, a new Microsoft ASP.NET Scan and Install Package is created.

Phase 2: Compliance scan
We recommend that you first assess how many systems the VPModule.msi file applies to and what systems require the file.

To execute the compliance scan, first use the ASP.NET Scan program to create an advertisement. This program is located in the Microsoft ASP.NET Scan and Install package.

Deploy this advertisement to a pilot group first, before you execute a broader deployment.

After you execute the compliance scan on a client system, you will receive one of the following return codes:

Important Systems that require the VPModule.msi file will return exit code 20000. Exit code 20000 is a failure code. The standard software distribution reports will put these systems into the failed category. Correct representation of the compliance status is available through the sample reports.

Use the sample reports that are located in the ASP.NET Scan - Advertisement Status category to monitor the progress of the detection script deployment and execution.

Report generation is described later in this article.

Phase 3: Module installation
As soon as the extent of non-compliant systems is known, SMS administrators can deploy the VPModule.msi file.

Create an SMS advertisement that is based on the ASP.NET Install program. This advertisement will deploy an MSI package that installs the mitigation module. The MSI package will be executed in an unattended manner, and a system restart should not be required.

Important Systems that require the VPModule.msi file will return exit code 20000. Exit code 20000 is a failure code. The standard software distribution reports will put these systems into the failed category. Correct representation of the compliance status is available through the sample reports.

Use the sample reports that are located in the ASP.NET Scan - Advertisement Status category to monitor the progress of the detection script deployment and execution.

Uninstall option
The MSI package also includes an uninstall option. Target the uninstall option only at systems that have the mitigation module installed.

To identify systems that have successfully installed mitigation module, a collection should be based on a query that includes the following condition: select * from  SMS_R_System inner join SMS_G_System_ADD_REMOVE_PROGRAMS on SMS_G_System_ADD_REMOVE_PROGRAMS.ResourceID = SMS_R_System.ResourceId where SMS_G_System_ADD_REMOVE_PROGRAMS.DisplayName = &quot;Microsoft ASP.NET ValidatePath Module&quot;

Sample reports
A set of sample reports that supports compliance assessment is included in this section. To implement the reports, copy and paste the following text in Notepad, and then save the file with a .mof extension. For example, use Aspnet.mof.

Note Make sure that the site code in the first line of the file is amended to reflect the site code of the primary site where these reports will be installed. For example, if you install these reports at SMS Primary Site A01, the first line should be:
 * 1) pragma namespace(&quot;\\\\.\\root\\sms\\site_A01&quot;)

When the file has been generated, you must compile it. At the SMS primary site server where the reports are to be installed and the SMS provider is located, run the compilation at a command prompt by typing the following:

mofcomp.exe aspnet.mof

The following are sample reports:
 * 1) pragma namespace(&quot;\\\\.\\root\\sms\\site_PPP&quot;)

////////////////////////////////////////////////////////////////////////////////////// // Please don't modify the following report. This report is already shipped with SMS ////////////////////////////////////////////////////////////////////////////////////// instance of SMS_Report as $N108 {   Category = &quot;Software Distribution - Advertisement Status&quot;; Comment = &quot;This report shows the status messages reported for a particular computer and advertisement.&quot;; DrillThroughColumns = {5}; GraphXCol = 1; GraphYCol = 2; MachineDetail = FALSE; MachineSource = FALSE; Name = &quot;Advertisement status messages for a particular client and advertisement&quot;; NumPrompts = 2; RefreshInterval = 0;

ReportParams = { instance of SMS_ReportParameter {   AllowEmpty = FALSE; DefaultValue = &quot;&quot;; PromptText = &quot;Advertisement ID&quot;; SampleValueSQL = &quot;begin\r\n if (@__filterwildcard = '')\r\n select AdvertisementID, AdvertisementName, Comment from v_Advertisement order by AdvertisementName\r\n else\r\n  select AdvertisementID, AdvertisementName, Comment from v_Advertisement\r\n  WHERE AdvertisementID like @__filterwildcard\r\n  order by AdvertisementName\r\nend&quot;; VariableName = &quot;AdvertID&quot;; }, instance of SMS_ReportParameter {   AllowEmpty = FALSE; DefaultValue = &quot;&quot;; PromptText = &quot;Computer Name&quot;; SampleValueSQL = &quot;begin\r\n if (@__filterwildcard = '')\r\n SELECT DISTINCT SYS.Netbios_Name0 from v_R_System SYS WHERE SYS.Client0=1 ORDER By SYS.Netbios_Name0\r\n else\r\n  SELECT DISTINCT SYS.Netbios_Name0 from v_R_System SYS WHERE SYS.Client0=1\r\n  and SYS.Netbios_Name0 like @__filterwildcard\r\n  ORDER By SYS.Netbios_Name0\r\nend&quot;; VariableName = &quot;Name&quot;; }};

SQLQuery = &quot;/* status message detail, params=machine name, AdvertisementID */\r\n\r\nselect DATEADD(ss,@__timezoneoffset,stat.Time) as Time, info.MessageStateName, info.MessageName, stat.MessageID, stat.RecordID\r\nfrom v_StatusMessage stat\r\njoin v_StatMsgAttributes att on stat.RecordID=att.RecordID and stat.Time=att.AttributeTime\r\nleft join v_AdvertisementStatusInformation info on stat.MessageID=info.MessageID\r\nwhere stat.Component in ('SMS System Offer Data Provider (ODP)', 'Available Programs Manager (APM)', 'Software Distribution','Device Client')\r\n   and stat.MachineName=@Name and att.AttributeID=401\r\n   and att.AttributeValue=@AdvertID\r\norder by stat.Time&quot;; StatusMessageDetailSource = TRUE; };

////////////////////////////////////////////////////////////////////////////////////// // New report for ASP .NET scan Advertisement ////////////////////////////////////////////////////////////////////////////////////// instance of SMS_Report as $N410 {   Category = &quot;ASP .NET Scan - Advertisement Status&quot;; Comment = &quot;This report will show a list of all resources that are in a specific state for ASP .NET scan advertisement. For example, you can see which resources have successfully run ASP .NET scan program and whether they are compliant or not.\r\n(Client type: 0 = Legacy Client; 1 = Advanced Client)&quot;; DrillThroughColumns = {9, 1};

DrillThroughReportPath = $N108; GraphXCol = 1; GraphYCol = 2; MachineDetail = FALSE; MachineSource = FALSE; Name = &quot;All system resources for ASP .NET scan advertisement in a specific state&quot;; NumPrompts = 2; RefreshInterval = 0;

ReportParams = { instance of SMS_ReportParameter {   AllowEmpty = FALSE; DefaultValue = &quot;&quot;; PromptText = &quot;Software Distribution Status&quot;; SampleValueSQL = &quot;begin\r\n if (@__filterwildcard = '')\r\n select distinct MessageStateName from v_AdvertisementStatusInformation where MessageState <= 13 order by MessageStateName\r\n else\r\n  select distinct MessageStateName from v_AdvertisementStatusInformation where MessageState <= 13\r\n  and MessageStateName like @__filterwildcard\r\n  order by MessageStateName\r\nend&quot;; VariableName = &quot;StateName&quot;; }, instance of SMS_ReportParameter {   AllowEmpty = FALSE; DefaultValue = &quot;&quot;; PromptText = &quot;Advertisement ID&quot;; SampleValueSQL = &quot;begin\r\n if (@__filterwildcard = '')\r\n select AdvertisementID, AdvertisementName, Comment from v_Advertisement order by AdvertisementName\r\n else\r\n  select AdvertisementID, AdvertisementName, Comment from v_Advertisement\r\n  WHERE AdvertisementID like @__filterwildcard\r\n  order by AdvertisementName\r\nend&quot;; VariableName = &quot;AdvertID&quot;; }};

SQLQuery = &quot;declare @State int\r\n\r\nselect @State=MessageState \r\nfrom v_AdvertisementStatusInformation\r\nwhere MessageStateName=@StateName and MessageState < 100\r\n\r\nif @State in (0,1,2,3) /* no status, accepted, rejected, expired */\r\n select sys.Netbios_Name0, sys.User_Domain0, sys.User_Name0, site.SMS_Installed_Sites0, Client_Type0, \r\n         LastAcceptanceMessageID, LastAcceptanceMessageIDName, \r\n         DATEADD(ss,@__timezoneoffset,LastAcceptanceStatusTime) as LastAcceptanceStatusTime,\r\n         AdvertisementID\r\n  from v_ClientAdvertisementStatus stat\r\n  join v_R_System sys on stat.ResourceID=sys.ResourceID\r\n  left join v_RA_System_SMSInstalledSites site on stat.ResourceID=site.ResourceID\r\n  where stat.LastAcceptanceState=@State and stat.AdvertisementID=@AdvertID\r\nelse if @StateName = 'Vulnerable' /* Vulnerable */\r\nselect sys.Netbios_Name0, sys.User_Domain0, sys.User_Name0,site.SMS_Installed_Sites0, Client_Type0, \r\n       LastStatusMessageID, LastStatusMessageIDName, \r\n       DATEADD(ss,@__timezoneoffset,LastStatusTime) as LastStatusTime, \r\n       AdvertisementID, LastExecutionResult, LastExecutionContext\r\n  from v_ClientAdvertisementStatus stat\r\n  join v_R_System sys on stat.ResourceID=sys.ResourceID\r\n  left join v_RA_System_SMSInstalledSites site on stat.ResourceID=site.ResourceID\r\n  where stat.LastState=11 and stat.AdvertisementID=@AdvertID\r\n and ISNULL(stat.LastExecutionResult, 0)='20000'\r\n else if @State = 11 /* failed */\r\n  select sys.Netbios_Name0, sys.User_Domain0, sys.User_Name0,site.SMS_Installed_Sites0, Client_Type0, \r\n       LastStatusMessageID, LastStatusMessageIDName, \r\n       DATEADD(ss,@__timezoneoffset,LastStatusTime) as LastStatusTime, \r\n       AdvertisementID, LastExecutionResult, LastExecutionContext\r\n  from v_ClientAdvertisementStatus stat\r\n  join v_R_System sys on stat.ResourceID=sys.ResourceID\r\n  left join v_RA_System_SMSInstalledSites site on stat.ResourceID=site.ResourceID\r\n  where stat.LastState=@State and stat.AdvertisementID=@AdvertID\r\nand ISNULL(stat.LastExecutionResult, 0)!='20000'\r\nelse if @State in (9,12,13) /* running, reboot pending, suceeded */\r\n  select sys.Netbios_Name0, sys.User_Domain0, sys.User_Name0, site.SMS_Installed_Sites0, Client_Type0, \r\n       LastStatusMessageID, LastStatusMessageIDName,\r\n       DATEADD(ss,@__timezoneoffset,LastStatusTime) as LastStatusTime, \r\n       AdvertisementID, LastExecutionContext\r\n  from v_ClientAdvertisementStatus stat\r\n  join v_R_System sys on stat.ResourceID=sys.ResourceID\r\n  left join v_RA_System_SMSInstalledSites site on stat.ResourceID=site.ResourceID\r\n  where stat.LastState=@State and stat.AdvertisementID=@AdvertID\r\nelse\r\n  select sys.Netbios_Name0, sys.User_Domain0, sys.User_Name0, site.SMS_Installed_Sites0, Client_Type0, \r\n       CASE LastStatusMessageID WHEN 65535 THEN 10002 ELSE LastStatusMessageID END as LastStatusMessageID, \r\n       LastStatusMessageIDName,\r\n       DATEADD(ss,@__timezoneoffset,LastStatusTime) as LastStatusTime, \r\n       AdvertisementID\r\n  from v_ClientAdvertisementStatus stat\r\n  join v_R_System sys on stat.ResourceID=sys.ResourceID\r\n  left join v_RA_System_SMSInstalledSites site on stat.ResourceID=site.ResourceID\r\n  where stat.LastState=@State and stat.AdvertisementID=@AdvertID&quot;; StatusMessageDetailSource = FALSE; XColLabel = &quot;&quot;; YColLabel = &quot;&quot;; };

////////////////////////////////////////////////////////////////////////////////////// // New report for ASP .NET scan Advertisement ////////////////////////////////////////////////////////////////////////////////////// instance of SMS_Report as $N411 {   Category = &quot;ASP .NET Scan - Advertisement Status&quot;; Comment = &quot;This report shows the status summary of all resources that have been targeted by an ASP .NET Scan advertisement. The summary is broken into two parts. Acceptance status will summarize how many resources have received, rejected, or not yet received the advertisement. Delivery status will summarize the resources that have run or attempted to run the scan program and are vulnerable.&quot;; DrillThroughColumns = {1, 4}; DrillThroughReportPath = $N410; GraphXCol = 1; GraphYCol = 2; MachineDetail = FALSE; MachineSource = FALSE; Name = &quot;ASP .NET scan Status of a specific advertisement&quot;; NumPrompts = 1; RefreshInterval = 0; ReportParams = { instance of SMS_ReportParameter {   AllowEmpty = FALSE; DefaultValue = &quot;&quot;; PromptText = &quot;Advertisement ID&quot;; SampleValueSQL = &quot;begin \n if (@__filterwildcard = '') \n select AdvertisementID, AdvertisementName, Comment from v_Advertisement order by AdvertisementName \n else \n  select AdvertisementID, AdvertisementName, Comment from v_Advertisement \n  WHERE AdvertisementID like @__filterwildcard \n  order by AdvertisementName \nend&quot;; VariableName = &quot;AdvertID&quot;; }};   SecurityKey = &quot;&quot;; SQLQuery = &quot;declare @Total int \ndeclare @Accepted int \n \nselect @Total=count(*), @Accepted=sum(case LastState when 0 then 0 else 1 end) \nfrom v_ClientAdvertisementStatus \nwhere AdvertisementID=@AdvertID \n \nselect LastAcceptanceStateName as C013, count(*) as C015,  \n      ROUND(100.0*count(*)/@Total,1) as C016, \nAdvertisementID \nfrom v_ClientAdvertisementStatus  \nwhere AdvertisementID=@AdvertID \ngroup by LastAcceptanceStateName, AdvertisementID \n \nselect LastStateName as C017, count(*) as C015,  \n       ROUND(100.0*count(*)/@Accepted,1)  as C016, \nAdvertisementID \nfrom v_ClientAdvertisementStatus  \nwhere AdvertisementID=@AdvertID and (LastState not in (0, 11) OR  \n(LastState = 11 and ISNULL(LastExecutionResult, 0) != '20000'))  \ngroup by LastStateName, AdvertisementID UNION  \n select 'Vulnerable' as C017, count(*) as C015,  \n ROUND(100.0*count(*)/@Accepted,1)  as C016, AdvertisementID  \nfrom v_ClientAdvertisementStatus  \nwhere AdvertisementID=@AdvertID and  \n(LastState = 11 and ISNULL(LastExecutionResult, 0) = '20000')  \ngroup by AdvertisementID&quot;; StatusMessageDetailSource = FALSE; };

