Avatar of lucifer82
lucifer82Flag for Hong Kong asked on

Object not a collection error when running VBScript at login

I'm trying to run this VBScript through kix for Citrix login script. The VBScript runs fine when I run it manually after user has logged into the Citrix. However I want it to run by kix calling the vbscript. It calls fine but it doesn't seem to run too well at the moment.

VBScript forces changes of the timezone for citrix user

The error message I get is

AEDT.vbs(29, 1) Microsoft VBScript runtime error: Object not a collection

AEDT.vbs is the vbscript file I'm running from kix command


Const HKEY_CLASSES_ROOT   = &H80000000
Const HKEY_CURRENT_USER   = &H80000001
Const HKEY_LOCAL_MACHINE  = &H80000002
Const HKEY_USERS          = &H80000003
 
Const REG_SZ        = 1
Const REG_EXPAND_SZ = 2
Const REG_BINARY    = 3
Const REG_DWORD     = 4
Const REG_MULTI_SZ  = 7
 
uBinary = Array(&Ha8,&Hfd,&Hff,&Hff,&H00,&H00,&H00,&H00,&Hc4,&Hff,&Hff,&Hff,&H00,&H00,&H04,&H00,&H00,&H00,&H01,&H00,&H03,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H0a,&H00,&H00,&H00,&H01,&H00,&H02,&H00,&H00,&H00,&H00,&H00,&H00,&H00)
 
' Chose computer name, registry tree and key path
'
strComputer = "." ' Use . for current machine
hDefKey = HKEY_CURRENT_USER
strKeyPath = "Software\Citrix\SessionTimeZone\"
 
' Connect to registry provider on target machine with current user
'
Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
 
' Enum the subkeys of the key path we've chosen
'
oReg.EnumKey hDefKey, strKeyPath, arrSubKeys
 
For Each strSubkey In arrSubKeys
 
  strKeyPath = strKeyPath + strSubkey
  
oReg.SetStringValue hDefKey, strKeyPath, "Display", "AUS Eastern Standard Time"
oReg.SetStringValue hDefKey, strKeyPath, "Dlt", "AUS Eastern Daylight Time"
oReg.SetBinaryValue hDefKey, strKeyPath, "TZI", uBinary
oReg.SetDWORDValue hDefKey, strKeyPath, "UseRegTimeZone", "00000001"
 
Next

Open in new window

Visual Basic ClassicCitrixVB Script

Avatar of undefined
Last Comment
RobSampson

8/22/2022 - Mon
Patrick Matthews

Hello lucifer82,

I don't see in the code where you set the variable arrSubKeys to a valid collection or array...

Regards,

Patrick
ASKER
lucifer82

isn't line 26 doing that??? or do I need to specifically say

Dim arrSubKeys(50)

Krys_K

hi
yes line 26 is doing that, however i wonder if its down to the fact that user regisry not loaded to fill that array at that point script runs??

Krystian
Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
ASKER
lucifer82

Yea I have thought about that too... I have also ran registry changes in kix command and that worked... but I couldn't figure out how I can resolve the session ID like what I have done in there in the VBScript.

Once the user logs in usually terminal server lock down policy applies to them so I don't think it will run this vbscript if I put it in the start up for example. So I need to run in during the login script... any idea would be great.
RobSampson

Hi, I have added quick check to see if arrSubKeys has been filled before it tries to go through them, but this won't fix the timing issue....

Rob.
Const HKEY_CLASSES_ROOT   = &H80000000
Const HKEY_CURRENT_USER   = &H80000001
Const HKEY_LOCAL_MACHINE  = &H80000002
Const HKEY_USERS          = &H80000003
 
Const REG_SZ        = 1
Const REG_EXPAND_SZ = 2
Const REG_BINARY    = 3
Const REG_DWORD     = 4
Const REG_MULTI_SZ  = 7
 
uBinary = Array(&Ha8,&Hfd,&Hff,&Hff,&H00,&H00,&H00,&H00,&Hc4,&Hff,&Hff,&Hff,&H00,&H00,&H04,&H00,&H00,&H00,&H01,&H00,&H03,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H0a,&H00,&H00,&H00,&H01,&H00,&H02,&H00,&H00,&H00,&H00,&H00,&H00,&H00)
 
' Chose computer name, registry tree and key path
'
strComputer = "." ' Use . for current machine
hDefKey = HKEY_CURRENT_USER
strKeyPath = "Software\Citrix\SessionTimeZone\"
 
' Connect to registry provider on target machine with current user
'
Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
 
' Enum the subkeys of the key path we've chosen
'
oReg.EnumKey hDefKey, strKeyPath, arrSubKeys
 
If IsNull(arrSubKeys) = False Then
	For Each strSubkey In arrSubKeys
	 
	strKeyPath = strKeyPath + strSubkey
	  
	oReg.SetStringValue hDefKey, strKeyPath, "Display", "AUS Eastern Standard Time"
	oReg.SetStringValue hDefKey, strKeyPath, "Dlt", "AUS Eastern Daylight Time"
	oReg.SetBinaryValue hDefKey, strKeyPath, "TZI", uBinary
	oReg.SetDWORDValue hDefKey, strKeyPath, "UseRegTimeZone", "00000001"
	 
	Next
