Working on a Provisioning Server project, I had to deal with the Trend Officescan product installation.
The problem was really critical because installing the Antivirus Software within the image would lead to a blue screen at boot time.
Not installing the software was not an option, as the Security Administrator would have not allowed that because even if the servers are "Read Only" they could be virus propagation vector.
During investigations we've found that if the antivirus software was installed at each boot (so not incorporated within the image but installed on top of it) the blue screen issue was over and the Antivirus Software perfectly working.
To automate the deployment process we decided to write a script and push it by machine GPO.
To ease administration processes and ensure the Antivirus Installation would never happen within a private image, I've developped the script provided in this article.
To know "where we are" the script is using two variables : the first one is the System Disk Type, leveraged by the iSSystemVdisk() function.
Then the script will read the "C:\Personality.ini" file. This file is generated on any Provisioning Server Client and contains the Image Type (Shared or Private).
By checking these two values, we can ensure we are within a private or shared image so we can decide to launch the task.
As usual, all constants have been integrated at the beginning of the script so you can easily modify them to fit your needs.
'-------------------------------------------------------------------------------------------
Const InstallTaskPath = "\\MyServer\Antivirus$\ClientOSCE8_32.exe"
Const TaskName = "Install_OFSCAN"
Const TaskDesc = "Antivirus Installation"
Main()
Sub Main()
DiskType = GetIniString("C:\Personality.ini","ArdenceData","_DiskMode","ERROR")
if iSSystemVdisk() And DiskType = "S" Then
LaunchProcess InstallTaskPath
WriteLog( TaskName & " : " & TaskDesc & " SUCCESS" & VbCrLf & VbCrLf & "iSSystemVdisk() = " & iSSystemVdisk() & VbCrLf & VbCrLf & "$DiskMode = " & DiskType)
else
WriteLog( TaskName & " : " & TaskDesc & " BYPASSED" & VbCrLf & VbCrLf & "iSSystemVdisk() = " & iSSystemVdisk() & VbCrLf & VbCrLf & "$DiskMode = " & DiskType)
End If
End Sub
'
' Write in the Envent Log
'
Sub WriteLog( msg )
on error resume next
Set objShell = Wscript.CreateObject("Wscript.Shell")
objShell.LogEvent 0, msg
End Sub
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' LaunchProcess(Path)
' Launch the Specified Process
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Sub LaunchProcess (Path)
on error resume next
err.clear
Set ObjShell = CreateObject("Wscript.Shell")
ObjShell.run Path , 0 , True
End Sub
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' System Disk Scan
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Ini File Reading
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Function GetINIString(Filename,Section, KeyName, Default)
on error resume next
Dim PosSection, PosEndSection, sContents, Value, Found
'Get contents of the INI file As a string
INIContents = GetFile(FileName)
'Find section
PosSection = InStr(1, INIContents, "[" & Section & "]", vbTextCompare)
If PosSection>0 Then
'Section exists. Find end of section
PosEndSection = InStr(PosSection, INIContents, vbCrLf & "[")
'?Is this last section?
If PosEndSection = 0 Then PosEndSection = Len(INIContents)+1
'Separate section contents
sContents = Mid(INIContents, PosSection, PosEndSection - PosSection)
If InStr(1, sContents, vbCrLf & KeyName & "=", vbTextCompare)>0 Then
Found = True
'Separate value of a key.
Value = SeparateField(sContents, vbCrLf & KeyName & "=", vbCrLf)
End If
End If
If isempty(Found) Then Value = Default
GetINIString = Value
End Function
'Separates one field between sStart And sEnd
Private Function SeparateField(ByVal sFrom, ByVal sStart, ByVal sEnd)
Dim PosB: PosB = InStr(1, sFrom, sStart, 1)
If PosB > 0 Then
PosB = PosB + Len(sStart)
Dim PosE: PosE = InStr(PosB, sFrom, sEnd, 1)
If PosE = 0 Then PosE = InStr(PosB, sFrom, vbCrLf, 1)
If PosE = 0 Then PosE = Len(sFrom) + 1
SeparateField = Mid(sFrom, PosB, PosE - PosB)
End If
End Function
'File functions
Private Function GetFile(ByVal FileName)
on error resume next
Set fso = CreateObject("Scripting.FileSystemObject")
GetFile = fso.OpenTextFile(FileName).ReadAll
End Function
'-------------------------------------------------------------------------------------------
Function iSSystemVdisk()
On Error Resume Next
iSSystemVdisk = False
Set objFso = CreateObject("Scripting.FileSystemObject")
SystemDrive = Left(objFso.GetSpecialFolder(1),2)
Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2")
Set colDiskDrives = objWMIService.ExecQuery("SELECT * FROM Win32_DiskDrive WHERE Caption = 'Citrix Virtual HBA SCSI Disk Device' OR Caption='Citrix Virtual Hard Disk'", "WQL", _
wbemFlagReturnImmediately + wbemFlagForwardOnly)
For Each objDrive In colDiskDrives
strDeviceID = Replace(objDrive.DeviceID, "\", "\\")
Set colPartitions = objWMIService.ExecQuery _
("ASSOCIATORS OF {Win32_DiskDrive.DeviceID=""" & _
strDeviceID & """} WHERE AssocClass = " & _
"Win32_DiskDriveToDiskPartition")
For Each objPartition In colPartitions
Set colLogicalDisks = objWMIService.ExecQuery _
("ASSOCIATORS OF {Win32_DiskPartition.DeviceID=""" & _
objPartition.DeviceID & """} WHERE AssocClass = " & _
"Win32_LogicalDiskToPartition")
For Each objLogicalDisk In colLogicalDisks
if objLogicalDisk.DeviceID = SystemDrive then
iSSystemVdisk = True
End if
Next
Next
Next
End Function
]