lucifer82
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
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
ASKER
isn't line 26 doing that??? or do I need to specifically say
Dim arrSubKeys(50)
Dim arrSubKeys(50)
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
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
ASKER
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.
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.
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.
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
Or, you could use this to "try" to get the subkeys for 10 seconds....
Regards,
Rob.
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
ASKER
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
I tested the second one too but I get the same error when it comes to the arrSubKey in line 35
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
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
Maybe there only one subkey and it's a string??
Rob.
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
ASKER
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.
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
Did you try my latest code? Would it return a string if there's only one subkey?
Rob.
Rob.
ASKER
I have tried but I get the original object not a collection error at the same point where the for loop begins.
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
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
it returned NULL
Maybe we need to set arrSubKeys to Null before making the EnumKey call...
Rob.
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
Sorry, if you put
WScript.Echo TypeName(arrSubKeys)
before
If IsNull(arrSubKeys) = False Then
What does it return?
Krystian
WScript.Echo TypeName(arrSubKeys)
before
If IsNull(arrSubKeys) = False Then
What does it return?
Krystian
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
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
Sorry, meant to say, change the 2 places i made Citrix to CitrixTest in the path name
Krystian
Krystian
ASKER
no it made no difference >_<
ASKER
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.
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.
Hmmm, the problem here is that you need to use EnumKey to return the subkey names under
HKCU\Software\Citrix\Sessi onTimeZone
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.
HKCU\Software\Citrix\Sessi
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
ASKER
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. >_<
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. >_<
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.
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
Nope made no difference...... =_="
Humph! Well, what if you just put
WScript.Sleep 30000
right at the top to wait 30 seconds before running....
WScript.Sleep 30000
right at the top to wait 30 seconds before running....
ASKER
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
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
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.
I think that if you execute your vbscript with the following command
wscript //B \\server\share\change_time
in the following file
%windir%\system32\usrlogon
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.
ASKER
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\Sessi onTimeZone \<SESSIOID HERE>
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.
HKCU\Software\Citrix\Sessi
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.
Hmmmm, maybe this article can help you control the values of the SessionTimeZone key...
http://support.citrix.com/article/CTX303498
Rob.
http://support.citrix.com/article/CTX303498
Rob.
ASKER
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.
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\SessionTi meZone\" & 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.
strKeyPath = "Software\Citrix\SessionTi
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
ASKER
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
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
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
ASKER
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.
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.
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.
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
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
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.shel l")
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\SessionTi meZone\"
' Connect to registry provider on target machine with current user
'
Set oReg = GetObject("winmgmts:{imper sonationLe vel=impers onate}!\\" & 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.
wscript.exe //B ShowRegValue.vbs
and this is the contentx of ShowRegValue.vbs:
Set objShell = CreateObject("wscript.shel
objShell.Run "wscript.exe ""U:\Windows\Application Compatibility Scripts\ShowRegValue2.vbs"
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,
' Chose computer name, registry tree and key path
'
strComputer = "." ' Use . for current machine
hDefKey = HKEY_CURRENT_USER
strKeyPath = "Software\Citrix\SessionTi
' Connect to registry provider on target machine with current user
'
Set oReg = GetObject("winmgmts:{imper
' 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
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. ^_^
However RobSampson's code looks interesting. I will definitely test it out next week and give you guys a feed back. ^_^
Hey lucifer...any luck with this?
Regards,
Rob.
Regards,
Rob.
ASKER
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.
Sure, no problem....just checking you're still awake ;-)
Rob.
Rob.
ASKER
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
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
'===========================================================
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.
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
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. =_="
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. =_="
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.
Well, good luck with it all! I hope it works for you.
Rob.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
No problem. Good work.
Rob.
Rob.
I don't see in the code where you set the variable arrSubKeys to a valid collection or array...
Regards,
Patrick