CitrixTools.Net Articles

Current Articles | Categories | Search | Syndication

Run tasks only within a "Shared" Provisioning Server Image

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

]

posted on Sunday, May 24, 2009 9:28 PM by Pierre Marmignon    

Previous Page | Next Page

COMMENTS

Hi Pierre

i have had similar issues with Trend Micro Office scan on XenApp in a provisioning environment.

1st i tried installing officescan on the master target device, which resulted in a constant vDisk inactive status and i was not able to build the image.

2nd i tried uninstalling officescan from the master target device, then i was able to complete a build of the xenapp vDisk.

3rd i tried to install Officescan in the Vdisk in private mode, which gave me a bluesceen (stop 7b error)

4th tried your above solution - installing officescan in standard mode vDisk at each boot - this however leads to the vDisk loosing connection to the Provisioning server.

I dont get why this works for you and my setup looses connection to the vDisk, which version of trend officescan are you using?

Best regards
Carsten Thue

posted @ Wednesday, July 22, 2009 10:03 AM by CarstenThue


Dear Carsten,

My customer is using version 8.X of OfficeScan.

Special exclusions have been set (c:\program Files\Citrix, .vdiskcache, EdgeSight Folders) to ensure it does not interfere with Citrix products.

Best Regards,

Pierre

posted @ Wednesday, August 12, 2009 10:29 AM by Pierre Marmignon


Pierre,

I am having the same issues as Carsten above.. Trend 8 and 10 hang the provisioned server during install.

I have setup the exclusions you mentioned. Did you exclude the pre-install scan as part of the Trend client package?

You are running in Xenserver correct?

Thank you,
Reade Bricker

posted @ Friday, August 14, 2009 5:05 PM by Reade


Hi Pierre,

in PVS 5.1 SP2 Citrix changed the file coding from ANSI to Unicode. This unfortunately breaks your script.

To get your script working again you have to change line 92 and replace

GetFile = fso.OpenTextFile(FileName).ReadAll

with

GetFile = fso.OpenTextFile(FileName,1,False,-1).ReadAll

Regards,
Tim
http://www.timarenz.de

posted @ Tuesday, March 09, 2010 10:17 AM by timarenz


Only registered users may post comments.