End If

Open in new window

RobSampson

Or, you could use this to "try" to get the subkeys for 10 seconds....

Regards,

Rob.
Const HKEY_CLASSES_ROOT   = &H80000000
Const HKEY_CURRENT_USER   = &H80000001
Const HKEY_LOCAL_MACHINE  = &H80000002
Const HKEY_USERS          = &H80000003
 
Const REG_SZ        = 1
Const REG_EXPAND_SZ = 2
Const REG_BINARY    = 3
Const REG_DWORD     = 4
Const REG_MULTI_SZ  = 7
 
uBinary = Array(&Ha8,&Hfd,&Hff,&Hff,&H00,&H00,&H00,&H00,&Hc4,&Hff,&Hff,&Hff,&H00,&H00,&H04,&H00,&H00,&H00,&H01,&H00,&H03,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H0a,&H00,&H00,&H00,&H01,&H00,&H02,&H00,&H00,&H00,&H00,&H00,&H00,&H00)
 
' Chose computer name, registry tree and key path
'
strComputer = "." ' Use . for current machine
hDefKey = HKEY_CURRENT_USER
strKeyPath = "Software\Citrix\SessionTimeZone\"
 
' Connect to registry provider on target machine with current user
'
Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
 
' Enum the subkeys of the key path we've chosen
'
 
intAttempt = 0
While IsNull(arrSubKeys) = True And intAttempt < 10
	oReg.EnumKey hDefKey, strKeyPath, arrSubKeys
	intAttempt = intAttempt + 1
	WScript.Sleep 1000
Wend
 
If IsNull(arrSubKeys) = False Then
	For Each strSubkey In arrSubKeys
	 
	strKeyPath = strKeyPath + strSubkey
	  
	oReg.SetStringValue hDefKey, strKeyPath, "Display", "AUS Eastern Standard Time"
	oReg.SetStringValue hDefKey, strKeyPath, "Dlt", "AUS Eastern Daylight Time"
	oReg.SetBinaryValue hDefKey, strKeyPath, "TZI", uBinary
	oReg.SetDWORDValue hDefKey, strKeyPath, "UseRegTimeZone", "00000001"
	 
	Next
End If

Open in new window

Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
ASKER
lucifer82

I've tried the first code and it ran but ignored the array part meaning that arrSubKey is null =_="

I tested the second one too but I get the same error when it comes to the arrSubKey in line 35
Krys_K

It would be interesteing to echo out what is in array as it appears that its not null if it errors on line 35 in Robs second script.

Try adding this bit under your For each bit and see what happens
If IsNull(arrSubKeys) = False Then
      For Each strSubkey In arrSubKeys

Wscript.echo type(arrSubKeys)

for i = 0 to ubound(arrSubKeys)
wscript.echo arrSubKeys(i)
next

Krystian

RobSampson

Maybe there only one subkey and it's a string??

Rob.
Const HKEY_CLASSES_ROOT   = &H80000000
Const HKEY_CURRENT_USER   = &H80000001
Const HKEY_LOCAL_MACHINE  = &H80000002
Const HKEY_USERS          = &H80000003
 
Const REG_SZ        = 1
Const REG_EXPAND_SZ = 2
Const REG_BINARY    = 3
Const REG_DWORD     = 4
Const REG_MULTI_SZ  = 7
 
uBinary = Array(&Ha8,&Hfd,&Hff,&Hff,&H00,&H00,&H00,&H00,&Hc4,&Hff,&Hff,&Hff,&H00,&H00,&H04,&H00,&H00,&H00,&H01,&H00,&H03,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H0a,&H00,&H00,&H00,&H01,&H00,&H02,&H00,&H00,&H00,&H00,&H00,&H00,&H00)
 
' Chose computer name, registry tree and key path
'
strComputer = "." ' Use . for current machine
hDefKey = HKEY_CURRENT_USER
strKeyPath = "Software\Citrix\SessionTimeZone\"
 
' Connect to registry provider on target machine with current user
'
Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
 
' Enum the subkeys of the key path we've chosen
'
 
intAttempt = 0
While IsNull(arrSubKeys) = True And intAttempt < 10
	oReg.EnumKey hDefKey, strKeyPath, arrSubKeys
	intAttempt = intAttempt + 1
	WScript.Sleep 1000
Wend
 
If IsNull(arrSubKeys) = False Then
	If TypeName(arrSubKeys) = "String" Then
		strKeyPath = strKeyPath + arrSubKeys
	Else
		For Each strSubkey In arrSubKeys		 
			strKeyPath = strKeyPath + strSubkey
			  
			oReg.SetStringValue hDefKey, strKeyPath, "Display", "AUS Eastern Standard Time"
			oReg.SetStringValue hDefKey, strKeyPath, "Dlt", "AUS Eastern Daylight Time"
			oReg.SetBinaryValue hDefKey, strKeyPath, "TZI", uBinary
			oReg.SetDWORDValue hDefKey, strKeyPath, "UseRegTimeZone", "00000001"
		 
		Next
