Wednesday, June 25, 2014

Correcting Time Sync Issues on Citrix PVS VDI

Anyone who has been working with PVS for a while has probably run in to some type of time synchronization or time skew issues on their VMs at some point. This causes issues with the VM clock being off sync beyond the time skew threshold causing kerberos errors and leads to GPOs not being pulled down and registration errors between the VDI and the desktop controller servers (See screenshot below). Some causes of time skew on PVS VMs are due to DST time being configured on a master image that hasn't been updated in a while (More info on DST here and here) and also time synchronization misconfiguration at the hypervisor layer. It is always important to have your hypervisor layer have the time synchronization setup for the hardware/system clock as this is by default sent up to the VM via guest OS tools.

An example of this issue causing registration issues with the Citrix Desktop Service (Event ID 1002):


Although as you can see this problem causes registration errors with the VM it eventually resolves itself after W32time had time to synchronize with the domain and also because the Citrix Desktop Service service has a short retry interval. However, this isn't the case with GPOs as the default refresh cycle is normally 90 minutes. After tieing the process of this all together I came up with a solution below to cover whatever case was causing the time sync issue. The key here was to start up the necessary actions in the correct order W32Time Sync->GPupdate->Start Citrix Desktop Service.

Please note that this is not a recommended solution by Citrix and you should do thorough testing in your environment before attempting this.

***I took the idea from here (at the bottom of the article) and took it another step to resolve the Citrix Desktop Service registration issues and GPO issues. I also found my process worked better by running w32time /resync in my script rather than making my service simply dependent on the w32time service to ensure time sync has fully completed before doing a GPupdate and starting the Desktop Registration process.

The solution (tested for a WinXP machine):



  • Set Citrix Desktop Service to manual and stop service

  • Create .BAT file with the following, (Optional: convert to .EXE with 3rd party software)
--------------------------------------------------------------
w32tm /resync
gpupdate /force
net start workstationagent
--------------------------------------------------------------


  • Create the "Citrix Startup" service:

"c:\program files\windows resource kits\tools\instsrv.exe" "Citrix Startup" "c:\program files\windows resource kits\tools\srvany.exe"

  • Open Regedit and navigate to the following: 
HKLM\SYSTEM\CurrentControlSet\Services\Citrix Startup

Right click Citrix Startup -> Add key called Parameters -> right click Parameters  and create a new string key named Application -> Fill in path (Ex c:\startup.bat or whatever you named the bat/exe above)

  • Add Startup dependencies to the service we created:

sc config "Citrix Startup" depend= netlogon/w32time



Thursday, June 5, 2014

Bulk disable AD users script

I wrote this quick handy script to disable a bunch of users from a text file. The client I was working at still had a 2003 level domain so I had to old school it with VBScript :)

Run this on a DC in your environment and fill in users in a text file named disableList.txt. I have it set to output to a disableUsers.bat file so you can inspect it before you run it.

Const ForReading = 1
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile1 = objFSO.OpenTextFile("disableList.txt", ForReading)

'Read in users
Dim ListToProcess()
i = 0
Do Until objFile1.AtEndOfStream
Redim Preserve ListToProcess(i)
ListToProcess(i) = objFile1.ReadLine
i = i + 1
Loop

objFile1.Close

outFile="disableUsers.bat"
Set objFile = objFSO.CreateTextFile(outFile,True)

For Each strLine in ListToProcess
 if strLine <> "" then
 objFile.Write "dsquery user -samid " & strLine & " | dsmod user -disabled yes " & vbCrLf
 End if
Next

objFile.Close

Tuesday, June 3, 2014

Implementing SCEP 2012 on Citrix PVS VDI

In this post, I'm going to explain how System Center Endpoint Protection 2012 was implemented on our Citrix PVS VDI machines at a client project I recently worked at. I hadn't found much about this online so I thought I'd share how it was done for us and hopefully it will help someone out!

They key issue with the PVS random pooled VDI was the lack of persistence for the virus definitions, so in this solution we move the virus definitions to a separate disk attached to our VDI. The first step to implementing this is to ensure you allocate enough space on your write cache drive or a separate drive to accommodate virus definitions, in my scenario I found 1GB seems to be sufficient for the SCEP files/definitions.


Once you have determined a suitable size for your separate SCEP drive or if you choose to combine it on your write cache drive (this is route I took) boot up your master image with the drive attached.

First, on the master image(s) ensure the SCCM client push account is added to the machine's local administrators. Once this is complete go ahead and create a device collection and add the master image(s) as resources in SCCM. Additionally, we created a separate device collection for our Citrix VDI images via OU. This is done to add our custom endpoint policies to later on.

Next, here is the steps I took on our XP VDI master image(s):

1. Install Windows Resource Toolkit: http://www.microsoft.com/en-us/download/details.aspx?id=17657 - This includes a tool called linkd, which we use to create a symbolic link.

2. Create D:\SCEP folder (or wherever your persistent drive is)

3. CD c:\documents and settings\all users\application data\microsoft\

4. “c:\program files\windows resource toolkit\tools\linkd.exe” “Microsoft Antimalware” “d:\scep”

5. Push/Install SCEP And SCCM client

6. Validate after installation that d:\scep folder is getting all the latest updates (check folder size properties is going up)

If you were using Windows 7 VDI do all the following above except:

Ignore step 1, and for step 3 change the directory to C:\Users\All Users\Microsoft and then step 4 use  mklink /D "Microsoft Antimalware" "d:\scep"

After you have completed that and notice that SCEP is running properly, you will need to do the following prior to shutting down your image before publishing in order to have the SCCM client generate appropriate MIFs for each machine

1. Open Powershell as administrator: net stop ccmexec

2. Followed by: del %WINDIR%\smscfg.ini

3. Followed by: Remove-Item -Path HKLM:\Software\Microsoft\SystemCertificates\SMS\Certificates\* -Force or from DOS using powershell -command “Remove-Item -Path HKLM:\Software\Microsoft\SystemCertificates\SMS\Certificates\* -Force”

4.Finally: wmic /namespace:\\root\ccm\invagt path inventoryActionStatus where InventoryActionID=”{00000000-0000-0000-0000-000000000001}” DELETE /NOINTERACTIVE

Once this is complete your image is almost ready to published out, however I found we needed a small logon script to get the images properly setup on their first boot so I created the following small batch file and attached it as a logon script for GPO:

mkdir d:\scep
net start msmpsvc

There is probably a more elegant solution to this such as a scheduled task that run once prior to shutting down your master image, let me know if you find a better solution! Once this is done you are ready to publish out your VDI. On boot you should see the SCEP client showing red in the tray and will pickup/start updating virus defs as defined by your policy. Again, you can validate your D:\SCEP has all the files/folders and is increasing in size once the updates begin. Also, don't forget to apply your antimalware policy with Citrix recommended file/folder exclusions. We also opted to turn scans off given this being a VDI environment.