Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2422 lines
113 KiB

  1. '********************************************************************
  2. '*
  3. '* Copyright (c) Microsoft Corporation. All rights reserved.
  4. '*
  5. '* Module Name: EVENTQUERY.vbs
  6. '*
  7. '* Abstract: Enables an administrator to query/view all existing
  8. '* events in a given event log(s).
  9. '*
  10. '*
  11. '********************************************************************
  12. ' Global declaration
  13. OPTION EXPLICIT
  14. ON ERROR RESUME NEXT
  15. Err.Clear
  16. '----------------------------------------------------------------
  17. ' Start of localization Content
  18. '----------------------------------------------------------------
  19. ' the filter operators specified by the user
  20. CONST L_OperatorEq_Text = "eq"
  21. CONST L_OperatorNe_Text = "ne"
  22. CONST L_OperatorGe_Text = "ge"
  23. CONST L_OperatorLe_Text = "le"
  24. CONST L_OperatorGt_Text = "gt"
  25. CONST L_OperatorLt_Text = "lt"
  26. ' the filters as given by the user
  27. CONST L_UserFilterDateTime_Text = "datetime"
  28. CONST L_UserFilterType_Text = "type"
  29. CONST L_UserFilterUser_Text = "user"
  30. CONST L_UserFilterComputer_Text = "computer"
  31. CONST L_UserFilterSource_Text = "source"
  32. CONST L_UserFilterDateCategory_Text = "category"
  33. CONST L_UserFilterId_Text = "id"
  34. ' the text displayed in columns when no output is obtained for display
  35. CONST L_TextNa_Text = "N/A"
  36. CONST L_TextNone_Text = "None"
  37. ' the following texts are used while parsing the command-line arguments
  38. ' (passed as input to the function component.getArguments)
  39. CONST L_MachineName_Text = "Server Name"
  40. CONST L_UserName_Text = "User Name"
  41. CONST L_UserPassword_Text = "User Password"
  42. CONST L_Format_Text = "Format"
  43. CONST L_Range_Text = "Range"
  44. CONST L_Filter_Text = "Filter"
  45. CONST L_Log_Text = "Logname"
  46. ' the column headers used in the output display
  47. CONST L_ColHeaderType_Text = "Type"
  48. CONST L_ColHeaderDateTime_Text = "Date Time"
  49. CONST L_ColHeaderSource_Text = "Source"
  50. CONST L_ColHeaderCategory_Text = "Category"
  51. CONST L_ColHeaderEventcode_Text = "Event"
  52. CONST L_ColHeaderUser_Text = "User"
  53. CONST L_ColHeaderComputerName_Text = "ComputerName"
  54. CONST L_ColHeaderDesription_Text = "Description"
  55. ' Maximum Column Header Lengths used to display various fields.
  56. ' Localization team can adjust these five column lengths to fit the localized strings, but
  57. ' their sum should come to 74. We always want to limit the total chars displayed per line to 79
  58. ' 74 chars + 5 spaces to separate the columns == 79 .
  59. CONST L_ColHeaderTypeLength_Text = 13
  60. CONST L_ColHeaderDateTimeLength_Text = 23
  61. CONST L_ColHeaderSourceLength_Text = 17 'This is the most preferred one to shorten.
  62. CONST L_ColHeaderComputerNameLength_Text = 15
  63. CONST L_ColHeaderEventcodeLength_Text = 6
  64. 'These can be changed as it will not have any effect on the display.
  65. CONST L_ColHeaderUserLength_Text = 20
  66. CONST L_ColHeaderCategoryLength_Text = 15
  67. CONST L_ColHeaderDesriptionLength_Text = 0
  68. ' variable use to concatenate the Localization Strings.
  69. ' Error Messages
  70. Dim UseCscriptErrorMessage
  71. Dim InvalidParameterErrorMessage
  72. Dim InvalidFormatErrorMessage
  73. Dim InvalidCredentialsForServerErrorMessage
  74. Dim InvalidCredentialsForUserErrorMessage
  75. Dim InvalidSyntaxErrorMessage
  76. Dim InvalidInputErrorMessage
  77. Dim InvalidORSyntaxInFilterErrorMessage
  78. Dim InvalidSyntaxMoreNoRepeatedErrorMessage
  79. CONST L_HelpSyntax1_Message = "Type ""%1 /?"" for usage."
  80. CONST L_HelpSyntax2_Message = "Type ""%2 /?"" for usage."
  81. CONST L_InvalidParameter1_ErrorMessage = "ERROR: Invalid Argument/Option - '%1'."
  82. InvalidParameterErrorMessage = L_InvalidParameter1_ErrorMessage & vbCRLF & L_HelpSyntax2_Message
  83. CONST L_InvalidFormat1_ErrorMessage = "ERROR: Invalid 'FORMAT' '%1' specified."
  84. InvalidFormatErrorMessage = L_InvalidFormat1_ErrorMessage & vbCRLF & L_HelpSyntax2_Message
  85. CONST L_InvalidRange_ErrorMessage = "ERROR: Invalid 'RANGE' '%1' specified."
  86. CONST L_Invalid_ErrorMessage = "ERROR: Invalid '%1'."
  87. CONST L_InvalidType_ErrorMessage = "ERROR: Invalid 'TYPE' '%1' specified for the 'FILTER' '%2'."
  88. CONST L_InvalidUser_ErrorMessage = "ERROR: Invalid 'USER' '%1' specified for the 'FILTER '%2'."
  89. CONST L_InvalidId_ErrorMessage = "ERROR: Invalid 'ID' '%1' specified for the 'FILTER' '%2'."
  90. CONST L_InvalidFilter_ErrorMessage = "ERROR: Invalid 'FILTER' '%1' specified for the 'FILTER' '%2'."
  91. CONST L_InvalidFilterFormat_ErrorMessage = "ERROR: The FILTER '%1' is not in the required format."
  92. CONST L_InvalidFilterOperation_ErrorMessage = "ERROR: Invalid FILTER operator '%1' specified for the filter '%2'."
  93. CONST L_InvalidCredentialsForServer1_ErrorMessage = "ERROR: Invalid Syntax. /U can only be specified only when /S is specified."
  94. InvalidCredentialsForServerErrorMessage = L_InvalidCredentialsForServer1_ErrorMessage & vbCRLF & L_HelpSyntax1_Message
  95. CONST L_InvalidCredentialsForUser1_ErrorMessage = "ERROR: Invalid Syntax. /P can be only specified only when /U is specified."
  96. InvalidCredentialsForUserErrorMessage = L_InvalidCredentialsForUser1_ErrorMessage & vbCRLF & L_HelpSyntax1_Message
  97. CONST L_InvalidOperator_ErrorMessage = "ERROR: Invalid operator specified for the range of dates in the 'DATETIME' filter."
  98. CONST L_InvalidDateTimeFormat_ErrorMessage = "ERROR: Invalid 'DATETIME' format specified. Format:MM/dd/yy(yyyy),hh:mm:ssAM([/PM)]"
  99. CONST L_ExecuteQuery_ErrorMessage = "ERROR: Unable to execute the query for the '%1' log."
  100. CONST L_LogDoesNotExist_ErrorMessage = "ERROR: The log file '%1' does not exist."
  101. CONST L_InstancesFailed_ErrorMessage = "ERROR: Unable to get the log details from the system."
  102. CONST L_InvalidSyntax1_ErrorMessage = "ERROR: Invalid Syntax."
  103. InvalidSyntaxErrorMessage = L_InvalidSyntax1_ErrorMessage & vbCRLF & L_HelpSyntax1_Message
  104. CONST L_InvalidInput1_ErrorMessage = "ERROR: Invalid input. Please check the input Values."
  105. InvalidInputErrorMessage = L_InvalidInput1_ErrorMessage & vbCRLF & L_HelpSyntax1_Message
  106. CONST L_ObjCreationFail_ErrorMessage = "ERROR: Unexpected Error, Query failed. "
  107. CONST L_InfoUnableToInclude_ErrorMessage = "ERROR: Unable to include the common module""CmdLib.Wsc""."
  108. CONST L_ComponentNotFound_ErrorMessage = "ERROR: Unable to create the component '%1'."
  109. CONST L_NoHeaderaNotApplicable_ErrorMessage = "ERROR: /NH option is allowed only for ""TABLE"" and ""CSV"" formats."
  110. CONST L_InValidServerName_ErrorMessage = "ERROR: Invalid Syntax. System name cannot be empty."
  111. CONST L_InValidUserName_ErrorMessage = "ERROR: Invalid Syntax. User name cannot be empty. "
  112. CONST L_InvalidORSyntaxInFilter1_ErrorMessage = "ERROR: Invalid 'OR' operation is specified for the filter."
  113. CONST L_InvalidORSyntaxInFilter2_ErrorMessage = "'OR' operation valid only for filters TYPE and ID."
  114. InvalidORSyntaxInFilterErrorMessage = L_InvalidORSyntaxInFilter1_ErrorMessage & vbCRLF & L_InvalidORSyntaxInFilter2_ErrorMessage
  115. CONST L_InvalidSyntaxMoreNoRepeated1_ErrorMessage = "ERROR: Invalid Syntax. '%1' option is not allowed more than 1 time(s)."
  116. InvalidSyntaxMoreNoRepeatedErrorMessage = L_InvalidSyntaxMoreNoRepeated1_ErrorMessage & vbCRLF & L_HelpSyntax2_Message
  117. ' Hints given in case of errors
  118. CONST L_HintCheckConnection_Message = "ERROR: Please check the system name, credentials and WMI (WBEM) service."
  119. ' Informational messages
  120. CONST L_InfoNoRecordsInFilter_Message = "INFO: No records available for the '%1' log with the specified criteria."
  121. CONST L_InfoNoRecords_Message = "INFO: No records available for the '%1' log."
  122. CONST L_InfoNoLogsPresent_Message = "INFO: No logs are available in the system."
  123. CONST L_InfoDisplayLog_Message = "Listing the events in '%1' log of host '%2'"
  124. ' Cscript usage strings
  125. CONST L_UseCscript1_ErrorMessage = "This script should be executed from the command prompt using CSCRIPT.EXE."
  126. CONST L_UseCscript2E_ErrorMessage = "For example: CSCRIPT %windir%\System32\EVENTQUERY.vbs <arguments>"
  127. CONST L_UseCscript3_ErrorMessage = "To set CScript as the default application to run .vbs files, run the following:"
  128. CONST L_UseCscript4_ErrorMessage = " CSCRIPT //H:CSCRIPT //S"
  129. CONST L_UseCscript5E_ErrorMessage = "You can then run ""%windir%\System32\EVENTQUERY.vbs <arguments>"" without preceding the script with CSCRIPT."
  130. ' Contents for showing help for Usage
  131. CONST L_ShowUsageLine00_Text = "No logs are available on this system for query."
  132. CONST L_ShowUsageLine01_Text = "EVENTQUERY.vbs [/S system [/U username [/P password]]] [/V] [/FI filter]"
  133. CONST L_ShowUsageLine02_Text = " [/FO format] [/R range] [/NH] [/L logname | *]"
  134. CONST L_ShowUsageLine03_Text = "Description:"
  135. CONST L_ShowUsageLine04_Text = " The EVENTQUERY.vbs script enables an administrator to list"
  136. CONST L_ShowUsageLine05_Text = " the events and event properties from one or more event logs."
  137. CONST L_ShowUsageLine06_Text = "Parameter List:"
  138. CONST L_ShowUsageLine07_Text = " /S system Specifies the remote system to connect to."
  139. CONST L_ShowUsageLine08_Text = " /U [domain\]user Specifies the user context under which the"
  140. CONST L_ShowUsageLine09_Text = " command should execute."
  141. CONST L_ShowUsageLine10_Text = " /P password Specifies the password for the given"
  142. CONST L_ShowUsageLine11_Text = " user context."
  143. CONST L_ShowUsageLine12_Text = " /V Displays verbose information. Specifies that "
  144. CONST L_ShowUsageLine13_Text = " the detailed information should be displayed "
  145. CONST L_ShowUsageLine14_Text = " in the output."
  146. CONST L_ShowUsageLine15_Text = " /FI filter Specifies the types of events to"
  147. CONST L_ShowUsageLine16_Text = " filter in or out of the query."
  148. CONST L_ShowUsageLine17_Text = " /FO format Specifies the format in which the output"
  149. CONST L_ShowUsageLine18_Text = " is to be displayed."
  150. CONST L_ShowUsageLine19_Text = " Valid formats are ""TABLE"", ""LIST"", ""CSV""."
  151. CONST L_ShowUsageLine20_Text = " /R range Specifies the range of events to list."
  152. CONST L_ShowUsageLine21_Text = " Valid Values are:"
  153. CONST L_ShowUsageLine22_Text = " 'N' - Lists 'N' most recent events."
  154. CONST L_ShowUsageLine23_Text = " '-N' - Lists 'N' oldest events."
  155. CONST L_ShowUsageLine24_Text = " 'N1-N2' - Lists the events N1 to N2."
  156. CONST L_ShowUsageLine25_Text = " /NH Specifies that the ""Column Header"" should"
  157. CONST L_ShowUsageLine26_Text = " not be displayed in the output."
  158. CONST L_ShowUsageLine27_Text = " Valid only for ""TABLE"" and ""CSV"" formats."
  159. CONST L_ShowUsageLine28_Text = " /L logname Specifies the log(s) to query."
  160. CONST L_ShowUsageLine29_Text = " /? Displays this help/usage message."
  161. CONST L_ShowUsageLine30_Text = " Valid Filters Operators allowed Valid Values"
  162. CONST L_ShowUsageLine31_Text = " ------------- ------------------ ------------"
  163. CONST L_ShowUsageLine32_Text = " DATETIME eq,ne,ge,le,gt,lt MM/dd/yy(yyyy),hh:mm:ssAM(/PM)"
  164. CONST L_ShowUsageLine33_Text = " TYPE eq,ne SUCCESS, ERROR, INFORMATION,"
  165. CONST L_ShowUsageLine34_Text = " WARNING, SUCCESSAUDIT,"
  166. CONST L_ShowUsageLine35_Text = " FAILUREAUDIT"
  167. CONST L_ShowUsageLine36_Text = " ID eq,ne,ge,le,gt,lt non-negative integer(0 - 65535)"
  168. CONST L_ShowUsageLine37_Text = " USER eq,ne string"
  169. CONST L_ShowUsageLine38_Text = " COMPUTER eq,ne string"
  170. CONST L_ShowUsageLine39_Text = " SOURCE eq,ne string"
  171. CONST L_ShowUsageLine40_Text = " CATEGORY eq,ne string"
  172. CONST L_ShowUsageLine41_Text = "NOTE: Filter ""DATETIME"" can be specified as ""FromDate-ToDate"""
  173. CONST L_ShowUsageLine42_Text = " Only ""eq"" operator can be used for this format."
  174. CONST L_ShowUsageLine43_Text = "Examples:"
  175. CONST L_ShowUsageLine44_Text = " EVENTQUERY.vbs "
  176. CONST L_ShowUsageLine45_Text = " EVENTQUERY.vbs /L system "
  177. CONST L_ShowUsageLine46_Text = " EVENTQUERY.vbs /S system /U user /P password /V /L *"
  178. CONST L_ShowUsageLine47_Text = " EVENTQUERY.vbs /R 10 /L Application /NH"
  179. CONST L_ShowUsageLine48_Text = " EVENTQUERY.vbs /R -10 /FO LIST /L Security"
  180. CONST L_ShowUsageLine49_Text = " EVENTQUERY.vbs /R 5-10 /L ""DNS Server"""
  181. CONST L_ShowUsageLine50_Text = " EVENTQUERY.vbs /FI ""Type eq Error"" /L Application"
  182. CONST L_ShowUsageLine51_Text = " EVENTQUERY.vbs /L Application"
  183. CONST L_ShowUsageLine52_Text = " /FI ""Datetime eq 08/15/02,03:15:00AM-08/15/02,03:15:00PM"""
  184. CONST L_ShowUsageLine53_Text = " EVENTQUERY.vbs /FI ""Datetime gt 07/04/02,04:27:00PM"" "
  185. CONST L_ShowUsageLine54_Text = " /FI ""Id gt 700"" /FI ""Type eq warning"" /L System"
  186. CONST L_ShowUsageLine55_Text = " EVENTQUERY.vbs /FI ""Type eq error OR Id gt 1000 """
  187. '-------------------------------------------------------------------------
  188. ' END of localization content
  189. '-------------------------------------------------------------------------
  190. ' Define default values
  191. CONST ConstDefaultFormat_Text = "TABLE"
  192. ' Define other format values
  193. CONST Const_List_Format_Text = "LIST"
  194. CONST Const_Csv_Format_Text = "CSV"
  195. ' Define constants
  196. CONST CONST_ERROR = 0
  197. CONST CONST_CSCRIPT = 2
  198. CONST CONST_SHOW_USAGE = 3
  199. CONST CONST_PROCEED = 4
  200. CONST CONST_ERROR_USAGE = 5
  201. CONST CONST_NO_MATCHES_FOUND = 0
  202. ' Define the Exit Values
  203. CONST EXIT_SUCCESS = 0
  204. CONST EXIT_UNEXPECTED = 255
  205. CONST EXIT_INVALID_INPUT = 254
  206. CONST EXIT_METHOD_FAIL = 250
  207. CONST EXIT_INVALID_PARAM = 999
  208. CONST EXIT_INVALID_PARAM_DEFAULT_OPTION_REPEATED = 777
  209. ' Define default values
  210. CONST CONST_ARRAYBOUND_NUMBER = 10
  211. CONST CONST_ID_NUMBER = 65535
  212. ' Define namespace and class names of wmi
  213. CONST CONST_NAMESPACE_CIMV2 = "root\cimv2"
  214. CONST CLASS_EVENTLOG_FILE = "Win32_NTEventlogFile"
  215. ' for blank line in help usage
  216. CONST EmptyLine_Text = " "
  217. ' Define the various strings used in the script
  218. '=============================================
  219. ' the valid options supported by the script
  220. CONST OPTION_SERVER = "s"
  221. CONST OPTION_USER = "u"
  222. CONST OPTION_PASSWORD = "p"
  223. CONST OPTION_FORMAT = "fo"
  224. CONST OPTION_RANGE = "r"
  225. CONST OPTION_NOHEADER = "nh"
  226. CONST OPTION_VERBOSE = "v"
  227. CONST OPTION_FILTER = "fi"
  228. CONST OPTION_HELP = "?"
  229. CONST OPTION_LOGNAME = "l"
  230. ' the property names on which the user given filters are applied
  231. CONST FLD_FILTER_DATETIME = "TimeGenerated"
  232. CONST FLD_FILTER_TYPE = "Type"
  233. CONST FLD_FILTER_USER = "User"
  234. CONST FLD_FILTER_COMPUTER = "ComputerName"
  235. CONST FLD_FILTER_SOURCE = "SourceName"
  236. CONST FLD_FILTER_CATEGORY = "CategoryString"
  237. CONST FLD_FILTER_ID = "EventCode"
  238. CONST FLD_FILTER_EVENTTYPE = "EventType"
  239. ' Define matching patterns used in validations
  240. CONST PATTERNFORMAT = "^(table|list|csv)$"
  241. CONST PATTERNTYPE = "^(SUCCESS|ERROR|INFORMATION|WARNING|SUCCESSAUDIT|FAILUREAUDIT)$"
  242. ' Property values on which the user is given for the filter TYPE is applied
  243. CONST PATTERNTYPE_ERROR = "ERROR"
  244. CONST PATTERNTYPE_WARNING = "WARNING"
  245. CONST PATTERNTYPE_INFORMATION = "INFORMATION"
  246. CONST PATTERNTYPE_SUCCESSAUDIT = "SUCCESSAUDIT"
  247. CONST PATTERNTYPE_FAILUREAUDIT = "FAILUREAUDIT"
  248. CONST PATTERNTYPE_SUCCESS = "SUCCESS"
  249. CONST FLDFILTERTYPE_SUCCESSAUDIT = "audit success"
  250. CONST FLDFILTERTYPE_FAILUREAUDIT = "audit failure"
  251. ' Define EventType
  252. CONST EVENTTYPE_SUCCESS = "0"
  253. CONST EVENTTYPE_ERROR = "1"
  254. CONST EVENTTYPE_WARNING = "2"
  255. CONST EVENTTYPE_INFORMATION = "3"
  256. CONST EVENTTYPE_SUCCESSAUDIT = "4"
  257. CONST EVENTTYPE_FAILUREAUDIT = "5"
  258. ' the operator symbols
  259. CONST SYMBOL_OPERATOR_EQ = "="
  260. CONST SYMBOL_OPERATOR_NE = "<>"
  261. CONST SYMBOL_OPERATOR_GE = ">="
  262. CONST SYMBOL_OPERATOR_LE = "<="
  263. CONST SYMBOL_OPERATOR_GT = ">"
  264. CONST SYMBOL_OPERATOR_LT = "<"
  265. ' Define matching patterns used in validations
  266. CONST PATTERN_RANGE = "^\d*-?\d+$"
  267. CONST PATTERN_FILTER = "^([a-z]+)([\s]+)([a-z]+)([\s]+)([\w+]|[\W+]|\\)"
  268. CONST PATTERN_DATETIME = "^\d{1,2}\/\d{1,2}\/\d{2,4},\d{1,2}:\d{1,2}:\d{1,2}(A|P)M$"
  269. CONST PATTERN_INVALID_USER = "\|\[|\]|\:|\||\<|\>|\+|\=|\;|\,|\?|\*"
  270. CONST PATTERN_ID = "^(\d+)$"
  271. CONST PATTERN_DATETIME_RANGE = "^\d{1,2}\/\d{1,2}\/\d{2,4},\d{1,2}:\d{1,2}:\d{1,2}(A|P)M\-\d{1,2}\/\d{1,2}\/\d{2,4},\d{1,2}:\d{1,2}:\d{1,2}(A|P)M$"
  272. ' Define UNC format for server name
  273. CONST UNC_Format_Servername = "\\"
  274. ' Define const for filter separation when OR or ANDis specified in filter
  275. CONST L_OperatorOR_Text = " OR "
  276. CONST L_OperatorAND_Text = " AND "
  277. ' Variable to trap local if already connection in wmiconnect function
  278. Dim blnLocalConnection
  279. blnLocalConnection = False 'defalut value
  280. ' to include the common module
  281. Dim component ' object to store common module
  282. Set component = CreateObject( "Microsoft.CmdLib" )
  283. If Err.Number Then
  284. WScript.Echo(L_InfoUnableToInclude_ErrorMessage)
  285. WScript.Quit(EXIT_METHOD_FAIL)
  286. End If
  287. ' referring the script host to common module
  288. Set component.ScriptingHost = WScript.Application
  289. ' Check whether the script is run using CScript
  290. If CInt( component.checkScript() ) <> CONST_CSCRIPT Then
  291. UseCscriptErrorMessage = L_UseCscript1_ErrorMessage & vbCRLF & _
  292. ExpandEnvironmentString(L_UseCscript2E_ErrorMessage) & vbCRLF & vbCRLF & _
  293. L_UseCscript3_ErrorMessage & vbCRLF & _
  294. L_UseCscript4_ErrorMessage & vbCRLF & vbCRLF & _
  295. ExpandEnvironmentString(L_UseCscript5E_ErrorMessage)
  296. WScript.Echo (UseCscriptErrorMessage)
  297. WScript.Quit(EXIT_UNEXPECTED)
  298. End If
  299. ' Calling the Main function
  300. Call VBMain()
  301. ' end of the Main
  302. Wscript.Quit(EXIT_SUCCESS)
  303. '********************************************************************
  304. '* Sub: VBMain
  305. '*
  306. '* Purpose: This is main function that starts execution
  307. '*
  308. '*
  309. '* Input/ Output: None
  310. '********************************************************************
  311. Sub VBMain()
  312. ON ERROR RESUME NEXT
  313. Err.clear
  314. ' Declare variables
  315. Dim intOpCode ' to check the operation asked for, Eg:Help /?, etc
  316. Dim strMachine ' the machine to query the events from
  317. Dim strUserName ' the user name to use to query the machine
  318. Dim strPassword ' the password for the user to query the machine
  319. Dim strFormat ' format of display, default is table
  320. Dim strRange ' to store the range of records specified
  321. Dim blnNoHeader ' flag to store if header is not required
  322. Dim blnVerboseDisplay ' flag to verify if verbose display is needed
  323. ReDim arrFilters(5) ' to store all the given filters
  324. Dim objLogs ' a object to store all the given logfles
  325. ' Initialize variables
  326. intOpCode = 0
  327. strFormat = ConstDefaultFormat_Text
  328. strRange = ""
  329. blnNoHeader = FALSE
  330. blnVerboseDisplay = FALSE
  331. ' create the collection object
  332. Set objLogs = CreateObject("Scripting.Dictionary")
  333. If Err.Number Then
  334. component.vbPrintf L_ComponentNotFound_ErrorMessage, Array("Scripting.Dictionary")
  335. WScript.Quit(EXIT_METHOD_FAIL)
  336. End If
  337. ' setting Dictionary object compare mode to VBBinaryCompare
  338. objLogs.CompareMode = VBBinaryCompare
  339. ' Parse the command line
  340. intOpCode = intParseCmdLine(strMachine, _
  341. strUserName, _
  342. strPassword, _
  343. arrFilters, _
  344. strFormat, _
  345. strRange, _
  346. blnVerboseDisplay, _
  347. blnNoHeader, _
  348. objLogs)
  349. If Err.number then
  350. ' error in parsing the Command line
  351. component.vbPrintf InvalidInputErrorMessage ,Array(Ucase(Wscript.ScriptName))
  352. WScript.Quit(EXIT_UNEXPECTED)
  353. End If
  354. ' check the operation specified by the user
  355. Select Case intOpCode
  356. Case CONST_SHOW_USAGE
  357. ' help asked for
  358. Call ShowUsage()
  359. Case CONST_PROCEED
  360. Call ShowEvents(strMachine, strUserName, strPassword, _
  361. arrFilters, strFormat, strRange, _
  362. blnVerboseDisplay, blnNoHeader, objLogs)
  363. ' completed successfully
  364. WScript.Quit(EXIT_SUCCESS)
  365. Case CONST_ERROR
  366. ' print common help message.
  367. component.vbPrintf L_HelpSyntax1_Message, Array(Ucase(Wscript.ScriptName))
  368. Wscript.Quit(EXIT_INVALID_INPUT)
  369. Case CONST_ERROR_USAGE
  370. ' help is asked for help with some other parameters
  371. component.vbPrintf InvalidSyntaxErrorMessage, Array(Ucase(Wscript.ScriptName))
  372. WScript.Quit(EXIT_INVALID_INPUT)
  373. Case EXIT_INVALID_PARAM_DEFAULT_OPTION_REPEATED
  374. 'Option repeated, input values specified. Message displayed by the parser so just exit with error code.
  375. Wscript.Quit(EXIT_INVALID_PARAM)
  376. Case Else
  377. 'Invalid input values specified.
  378. component.vbPrintf InvalidSyntaxErrorMessage, Array(Ucase(Wscript.ScriptName))
  379. Wscript.Quit(EXIT_INVALID_PARAM)
  380. End Select
  381. End Sub
  382. '*************************** End of Main **************************
  383. '********************************************************************
  384. '* Function: intParseCmdLine
  385. '*
  386. '* Purpose: Parses the command line arguments to the variables
  387. '*
  388. '* Input:
  389. '* [out] strMachine machine to query events from
  390. '* [out] strUserName user name to connect to the machine
  391. '* [out] strPassword password for the user
  392. '* [out] arrFilters the array containing the filters
  393. '* [out] strFormat the display format
  394. '* [out] strRange the range of records required
  395. '* [out] blnVerboseDisplay flag to verify if verbose display is needed
  396. '* [out] blnNoHeader flag to verify if noheader display is needed
  397. '* [out] objLogs to store all the given logfles
  398. '* Output: Returns CONST_PROCEED, CONST_SHOW_USAGE or CONST_ERROR
  399. '* Displays error message and quits if invalid option is asked
  400. '*
  401. '********************************************************************
  402. Private Function intParseCmdLine( ByRef strMachine, _
  403. ByRef strUserName, _
  404. ByRef strPassword, _
  405. ByRef arrFilters, _
  406. ByRef strFormat, _
  407. ByRef strRange, _
  408. ByRef blnVerboseDisplay, _
  409. ByRef blnNoHeader,_
  410. ByRef objLogs)
  411. ON ERROR RESUME NEXT
  412. Err.Clear
  413. Dim strUserGivenArg ' to temporarily store the user given arguments to script
  414. Dim strTemp ' to store temporary values
  415. Dim intArgIter ' to count the number of arguments given by user
  416. Dim intArgLogType ' to count number of log files specified - Used in ReDim
  417. Dim intFilterCount ' to count number of filters specified - Used in ReDim
  418. Dim blnHelp ' to check if already Help is specified
  419. Dim blnFormat ' to check if already Format is specified
  420. Dim blnRange ' to check if already Range is specified
  421. Dim blnServer ' to check if already Server is specified
  422. Dim blnPassword ' to check if already Password is specified
  423. Dim blnUser ' to check if already User is specified
  424. strUserGivenArg = ""
  425. intArgLogType = 0
  426. intFilterCount = 0
  427. intArgIter = 0
  428. 'default values
  429. blnHelp = False
  430. blnPassword = False
  431. blnUser = False
  432. blnServer = False
  433. blnFormat = False
  434. ' Retrieve the command line and set appropriate variables
  435. Do While intArgIter <= Wscript.arguments.Count - 1
  436. strUserGivenArg = Wscript.arguments.Item(intArgIter)
  437. IF Left( strUserGivenArg,1) = "/" OR Left( strUserGivenArg,1) = "-" Then
  438. strUserGivenArg = Right( strUserGivenArg,Len(strUserGivenArg) -1 )
  439. Select Case LCase(strUserGivenArg)
  440. Case LCase(OPTION_SERVER)
  441. 'If more than 1 time(s) is spcecified
  442. If blnServer =True Then
  443. component.vbPrintf InvalidSyntaxMoreNoRepeatedErrorMessage, Array(Wscript.arguments.Item(intArgIter), Ucase(Wscript.ScriptName))
  444. intParseCmdLine = EXIT_INVALID_PARAM_DEFAULT_OPTION_REPEATED
  445. Exit Function
  446. End If
  447. If Not component.getArguments(L_MachineName_Text, strMachine, intArgIter, FALSE) Then
  448. intParseCmdLine = CONST_ERROR
  449. Exit Function
  450. End If
  451. blnServer =True
  452. intArgIter = intArgIter + 1
  453. Case LCase(OPTION_USER)
  454. 'If more than 1 time(s) is spcecified
  455. If blnUser =True Then
  456. component.vbPrintf InvalidSyntaxMoreNoRepeatedErrorMessage, Array(Wscript.arguments.Item(intArgIter), Ucase(Wscript.ScriptName))
  457. intParseCmdLine = EXIT_INVALID_PARAM_DEFAULT_OPTION_REPEATED
  458. Exit Function
  459. End If
  460. If Not component.getArguments(L_UserName_Text, strUserName, intArgIter, FALSE) Then
  461. intParseCmdLine = CONST_ERROR
  462. Exit Function
  463. End If
  464. blnUser =True
  465. intArgIter = intArgIter + 1
  466. Case LCase(OPTION_PASSWORD)
  467. 'If more than 1 time(s) is spcecified
  468. If blnPassword =True Then
  469. component.vbPrintf InvalidSyntaxMoreNoRepeatedErrorMessage, Array(Wscript.arguments.Item(intArgIter), Ucase(Wscript.ScriptName))
  470. intParseCmdLine = EXIT_INVALID_PARAM_DEFAULT_OPTION_REPEATED
  471. Exit Function
  472. End If
  473. If Not component.getArguments(L_UserPassword_Text, strPassword, intArgIter, FALSE) Then
  474. intParseCmdLine = CONST_ERROR
  475. Exit Function
  476. End If
  477. blnPassword =True
  478. intArgIter = intArgIter + 1
  479. Case LCase(OPTION_FORMAT)
  480. 'If more than 1 time(s) is spcecified
  481. If blnFormat =True Then
  482. component.vbPrintf InvalidSyntaxMoreNoRepeatedErrorMessage, Array(Wscript.arguments.Item(intArgIter), Ucase(Wscript.ScriptName))
  483. intParseCmdLine = EXIT_INVALID_PARAM_DEFAULT_OPTION_REPEATED
  484. Exit Function
  485. End If
  486. If Not component.getArguments(L_Format_Text,strFormat, intArgIter, FALSE) Then
  487. intParseCmdLine = CONST_ERROR
  488. Exit Function
  489. End If
  490. blnFormat =True
  491. intArgIter = intArgIter + 1
  492. Case LCase(OPTION_RANGE)
  493. 'If more than 1 time(s) is spcecified
  494. If blnRange =True Then
  495. component.vbPrintf InvalidSyntaxMoreNoRepeatedErrorMessage, Array(Wscript.arguments.Item(intArgIter), Ucase(Wscript.ScriptName))
  496. intParseCmdLine = EXIT_INVALID_PARAM_DEFAULT_OPTION_REPEATED
  497. Exit Function
  498. End If
  499. If Not component.getArguments(L_Range_Text,strRange, intArgIter,TRUE) Then
  500. intParseCmdLine = CONST_ERROR
  501. Exit Function
  502. End If
  503. blnRange =True
  504. intArgIter = intArgIter + 1
  505. Case LCase(OPTION_NOHEADER)
  506. 'If more than 1 time(s) is spcecified
  507. If blnNoHeader =True Then
  508. component.vbPrintf InvalidSyntaxMoreNoRepeatedErrorMessage, Array(Wscript.arguments.Item(intArgIter), Ucase(Wscript.ScriptName))
  509. intParseCmdLine = EXIT_INVALID_PARAM_DEFAULT_OPTION_REPEATED
  510. Exit Function
  511. End If
  512. blnNoHeader = TRUE
  513. intArgIter = intArgIter + 1
  514. Case LCase(OPTION_VERBOSE)
  515. 'If more than 1 time(s) is spcecified
  516. If blnVerboseDisplay =True Then
  517. component.vbPrintf InvalidSyntaxMoreNoRepeatedErrorMessage, Array(Wscript.arguments.Item(intArgIter), Ucase(Wscript.ScriptName))
  518. intParseCmdLine = EXIT_INVALID_PARAM_DEFAULT_OPTION_REPEATED
  519. Exit Function
  520. End If
  521. blnVerboseDisplay = TRUE
  522. intArgIter = intArgIter + 1
  523. Case LCase(OPTION_FILTER)
  524. If Not component.getArguments(L_Filter_Text, strTemp, intArgIter, FALSE) Then
  525. intParseCmdLine = CONST_ERROR
  526. Exit Function
  527. End If
  528. arrFilters(intFilterCount) = strTemp
  529. intFilterCount = intFilterCount + 1
  530. intArgIter = intArgIter + 1
  531. If ((intFilterCount MOD 5) = 0) Then
  532. ReDim PRESERVE arrFilters(intFilterCount + 5)
  533. End If
  534. Case LCase(OPTION_HELP)
  535. If blnHelp =True then
  536. intParseCmdLine = EXIT_INVALID_PARAM
  537. Exit Function
  538. End If
  539. blnHelp =True
  540. intParseCmdLine = CONST_SHOW_USAGE
  541. intArgIter = intArgIter + 1
  542. Case LCase(OPTION_LOGNAME)
  543. If Not component.getArguments(L_Log_Text, strTemp, intArgIter, FALSE) Then
  544. intParseCmdLine = CONST_ERROR
  545. Exit Function
  546. Else
  547. If NOT objLogs.Exists(LCase(strTemp)) Then
  548. objLogs.Add LCase(strTemp), -1
  549. End If
  550. intArgIter = intArgIter + 1
  551. End if
  552. Case Else
  553. ' invalid switch specified
  554. component.vbPrintf InvalidParameterErrorMessage, Array(Wscript.arguments.Item(intArgIter),Ucase(Wscript.ScriptName))
  555. Wscript.Quit(EXIT_INVALID_INPUT)
  556. End Select
  557. Else
  558. ' invalid argument specified
  559. component.vbPrintf InvalidParameterErrorMessage, Array(Wscript.arguments.Item(intArgIter),Ucase(Wscript.ScriptName))
  560. Wscript.Quit(EXIT_INVALID_INPUT)
  561. End IF
  562. Loop '** intArgIter <= Wscript.arguments.Count - 1
  563. ' preserving the array with current dimension
  564. ReDim PRESERVE arrFilters(intFilterCount-1)
  565. ' if no logs specified for query
  566. If (ObjLogs.Count = 0 ) Then
  567. ObjLogs.Add "*", -1
  568. End If
  569. ' check for invalid usage of help
  570. If blnHelp and intArgIter > 1 Then
  571. intParseCmdLine = CONST_ERROR_USAGE
  572. Exit Function
  573. End If
  574. 'check with default case : no arguments specified
  575. If IsEmpty(intParseCmdLine) Then
  576. intParseCmdLine = CONST_PROCEED
  577. End If
  578. End Function
  579. '********************************************************************
  580. '* Function: ValidateArguments
  581. '*
  582. '* Purpose: Validates the command line arguments given by the user
  583. '*
  584. '* Input:
  585. '* [in] strMachine machine to query events from
  586. '* [in] strUserName user name to connect to the machine
  587. '* [in] strPassword password for the user
  588. '* [in] strFormat the display format
  589. '* [in] strRange the range of records required
  590. '* [in] blnNoHeader flag to verify if noheader display is needed
  591. '* [out] arrFilters the array containing the filters
  592. '*
  593. '* Output: Returns true if all valid else displays error message and quits
  594. '* Gets the password from the user if not specified along with User.
  595. '*
  596. '********************************************************************
  597. Private Function ValidateArguments (ByVal strMachine, _
  598. ByVal strUserName, _
  599. ByVal strPassword, _
  600. ByRef arrFilters, _
  601. ByVal strFormat, _
  602. ByVal strRange,_
  603. ByVal blnNoHeader)
  604. ON ERROR RESUME NEXT
  605. Err.Clear
  606. Dim arrTemp ' to store temporary array values
  607. ' Check if invalid Server name is given
  608. If NOT ISEMPTY(strMachine) THEN
  609. If Trim(strMachine) = vbNullString Then
  610. WScript.Echo (L_InValidServerName_ErrorMessage)
  611. WScript.Quit(EXIT_INVALID_INPUT)
  612. End If
  613. End If
  614. 'Check if invalid User name is given
  615. If NOT ISEMPTY(strUserName) THEN
  616. If Trim(strUserName) = vbNullString Then
  617. WScript.Echo (L_InValidUserName_ErrorMessage )
  618. WScript.Quit(EXIT_INVALID_INPUT)
  619. End If
  620. End If
  621. ' ERROR if user is given without machine OR
  622. ' password is given without user
  623. If ((strUserName <> VBEmpty) AND (strMachine = VBEmpty)) Then
  624. component.vbPrintf InvalidCredentialsForServerErrorMessage, Array(Ucase(Wscript.ScriptName))
  625. WScript.Quit(EXIT_INVALID_INPUT)
  626. ElseIf ((strPassword <> VBEmpty) AND (strUserName = VBEmpty))Then
  627. component.vbPrintf InvalidCredentialsForUserErrorMessage, Array(Ucase(Wscript.ScriptName))
  628. WScript.Quit(EXIT_INVALID_INPUT)
  629. End If
  630. ' only table, list and csv display formats allowed
  631. ' PATTERNFORMAT '"^(table|list|csv)$"
  632. If CInt(component.matchPattern(PATTERNFORMAT,strFormat)) = CONST_NO_MATCHES_FOUND Then
  633. component.vbPrintf InvalidFormatErrormessage, Array(strFormat ,Ucase(Wscript.ScriptName))
  634. WScript.Quit(EXIT_INVALID_INPUT)
  635. End If
  636. ' check : -n header is specified for format of 'LIST' option
  637. If blnNoHeader =True and Lcase(strFormat) = Lcase(Const_List_Format_Text) then
  638. WScript.Echo (L_NoHeaderaNotApplicable_ErrorMessage)
  639. WScript.Quit(EXIT_INVALID_INPUT)
  640. End If
  641. If Len(Trim(strRange)) > 0 Then
  642. ' range is specified, valid formats are N, -N or N1-N2
  643. ' PATTERN_RANGE '"^(\d+|\-\d+|\d+\-\d+)$"
  644. If CInt(component.matchPattern(PATTERN_RANGE, strRange)) = CONST_NO_MATCHES_FOUND Then
  645. component.vbPrintf L_InvalidRange_ErrorMessage, Array(strRange)
  646. WScript.Quit(EXIT_INVALID_INPUT)
  647. Else
  648. strRange = CLng(Abs(strRange))
  649. 'this err an be trappped when N1-N2 option is given
  650. If Err.Number Then
  651. arrTemp = split(strRange, "-", 2, VBBinaryCompare)
  652. If CLng(arrTemp(0)) => CLng(arrTemp(1)) Then
  653. ' invalid range
  654. component.vbPrintf L_InvalidRange_ErrorMessage, Array(strRange)
  655. WScript.Quit(EXIT_INVALID_INPUT)
  656. End If
  657. Err.Clear 'if no invalid range N1-N2 clear the error
  658. Else
  659. If Abs(strRange) = 0 Then
  660. component.vbPrintf L_InvalidRange_ErrorMessage, Array(strRange)
  661. WScript.Quit(EXIT_INVALID_INPUT)
  662. End If
  663. End If
  664. End If
  665. End If
  666. ValidateArguments = TRUE
  667. End Function
  668. '********************************************************************
  669. '* Function: ValidateFilters
  670. '*
  671. '* Purpose: Validates the filters given by the user.
  672. '*
  673. '* Input: [in] Objservice the WMI service object
  674. '* Input: [out] arrFilters the array containing the filters
  675. '*
  676. '* Output: If filter is invalid, displays error message and quits
  677. '* If valid, filter is prepared for the query and returns true
  678. '*
  679. '********************************************************************
  680. Private Function ValidateFilters(ByRef arrFilters ,ByVal ObjService)
  681. ON ERROR RESUME NEXT
  682. Err.Clear
  683. Dim j ' to use in the loop
  684. Dim strFilter ' to store the user given filter (Eg:"Type eq Error")
  685. Dim arrTempProp ' to store the temporary array filterproperty
  686. Dim arrTempOperAndVal ' to store the temporary array filteroperator and filtervalue
  687. Dim strTemp ' to store temporary values
  688. Dim arrTemp ' to store temporary values of datetime when Range is given (Date1-Date2)
  689. Dim strFilterProperty ' the filter criteria that is specified (Eg:Type, ID)
  690. Dim strFilterOperation ' the operation specified (Eg: eq, gt)
  691. Dim strFilterValue ' the filter value specified
  692. Dim objInstance ' to refer to the instances of the objEnumerator
  693. Dim objEnumerator ' to store the results of the query is executed
  694. Dim strTempQuery ' string to make query
  695. Dim strTimeZone ' to store the TimeZone of the Queried system
  696. Dim strSign ' to store "+|-" sign value of TimeZone
  697. ' validate each filter stored in the array
  698. For j = 0 to UBound(arrFilters)
  699. strFilter = arrFilters(j)
  700. 'check eigther "OR or AND" is present inthe filter value
  701. 'Example : "type eq warning " OR " type eq error" [to support (OR + AND) ing in Filter Switch]
  702. 'Make a flag in this case "OR or AND" is present/not
  703. 'split it by "OR or AND " SEND as No. of Array elements
  704. Dim blnOR 'boolean to refer 'OR' operation is specified
  705. Dim blnAND 'boolean to refer 'AND' operation is specified
  706. Dim strArrFilter 'string to store array of filters if OR or AND is specified
  707. blnOR =False 'Initialise to False
  708. blnAND=False 'Initialise to False
  709. If UBOUND(Split(LCase(strFilter),LCase(L_OperatorOR_Text)) ) > 0 Then
  710. ' Check if filter have more no of OR with any AND Option(s)
  711. If UBOUND(Split(LCase(strFilter),LCase(L_OperatorOR_Text)) ) > 1 Or _
  712. UBOUND(Split(LCase(strFilter),LCase(L_OperatorAND_Text)) ) >0 Then
  713. component.vbPrintf L_InvalidFilterFormat_ErrorMessage, Array(strFilter)
  714. WScript.Quit(EXIT_INVALID_INPUT)
  715. End If
  716. 'setting the flag if " OR " specified in filter
  717. blnOR =TRUE
  718. 'split with "OR"
  719. strArrFilter = Split(LCase(strFilter),LCase(L_OperatorOR_Text))
  720. ElseIf UBOUND(Split(LCase(strFilter),LCase(L_OperatorAND_Text)) ) > 0 Then
  721. ' Check if filter have more no of AND with OR Option(s)
  722. If UBOUND(Split(LCase(strFilter),LCase(L_OperatorAND_Text)) ) > 1 Or _
  723. UBOUND(Split(LCase(strFilter),LCase(L_OperatorOR_Text)) ) > 0 Then
  724. component.vbPrintf L_InvalidFilterFormat_ErrorMessage, Array(strFilter)
  725. WScript.Quit(EXIT_INVALID_INPUT)
  726. End If
  727. 'setting the flag if " AND " specified in filter
  728. blnAND =TRUE
  729. 'split with "AND"
  730. strArrFilter = Split(LCase(strFilter),LCase(L_OperatorAND_Text))
  731. Else
  732. 'make single dimension array UBOUND = 0
  733. strArrFilter = Array(strFilter)
  734. End If
  735. Dim k ' to use in the loop
  736. Dim strTempFilter ' used to format Query string
  737. 'process the array for validatation
  738. 'UBOUND = 0 say normal filter specified
  739. For k = 0 to UBound(strArrFilter)
  740. If UBound(strArrFilter) > 0 then
  741. strFilter =strArrFilter(k)
  742. Else
  743. 'this is the first element allways
  744. strFilter =strArrFilter(0)
  745. End If
  746. ' check if 3 parameters are passed as input to filter
  747. ' PATTERN_FILTER "^([a-z]+)([\s]+)([a-z]+)([\s]+)(\w+)"
  748. strFilter = Trim( strFilter ) ' trim the value
  749. If CInt(component.matchPattern(PATTERN_FILTER, strFilter)) <= 0 Then
  750. component.vbPrintf L_InvalidFilterFormat_ErrorMessage, Array(strFilter)
  751. WScript.Quit(EXIT_INVALID_INPUT)
  752. End If
  753. ' This is to eliminate any no.of blank Char(s) between three valid input values
  754. ' i.e..filter "property ---operation ----value"
  755. ' first SPLIT the space delimiter string into array size of 2.
  756. ' and get the property value
  757. arrTempProp = split(Trim(strFilter)," ",2,VBBinaryCompare)
  758. strFilterProperty = arrTempProp(0)
  759. ' now trim it and again SPLIT the second element of arrTempProp into an array of size 2.
  760. ' and get the operation and value
  761. arrTempOperAndVal = split(Trim(arrTempProp(1))," ",2,VBBinaryCompare)
  762. strFilterOperation = arrTempOperAndVal(0)
  763. strFilterValue = Ltrim(arrTempOperAndVal(1))
  764. If LCase(strFilterProperty) = LCase(L_UserFilterDateTime_Text) OR _
  765. LCase(strFilterProperty) = LCase(L_UserFilterId_Text) Then
  766. ' the following are valid operators
  767. If LCase(strFilterOperation) = LCase(L_OperatorEq_Text) OR _
  768. LCase(strFilterOperation) = LCase(L_OperatorNe_Text) OR _
  769. LCase(strFilterOperation) = LCase(L_OperatorGe_Text) OR _
  770. LCase(strFilterOperation) = LCase(L_OperatorLe_Text) OR _
  771. LCase(strFilterOperation) = LCase(L_OperatorGt_Text) OR _
  772. LCase(strFilterOperation) = LCase(L_OperatorLt_Text) Then
  773. strTemp = ReplaceOperators(strFilterOperation)
  774. strFilterOperation = strTemp
  775. Else
  776. component.vbPrintf L_InvalidFilterOperation_ErrorMessage, Array(strFilterOperation, strFilter)
  777. WScript.Quit(EXIT_INVALID_INPUT)
  778. End If
  779. ElseIf LCase(strFilterProperty) = LCase(L_UserFilterType_Text) OR _
  780. LCase(strFilterProperty) = LCase(L_UserFilterUser_Text) OR _
  781. LCase(strFilterProperty) = LCase(L_UserFilterComputer_Text) OR _
  782. LCase(strFilterProperty) = LCase(L_UserFilterSource_Text) OR _
  783. LCase(strFilterProperty) = LCase(L_UserFilterDateCategory_Text) Then
  784. ' for others, only these two operators are valid
  785. If LCase(strFilterOperation) = LCase(L_OperatorEq_Text) OR _
  786. LCase(strFilterOperation) = LCase(L_OperatorNe_Text) Then
  787. strTemp = ReplaceOperators(strFilterOperation)
  788. strFilterOperation = strTemp
  789. Else
  790. component.vbPrintf L_InvalidFilterOperation_ErrorMessage, _
  791. Array(strFilterOperation, strFilter)
  792. WScript.Quit(EXIT_INVALID_INPUT)
  793. End If
  794. Else
  795. component.vbPrintf L_InvalidFilterOperation_ErrorMessage, _
  796. Array(strFilterProperty, strFilter)
  797. WScript.Quit(EXIT_INVALID_INPUT)
  798. End If
  799. ' validate the filter asked for
  800. Select Case LCase(strFilterProperty)
  801. Case L_UserFilterDateTime_Text
  802. 'Checking " OR " is only supported property EQ "TYPE OR ID" only
  803. If blnOR = True then
  804. WScript.Echo InvalidORSyntaxInFilterErrorMessage
  805. WScript.Quit(EXIT_INVALID_INPUT)
  806. End If
  807. ' Here To find Time Zone of system from CLASS_TIMEZONE_FILE
  808. strTempQuery = "SELECT * FROM Win32_OperatingSystem "
  809. Set objEnumerator = objService.ExecQuery(strTempQuery,,0)
  810. ' getting the Time Zone
  811. For each objInstance in objEnumerator
  812. strTimeZone = objInstance.CurrentTimeZone
  813. Next
  814. 'here to format timeZome value as '+/-' UUU
  815. If Isnull(strTimeZone) or IsEmpty(strTimeZone)then
  816. strTimeZone =0
  817. End If
  818. 'default sign
  819. strSign ="+"
  820. IF strTimeZone < 0 THEN
  821. strSign ="-"
  822. End If
  823. If Len(strTimeZone) < 4 then
  824. If Len(strTimeZone) = 3 then
  825. If strTimeZone < 0 then
  826. strTimeZone = Replace(strTimeZone,"-","0")
  827. End If
  828. ElseIf Len(strTimeZone) = 2 then
  829. If strTimeZone < 0 then
  830. strTimeZone = Replace(strTimeZone,"-","00")
  831. Else
  832. strTimeZone = "0" & strTimeZone
  833. End If
  834. ElseIf Len(strTimeZone) = 1 then
  835. IF strTimeZone >= 0 Then
  836. strTimeZone = "00" & strTimeZone
  837. End if
  838. End If
  839. 'return to a format as "+|-" & UUU
  840. strTimeZone= strSign & strTimeZone
  841. End If
  842. ' check for the valid format - MM/dd/yy,hh:mm:ssPM
  843. ' PATTERN_DATETIME
  844. If CInt(component.matchPattern(PATTERN_DATETIME, strFilterValue)) > 0 Then
  845. If component.validateDateTime(strFilterValue) Then
  846. ' a valid datetime filter. Prepare for query
  847. strFilterProperty = FLD_FILTER_DATETIME
  848. strTemp = component.changeToWMIDateTime(strFilterValue,strTimeZone)
  849. ' Format the input
  850. ' TimeGenerated > "07/25/2000 10:12:00 PM"
  851. strFilterValue = Chr(34) & strTemp & Chr(34)
  852. End If
  853. Else
  854. ' match for range of dates in the format
  855. ' MM/dd/yy,hh:mm:ssPM - MM/dd/yy,hh:mm:ssAM
  856. ' PATTERN_DATETIME_RANGE
  857. If CInt(component.matchPattern(PATTERN_DATETIME_RANGE, strFilterValue)) > 0 Then
  858. strFilterProperty = FLD_FILTER_DATETIME
  859. ' Only = operation supported in this format
  860. If strFilterOperation <> "=" Then
  861. WScript.Echo (L_InvalidOperator_ErrorMessage)
  862. WScript.Quit(EXIT_INVALID_INPUT)
  863. End If
  864. arrTemp = split(strFilterValue,"-",2,VBBinaryCompare)
  865. If component.validateDateTime(arrTemp(0)) Then
  866. ' a valid datetime filter. Prepare for query
  867. strTemp = component.changeToWMIDateTime(arrTemp(0),strTimeZone)
  868. ' Format the input
  869. ' TimeGenerated > "07/04/2002 10:12:00 PM"
  870. strFilterOperation = ">="
  871. strFilterValue = Chr(34) & strTemp & Chr(34)
  872. If component.validateDateTime(arrTemp(1)) Then
  873. ' a valid datetime filter. Prepare for query
  874. strTemp = component.changeToWMIDateTime(arrTemp(1),strTimeZone)
  875. ' Format the input
  876. ' TimeGenerated > "07/04/2002 10:12:00 PM"
  877. strFilterValue = strFilterValue & _
  878. " AND " & strFilterProperty & "<="& Chr(34)_
  879. & strTemp & Chr(34)
  880. End If
  881. End If
  882. Else
  883. component.vbPrintf L_InvalidDateTimeFormat_ErrorMessage, Array(strFilter)
  884. WScript.Quit(EXIT_INVALID_INPUT)
  885. End If
  886. End If
  887. Case L_UserFilterType_Text
  888. ' the following values are only valid for the "Type" filter
  889. ' Valid: ERROR|INFORMATION|WARNING|SUCCESSAUDIT|FAILUREAUDIT
  890. ' PATTERNTYPE
  891. If CInt(component.matchPattern(PATTERNTYPE, strFilterValue)) = _
  892. CONST_NO_MATCHES_FOUND Then
  893. component.vbPrintf L_InvalidType_ErrorMessage, Array(strFilterValue, strFilter)
  894. WScript.Quit(EXIT_INVALID_INPUT)
  895. Else
  896. ' here we need to check if running on WINXP or not
  897. If ( IsWinXP ( ObjService) = TRUE ) Then
  898. ' a valid type filter. Prepare for query
  899. If LCase(strFilterValue) =LCase(PATTERNTYPE_ERROR) Then
  900. strFilterValue = EVENTTYPE_ERROR
  901. ElseIf LCase(strFilterValue) =LCase(PATTERNTYPE_WARNING) Then
  902. strFilterValue = EVENTTYPE_WARNING
  903. ElseIf LCase(strFilterValue) =LCase(PATTERNTYPE_INFORMATION) Then
  904. strFilterValue = EVENTTYPE_INFORMATION
  905. ElseIf LCase(strFilterValue) =LCase(PATTERNTYPE_SUCCESSAUDIT) Then
  906. strFilterValue = EVENTTYPE_SUCCESSAUDIT
  907. ElseIf LCase(strFilterValue) =LCase(PATTERNTYPE_FAILUREAUDIT) Then
  908. strFilterValue = EVENTTYPE_FAILUREAUDIT
  909. ElseIf LCase(strFilterValue) =LCase(PATTERNTYPE_SUCCESS) Then
  910. strFilterValue = EVENTTYPE_SUCCESS
  911. End If
  912. ' a valid type filter. Prepare for query
  913. strFilterProperty = FLD_FILTER_EVENTTYPE
  914. Else
  915. If LCase(strFilterValue) =LCase(PATTERNTYPE_SUCCESSAUDIT) Then
  916. strFilterValue = FLDFILTERTYPE_SUCCESSAUDIT
  917. ElseIf LCase(strFilterValue) =LCase(PATTERNTYPE_FAILUREAUDIT) Then
  918. strFilterValue = FLDFILTERTYPE_FAILUREAUDIT
  919. End If
  920. ' a valid type filter. Prepare for query
  921. strFilterProperty = FLD_FILTER_TYPE
  922. End If
  923. End If
  924. Case L_UserFilterUser_Text
  925. 'Checking " OR " is only supported property EQ "TYPE OR ID" only
  926. If blnOR = True then
  927. WScript.Echo InvalidORSyntaxInFilterErrorMessage
  928. WScript.Quit(EXIT_INVALID_INPUT)
  929. End If
  930. ' these are invalid characters for a user name
  931. ' PATTERN_INVALID_USER
  932. If CInt(component.matchPattern(PATTERN_INVALID_USER, strFilterValue)) > 0 Then
  933. component.vbPrintf L_InvalidUser_ErrorMessage , Array(strFilterValue, strFilter)
  934. WScript.Quit(EXIT_INVALID_INPUT)
  935. Else
  936. ' a valid user filter. Prepare for query
  937. If InStr(1, strFilterValue, "\", VBBinaryCompare) Then
  938. strFilterValue = Replace(strFilterValue, "\","\\")
  939. End If
  940. If LCase(strFilterValue) =LCase(L_TextNa_Text) Then
  941. strFilterValue = Null
  942. End If
  943. End If
  944. strFilterProperty = FLD_FILTER_USER
  945. Case L_UserFilterComputer_Text
  946. ' a valid computer filter. Prepare for query
  947. strFilterProperty = FLD_FILTER_COMPUTER
  948. 'Checking " OR " is only supported property EQ "TYPE OR ID" only
  949. If blnOR = True then
  950. WScript.Echo InvalidORSyntaxInFilterErrorMessage
  951. WScript.Quit(EXIT_INVALID_INPUT)
  952. End If
  953. Case L_UserFilterSource_Text
  954. ' a valid Source filter. Prepare for query
  955. strFilterProperty = FLD_FILTER_SOURCE
  956. 'Checking " OR " is only supported property EQ "TYPE OR ID" only
  957. If blnOR = True then
  958. WScript.Echo InvalidORSyntaxInFilterErrorMessage
  959. WScript.Quit(EXIT_INVALID_INPUT)
  960. End If
  961. Case L_UserFilterDateCategory_Text
  962. 'Checking " OR " is only supported property EQ "TYPE OR ID" only
  963. If blnOR = True then
  964. WScript.Echo InvalidORSyntaxInFilterErrorMessage
  965. WScript.Quit(EXIT_INVALID_INPUT)
  966. End If
  967. ' a valid Category filter. Prepare for query
  968. If LCase(strFilterValue) =LCase(L_TextNone_Text) Then
  969. strFilterValue = Null
  970. End If
  971. strFilterProperty = FLD_FILTER_CATEGORY
  972. Case L_UserFilterId_Text
  973. ' check if the given id is a number
  974. ' PATTERN_ID '"^(\d+)$"
  975. If CInt(component.matchPattern(PATTERN_ID, strFilterValue)) = CONST_NO_MATCHES_FOUND Then
  976. component.vbPrintf L_InvalidId_ErrorMessage, Array(strFilterValue, strFilter)
  977. WScript.Quit(EXIT_INVALID_INPUT)
  978. Else
  979. ' Invalid ID Number validation
  980. If ( Clng(strFilterValue) > CONST_ID_NUMBER )Then
  981. component.vbPrintf L_InvalidId_ErrorMessage, Array(strFilterValue, strFilter)
  982. WScript.Quit(EXIT_INVALID_INPUT)
  983. End If
  984. ' a valid id filter. Prepare for query
  985. strFilterProperty = FLD_FILTER_ID
  986. End If
  987. Case Else
  988. ' invalid filter specified
  989. component.vbPrintf L_InvalidFilter_ErrorMessage, Array(strFilterProperty, strFilter)
  990. WScript.Quit(EXIT_INVALID_INPUT)
  991. End Select
  992. If LCase(strFilterProperty) = LCase(FLD_FILTER_DATETIME) OR IsNull(strFilterValue) Then
  993. ' This is to handle NULL WMI property values i.e in category or type
  994. If IsNull(strFilterValue) Then
  995. strFilter = strFilterProperty & strFilterOperation & strFilterValue & "Null"
  996. Else
  997. strFilter = strFilterProperty & strFilterOperation & strFilterValue
  998. End If
  999. Else
  1000. strFilter = strFilterProperty & _
  1001. strFilterOperation & Chr(34) & strFilterValue & Chr(34)
  1002. End If
  1003. 'Binding the string with "OR or AND " to Prepare for query if blnOR or blnAND is TRUE
  1004. If blnOR =TRUE Then
  1005. If k = 0 then
  1006. strTempFilter = strFilter
  1007. Else
  1008. strTempFilter = strTempFilter & " OR " & strFilter
  1009. End If
  1010. ElseIf blnAND =TRUE Then
  1011. If k = 0 then
  1012. strTempFilter = strFilter
  1013. Else
  1014. strTempFilter = strTempFilter & " AND " & strFilter
  1015. End If
  1016. End If
  1017. Next
  1018. 'Set again making single filter string element if blnOR is TRUE
  1019. If blnOR =TRUE or blnAND = True Then
  1020. 'this "()" Add the order of precedence of operation is SQL
  1021. strFilter = "( " & strTempFilter & ")"
  1022. End If
  1023. 'Here setting filter to main array
  1024. arrFilters(j) = strFilter
  1025. Next
  1026. ValidateFilters = TRUE
  1027. End Function
  1028. '********************************************************************
  1029. '* Function: ReplaceOperators
  1030. '*
  1031. '* Purpose: Replaces the operator in string form with its symbol
  1032. '*
  1033. '* Input:
  1034. '* [in] strFilterOperation the operation
  1035. '*
  1036. '* Output: Returns the symbolic operator
  1037. '* If invalid operator, displays error message and quits
  1038. '*
  1039. '********************************************************************
  1040. Private Function ReplaceOperators(ByVal strFilterOperation)
  1041. ON ERROR RESUME NEXT
  1042. Err.Clear
  1043. Select Case LCase(strFilterOperation)
  1044. Case L_OperatorEq_Text
  1045. ReplaceOperators = SYMBOL_OPERATOR_EQ
  1046. Case L_OperatorNe_Text
  1047. ReplaceOperators = SYMBOL_OPERATOR_NE
  1048. Case L_OperatorGe_Text
  1049. ReplaceOperators = SYMBOL_OPERATOR_GE
  1050. Case L_OperatorLe_Text
  1051. ReplaceOperators = SYMBOL_OPERATOR_LE
  1052. Case L_OperatorGt_Text
  1053. ReplaceOperators = SYMBOL_OPERATOR_GT
  1054. Case L_OperatorLt_Text
  1055. ReplaceOperators = SYMBOL_OPERATOR_LT
  1056. Case Else
  1057. ' not a valid operator
  1058. component.vbPrintf L_Invalid_ErrorMessage, Array(strFilterOperation)
  1059. WScript.Quit(EXIT_INVALID_PARAM)
  1060. End Select
  1061. End Function
  1062. '********************************************************************
  1063. '* Sub : VerifyLogAndGetMaxRecords
  1064. '*
  1065. '* Purpose: populates the output array with count of records in given input array
  1066. '*
  1067. '* Input: [in] objService the WMI service object
  1068. '* [out] objLogs the object containing the logs & max count of records corresponding log
  1069. '*
  1070. '* Output: array's are populates with logfile names and its count of max records
  1071. '*
  1072. '********************************************************************
  1073. Private Sub VerifyLogAndGetMaxRecords(ByVal objService, _
  1074. ByRef objLogs)
  1075. ON ERROR RESUME NEXT
  1076. Err.Clear
  1077. Dim strTempQuery ' string to make query
  1078. Dim objEnumerator ' to get the collection object after query
  1079. Dim objInstance ' to refer to each instance of the results got
  1080. Dim i ' for initialing loop
  1081. Dim strLogFile ' used to store log file inside loop
  1082. Dim arrKeyName ' used to store key value of Dictionary object for processing loop
  1083. arrKeyName = objLogs.Keys
  1084. For i = 0 to objLogs.Count -1
  1085. strLogFile = arrKeyName(i)
  1086. If Not strLogFile = "*" Then
  1087. ' Check if log file exists, by querying
  1088. strTempQuery = "SELECT NumberOfRecords FROM Win32_NTEventlogFile " &_
  1089. "WHERE LogfileName=" & Chr(34) & strLogFile & Chr(34)
  1090. Set objEnumerator = objService.ExecQuery(strTempQuery,,0)
  1091. If Err.Number Then
  1092. component.vbPrintf L_ExecuteQuery_ErrorMessage, Array(strLogFile)
  1093. WScript.Quit(EXIT_METHOD_FAIL)
  1094. End If
  1095. ' check if given log is present
  1096. If ObjEnumerator.Count <> 1 Then
  1097. component.vbPrintf L_LogDoesNotExist_ErrorMessage, Array(strLogFile)
  1098. 'If Count of Logs = 1 Quit Here
  1099. If objLogs.Count= 1 Then
  1100. WScript.Quit(EXIT_INVALID_INPUT)
  1101. End If
  1102. 'If more proceed ..
  1103. objLogs.Remove(strLogFile)
  1104. Else
  1105. ' get maximum number of records in that log(used if range specified)
  1106. For each objInstance in objEnumerator
  1107. If objInstance.NumberOfRecords <> "" Then
  1108. objLogs.Item(strLogFile) = objInstance.NumberOfRecords
  1109. Else
  1110. objLogs.Item(strLogFile) = 0
  1111. End If
  1112. Next
  1113. End If
  1114. Set ObjEnumerator = Nothing
  1115. End If
  1116. Next
  1117. If objLogs.Exists("*") Then
  1118. ' if the * is specified, populate array with elements
  1119. objLogs.Remove("*")
  1120. ' get the instances of the logs present in the system
  1121. Set objEnumerator = objService.InstancesOf(CLASS_EVENTLOG_FILE)
  1122. If Err.number Then
  1123. Wscript.Echo (L_InstancesFailed_ErrorMessage)
  1124. WScript.Quit(EXIT_METHOD_FAIL)
  1125. End If
  1126. ' if no logs present
  1127. If objEnumerator.Count <= 0 Then
  1128. WScript.Echo (L_InfoNoLogsPresent_Message)
  1129. WScript.Quit(EXIT_UNEXPECTED)
  1130. Else
  1131. For Each objInstance In objEnumerator
  1132. If Not IsEmpty(objInstance.LogfileName) Then
  1133. If NOT objLogs.Exists(LCase(objInstance.LogfileName)) Then
  1134. If objInstance.NumberOfRecords Then
  1135. objLogs.Add LCase(objInstance.LogfileName), objInstance.NumberOfRecords
  1136. Else
  1137. objLogs.Add LCase(objInstance.LogfileName), 0
  1138. End If
  1139. End If
  1140. End If
  1141. Next
  1142. End If
  1143. End If
  1144. End Sub
  1145. '********************************************************************
  1146. '* Function: BuildFiltersForQuery
  1147. '*
  1148. '* Purpose: Builds the query with the filter arguments
  1149. '*
  1150. '* Input: [in] arrFilters the array containing the filter conditions
  1151. '*
  1152. '* Output: Returns the string to be concatenated to the main query
  1153. '*
  1154. '********************************************************************
  1155. Function BuildFiltersForQuery(ByVal arrFilters)
  1156. ON ERROR RESUME NEXT
  1157. Err.Clear
  1158. Dim strTempFilter ' to store the return string
  1159. Dim i ' used in loop
  1160. strTempFilter = ""
  1161. For i = 0 to UBound(arrFilters)
  1162. strTempFilter = strTempFilter & " AND "
  1163. strTempFilter = strTempFilter & arrFilters(i)
  1164. Next
  1165. BuildFiltersForQuery = strTempFilter
  1166. End Function
  1167. '********************************************************************
  1168. '* Function : BuildRangeForQuery
  1169. '*
  1170. '* Purpose: Builds the range boundaries to display the records.
  1171. '*
  1172. '* Input: [in] strRange ' the range specified by the user
  1173. '* Will be in the format N, -N or N-N
  1174. '* [in] intFiltersSpecified ' array containing the filters number
  1175. '* [in] objService ' the service object
  1176. '* [out] intRecordRangeFrom ' where do we start the display of records?
  1177. '* [out] intRecordRangeTo ' where do we stop displaying records
  1178. '* [out] strFilterLog ' log file to build query
  1179. '* [out] strQuery ' to build query according to given Range Type
  1180. '* Output: Sets the value for the start and end of display boundaries.
  1181. '*
  1182. '********************************************************************
  1183. Private Function BuildRangeForQuery(ByVal strRange, _
  1184. ByRef intRecordRangeFrom, _
  1185. ByRef intRecordRangeTo,_
  1186. ByVal intFiltersSpecified,_
  1187. ByRef strQuery,_
  1188. ByVal ObjService,_
  1189. ByVal strFilterLog )
  1190. ON ERROR RESUME NEXT
  1191. Err.Clear
  1192. Dim intMaxEventRecordsPresent ' to store the max recods in the log
  1193. Dim arrRangeValues ' to store the split values if range is of the type N-N
  1194. Dim objInstance ' to refer to the instances of the objEnumerator
  1195. Dim objEnumerator ' to store the results of the query is executed
  1196. Dim FilterRecordCount ' to store the count of records if filter with +N specified
  1197. FilterRecordCount = 0
  1198. BuildRangeForQuery = strquery 'intialize
  1199. Dim currentMaxRecordnumber 'curentMaxrecord number
  1200. Dim currentMinRecordnumber 'curentMinrecord number
  1201. currentMaxRecordnumber = 0
  1202. currentMinRecordnumber = 0
  1203. ' save the max. no. of records available in the current log
  1204. intMaxEventRecordsPresent = intRecordRangeTo
  1205. ' find the count of events / logfile if Filter is specified .
  1206. If intFiltersSpecified >= 0 Then
  1207. Set objEnumerator = objService.ExecQuery(strQuery,"WQL",0,null)
  1208. If Err.number Then
  1209. component.vbPrintf L_ExecuteQuery_ErrorMessage, Array(strFilterLog)
  1210. Exit Function
  1211. End if
  1212. FilterRecordCount= objEnumerator.count
  1213. Set objEnumerator= Nothing 'releases the memory
  1214. End If
  1215. ' check the type of range specified ( first N / last N / N1 - N2 )
  1216. If ( IsNumeric(strRange) ) Then
  1217. ' range is first N or last N
  1218. ' now check whether it is first N or last N
  1219. If strRange < 0 Then
  1220. If intFiltersSpecified >= 0 Then
  1221. ' first N records
  1222. ' initial the counter so that all the out is displayed
  1223. If FilterRecordCount > CLng(Abs(strRange)) then
  1224. intRecordRangeFrom = FilterRecordCount - CLng(Abs(strRange)) + 1
  1225. intRecordRangeTo = FilterRecordCount
  1226. Else
  1227. intRecordRangeFrom = 0
  1228. intRecordRangeTo = FilterRecordCount
  1229. End If
  1230. Else
  1231. Set objEnumerator = objService.ExecQuery(strQuery,"WQL",48,null)
  1232. For Each objInstance In objEnumerator
  1233. currentMaxRecordnumber= objInstance.RecordNumber
  1234. Exit for
  1235. Next
  1236. If currentMaxRecordnumber > intMaxEventRecordsPresent then
  1237. currentMinRecordnumber = currentMaxRecordnumber - intMaxEventRecordsPresent
  1238. intMaxEventRecordsPresent = currentMaxRecordnumber
  1239. End If
  1240. Set objEnumerator= Nothing 'releases the memory
  1241. ' N means record number <= N
  1242. ' initial the counter s+o that all the out is displayed
  1243. ' build the query
  1244. BuildRangeForQuery = strQuery & " AND RecordNumber <= "& CLng(Abs(strRange)) + currentMinRecordnumber
  1245. End If
  1246. Else
  1247. ' *** range is last N (i.e -N)
  1248. If intFiltersSpecified >= 0 Then
  1249. If FilterRecordCount > CLng(Abs(strRange)) then
  1250. intRecordRangeFrom =0
  1251. intRecordRangeTo = CLng(Abs(strRange))
  1252. Else
  1253. intRecordRangeFrom =0
  1254. intRecordRangeTo = FilterRecordCount
  1255. End If
  1256. Else
  1257. Set objEnumerator = objService.ExecQuery(strQuery,"WQL",48,null)
  1258. 'getting current max recordnumber
  1259. For Each objInstance In objEnumerator
  1260. currentMaxRecordnumber= objInstance.RecordNumber
  1261. Exit for
  1262. Next
  1263. If currentMaxRecordnumber > intMaxEventRecordsPresent then
  1264. currentMinRecordnumber = currentMaxRecordnumber - intMaxEventRecordsPresent
  1265. intMaxEventRecordsPresent = currentMaxRecordnumber
  1266. End If
  1267. Set objEnumerator= Nothing 'releases the memory
  1268. ' -N means record number > (maxNumber - N )
  1269. ' initial the counter so that all the out is displayed
  1270. ' build the query
  1271. If CLng(Abs(strRange)) > intMaxEventRecordsPresent Then
  1272. 'Show all records
  1273. BuildRangeForQuery =strQuery & " AND RecordNumber > 0 "
  1274. Else
  1275. BuildRangeForQuery =strQuery & " AND RecordNumber > " & intMaxEventRecordsPresent - CLng(Abs(strRange))
  1276. End If
  1277. End If
  1278. End If
  1279. Else
  1280. ' range of records asked for N-N case
  1281. arrRangeValues = split(strRange,"-", 2, VBBinaryCompare)
  1282. If intFiltersSpecified >= 0 Then
  1283. If CLng(arrRangeValues(0)) < FilterRecordCount then
  1284. ' initial the counter so that all the out is displayed
  1285. intRecordRangeFrom = CLng(arrRangeValues(0))
  1286. intRecordRangeTo = CLng(arrRangeValues(1))
  1287. Else
  1288. 'forcebly putting the invaid query
  1289. 'when N1 > FilterRecordCount to avoid unnessaray looping between intRecordRangeFrom TO intRecordRangeTo
  1290. BuildRangeForQuery =strQuery & " AND RecordNumber = 0 "
  1291. End If
  1292. Else
  1293. Set objEnumerator = objService.ExecQuery(strQuery,"WQL",48,null)
  1294. For Each objInstance In objEnumerator
  1295. currentMaxRecordnumber= objInstance.RecordNumber
  1296. Exit for
  1297. Next
  1298. If currentMaxRecordnumber > intMaxEventRecordsPresent then
  1299. currentMinRecordnumber = currentMaxRecordnumber - intMaxEventRecordsPresent
  1300. intMaxEventRecordsPresent = currentMaxRecordnumber
  1301. End If
  1302. Set objEnumerator= Nothing 'releases the memory
  1303. ' build the query
  1304. BuildRangeForQuery =strQuery & " AND RecordNumber >= "& CLng(arrRangeValues(0))+ currentMinRecordnumber & " AND RecordNumber <= " & CLng(arrRangeValues(1)) + currentMinRecordnumber
  1305. End If
  1306. End If
  1307. End Function
  1308. '********************************************************************
  1309. '* Sub: ShowEvents
  1310. '*
  1311. '* Purpose: Displays the EventLog details
  1312. '*
  1313. '* Input:
  1314. '* [in] strMachine machine to query events from
  1315. '* [in] strUserName user name to connect to the machine
  1316. '* [in] strPassword password for the user
  1317. '* [in] arrFilters the array containing the filters
  1318. '* [in] strFormat the display format
  1319. '* [in] strRange the range of records required
  1320. '* [in] blnVerboseDisplay flag to verify if verbose display is needed
  1321. '* [in] blnNoHeader flag to verify if noheader display is needed
  1322. '* [in] objLogs to store all the given logfles
  1323. '* Output: Displays error message and quits if connection fails
  1324. '* Calls component.showResults() to display the event records
  1325. '*
  1326. '********************************************************************
  1327. Private Sub ShowEvents(ByVal strMachine, _
  1328. ByVal strUserName, _
  1329. ByVal strPassword, _
  1330. ByRef arrFilters, _
  1331. ByVal strFormat, _
  1332. ByVal strRange, _
  1333. ByVal blnVerboseDisplay, _
  1334. ByVal blnNoHeader,_
  1335. ByRef objLogs)
  1336. ON ERROR RESUME NEXT
  1337. Err.Clear
  1338. Dim objService ' the WMI service object
  1339. Dim objEnumerator ' to store the results of the query is executed
  1340. Dim objInstance ' to refer to the instances of the objEnumerator
  1341. Dim strFilterLog ' to refer to each log specified by the user
  1342. Dim strTemp ' to store the temporary variables
  1343. Dim strQuery ' to store the query obtained for given conditions
  1344. Dim arrResults ' to store the columns of each filter
  1345. Dim arrHeader ' to store the array header values
  1346. Dim arrMaxLength ' to store the maximum length for each column
  1347. Dim arrFinalResults ' used to send the arrResults to component.showResults()
  1348. Dim arrTemp ' to store temporary array values
  1349. Dim intLoopCount ' used in the loop
  1350. Dim intElementCount ' used as array subscript
  1351. Dim strFilterQuery ' to store the query for the given filters
  1352. Dim intResultCount ' used to count no of records that are fetched in the query
  1353. Dim blnPrintHeader ' used to check header is printed or not in resulted Query
  1354. ' the following are used for implementing the range option
  1355. Dim intRecordRangeFrom ' to store the display record beginning number
  1356. Dim intRecordRangeTo ' to store the display record ending number
  1357. Dim arrKeyName ' to store then key value of dictionary object
  1358. Dim strTempQuery ' to store a string for -N range values
  1359. Dim arrblnDisplay ' array to show the status of display of verbose mode for showresults function
  1360. Dim intDataCount ' used in looping to get value of Insertion string for the field "Description column"
  1361. Dim i ' used for looping to enable All special privileges
  1362. Dim objDateTimeObject ' Object to get the date and time in the current locale/calender format.
  1363. ' flag to set condition specific locale & default value setting
  1364. Dim bLocaleChanged
  1365. bLocaleChanged =FALSE
  1366. 'Validating the arguments which are passed from commandline
  1367. If NOT (ValidateArguments(strMachine, strUserName, strPassword, _
  1368. arrFilters, strFormat, strRange , blnNoHeader)) Then
  1369. WScript.Quit(EXIT_UNEXPECTED)
  1370. End If
  1371. ' checking for UNC format (\\machine) for the system name
  1372. If Left(strMachine,2) = UNC_Format_Servername Then
  1373. If Len(strMachine) = 2 Then
  1374. component.vbPrintf InvalidInputErrorMessage ,Array(Wscript.ScriptName)
  1375. WScript.Quit(EXIT_UNEXPECTED)
  1376. End if
  1377. strMachine = Mid(strMachine,3,Len(strMachine))
  1378. End If
  1379. 'getting the password ....
  1380. If ((strUserName <> VBEmpty) AND ((strPassword = VBEmpty) OR (strPassword = "*")))Then
  1381. strPassword = component.getPassword()
  1382. End If
  1383. ' To set GetSupportedUserLocale for Some Diff locales
  1384. bLocaleChanged =GetSupportedUserLocale()
  1385. 'Establish a connection with the server.
  1386. If NOT component.wmiConnect(CONST_NAMESPACE_CIMV2 , _
  1387. strUserName , _
  1388. strPassword , _
  1389. strMachine , _
  1390. blnLocalConnection , _
  1391. objService ) Then
  1392. Wscript.Echo(L_HintCheckConnection_Message)
  1393. WScript.Quit(EXIT_METHOD_FAIL)
  1394. End If
  1395. ' set the previlige's To query all event's in eventlog's .
  1396. objService.Security_.Privileges.AddAsString("SeSecurityPrivilege")
  1397. 'Enable all privileges as some DC's were requiring special privileges
  1398. For i = 1 to 26
  1399. objService.Security_.Privileges.Add(i)
  1400. Next
  1401. ' get the HostName from the function
  1402. strMachine = component.getHostName( objService)
  1403. ' Validating the Filter which is passed from commandline
  1404. If UBound(arrFilters) >= 0 Then
  1405. ' filters are specified. Validate them
  1406. If Not ValidateFilters(arrFilters,objService ) Then
  1407. WScript.Quit(EXIT_INVALID_INPUT)
  1408. End If
  1409. End If
  1410. blnPrintHeader = TRUE
  1411. If blnNoHeader Then
  1412. blnPrintHeader = FALSE
  1413. End If
  1414. ' Initialize - header to display, the maximum length of each column and
  1415. ' number of columns present
  1416. arrHeader = Array(L_ColHeaderType_Text,L_ColHeaderEventcode_Text, L_ColHeaderDateTime_Text,_
  1417. L_ColHeaderSource_Text,L_ColHeaderComputerName_Text)
  1418. ' first initialize the array with N/A
  1419. arrResults = Array(L_TextNa_Text,L_TextNa_Text,L_TextNa_Text,L_TextNa_Text,L_TextNa_Text,L_TextNa_Text,_
  1420. L_TextNa_Text,L_TextNa_Text)
  1421. arrMaxLength = Array(L_ColHeaderTypeLength_Text,L_ColHeaderEventcodeLength_Text, L_ColHeaderDateTimeLength_Text,_
  1422. L_ColHeaderSourceLength_Text, L_ColHeaderComputerNameLength_Text, L_ColHeaderCategoryLength_Text,_
  1423. L_ColHeaderUserLength_Text, L_ColHeaderDesriptionLength_Text)
  1424. arrblnDisplay = Array(0, 0, 0, 0, 0, 1, 1, 1)
  1425. If blnVerboseDisplay Then
  1426. arrblnDisplay = Array(0, 0, 0, 0, 0, 0, 0,0)
  1427. arrHeader = Array( L_ColHeaderType_Text,L_ColHeaderEventcode_Text, L_ColHeaderDateTime_Text, _
  1428. L_ColHeaderSource_Text,L_ColHeaderComputerName_Text,L_ColHeaderCategory_Text,_
  1429. L_ColHeaderUser_Text, L_ColHeaderDesription_Text)
  1430. End IF
  1431. If UBound(arrFilters) >=0 Then
  1432. strFilterQuery = BuildFiltersForQuery(arrFilters)
  1433. End If
  1434. ' call function to verify given log and also get records count in log
  1435. Call VerifyLogAndGetMaxRecords(objService, objLogs)
  1436. arrKeyName = objLogs.Keys
  1437. intResultCount = 0
  1438. intLoopCount = 0
  1439. ' not to display any blank line for CSV format
  1440. If Not ( Lcase(strFormat) = Lcase(Const_Csv_Format_Text)) Then
  1441. ' blank line before first data is displayed on console
  1442. WScript.Echo EmptyLine_Text
  1443. End If
  1444. Do While (intLoopCount < objLogs.Count)
  1445. 'setting Header to print every Log file explicilty
  1446. If blnNoHeader Then
  1447. blnPrintHeader = FALSE
  1448. Else
  1449. blnPrintHeader = TRUE
  1450. End If
  1451. If CLng(objLogs.Item(arrKeyName(intLoopCount))) > 0 Then
  1452. strFilterLog = arrKeyName(intLoopCount)
  1453. intRecordRangeFrom = 0
  1454. intRecordRangeTo = CLng(objLogs.Item(arrKeyName(intLoopCount)))
  1455. ' build the query
  1456. strQuery = "Select * FROM Win32_NTLogEvent WHERE Logfile=" &_
  1457. Chr(34) & strFilterLog & Chr(34)
  1458. If UBound(arrFilters) >=0 Then
  1459. strQuery = strQuery & strFilterQuery
  1460. End If
  1461. If Len(Trim(CStr(strRange))) > 0 Then
  1462. ' building again query for -N condition in range switch
  1463. strQuery = BuildRangeForQuery(strRange,intRecordRangeFrom, _
  1464. intRecordRangeTo, UBound(arrFilters),strQuery,objService,strFilterLog)
  1465. End If
  1466. ' process the results, else go for next log
  1467. Set objEnumerator = objService.ExecQuery(strQuery,"WQL",48,null)
  1468. If Err.Number Then
  1469. component.vbPrintf L_ExecuteQuery_ErrorMessage, Array(strFilterLog)
  1470. ' if error occurred in the query, go for next log
  1471. intLoopCount = intLoopCount + 1
  1472. Err.clear ' for next loop if more logs present
  1473. Else
  1474. intElementCount = 0
  1475. ' Create DateTimeObject to get the date and time in user specific format.
  1476. Set objDateTimeObject = CreateObject("ScriptingUtils.DateTimeObject")
  1477. If Err.Number Then
  1478. component.vbPrintf L_ComponentNotFound_ErrorMessage, Array("ScriptingUtils.DateTimeObject")
  1479. WScript.Quit(EXIT_METHOD_FAIL)
  1480. End If
  1481. ReDim arrFinalResults(CONST_ARRAYBOUND_NUMBER)
  1482. For each objInstance in objEnumerator
  1483. ' inside error trapping for most unexpected case...
  1484. If Err.number then Exit For
  1485. intResultCount = intResultCount + 1
  1486. 'print the header for each log file along with Host Name
  1487. 'important:: if and only if we have Data
  1488. If intResultCount = 1 Then
  1489. ' not to display any header for CSV format
  1490. If NOT ( Lcase(strFormat) = Lcase(Const_Csv_Format_Text)) Then
  1491. WScript.Echo(String(78,"-"))
  1492. component.vbPrintf L_InfoDisplayLog_Message ,Array(strFilterLog,strMachine)
  1493. WScript.Echo(String(78,"-"))
  1494. End If
  1495. End If
  1496. ' check whether the current record is fitting
  1497. ' within the required range
  1498. If ( intResultCount >= intRecordRangeFrom ) And _
  1499. ( intResultCount <= intRecordRangeTo ) Then
  1500. ' record fitting the range ... this has to be displayed
  1501. If objInstance.Type <> "" Then
  1502. arrResults(0) = objInstance.Type
  1503. Else
  1504. arrResults(0) = L_TextNa_Text
  1505. End If
  1506. If objInstance.EventCode <> "" Then
  1507. arrResults(1) = objInstance.EventCode
  1508. Else
  1509. arrResults(1) = L_TextNa_Text
  1510. End If
  1511. If (NOT IsEmpty(objInstance.TimeGenerated)) Then
  1512. strTemp = objInstance.TimeGenerated
  1513. 'is LOCALE CHANGED
  1514. If bLocaleChanged <> TRUE Then
  1515. 'format DatTime as DATE & "Space" & TIME
  1516. ' Use new sriptutil library dll version instead
  1517. arrResults(2) = objDateTimeObject.GetDateAndTime(strTemp)
  1518. Else
  1519. arrResults(2) = Mid(strTemp,5,2) & "/" & Mid(strTemp,7,2) & "/" &_
  1520. Mid(strTemp,1,4) & " " & Mid(strTemp,9,2) & ":" &_
  1521. Mid(strTemp,11,2) & ":" & Mid(strTemp,13,2)
  1522. End If
  1523. Else
  1524. arrResults(2) = L_TextNa_Text
  1525. End If
  1526. If objInstance.SourceName <> "" Then
  1527. arrResults(3) = objInstance.SourceName
  1528. Else
  1529. arrResults(3) = L_TextNa_Text
  1530. End If
  1531. If objInstance.ComputerName <> "" Then
  1532. arrResults(4) =objInstance.ComputerName
  1533. Else
  1534. arrResults(4) = L_TextNa_Text
  1535. End If
  1536. If blnVerboseDisplay Then
  1537. If objInstance.CategoryString <> "" Then
  1538. arrResults(5) = Replace(objInstance.CategoryString, VbCrLf, "")
  1539. Else
  1540. arrResults(5) = L_TextNone_Text ' None display
  1541. End If
  1542. If (NOT IsNull(objInstance.User)) Then
  1543. arrResults(6) = objInstance.User
  1544. Else
  1545. arrResults(6) = L_TextNa_Text
  1546. End If
  1547. If objInstance.Message <> "" Then
  1548. arrResults(7) = Trim(Replace(Replace(objInstance.Message, VbCrLf, " "),VbCr," "))
  1549. Else
  1550. 'Check whether either value is present in "InsertionStrings" column .
  1551. If (NOT IsNull(objInstance.InsertionStrings)) Then
  1552. arrTemp = objInstance.InsertionStrings
  1553. 'removing default value "N/A"
  1554. arrResults(7)= ""
  1555. For intDataCount = 0 to UBound(arrTemp)
  1556. arrResults(7) = arrResults(7) & " " & Trim(Replace(Replace(arrTemp(intDataCount), VbCrLf, " ") ,VbCr," "))
  1557. Next
  1558. arrResults(7) = Trim(arrResults(7))
  1559. Else
  1560. arrResults(7) = L_TextNa_Text
  1561. End If
  1562. End If
  1563. End If
  1564. ' add the record to the queue of records that has to be displayed
  1565. arrFinalResults( intElementCount ) = arrResults
  1566. intElementCount = intElementCount + 1 ' increment the buffer
  1567. ' check whether the output buffer is filled and ready for display
  1568. ' onto the screen or not
  1569. If intElementCount = CONST_ARRAYBOUND_NUMBER +1 Then
  1570. ' Disable error handler for any broken pipe can catch by HOST
  1571. On Error GoTo 0
  1572. ' Call the display function with required parameters
  1573. Call component.showResults(arrHeader, arrFinalResults, arrMaxLength, _
  1574. strFormat, blnPrintHeader, arrblnDisplay)
  1575. blnPrintHeader = FALSE
  1576. ' Enable error handler
  1577. On Error Resume Next
  1578. Redim arrFinalResults(CONST_ARRAYBOUND_NUMBER) ' clear the existing buffer contents
  1579. intElementCount = 0 ' reset the buffer start
  1580. End If
  1581. End If
  1582. ' check whether the last record number that has to be displayed is
  1583. ' crossed or not ... if crossed exit the loop without proceeding further
  1584. If ( intResultCount >= intRecordRangeTo ) Then
  1585. ' max. TO range is crossed/reached ... no need of further looping
  1586. Exit For
  1587. End If
  1588. Next
  1589. ' Release the component as we dont need it any more.
  1590. Set objDateTimeObject = Nothing
  1591. ' check whether there any pending in the output buffer that has to be
  1592. ' displayed
  1593. If intElementCount > 0 Then
  1594. ' resize the array so that the buffer is shrinked to its content size
  1595. ReDim Preserve arrFinalResults( intElementCount - 1 )
  1596. ' Disable error handler for any broken pipe can catch by HOST
  1597. On Error GoTo 0
  1598. ' Call the display function with required parameters
  1599. Call component.showResults(arrHeader, arrFinalResults, arrMaxLength, _
  1600. strFormat, blnPrintHeader, arrblnDisplay)
  1601. ' Enable error handler
  1602. On Error Resume Next
  1603. Else ' array bounds checking
  1604. If intResultCount = 0 Then
  1605. 'ie no records found
  1606. If UBound(arrFilters) >= 0 OR Len(Trim(CStr(strRange))) > 0 Then
  1607. ' message no records present if filter specified
  1608. component.vbPrintf L_InfoNoRecordsInFilter_Message, Array(strFilterLog)
  1609. Else
  1610. 'message no records present if filter not specified
  1611. component.vbPrintf L_InfoNoRecords_Message, Array(strFilterLog)
  1612. End If
  1613. End If ' intResultCount = 0
  1614. End If ' array bounds checking
  1615. End If
  1616. Else
  1617. 'message no records present
  1618. component.vbPrintf L_InfoNoRecords_Message, Array(arrKeyName(intLoopCount))
  1619. ' to print any blank line for LIST format if no records present
  1620. If (Lcase(strFormat) = Lcase(Const_LIST_Format_Text)) AND (intLoopCount < objLogs.Count )Then
  1621. ' blank line before end of the Next Each Log file details
  1622. WScript.Echo EmptyLine_Text
  1623. END If
  1624. End If
  1625. ' re-initialize all the needed variables
  1626. intResultCount = 0
  1627. Set objEnumerator = Nothing
  1628. intLoopCount = intLoopCount + 1
  1629. ' display blank line for next log except List format
  1630. If ( Lcase(strFormat) <> Lcase(Const_LIST_Format_Text)) Then
  1631. If (intLoopCount < objLogs.Count) then
  1632. ' blank line before end of the Next Each Log file details
  1633. WScript.Echo EmptyLine_Text
  1634. End If
  1635. End If
  1636. Loop ' do-while
  1637. End Sub
  1638. '********************************************************************
  1639. '* Function: GetSupportedUserLocale
  1640. '*
  1641. '* Purpose:This function checks if the current locale is supported or not.
  1642. '*
  1643. '* Output: Returns TRUE or FALSE
  1644. '*
  1645. '********************************************************************
  1646. Private Function GetSupportedUserLocale()
  1647. ON ERROR RESUME NEXT
  1648. Err.Clear
  1649. GetSupportedUserLocale =FALSE
  1650. CONST LANG_ARABIC = &H01
  1651. CONST LANG_HEBREW = &H0d
  1652. CONST LANG_HINDI = &H39
  1653. CONST LANG_TAMIL = &H49
  1654. CONST LANG_THAI = &H1e
  1655. CONST LANG_VIETNAMESE = &H2a
  1656. ' extract primary language id from a language id
  1657. ' i.e. PRIMARYLANGID(lgid) ((WORD )(lgid) & 0x3ff)
  1658. ' const for bitwise operation
  1659. CONST SUBID = 1023 '0x3ff
  1660. Dim Lcid ' to store LocaleId
  1661. Dim PrimarylangId ' to store PRIMARYLANGID
  1662. ' get the current locale
  1663. Lcid=GetLocale()
  1664. ' Convert LCID >>>>>>>>>>>>> PRIMARYLANGID
  1665. ' BIT Wise And Operation
  1666. ' formating to compare HEX Value's
  1667. PrimarylangId = Hex ( Lcid AND SUBID)
  1668. ' check whether the current locale is supported by our tool or not
  1669. ' if not change the locale to the English which is our default locale
  1670. Select Case PrimarylangId
  1671. ' here to check the values
  1672. Case Hex(LANG_ARABIC),Hex(LANG_HEBREW),Hex(LANG_THAI) ,Hex(LANG_HINDI ),Hex(LANG_TAMIL) ,Hex(LANG_VIETNAMESE)
  1673. GetSupportedUserLocale =TRUE
  1674. Exit Function
  1675. End Select
  1676. End Function
  1677. ' ****************************************************************************************
  1678. '* Function : IsWinXP
  1679. '*
  1680. '* Purpose:This function checks if the OS is Windows XP or newer.
  1681. '*
  1682. '* Input: [in] Objservice the service object
  1683. '* Output: Returns TRUE or FALSE
  1684. '*
  1685. ' ****************************************************************************************
  1686. Private Function IsWinXP ( ByVal objService)
  1687. ON ERROR RESUME NEXT
  1688. Err.Clear
  1689. CONST WIN2K_MAJOR_VERSION = 5000
  1690. CONST WINXP_MAJOR_VERSION = 5001
  1691. Dim strQuery ' to store the query to be executed
  1692. Dim objEnum ' collection object
  1693. Dim objInstance ' instance object
  1694. Dim strVersion ' to store the OS version
  1695. Dim arrVersionElements ' to store the OS version elements
  1696. Dim CurrentMajorVersion ' the major version number
  1697. ISWinXP= FALSE
  1698. strQuery = "Select * From Win32_operatingsystem"
  1699. Set objEnum = objService.ExecQuery(strQuery,"WQL",0,NULL)
  1700. For each objInstance in objEnum
  1701. strVersion= objInstance.Version
  1702. Next
  1703. ' OS Version : 5.1.xxxx(Windows XP), 5.0.xxxx(Windows 2000)
  1704. arrVersionElements = split(strVersion,".")
  1705. ' converting to major version
  1706. CurrentMajorVersion = arrVersionElements(0) * 1000 + arrVersionElements(1)
  1707. ' Determine the OS Type
  1708. ' WinXP > Win2K
  1709. If CInt(CurrentMajorVersion) >= CInt(WINXP_MAJOR_VERSION) Then
  1710. IsWinXP= TRUE
  1711. End If
  1712. End Function
  1713. ' ****************************************************************************************
  1714. '* Function : ExpandEnvironmentString()
  1715. '*
  1716. '* Purpose:This function Expands the Environment Variables
  1717. '*
  1718. '* Input: [in] strOriginalString the string need to expand for EnvironmentsettingValue
  1719. '* Output: Returns ExpandedEnvironmentString
  1720. '*
  1721. ' ****************************************************************************************
  1722. Private Function ExpandEnvironmentString( ByVal strOriginalString)
  1723. ON ERROR RESUME NEXT
  1724. Err.Clear
  1725. Dim ObjWshShell ' Object to hold Shell
  1726. 'create the shell object
  1727. Set ObjWshShell = CreateObject("WScript.Shell")
  1728. If Err.Number Then
  1729. component.vbPrintf L_ComponentNotFound_ErrorMessage, Array("WScript.Shell")
  1730. WScript.Quit(EXIT_METHOD_FAIL)
  1731. End If
  1732. 'return the string
  1733. ExpandEnvironmentString= ObjWshShell.ExpandEnvironmentStrings(strOriginalString)
  1734. End Function
  1735. '********************************************************************
  1736. '* Sub: ShowUsage
  1737. '*
  1738. '* Purpose: Shows the correct usage to the user.
  1739. '*
  1740. '* Output: Help messages are displayed on screen.
  1741. '*
  1742. '********************************************************************
  1743. Private Sub ShowUsage ()
  1744. WScript.Echo EmptyLine_Text
  1745. WScript.Echo L_ShowUsageLine01_Text
  1746. WScript.Echo L_ShowUsageLine02_Text
  1747. WScript.Echo EmptyLine_Text
  1748. WScript.Echo L_ShowUsageLine03_Text
  1749. WScript.Echo L_ShowUsageLine04_Text
  1750. WScript.Echo L_ShowUsageLine05_Text
  1751. WScript.Echo EmptyLine_Text
  1752. WScript.Echo L_ShowUsageLine06_Text
  1753. WScript.Echo L_ShowUsageLine07_Text
  1754. WScript.Echo EmptyLine_Text
  1755. WScript.Echo L_ShowUsageLine08_Text
  1756. WScript.Echo L_ShowUsageLine09_Text
  1757. WScript.Echo EmptyLine_Text
  1758. WScript.Echo L_ShowUsageLine10_Text
  1759. WScript.Echo L_ShowUsageLine11_Text
  1760. WScript.Echo EmptyLine_Text
  1761. WScript.Echo L_ShowUsageLine12_Text
  1762. WScript.Echo L_ShowUsageLine13_Text
  1763. WScript.Echo L_ShowUsageLine14_Text
  1764. WScript.Echo EmptyLine_Text
  1765. WScript.Echo L_ShowUsageLine15_Text
  1766. WScript.Echo L_ShowUsageLine16_Text
  1767. WScript.Echo EmptyLine_Text
  1768. WScript.Echo L_ShowUsageLine17_Text
  1769. WScript.Echo L_ShowUsageLine18_Text
  1770. WScript.Echo L_ShowUsageLine19_Text
  1771. WScript.Echo EmptyLine_Text
  1772. WScript.Echo L_ShowUsageLine20_Text
  1773. WScript.Echo L_ShowUsageLine21_Text
  1774. WScript.Echo L_ShowUsageLine22_Text
  1775. WScript.Echo L_ShowUsageLine23_Text
  1776. WScript.Echo L_ShowUsageLine24_Text
  1777. WScript.Echo EmptyLine_Text
  1778. WScript.Echo L_ShowUsageLine25_Text
  1779. WScript.Echo L_ShowUsageLine26_Text
  1780. WScript.Echo L_ShowUsageLine27_Text
  1781. WScript.Echo EmptyLine_Text
  1782. WScript.Echo L_ShowUsageLine28_Text
  1783. WScript.Echo EmptyLine_Text
  1784. WScript.Echo L_ShowUsageLine29_Text
  1785. WScript.Echo EmptyLine_Text
  1786. WScript.Echo L_ShowUsageLine30_Text
  1787. WScript.Echo L_ShowUsageLine31_Text
  1788. WScript.Echo L_ShowUsageLine32_Text
  1789. WScript.Echo L_ShowUsageLine33_Text
  1790. WScript.Echo L_ShowUsageLine34_Text
  1791. WScript.Echo L_ShowUsageLine35_Text
  1792. WScript.Echo L_ShowUsageLine36_Text
  1793. WScript.Echo L_ShowUsageLine37_Text
  1794. WScript.Echo L_ShowUsageLine38_Text
  1795. WScript.Echo L_ShowUsageLine39_Text
  1796. WScript.Echo L_ShowUsageLine40_Text
  1797. WScript.Echo EmptyLine_Text
  1798. WScript.Echo L_ShowUsageLine41_Text
  1799. WScript.Echo L_ShowUsageLine42_Text
  1800. WScript.Echo EmptyLine_Text
  1801. WScript.Echo L_ShowUsageLine43_Text
  1802. WScript.Echo L_ShowUsageLine44_Text
  1803. WScript.Echo L_ShowUsageLine45_Text
  1804. WScript.Echo L_ShowUsageLine46_Text
  1805. WScript.Echo L_ShowUsageLine47_Text
  1806. WScript.Echo L_ShowUsageLine48_Text
  1807. WScript.Echo L_ShowUsageLine49_Text
  1808. WScript.Echo L_ShowUsageLine50_Text
  1809. WScript.Echo L_ShowUsageLine51_Text
  1810. WScript.Echo L_ShowUsageLine52_Text
  1811. WScript.Echo L_ShowUsageLine53_Text
  1812. WScript.Echo L_ShowUsageLine54_Text
  1813. WScript.Echo L_ShowUsageLine55_Text
  1814. End Sub
  1815. '-----------------------------------------------------------------------------
  1816. ' End of the Script
  1817. '-----------------------------------------------------------------------------
  1818. '' SIG '' Begin signature block
  1819. '' SIG '' MIIaLwYJKoZIhvcNAQcCoIIaIDCCGhwCAQExDjAMBggq
  1820. '' SIG '' hkiG9w0CBQUAMGYGCisGAQQBgjcCAQSgWDBWMDIGCisG
  1821. '' SIG '' AQQBgjcCAR4wJAIBAQQQTvApFpkntU2P5azhDxfrqwIB
  1822. '' SIG '' AAIBAAIBAAIBAAIBADAgMAwGCCqGSIb3DQIFBQAEELmj
  1823. '' SIG '' QQS0Y3CEMHawptKqDgegghS8MIICvDCCAiUCEEoZ0jiM
  1824. '' SIG '' glkcpV1zXxVd3KMwDQYJKoZIhvcNAQEEBQAwgZ4xHzAd
  1825. '' SIG '' BgNVBAoTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxFzAV
  1826. '' SIG '' BgNVBAsTDlZlcmlTaWduLCBJbmMuMSwwKgYDVQQLEyNW
  1827. '' SIG '' ZXJpU2lnbiBUaW1lIFN0YW1waW5nIFNlcnZpY2UgUm9v
  1828. '' SIG '' dDE0MDIGA1UECxMrTk8gTElBQklMSVRZIEFDQ0VQVEVE
  1829. '' SIG '' LCAoYyk5NyBWZXJpU2lnbiwgSW5jLjAeFw05NzA1MTIw
  1830. '' SIG '' MDAwMDBaFw0wNDAxMDcyMzU5NTlaMIGeMR8wHQYDVQQK
  1831. '' SIG '' ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMRcwFQYDVQQL
  1832. '' SIG '' Ew5WZXJpU2lnbiwgSW5jLjEsMCoGA1UECxMjVmVyaVNp
  1833. '' SIG '' Z24gVGltZSBTdGFtcGluZyBTZXJ2aWNlIFJvb3QxNDAy
  1834. '' SIG '' BgNVBAsTK05PIExJQUJJTElUWSBBQ0NFUFRFRCwgKGMp
  1835. '' SIG '' OTcgVmVyaVNpZ24sIEluYy4wgZ8wDQYJKoZIhvcNAQEB
  1836. '' SIG '' BQADgY0AMIGJAoGBANMuIPBofCwtLoEcsQaypwu3EQ1X
  1837. '' SIG '' 2lPYdePJMyqy1PYJWzTz6ZD+CQzQ2xtauc3n9oixncCH
  1838. '' SIG '' Jet9WBBzanjLcRX9xlj2KatYXpYE/S1iEViBHMpxlNUi
  1839. '' SIG '' WC/VzBQFhDa6lKq0TUrp7jsirVaZfiGcbIbASkeXarSm
  1840. '' SIG '' NtX8CS3TtDmbAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEA
  1841. '' SIG '' YVUOPnvHkhJ+ERCOIszUsxMrW+hE5At4nqR+86cHch7i
  1842. '' SIG '' We/MhOOJlEzbTmHvs6T7Rj1QNAufcFb2jip/F87lY795
  1843. '' SIG '' aQdzLrCVKIr17aqp0l3NCsoQCY/Os68olsR5KYSS3P+6
  1844. '' SIG '' Z0JIppAQ5L9h+JxT5ZPRcz/4/Z1PhKxV0f0RY2MwggQC
  1845. '' SIG '' MIIDa6ADAgECAhAIem1cb2KTT7rE/UPhFBidMA0GCSqG
  1846. '' SIG '' SIb3DQEBBAUAMIGeMR8wHQYDVQQKExZWZXJpU2lnbiBU
  1847. '' SIG '' cnVzdCBOZXR3b3JrMRcwFQYDVQQLEw5WZXJpU2lnbiwg
  1848. '' SIG '' SW5jLjEsMCoGA1UECxMjVmVyaVNpZ24gVGltZSBTdGFt
  1849. '' SIG '' cGluZyBTZXJ2aWNlIFJvb3QxNDAyBgNVBAsTK05PIExJ
  1850. '' SIG '' QUJJTElUWSBBQ0NFUFRFRCwgKGMpOTcgVmVyaVNpZ24s
  1851. '' SIG '' IEluYy4wHhcNMDEwMjI4MDAwMDAwWhcNMDQwMTA2MjM1
  1852. '' SIG '' OTU5WjCBoDEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4x
  1853. '' SIG '' HzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsx
  1854. '' SIG '' OzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczov
  1855. '' SIG '' L3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTAxMScwJQYD
  1856. '' SIG '' VQQDEx5WZXJpU2lnbiBUaW1lIFN0YW1waW5nIFNlcnZp
  1857. '' SIG '' Y2UwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
  1858. '' SIG '' AQDAemGH67KnA2MbKxph3oC3FR2gi5A9uyeShBQ564XO
  1859. '' SIG '' KZIGZkikA0+N6E+n8K9e0S8Zx5HxtZ57kSHO6f/jTvD8
  1860. '' SIG '' r5VYuGMt5o72KRjNcI5Qw+2Wu0DbviXoQlXW9oXyBueL
  1861. '' SIG '' mRwx8wMP1EycJCrcGxuPgvOw76dN4xSn4I/Wx2jCYVip
  1862. '' SIG '' ctT4MEhP2S9vYyDZicqCe8JLvCjFgWjn5oJArEY6oPk/
  1863. '' SIG '' Ns1Mu1RCWnple/6E5MdHVKy5PeyAxxr3xDOBgckqlft/
  1864. '' SIG '' XjqHkBTbzC518u9r5j2pYL5CAapPqluoPyIxnxIV+XOh
  1865. '' SIG '' HoKLBCvqRgJMbY8fUC6VSyp4BoR0PZGPLEcxAgMBAAGj
  1866. '' SIG '' gbgwgbUwQAYIKwYBBQUHAQEENDAyMDAGCCsGAQUFBzAB
  1867. '' SIG '' hiRodHRwOi8vb2NzcC52ZXJpc2lnbi5jb20vb2NzcC9z
  1868. '' SIG '' dGF0dXMwCQYDVR0TBAIwADBEBgNVHSAEPTA7MDkGC2CG
  1869. '' SIG '' SAGG+EUBBwEBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8v
  1870. '' SIG '' d3d3LnZlcmlzaWduLmNvbS9ycGEwEwYDVR0lBAwwCgYI
  1871. '' SIG '' KwYBBQUHAwgwCwYDVR0PBAQDAgbAMA0GCSqGSIb3DQEB
  1872. '' SIG '' BAUAA4GBAC3zT2NgLBja9SQPUrMM67O8Z4XCI+2PRg3P
  1873. '' SIG '' Gk2+83x6IDAyGGiLkrsymfCTuDsVBid7PgIGAKQhkoQT
  1874. '' SIG '' CsWY5UBXxQUl6K+vEWqp5TvL6SP2lCldQFXzpVOdyDY6
  1875. '' SIG '' OWUIc3OkMtKvrL/HBTz/RezD6Nok0c5jrgmn++Ib4/1B
  1876. '' SIG '' CmqWMIIEEjCCAvqgAwIBAgIPAMEAizw8iBHRPvZj7N9A
  1877. '' SIG '' MA0GCSqGSIb3DQEBBAUAMHAxKzApBgNVBAsTIkNvcHly
  1878. '' SIG '' aWdodCAoYykgMTk5NyBNaWNyb3NvZnQgQ29ycC4xHjAc
  1879. '' SIG '' BgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEhMB8G
  1880. '' SIG '' A1UEAxMYTWljcm9zb2Z0IFJvb3QgQXV0aG9yaXR5MB4X
  1881. '' SIG '' DTk3MDExMDA3MDAwMFoXDTIwMTIzMTA3MDAwMFowcDEr
  1882. '' SIG '' MCkGA1UECxMiQ29weXJpZ2h0IChjKSAxOTk3IE1pY3Jv
  1883. '' SIG '' c29mdCBDb3JwLjEeMBwGA1UECxMVTWljcm9zb2Z0IENv
  1884. '' SIG '' cnBvcmF0aW9uMSEwHwYDVQQDExhNaWNyb3NvZnQgUm9v
  1885. '' SIG '' dCBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IB
  1886. '' SIG '' DwAwggEKAoIBAQCpAr3BcOY78k4bKJ+XeF4w6qKpjSVf
  1887. '' SIG '' +P6VTKO3/p2iID58UaKboo9gMmvRQmR57qx2yVTa8uuc
  1888. '' SIG '' hhyPn4Rms8VremIj1h083g8BkuiWxL8tZpqaaCaZ0Dos
  1889. '' SIG '' vwy1WCbBRucKPjiWLKkoOajsSYNC44QPu5psVWGsgnyh
  1890. '' SIG '' YC13TOmZtGQ7mlAcMQgkFJ+p55ErGOY9mGMUYFgFZZ8d
  1891. '' SIG '' N1KH96fvlALGG9O/VUWziYC/OuxUlE6u/ad6bXROrxjM
  1892. '' SIG '' lgkoIQBXkGBpN7tLEgc8Vv9b+6RmCgim0oFWV++2O14W
  1893. '' SIG '' gXcE2va+roCV/rDNf9anGnJcPMq88AijIjCzBoXJsyB3
  1894. '' SIG '' E4XfAgMBAAGjgagwgaUwgaIGA1UdAQSBmjCBl4AQW9Bw
  1895. '' SIG '' 72lyniNRfhSyTY7/y6FyMHAxKzApBgNVBAsTIkNvcHly
  1896. '' SIG '' aWdodCAoYykgMTk5NyBNaWNyb3NvZnQgQ29ycC4xHjAc
  1897. '' SIG '' BgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEhMB8G
  1898. '' SIG '' A1UEAxMYTWljcm9zb2Z0IFJvb3QgQXV0aG9yaXR5gg8A
  1899. '' SIG '' wQCLPDyIEdE+9mPs30AwDQYJKoZIhvcNAQEEBQADggEB
  1900. '' SIG '' AJXoC8CN85cYNe24ASTYdxHzXGAyn54Lyz4FkYiPyTrm
  1901. '' SIG '' IfLwV5MstaBHyGLv/NfMOztaqTZUaf4kbT/JzKreBXzd
  1902. '' SIG '' MY09nxBwarv+Ek8YacD80EPjEVogT+pie6+qGcgrNyUt
  1903. '' SIG '' vmWhEoolD2Oj91Qc+SHJ1hXzUqxuQzIH/YIX+OVnbA1R
  1904. '' SIG '' 9r3xUse958Qw/CAxCYgdlSkaTdUdAqXxgOADtFv0sd3I
  1905. '' SIG '' V+5lScdSVLa0AygS/5DW8AiPfriXxas3LOR65Kh343ag
  1906. '' SIG '' ANBqP8HSNorgQRKoNWobats14dQcBOSoRQTIWjM4bk0c
  1907. '' SIG '' DWK3CqKM09VUP0bNHFWmcNsSOoeTdZ+n0qAwggTJMIID
  1908. '' SIG '' saADAgECAhBqC5lPwADeqhHU2ECaqL7mMA0GCSqGSIb3
  1909. '' SIG '' DQEBBAUAMHAxKzApBgNVBAsTIkNvcHlyaWdodCAoYykg
  1910. '' SIG '' MTk5NyBNaWNyb3NvZnQgQ29ycC4xHjAcBgNVBAsTFU1p
  1911. '' SIG '' Y3Jvc29mdCBDb3Jwb3JhdGlvbjEhMB8GA1UEAxMYTWlj
  1912. '' SIG '' cm9zb2Z0IFJvb3QgQXV0aG9yaXR5MB4XDTAwMTIxMDA4
  1913. '' SIG '' MDAwMFoXDTA1MTExMjA4MDAwMFowgaYxCzAJBgNVBAYT
  1914. '' SIG '' AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH
  1915. '' SIG '' EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y
  1916. '' SIG '' cG9yYXRpb24xKzApBgNVBAsTIkNvcHlyaWdodCAoYykg
  1917. '' SIG '' MjAwMCBNaWNyb3NvZnQgQ29ycC4xIzAhBgNVBAMTGk1p
  1918. '' SIG '' Y3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBMIIBIDANBgkq
  1919. '' SIG '' hkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEAooQVU9gLMA40
  1920. '' SIG '' lf86G8LzL3ttNyNN89KM5f2v/cUCNB8kx+Wh3FTsfgJ0
  1921. '' SIG '' R6vbMlgWFFEpOPF+srSMOke1OU5uVMIxDDpt+83Ny1Cc
  1922. '' SIG '' G66n2NlKJj+1xcuPluJJ8m3Y6ZY+3gXP8KZVN60vYM2A
  1923. '' SIG '' YUKhSVRKDxi3S9mTmTBaR3VktNO73barDJ1PuHM7GDqq
  1924. '' SIG '' tIeMsIiwTU8fThG1M4DfDTpkb0THNL1Kk5u8ph35BSNO
  1925. '' SIG '' YCmPzCryhJqZrajbCnB71jRBkKW3ZsdcGx2jMw6bVAMa
  1926. '' SIG '' P5iQuMznPQR0QxyP9znms6xIemsqDmIBYTl2bv0+mAdL
  1927. '' SIG '' FPEBRv0VAOBH2k/kBeSAJQIBA6OCASgwggEkMBMGA1Ud
  1928. '' SIG '' JQQMMAoGCCsGAQUFBwMDMIGiBgNVHQEEgZowgZeAEFvQ
  1929. '' SIG '' cO9pcp4jUX4Usk2O/8uhcjBwMSswKQYDVQQLEyJDb3B5
  1930. '' SIG '' cmlnaHQgKGMpIDE5OTcgTWljcm9zb2Z0IENvcnAuMR4w
  1931. '' SIG '' HAYDVQQLExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xITAf
  1932. '' SIG '' BgNVBAMTGE1pY3Jvc29mdCBSb290IEF1dGhvcml0eYIP
  1933. '' SIG '' AMEAizw8iBHRPvZj7N9AMBAGCSsGAQQBgjcVAQQDAgEA
  1934. '' SIG '' MB0GA1UdDgQWBBQpXLkbts0z7rueWX335couxA00KDAZ
  1935. '' SIG '' BgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8E
  1936. '' SIG '' BAMCAUYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0B
  1937. '' SIG '' AQQFAAOCAQEARVjimkF//J2/SHd3rozZ5hnFV7QavbS5
  1938. '' SIG '' XwKhRWo5Wfm5J5wtTZ78ouQ4ijhkIkLfuS8qz7fWBsrr
  1939. '' SIG '' Kr/gGoV821EIPfQi09TAbYiBFURfZINkxKmULIrbkDdK
  1940. '' SIG '' D7fo1GGPdnbh2SX/JISVjQRWVJShHDo+grzupYeMHIxL
  1941. '' SIG '' eV+1SfpeMmk6H1StdU3fZOcwPNtkSUT7+8QcQnHmoD1F
  1942. '' SIG '' 7msAn6xCvboRs1bk+9WiKoHYH06iVb4nj3Cmomwb/1SK
  1943. '' SIG '' gryBS6ahsWZ6qRenywbAR+ums+kxFVM9KgS//3NI3Isn
  1944. '' SIG '' Q/xj6O4kh1u+NtHoMfUy2V7feXq6MKxphkr7jBG/G41U
  1945. '' SIG '' WTCCBQ8wggP3oAMCAQICCmEHEUMAAAAAADQwDQYJKoZI
  1946. '' SIG '' hvcNAQEFBQAwgaYxCzAJBgNVBAYTAlVTMRMwEQYDVQQI
  1947. '' SIG '' EwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4w
  1948. '' SIG '' HAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKzAp
  1949. '' SIG '' BgNVBAsTIkNvcHlyaWdodCAoYykgMjAwMCBNaWNyb3Nv
  1950. '' SIG '' ZnQgQ29ycC4xIzAhBgNVBAMTGk1pY3Jvc29mdCBDb2Rl
  1951. '' SIG '' IFNpZ25pbmcgUENBMB4XDTAyMDUyNTAwNTU0OFoXDTAz
  1952. '' SIG '' MTEyNTAxMDU0OFowgaExCzAJBgNVBAYTAlVTMRMwEQYD
  1953. '' SIG '' VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25k
  1954. '' SIG '' MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x
  1955. '' SIG '' KzApBgNVBAsTIkNvcHlyaWdodCAoYykgMjAwMiBNaWNy
  1956. '' SIG '' b3NvZnQgQ29ycC4xHjAcBgNVBAMTFU1pY3Jvc29mdCBD
  1957. '' SIG '' b3Jwb3JhdGlvbjCCASIwDQYJKoZIhvcNAQEBBQADggEP
  1958. '' SIG '' ADCCAQoCggEBAKqZvTmoGCf0Kz0LTD98dy6ny7XRjA3C
  1959. '' SIG '' OnTXk7XgoEs/WV7ORU+aeSnxScwaR+5Vwgg+EiD4VfLu
  1960. '' SIG '' X9Pgypa8MN7+WMgnMtCFVOjwkRC78yu+GeUDmwuGHfOw
  1961. '' SIG '' OYy4/QsdPHMmrFcryimiFZCCFeJ3o0BSA4udwnC6H+k0
  1962. '' SIG '' 9vM1kk5Vg/jaMLYg3lcGtVpCBt5Zy/Lfpr0VR3EZJSPS
  1963. '' SIG '' y2+bGXnfalvxdgV5KfzDVsqPRAiFVYrLyA9GS1XLjJZ3
  1964. '' SIG '' SofoqUEGx/8N6WhXY3LDaVe0Q88yOjDcG+nVQyYqef6V
  1965. '' SIG '' 2yJnJMkv0DTj5vtRSYa4PNAlX9bsngNhh6loQMf44gPm
  1966. '' SIG '' zwUCAwEAAaOCAUAwggE8MA4GA1UdDwEB/wQEAwIGwDAT
  1967. '' SIG '' BgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUa8jG
  1968. '' SIG '' USDwtC/ToLauf14msriHUikwgakGA1UdIwSBoTCBnoAU
  1969. '' SIG '' KVy5G7bNM+67nll99+XKLsQNNCihdKRyMHAxKzApBgNV
  1970. '' SIG '' BAsTIkNvcHlyaWdodCAoYykgMTk5NyBNaWNyb3NvZnQg
  1971. '' SIG '' Q29ycC4xHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3Jh
  1972. '' SIG '' dGlvbjEhMB8GA1UEAxMYTWljcm9zb2Z0IFJvb3QgQXV0
  1973. '' SIG '' aG9yaXR5ghBqC5lPwADeqhHU2ECaqL7mMEoGA1UdHwRD
  1974. '' SIG '' MEEwP6A9oDuGOWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNv
  1975. '' SIG '' bS9wa2kvY3JsL3Byb2R1Y3RzL0NvZGVTaWduUENBLmNy
  1976. '' SIG '' bDANBgkqhkiG9w0BAQUFAAOCAQEANSP9E1T86dzw3QwU
  1977. '' SIG '' evqns879pzrIuuXn9gP7U9unmamgmzacA+uCRxwhvRTL
  1978. '' SIG '' 52dACccWkQJVzkNCtM0bXbDzMgQ9EuUdpwenj6N+RVV2
  1979. '' SIG '' G5aVkWnw3TjzSInvcEC327VVgMADxC62KNwKgg7HQ+N6
  1980. '' SIG '' SF24BomSQGxuxdz4mu8LviEKjC86te2nznGHaCPhs+QY
  1981. '' SIG '' fbhHAaUrxFjLsolsX/3TLMRvuCOyDf888hFFdPIJBpkY
  1982. '' SIG '' 3W/AhgEYEh0rFq9W72UzoepnTvRLgqvpD9wB+t9gf2ZH
  1983. '' SIG '' XcsscMx7TtkGuG6MDP5iHkL5k3yiqwqe0CMQrk17J5Fv
  1984. '' SIG '' Jr5o+qY/nyPryJ27hzGCBN0wggTZAgEBMIG1MIGmMQsw
  1985. '' SIG '' CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQ
  1986. '' SIG '' MA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9z
  1987. '' SIG '' b2Z0IENvcnBvcmF0aW9uMSswKQYDVQQLEyJDb3B5cmln
  1988. '' SIG '' aHQgKGMpIDIwMDAgTWljcm9zb2Z0IENvcnAuMSMwIQYD
  1989. '' SIG '' VQQDExpNaWNyb3NvZnQgQ29kZSBTaWduaW5nIFBDQQIK
  1990. '' SIG '' YQcRQwAAAAAANDAMBggqhkiG9w0CBQUAoIGqMBkGCSqG
  1991. '' SIG '' SIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcC
  1992. '' SIG '' AQsxDjAMBgorBgEEAYI3AgEVMB8GCSqGSIb3DQEJBDES
  1993. '' SIG '' BBDaMnDARVd2uJyaAxK0dOXIME4GCisGAQQBgjcCAQwx
  1994. '' SIG '' QDA+oB6AHABFAHYAZQBuAHQAUQB1AGUAcgB5AC4AdgBi
  1995. '' SIG '' AHOhHIAad3d3Lm1pY3Jvc29mdC5jb20vd2luZG93cyAw
  1996. '' SIG '' DQYJKoZIhvcNAQEBBQAEggEAPf6uEojLWzpkv15s5nmE
  1997. '' SIG '' MG5uPg5iWWzffTn8e8FHNyheB2CxrLG0PrGw+GAIiT+f
  1998. '' SIG '' lwN2LZfj/KDgRrMGIB6WP5rs46cEHn/44xs/Y7QfOX92
  1999. '' SIG '' djs+nRnug48PbhAt37ZTSq7uZv58UBb/YAGN/v5vw5BB
  2000. '' SIG '' RAuecTE1J+twxAsX2B/sqXpiczL26lnxehDkI0Jdqfi4
  2001. '' SIG '' a/0NeukzSBj3OgOPPMktwVKi/0oPqm31DbwOzAgm+GLy
  2002. '' SIG '' ag34tmUfA7W+uwQRjnm+jyQ+ZGMLyGIaPjYMmgw9ewJP
  2003. '' SIG '' 2+G/yd9ROG8VjL+GX9k6EUUinzA34wH/Zds6tsZtpIHg
  2004. '' SIG '' HTYTkBbsHZA34aGCAkwwggJIBgkqhkiG9w0BCQYxggI5
  2005. '' SIG '' MIICNQIBATCBszCBnjEfMB0GA1UEChMWVmVyaVNpZ24g
  2006. '' SIG '' VHJ1c3QgTmV0d29yazEXMBUGA1UECxMOVmVyaVNpZ24s
  2007. '' SIG '' IEluYy4xLDAqBgNVBAsTI1ZlcmlTaWduIFRpbWUgU3Rh
  2008. '' SIG '' bXBpbmcgU2VydmljZSBSb290MTQwMgYDVQQLEytOTyBM
  2009. '' SIG '' SUFCSUxJVFkgQUNDRVBURUQsIChjKTk3IFZlcmlTaWdu
  2010. '' SIG '' LCBJbmMuAhAIem1cb2KTT7rE/UPhFBidMAwGCCqGSIb3
  2011. '' SIG '' DQIFBQCgWTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcB
  2012. '' SIG '' MBwGCSqGSIb3DQEJBTEPFw0wMjA3MTUyMjEyNDBaMB8G
  2013. '' SIG '' CSqGSIb3DQEJBDESBBB+VnFaley0kGY2xc8t1vJEMA0G
  2014. '' SIG '' CSqGSIb3DQEBAQUABIIBAIR3KgNSALKTeXW2KnX5jWzL
  2015. '' SIG '' tRAl+F/+HbCW6D0QGpGlg/OaCUHHF/d0M3fak8SKtrYM
  2016. '' SIG '' 17zhHxqT2HqsoorcMOnyYjIKrW1XMD6sHZTa+1bbOriy
  2017. '' SIG '' z4N6zqeNKzXffYsXyIdM60csQ7romWZm0H5+RjP/WtHT
  2018. '' SIG '' K3KA3YgHLBWMm2B0U4mmEgNHL0GQwXg/zRONB9Q+GWcA
  2019. '' SIG '' LwSodGbOk256VgWqHpmErPjwHKCcHRcBBFphYRZeIwyd
  2020. '' SIG '' c2YNb7y8B33uQc3glXna8FWBR9BUXOMbm7UWqlycmBRp
  2021. '' SIG '' jM3MvVBUPEeV3wLTVtUwKg4Os4jse3Qb4e1ovWqrcnwA
  2022. '' SIG '' f9rNehliStQ=
  2023. '' SIG '' End signature block