End If

Open in new window

Your help has saved me hundreds of hours of internet surfing.
fblack61
ASKER
lucifer82

this is what I've changed for some testing

at the moment it's telling me that registry has loaded since it returned some value, and also telling me that array is null.

EnumKey is working, oReg is not null from what I've found out.
Const HKEY_CLASSES_ROOT   = &H80000000
Const HKEY_CURRENT_USER   = &H80000001
Const HKEY_LOCAL_MACHINE  = &H80000002
Const HKEY_USERS          = &H80000003
 
Const REG_SZ        = 1
Const REG_EXPAND_SZ = 2
Const REG_BINARY    = 3
Const REG_DWORD     = 4
Const REG_MULTI_SZ  = 7
 
uBinary = Array(&Ha8,&Hfd,&Hff,&Hff,&H00,&H00,&H00,&H00,&Hc4,&Hff,&Hff,&Hff,&H00,&H00,&H04,&H00,&H00,&H00,&H01,&H00,&H03,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H0a,&H00,&H00,&H00,&H01,&H00,&H02,&H00,&H00,&H00,&H00,&H00,&H00,&H00)
 
' Chose computer name, registry tree and key path
'
strComputer = "." ' Use . for current machine
hDefKey = HKEY_CURRENT_USER
strKeyPath = "Software\Citrix\SessionTimeZone\"
 
' Connect to registry provider on target machine with current user
'
Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
 
' Enum the subkeys of the key path we've chosen
'
 
 
If IsNull(oReg) = False Then
 
