We have been using a VBScript developed by Onno de Vries in a procedure for customers using Symantec Endpoint Protection to make certain that the virus definitions are up to date. This has been working fine until we had a customer upgrade to SEP12.
The text of the vbscript is:
'** '** '** '** Developed by Onno de Vries, Senior Consultant Kaseya Benelux on behalf of Kaseya. '** Date : 05-11-2007 '** Version: 1.0 '** '** '************************************************************************************* '** Several Declarations '** Dim AgentDir,FileLocation,FileName,SearchCurrent,SearchUsed,StartChar,CurrentFound,UsedFound Const ForReading = 1 '** '** Enable parsing arguments to the vbs and collect them '** Set ArgObj = Wscript.Arguments AgentDir = ArgObj(0) FileLocation = ArgObj(1) '** '** Set Variables for further processing '** FileName = "DefInfo.dat" SearchUsed = "CurDefs=" StartChar = "=" UsedFound = 0 '** '** Open the definfo.dat file for reading to find the line containing the Current Definitions and Used Definitions '** Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFile = objFSO.OpenTextFile(FileLocation + "\" + FileName, ForReading) 'Set objFile = objFSO.OpenTextFile("c:\temp\DefInfo.dat", ForReading) '** '**Search the line in the file that contains the Definition numbers. '** Do Until objFile.AtEndOfStream strLine = objFile.ReadLine If Instr(1, strLine, SearchUsed, 1) > 0 Then '** '**The line containting the Current Definition is found, now locate the Current Definition itself within this line. '** CurrentDefinition = Mid(strLine,Instr(1, strLine, StartChar, 1)+1, Len(strLine)-Len(SearchCurrent)) '** '**set pointer for further processing (see below) '** CurrentFound = 1 Exit do End If Loop ObjFile.Close If CurrentFound =1 Then '** '** calculate the difference in days, write this to a seperate file to be used in the Kaseya script. '** Then you can enter any number of days in the 2nd script If statement that your maximum difference is before an alarm is generated. '** dC = Mid(CurrentDefinition, 7,2) mC = Mid(CurrentDefinition, 5,2) yC= Left(CurrentDefinition,4) Age = DateDiff("d",CDate(dC & "/" & mC & "/" & yC),Date) Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFile = objFSO.CreateTextFile(AgentDir + "\Age.txt") objFile.WriteLine(Age) objFile.Close '** '**Write the Current Definition to a file, so the Kaseya script can pick it up. '** Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFile = objFSO.CreateTextFile(AgentDir + "\CurrentDefinition.txt") objFile.WriteLine(CurrentDefinition) objFile.Close '** '**Write the Used Definition to a file, so the Kaseya script can pick it up. '** Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFile = objFSO.CreateTextFile(AgentDir + "\UsedDefinition.txt") objFile.WriteLine(UsedDefinition) objFile.Close Else '** '** When Current of Used Definition is not found, check SeachCurrent/SearchUsed/StartChar/ variables and/or NumberSearch routine! '** For notifying you that something is wrong, Definition number "0000" is entered in the file (the Kaseya Script will pick this up.) '** If CurrentFound = 0 And UsedFound = 0 Then Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFile = objFSO.CreateTextFile(AgentDir + "\CurrentDefinition.txt") objFile.WriteLine("0000") objFile.Close Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFile = objFSO.CreateTextFile(AgentDir + "\UsedDefinition.txt") objFile.WriteLine("0000") objFile.Close Else if CurrentFound = 1 Then '** '** When only Current Definition is found, check SeachCurrent/SearchUsed/StartChar/ variables and/or NumberSearch routine! '** For notifying you that something is wrong, Used Definition number "0000" is entered in the file (the Kaseya Script will pick this up.) '** Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFile = objFSO.CreateTextFile(AgentDir + "\UsedDefinition.txt") objFile.WriteLine("0000") objFile.Close Else '** '** When onlyUsed Definition is found, check SeachCurrent/SearchUsed/StartChar/ variables and/or NumberSearch routine! '** For notifying you that something is wrong, Current Definition number "0000" is entered in the file (the Kaseya Script will pick this up.) '** Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFile = objFSO.CreateTextFile(AgentDir + "\CurrentDefinition.txt") objFile.WriteLine("0000") objFile.Close End If End If End If set ArgObj = Nothing
What I am seeing now is that the procedure running this script just hangs no matter how much time you give it. When I attempt to run the script using wscript I get the following message:
Script: C:\Proguard\CheckDefsUpToDate_Symantec.vbs
Line: 18
Char: 2
Error: Subscript out of range
Code: 800A0009
Source: Microsoft VBScript runtime error
I have researched the error and it appears to be related to the following arguements:
AgentDir = ArgObj(0)
However I have had no luck in figuring out what exactly is wrong. I am a noob when it comes to vbscripts, so any help would be greatly appreciated.
Thanks
AgentDir is the first argument that you're passing to the script when you call it. FileLocation is the second argument that you pass when you call the script. Something is wrong with the first argument you are passing to the script. Check to see if the Agent Directory location has changed with the SEP Agent upgrade and then pass the corrected info to the script when you call it.
As AgentDir is not set in the script itself, is that something that would be configured in another portion of the Agent Procedure, or does it have a default value (like %systemroot%\temp)?
I bet the registry returns the path for the definfo.dat files as being something like
F:\Program Files\Common Files\Symantec Shared\VirusDef\20131127.003
But I'll also bet if you check the definfo.dat file is actually in
F:\Program Files\Common Files\Symantec Shared\VirusDefs
This seems to be the case with SEP 12
So I just added the follwing to my vbscript.
Essentially if it cant find definfo.dat in the path from the registry then look up one level as well
e.g.
If (CreateObject("Scripting.FileSystemObject")).FileExists(FileLocation + "\" + FileName) Then
else
if instr(FileLocation,"VirusDefs") > 0 then
Trimlength = instr(FileLocation,"VirusDefs")
FileLocation = left(FileLocation,Trimlength + 8)
end if
Hope this helps
Paul
There is no parsing of the registry in the original script. The AgentDir path is the first one of two arguments that are passed to the script by the calling procedure. The procedure calling the script would need to be edited to provide the correct path for the 12.x version of SEP. If you decide to go with Paul's route, which is certainly doable, you would need to edit the script to remove the requirement for the first argument and use Paul's snippet to replace it. Then you would also need to edit the calling procedure so that you didn't pass the path when the script is called.
FileLocation = ArgObj(1) is passed to the script from the Kaseya script , which checks the registry values of the vaRIOUSE KETS DEPENDING ON IF IT IS v11 OR 12 ETC
E.G. HKEY_LOCAL_MACHINE\SOFTWARE\Symantec\Symantec Endpoint Protection\CurrentVersion\SharedDefs\DEFWATCH_10
In SEP 11 the value returned was something like F:\Program Files\Common Files\Symantec Shared\VirusDef\20131127.003 and it was in this path the vbscript could then locate the definfo.dat.
BUT in SEP 12 it is no longer the correct path , hence you need to look in e.g. F:\Program Files\Common Files\Symantec Shared\VirusDef instead.
So I still use both arguments as A) I need to know where to save the age.txt , UsedDefinition.txt etc files , and B I need to know the path to the definfo.dat
So my added code ..would go
FileLocation = ArgObj(1)
'**
'** Set Variables for further processing
FileName = "DefInfo.dat"
SearchUsed = "CurDefs="
StartChar = "="
UsedFound = 0
'** Open the definfo.dat file for reading to find the line containing the Current Definitions and Used Definitions
Set objFSO = CreateObject("Scripting.FileSystemObject")
etc
as per the orginal post
That looks good, Paul and should answer the OP's questions.
My apologies for not getting back to you sooner. Thank you both for your assistance on this. I am testing it now and will let you know how it works out.
It appears that the procedure is still stalling when it goes to run the VBScript, even after adding the lines that Paul suggested in the location that he suggested. It appears that the script is still not getting the correct information from the agent procedure.
I have looked the procedure over and cannot see where this is failing. I have exported the procedure and the xml data for it is below.
<?xml version="1.0" encoding="utf-8"?>
<ScriptExport xmlns:xsi="www.w3.org/.../XMLSchema-instance" xmlns:xsd="www.w3.org/.../XMLSchema" xmlns="www.kaseya.com/.../Scripting">
<Procedure name="Symantec 12 Check Virus Defs 1-2" treePres="3" id="793937672" folderId="11216137914923888469227111" treeFullPath="NOC Scripts.Symantec AV Scripts">
<Body description="This checks to see if you have Symantec installed. Then report on the version. Example of how Symantec reports: 2005 (year) 06 (Day) 01 (month).21 (version) 20050601.21">
<If description="This checks to see if you have Symantec installed. Then report on the version. Example of how Symantec reports: 2005 (year) 06 (Day) 01 (month).21 (version) 20050601.21">
<Condition name="TestRegistryKey">
<Parameter xsi:type="StringParameter" name="Path" value="HKEY_LOCAL_MACHINE\SOFTWARE\Symantec\Symantec Endpoint Protection\AV" />
<Parameter xsi:type="EnumParameter" name="Condition" value="Exists" />
</Condition>
<Then>
<Statement name="PauseScript" continueOnFail="false" osType="Windows">
<Parameter xsi:type="IntegerParameter" name="Seconds" value="300" />
</Statement>
<Statement name="GetVariable" continueOnFail="false">
<Parameter xsi:type="EnumParameter" name="VariableType" value="AgentTempDirectory" />
<Parameter xsi:type="StringParameter" name="SourceContent" value="" />
<Parameter xsi:type="StringParameter" name="VariableName" value="AgentTemp" />
<Parameter xsi:type="EnumParameter" name="VariableType" value="RegistryValue" />
<Parameter xsi:type="StringParameter" name="SourceContent" value="HKEY_LOCAL_MACHINE\SOFTWARE\Symantec\Symantec Endpoint Protection\CurrentVersion\Content\Virusdefs" />
<Parameter xsi:type="StringParameter" name="VariableName" value="DefInfoLocation" />
<Statement name="WriteFile" continueOnFail="false">
<Parameter xsi:type="StringParameter" name="Path" value="#AgentTemp#\CheckDefsUpToDate_Symantec-1.vbs" />
<Parameter xsi:type="StringParameter" name="ManagedFile" value="VSASharedFiles\SymantecDefCheck\CheckDefsUpToDate_Symantec-1.vbs" />
<Parameter xsi:type="BooleanParameter" name="DeleteAfter" value="False" />
<Statement name="ExecuteFile" continueOnFail="false">
<Parameter xsi:type="StringParameter" name="Path" value="%SYSTEMROOT%\SYSTEM32\WSCRIPT.EXE" />
<Parameter xsi:type="StringParameter" name="Arguments" value="#AgentTemp#\CheckDefsUpToDate_Symantec-1.vbs #AgentTemp# #DefInfoLocation#" />
<Parameter xsi:type="EnumParameter" name="ExecuteAccount" value="System" />
<Parameter xsi:type="BooleanParameter" name="WaitComplete" value="True" />
<Parameter xsi:type="EnumParameter" name="VariableType" value="FileContent" />
<Parameter xsi:type="StringParameter" name="SourceContent" value="#AgentTemp#\CurrentDefinition.txt" />
<Parameter xsi:type="StringParameter" name="VariableName" value="CurDefs" />
<Parameter xsi:type="StringParameter" name="SourceContent" value="#AgentTemp#\Age.txt" />
<Parameter xsi:type="StringParameter" name="VariableName" value="Age" />
<Statement name="ExecuteScript" continueOnFail="false">
<Parameter xsi:type="StringParameter" name="ScriptID" value="1896146672" />
<Parameter xsi:type="StringParameter" name="ScriptName" value="Symantec 12 Check Virus Defs 2-2" />
<Parameter xsi:type="StringParameter" name="TimeDelay" value="" />
<Parameter xsi:type="EnumParameter" name="TimeUnit" value="Immediate" />
<Statement name="DeleteFile" continueOnFail="false">
<Parameter xsi:type="StringParameter" name="Path" value="#AgentTemp#\CurrentDefinition.txt" />
<Parameter xsi:type="StringParameter" name="Path" value="#AgentTemp#\Age.txt" />
</Then>
<Else>
<Statement name="WriteScriptLogEntry" continueOnFail="false">
<Parameter xsi:type="StringParameter" name="Comment" value="Symantec Antivirus not Found." />
<Statement name="ExecuteShellCommand" continueOnFail="false">
<Parameter xsi:type="StringParameter" name="Command" value="%systemroot%\system32\eventcreate.exe /L APPLICATION /ID 990 /T ERROR /D "Symantec AV not Installed" /SO SymantecAV" />
<Parameter xsi:type="EnumParameter" name="ExecuteAccount" value="User" />
<Parameter xsi:type="BooleanParameter" name="Is64Bit" value="False" />
</Else>
</If>
</Body>
</Procedure>
</ScriptExport>
Log onto the machine and check.
I think the reg path you're returning as the DefInfoLocation is incomplete
What value is returned from
HKEY_LOCAL_MACHINE\SOFTWARE\Symantec\Symantec Endpoint Protection\CurrentVersion\Content\Virusdefs
This should return the path to the definfo.dat file so I think you need to be searching for
e.g What does
HKEY_LOCAL_MACHINE\SOFTWARE\Symantec\Symantec Endpoint Protection\CurrentVersion\SharedDefs\DEFWATCH_10
return instead ?