WScript.echo "oReg contains " & oReg.GetDWORDValue(hDefKey, "Software\Citrix\", "DisablePlayAnimations")
 
 If oReg.EnumKey(hDefKey, strKeyPath, arrSubKeys) = False Then
 
	If IsNull(arrSubKeys) = False Then
        	For Each strSubkey In arrSubKeys
         
        	strKeyPath = strKeyPath + strSubkey
          
        	oReg.SetStringValue hDefKey, strKeyPath, "Display", "AUS Eastern Standard Time"
        	oReg.SetStringValue hDefKey, strKeyPath, "Dlt", "AUS Eastern Daylight Time"
        	oReg.SetBinaryValue hDefKey, strKeyPath, "TZI", uBinary
        	oReg.SetDWORDValue hDefKey, strKeyPath, "UseRegTimeZone", "00000001"
         
        	Next
	Else
	Wscript.echo "array is null"
	End If
 Else
 Wscript.echo "EnumKey has error"
 End If
Else
Wscript.echo "oReg null"
End If

Open in new window

RobSampson

Did you try my latest code? Would it return a string if there's only one subkey?

Rob.
ASKER
lucifer82

I have tried but I get the original object not a collection error at the same point where the for loop begins.
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
Krys_K

After this
If IsNull(arrSubKeys) = False Then

Put
WScript.Echo TypeName(arrSubKeys)

Then we will know what type ity actually is. String, Object, Array, Integer etc..
Let us know what it comes back as

Krystian
ASKER
lucifer82

it returned NULL
RobSampson

Maybe we need to set arrSubKeys to Null before making the EnumKey call...

Rob.
Const HKEY_CLASSES_ROOT   = &H80000000
Const HKEY_CURRENT_USER   = &H80000001
Const HKEY_LOCAL_MACHINE  = &H80000002
Const HKEY_USERS          = &H80000003
 
Const REG_SZ        = 1
Const REG_EXPAND_SZ = 2
Const REG_BINARY    = 3
Const REG_DWORD     = 4
Const REG_MULTI_SZ  = 7
 
uBinary = Array(&Ha8,&Hfd,&Hff,&Hff,&H00,&H00,&H00,&H00,&Hc4,&Hff,&Hff,&Hff,&H00,&H00,&H04,&H00,&H00,&H00,&H01,&H00,&H03,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H0a,&H00,&H00,&H00,&H01,&H00,&H02,&H00,&H00,&H00,&H00,&H00,&H00,&H00)
 
' Chose computer name, registry tree and key path
'
strComputer = "." ' Use . for current machine
hDefKey = HKEY_CURRENT_USER
strKeyPath = "Software\Citrix\SessionTimeZone\"
 
' Connect to registry provider on target machine with current user
'
Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
 
' Enum the subkeys of the key path we've chosen
'
 
intAttempt = 0
arrSubKeys = Null
While IsNull(arrSubKeys) = True And intAttempt < 10
	oReg.EnumKey hDefKey, strKeyPath, arrSubKeys
	intAttempt = intAttempt + 1
	WScript.Sleep 1000
Wend
 
If IsNull(arrSubKeys) = False Then
	If TypeName(arrSubKeys) = "String" Then
		strKeyPath = strKeyPath + arrSubKeys
	Else
		For Each strSubkey In arrSubKeys		 
			strKeyPath = strKeyPath + strSubkey
			  
			oReg.SetStringValue hDefKey, strKeyPath, "Display", "AUS Eastern Standard Time"
			oReg.SetStringValue hDefKey, strKeyPath, "Dlt", "AUS Eastern Daylight Time"
			oReg.SetBinaryValue hDefKey, strKeyPath, "TZI", uBinary
			oReg.SetDWORDValue hDefKey, strKeyPath, "UseRegTimeZone", "00000001"
		 
		Next
	End If
End If

Open in new window

This is the best money I have ever spent. I cannot not tell you how many times these folks have saved my bacon. I learn so much from the contributors.
rwheeler23
Krys_K

Sorry, if you put
WScript.Echo TypeName(arrSubKeys)
before
If IsNull(arrSubKeys) = False Then
What does it return?

Krystian
Krys_K

Hi
I've tested your code and there were some issues.

i have changed some bits to make it work correctly now - at least for me anyway.

First off, you were trying to get a DWord value, which wasn't working for me, so i changed it to grab teh value intoa variable then i output the variable.
2nd, you were concatenating a path string which was putting the path plus each subkey on teh end of eachother
so the first time it went round the loop, the path was correct, then it was trying to find path + subkey1 + next subkey which of course, never existed.
I changed it to always use the correct path round the loop

See how you get on

Krystian
Const HKEY_CLASSES_ROOT   = &H80000000
Const HKEY_CURRENT_USER   = &H80000001
Const HKEY_LOCAL_MACHINE  = &H80000002
Const HKEY_USERS          = &H80000003
 
Const REG_SZ        = 1
Const REG_EXPAND_SZ = 2
Const REG_BINARY    = 3
Const REG_DWORD     = 4
Const REG_MULTI_SZ  = 7
 
uBinary = Array(&Ha8,&Hfd,&Hff,&Hff,&H00,&H00,&H00,&H00,&Hc4,&Hff,&Hff,&Hff,&H00,&H00,&H04,&H00,&H00,&H00,&H01,&H00,&H03,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H0a,&H00,&H00,&H00,&H01,&H00,&H02,&H00,&H00,&H00,&H00,&H00,&H00,&H00)
 
' Chose computer name, registry tree and key path
'
strComputer = "." ' Use . for current machine
hDefKey = &H80000001'HKEY_CURRENT_USER
strKeyPath = "Software\CitrixTest\SessionTimeZone\"
 
' Connect to registry provider on target machine with current user
'
Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
 
' Enum the subkeys of the key path we've chosen
'
 
 
If IsNull(oReg) = False Then
 
oReg.GetDWORDValue hDefKey, "Software\CitrixTest\", "DisablePlayAnimations", iDWordValue
WScript.echo "oReg contains " & iDWordValue
 
 If oReg.EnumKey(hDefKey, strKeyPath, arrSubKeys) = False Then
 
	If IsNull(arrSubKeys) = False Then
        	For Each strSubkey In arrSubKeys
 
        	oReg.SetStringValue hDefKey, strKeyPath & strSubKey, "Display", "AUS Eastern Standard Time"
        	oReg.SetStringValue hDefKey, strKeyPath & strSubKey, "Dlt", "AUS Eastern Daylight Time"
        	oReg.SetBinaryValue hDefKey, strKeyPath & strSubKey, "TZI", uBinary
        	oReg.SetDWORDValue hDefKey, strKeyPath & strSubKey, "UseRegTimeZone", "00000001"
 
        	Next
	Else
		Wscript.echo "array is null"
	End If
 Else
	 Wscript.echo "EnumKey has error"
 End If
Else
	Wscript.echo "oReg null"
End If

Open in new window

Krys_K

Sorry, meant to say, change the 2 places i made Citrix to CitrixTest in the path name

Krystian
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
ASKER
lucifer82

no it made no difference >_<
ASKER
lucifer82

hmmm after several testing at this point it just doesn't like using array at all.

Does anyone know how to get the keyvalue as string instead of array? I know that it will only return one value anyway so it doesn't really need to be in array.
RobSampson

Hmmm, the problem here is that you need to use EnumKey to return the subkey names under
HKCU\Software\Citrix\SessionTimeZone
because you can't be sure what the actual name of the subkey is that you'll be changing values for.

This code works for me, without changing any values, just reporting on what the subkey names are....

Regards,

Rob.
Const HKEY_CLASSES_ROOT   = &H80000000
Const HKEY_CURRENT_USER   = &H80000001
Const HKEY_LOCAL_MACHINE  = &H80000002
Const HKEY_USERS          = &H80000003
 
Const REG_SZ        = 1
Const REG_EXPAND_SZ = 2
Const REG_BINARY    = 3
Const REG_DWORD     = 4
Const REG_MULTI_SZ  = 7
 
uBinary = Array(&Ha8,&Hfd,&Hff,&Hff,&H00,&H00,&H00,&H00,&Hc4,&Hff,&Hff,&Hff,&H00,&H00,&H04,&H00,&H00,&H00,&H01,&H00,&H03,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H0a,&H00,&H00,&H00,&H01,&H00,&H02,&H00,&H00,&H00,&H00,&H00,&H00,&H00)
 
' Chose computer name, registry tree and key path
'
strComputer = "." ' Use . for current machine
hDefKey = HKEY_CURRENT_USER
strKeyPath = "Software\Citrix\SessionTimeZone\"
 
' Connect to registry provider on target machine with current user
'
Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
 
' Enum the subkeys of the key path we've chosen
'
 
intAttempt = 0
arrSubKeys = Null
While IsNull(arrSubKeys) = True And intAttempt < 10
	oReg.EnumKey hDefKey, strKeyPath, arrSubKeys
	intAttempt = intAttempt + 1
	WScript.Sleep 1000
Wend
 
If IsNull(arrSubKeys) = False Then
	If TypeName(arrSubKeys) = "String" Then
		strSubKeyPath = strKeyPath & arrSubKeys
		MsgBox "String: " & strSubKeyPath
	Else
		MsgBox "There are " & UBound(arrSubKeys) + 1 & " subkeys."
		For Each strSubkey In arrSubKeys	 
			strSubKeyPath = strKeyPath & strSubkey
			MsgBox "Array: " & strSubKeyPath
			'oReg.SetStringValue hDefKey, strSubKeyPath, "Display", "AUS Eastern Standard Time"
			'oReg.SetStringValue hDefKey, strSubKeyPath, "Dlt", "AUS Eastern Daylight Time"
			'oReg.SetBinaryValue hDefKey, strSubKeyPath, "TZI", uBinary
			'oReg.SetDWORDValue hDefKey, strSubKeyPath, "UseRegTimeZone", 1
		 
		Next
	End If
End If

Open in new window

All of life is about relationships, and EE has made a viirtual community a real community. It lifts everyone's boat
William Peck
ASKER
lucifer82

Yea I think I found the problem.

The key -> Session ID doesn't seem to be created in the registry at the point of when the login script is running hence why it give me an error when using it through the login script.

This explains why it works after I login and run the script manually.

Now I need to see if there is either another way other than Enumkey to return the value from some where else or find out when I can run the script so that it has loaded the key into registry. >_<
RobSampson

What if you increase the wait time on this line:
While IsNull(arrSubKeys) = True And intAttempt < 10

to, I don't know
While IsNull(arrSubKeys) = True And intAttempt < 120

to wait up to two minutes for the arrSubkeys to not be Null?

Does that help?

Rob.
ASKER
lucifer82

Nope made no difference...... =_="
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
RobSampson

Humph!  Well, what if you just put
WScript.Sleep 30000

right at the top to wait 30 seconds before running....
ASKER
lucifer82

I think it's more to do with "when" this script runs in process that windows creates the registry values. At the login it probably doesn't created and once you see the login process is completed (when u see windows explorer running) is when it loads everything..... =_="""""

it's a tough one.... I'm this close to getting this fix and it will be a great fix for a lot of people
RobSampson

Where have you applied this login script?

I think that if you execute your vbscript with the following command
wscript //B \\server\share\change_time_zone.vbs

in the following file
%windir%\system32\usrlogon.cmd

on the Citrix server, you will have that command execute after login, and it should work.  I use this method to make some registry changes at logon for Lotus Notes R8.

Regards,

Rob.
Experts Exchange is like having an extremely knowledgeable team sitting and waiting for your call. Couldn't do my job half as well as I do without it!
James Murphy
ASKER
lucifer82

RobSampson, I have tested the way you have mentioned above but it seems that when I run this script at the logon this "session" Key

HKCU\Software\Citrix\SessionTimeZone\<SESSIOIDHERE>

does not exist. Hence why my script does not run correctly. I'm seeking a way at the moment to find a session ID prior to the login script is initiated.

At the moment I'm testing on the actual citrix box where writing a script to check the session ID and return it to say txt file so that I may able to call that script during the login script to get the session id there instead of reading the registry value. This way I may still have a chance to have it all in the login script.

I have thought about the alternative way to fix this issue but it's rather messy. It was to allow all the users allow changes to the registry value, than make a script to copy this vbs file into their "startup" folder with a bat file to excute "after" they have logged on. This is a messy work around as there is NO garentee that bat file will run correctly and it needs to copy a file all the time assuming that it does.
RobSampson

Hmmmm, maybe this article can help you control the values of the SessionTimeZone key...
http://support.citrix.com/article/CTX303498

Rob.
ASKER
lucifer82

yea I've already worked out how to change the value of it. I can always push the registry key, however for my script to work I need to find out what session ID I'm currently on. Hence why I'm struggling to find a way around it.  I want to automate as much as possible and not rely on the "start up" folder.
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
RobSampson

Hmmm...well....what if you used code like this obtain the current sessions Session ID, then you could just try to directly change the value of that
strKeyPath = "Software\Citrix\SessionTimeZone\" & strSessionID

key??

As I mentioned....with this executed by the usrlogon.cmd script, it should work with the keys loaded...

Are you using published applications, or a published desktop?

Regards,

Rob.
On Error Resume Next
 
Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20
 
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\Citrix")
Set colItems = objWMIService.ExecQuery("SELECT SessionUser,SessionID FROM MetaFrame_Session", "WQL", _
		wbemFlagReturnImmediately + wbemFlagForwardOnly)
 
Set objNetwork = CreateObject("WScript.Network")
strUsername = objNetwork.UserName
strSessionID = ""
If strUsername <> "" Then
	For Each objItem In colItems
		strSessionUser = objItem.SessionUser
		If InStr(LCase(strSessionUser), LCase(strUsername)) > 0 Then
			strSessionID = objItem.SessionID
			Exit For
		End If
	Next
End If
 
If strSessionID <> "" Then
	MsgBox "Your session ID is " & strSessionID
End If

Open in new window

ASKER
lucifer82

No that didn't work either, I'm currently working on a way around it. It's rather messy way but does work. =_=" I will post up the result hopefully this afternoon
Krys_K

Hi there

standing back from this and thinking about robs script where it waits - but doesn't work makes me think along the lines of:
In AD for example, you can set a policy to run logon scripts synchronously or asynchronously.
I'm wondering if this is the same for Citirx logon? if so, then setting it to asynchronously would mean that the script runs but the logon process will continue regardless of the script finishing or not, then at some point the SessionID will be created and the script will eventually pick this up!

Just a thought :)

Krystian
I started with Experts Exchange in 2004 and it's been a mainstay of my professional computing life since. It helped me launch a career as a programmer / Oracle data analyst
William Peck
ASKER
lucifer82

what I was thinking from running few testing is that registry key values are not loaded at all so unless I find out the steps of how windows and/or citrix loads the registry values I wouldn't get this code to run.
RobSampson

Hmmm, the HKCU hive must be loaded at some point....that's the way Windows works....

Perhaps it is a synchoronous issue.....here's quite an indepth run-down of the Citrix logon process:
http://www.thomaskoetzing.de/index.php?option=com_content&task=view&id=117&Itemid=86

That may help understand where you can apply things...I'll have to write a logon script to query the registry for my Citrix logon to see what's going on further.....perhaps I can do that tomorrow...

Regards,

Rob.
Krys_K

Hi

can you confirm that you could get this to work once the user was logged in?? some posts ago you mentioned it worked after a user was logged in and you ran it manually. what did you run manually? the whole kix adn vbscript or just the script? if it's just the script then can you run it manually with both Kix and VBS?
If either way works manually after logon then either its a synchronous issue or that something happens other than logging in that creates that key in the registry!?!

Just a thought.

Krystian
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
RobSampson

OK, I just figured something out!  The script would always run synchronously, meaning Citrix would sit at "Running Logon Scripts" until the script was finished, and wasn't able to read the registry keys yet.  So, I put this in the UsrLogon.cmd file:
wscript.exe //B ShowRegValue.vbs

and this is the contentx of ShowRegValue.vbs:
Set objShell = CreateObject("wscript.shell")
objShell.Run "wscript.exe ""U:\Windows\Application Compatibility Scripts\ShowRegValue2.vbs""", 1, False

Pretty straightforward, that just execute another script, being ShowRegValue2.vbs, and *doesn't* wait for that to finish....this is the key....

And with the contents of ShowRegValue2.vbs being:

'====================
Const HKEY_CLASSES_ROOT   = &H80000000
Const HKEY_CURRENT_USER   = &H80000001
Const HKEY_LOCAL_MACHINE  = &H80000002
Const HKEY_USERS          = &H80000003
 
Const REG_SZ        = 1
Const REG_EXPAND_SZ = 2
Const REG_BINARY    = 3
Const REG_DWORD     = 4
Const REG_MULTI_SZ  = 7
 
uBinary = Array(&Ha8,&Hfd,&Hff,&Hff,&H00,&H00,&H00,&H00,&Hc4,&Hff,&Hff,&Hff,&H00,&H00,&H04,&H00,&H00,&H00,&H01,&H00,&H03,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H0a,&H00,&H00,&H00,&H01,&H00,&H02,&H00,&H00,&H00,&H00,&H00,&H00,&H00)
 
' Chose computer name, registry tree and key path
'
strComputer = "." ' Use . for current machine
hDefKey = HKEY_CURRENT_USER
strKeyPath = "Software\Citrix\SessionTimeZone\"
 
' Connect to registry provider on target machine with current user
'
Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
 
' Enum the subkeys of the key path we've chosen
'
 
intAttempt = 0
arrSubKeys = Null
While IsNull(arrSubKeys) = True And intAttempt < 10
      oReg.EnumKey hDefKey, strKeyPath, arrSubKeys
      intAttempt = intAttempt + 1
      WScript.Sleep 1000
Wend
 
If IsNull(arrSubKeys) = False Then
      If TypeName(arrSubKeys) = "String" Then
            strSubKeyPath = strKeyPath & arrSubKeys
            MsgBox "String: " & strSubKeyPath
      Else
            MsgBox "There are " & UBound(arrSubKeys) + 1 & " subkeys."
            For Each strSubkey In arrSubKeys       
                  strSubKeyPath = strKeyPath & strSubkey
                  MsgBox "Array: " & strSubKeyPath
                  'oReg.SetStringValue hDefKey, strSubKeyPath, "Display", "AUS Eastern Standard Time"
                  'oReg.SetStringValue hDefKey, strSubKeyPath, "Dlt", "AUS Eastern Daylight Time"
                  'oReg.SetBinaryValue hDefKey, strSubKeyPath, "TZI", uBinary
                  'oReg.SetDWORDValue hDefKey, strSubKeyPath, "UseRegTimeZone", 1
             
            Next
      End If
End If
'====================

This means it tries for up 10 seconds *after* the login scripts have finished, to read the values.....

Try that out....I think it should work.

Regards,

Rob.
ASKER
lucifer82

Krys_K: yes my original vbs script to read the registry key to run the rest of the code works fine after user has logged into the citrix session. At the moment I have a work around which is slightly messy but working.

However RobSampson's code looks interesting. I will definitely test it out next week and give you guys a feed back. ^_^
RobSampson

Hey lucifer...any luck with this?

Regards,

Rob.
Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
ASKER
lucifer82

sorry RobSampson been busy at work haven't had a chance to test ur theory as yet. I'll try to make time tmr and apply.
RobSampson

Sure, no problem....just checking you're still awake ;-)

Rob.
ASKER
lucifer82

It partially worked in the sense that it showed me the key but when I put the reg edit part it didn't seem to apply.

So I'm currently applying what is working that I found out.

1. Make sure in your GPO to Disable "Prevent access to registry editing tools"
2. In the Citrix policy Enable "Do not use local time"
3. In the login script login.cmd call citirx.kix
4. citrix.kix will write a fild "IP.txt" which contains the 2nd oct of IP address to determine which branch user is connecting from.
5. place a TimeZone.cmd in users \Start Menu\Programs\Startup which initiates TimeZone.vbs



'======login.cmd
 
\\server\netlogon\kix32.exe \\server\netlogon\citrix.kix
 
'============================================================
 
'======citrix.kix
 
 
; "Determine IP Address"
 
	$WTS = CreateObject ("WTSManager.Shell")
	$ClientIP = Cstr ($WTS.MyIPAddress)
 
; "This line matches the first two bits of the IP (EG: "192.168")"
	$1oct=split(join(split($ClientIP,' '),''),'.')[0] + "." + split(join(split($ClientIP,' '),''),'.')[1]
; "This line matches the third bit"
	$2oct=split(join(split($ClientIP,' '),''),'.')[2]
 
 
; "Write the value to a file in the users U: drive for TimeZone Script"
 
	DEL "U:\IP.txt"
 
	Open(1,"U:\IP.txt",5)
	writeline(1, "$2oct")
	Close(1)
 
'===========================================================
 
'========TimeZone.cmd
 
cscript \\server\netlogon\timezone\AllTimeZone.vbs
 
'===========================================================
 
'========TimeZone.vbs
 
' Constants (taken from WinReg.h)
'
Const HKEY_CLASSES_ROOT   = &H80000000
Const HKEY_CURRENT_USER   = &H80000001
Const HKEY_LOCAL_MACHINE  = &H80000002
Const HKEY_USERS          = &H80000003
 
Const REG_SZ        = 1
Const REG_EXPAND_SZ = 2
Const REG_BINARY    = 3
Const REG_DWORD     = 4
Const REG_MULTI_SZ  = 7
 
uBinary_AEDT = Array(&Ha8,&Hfd,&Hff,&Hff,&H00,&H00,&H00,&H00,&Hc4,&Hff,&Hff,&Hff,&H00,&H00,&H04,&H00,&H00,&H00,&H01,&H00,&H03,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H0a,&H00,&H00,&H00,&H01,&H00,&H02,&H00,&H00,&H00,&H00,&H00,&H00,&H00)
 
uBinary_AEST = Array(&Ha8,&Hfd,&Hff,&Hff,&H00,&H00,&H00,&H00,&Hc4,&Hff,&Hff,&Hff,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00)
 
uBinary_WAET = Array(&H20,&Hfe,&Hff,&Hff,&H00,&H00,&H00,&H00,&Hc4,&Hff,&Hff,&Hff,&H00,&H00,&H03,&H00,&H00,&H00,&H05,&H00,&H03,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H0a,&H00,&H00,&H00,&H05,&H00,&H02,&H00,&H00,&H00,&H00,&H00,&H00,&H00)
 
uBinary_ACDT = Array(&Hc6,&Hfd,&Hff,&Hff,&H00,&H00,&H00,&H00,&Hc4,&Hff,&Hff,&Hff,&H00,&H00,&H04,&H00,&H00,&H00,&H01,&H00,&H03,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H0a,&H00,&H00,&H00,&H01,&H00,&H02,&H00,&H00,&H00,&H00,&H00,&H00,&H00)
 
' Chose computer name, registry tree and key path
'
strComputer = "." ' Use . for current machine
hDefKey = HKEY_CURRENT_USER
strKeyPath = "Software\Citrix\SessionTimeZone\"
 
' Connect to registry provider on target machine with current user
'
Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
 
' Enum the subkeys of the key path we've chosen
'
oReg.EnumKey hDefKey, strKeyPath, arrSubKeys
 
Const ForReading = 1
 
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile("u:\IP.txt", ForReading)
 
strLine = objTextFile.ReadLine
Wscript.Echo strLine
 
objTextFile.Close
 
 
For Each strSubkey In arrSubKeys
 
  Select case strLine
  
'==============================================================================================  
 
  Case "7"
    
    strKeyPath = strKeyPath + strSubkey
 
    oReg.SetStringValue hDefKey, strKeyPath, "Display", "E. Australia Standard Time"
    oReg.SetStringValue hDefKey, strKeyPath, "Dlt", "E. Australia Standard Time"
    oReg.SetBinaryValue hDefKey, strKeyPath, "TZI", uBinary_AEST
    oReg.SetDWORDValue hDefKey, strKeyPath, "UseRegTimeZone", "00000001"
    
    Wscript.Echo "AEST"  
     
'============================================================================================== 
 
  Case "11"
  
    'Roxby Downs
  
    strKeyPath = strKeyPath + strSubkey
  
    oReg.SetStringValue hDefKey, strKeyPath, "Display", "Cen. Australia Standard Time"
    oReg.SetStringValue hDefKey, strKeyPath, "Dlt", "Cen. Australia Daylight Time"
    oReg.SetBinaryValue hDefKey, strKeyPath, "TZI", uBinary_ACDT
    oReg.SetDWORDValue hDefKey, strKeyPath, "UseRegTimeZone", "00000001"
    
    Wscript.Echo "ACDT"    
    
'==============================================================================================  
 
  Case "15"
 
    'Port Headland
 
    strKeyPath = strKeyPath + strSubkey
  
    oReg.SetStringValue hDefKey, strKeyPath, "Display", "W. Australia Standard Time"
    oReg.SetStringValue hDefKey, strKeyPath, "Dlt", "W. Australia Daylight Time"
    oReg.SetBinaryValue hDefKey, strKeyPath, "TZI", uBinary_WAET
    oReg.SetDWORDValue hDefKey, strKeyPath, "UseRegTimeZone", "00000001"
    
    Wscript.Echo "WAET" 
 
 
'==============================================================================================
 
  Case "12"
 
    'Noble Park
 
    strKeyPath = strKeyPath + strSubkey
  
    oReg.SetStringValue hDefKey, strKeyPath, "Display", "AUS Eastern Standard Time"
    oReg.SetStringValue hDefKey, strKeyPath, "Dlt", "AUS Eastern Daylight Time"
    oReg.SetBinaryValue hDefKey, strKeyPath, "TZI", uBinary_AEDT
    oReg.SetDWORDValue hDefKey, strKeyPath, "UseRegTimeZone", "00000001"
    
    Wscript.Echo "AEDT"
  
 
'==============================================================================================
 
  Case Else
 
    Wscript.Echo "TimeZone was not set correctly"
 
  End Select
 
Next
 
 
 
 
 
'===========================================================

Open in new window

Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
RobSampson

Wow, that's quite involved, but as least it works ;-)

So do you still have any issue with that approach?

It seems like a relatively logical process, given that Citrix will always to execute it's scripts synchoronously....

Regards,

Rob.
ASKER
lucifer82

As long as I proceed with this process it does work at this point. I can't guarantee about the time changes when the day light saving finishes at April? So it's currently in testing phase but applying the current summer time is working for sure.

It is rather trouble some but that's the only way I found that would perform viewing the registry value and apply registry changes.

so now I just have to wait till time changes over I suppose.... unless I need to write a script also to tell it to change the registry value to standard time at this particular date. =_="
RobSampson

Ah, so it's a whole DST issue....no doubt brought about by the numerous MS patches that were supposed to fix the timezones....I know, I've been plagued by these myself, and we have a pretty crude hack ourselves to "sync" all of our client and server times.....

Well, good luck with it all! I hope it works for you.

Rob.
Your help has saved me hundreds of hours of internet surfing.
fblack61
ASKER CERTIFIED SOLUTION
lucifer82

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
See how we're fighting big data
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
RobSampson

No problem. Good work.

Rob.