Re: Logon script - function array and select case not working




"Nex6" <Nex6@xxxxxxxxxxxxxxx> wrote in message news:alpine.WNT.2.00.0906091721360.8168@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
This, is really the first time I tryed to mess with arrays and select case, I do a fair amount of scripting but nothing with case and arrays. i used a dicionary object but that was it.

On Tue, 9 Jun 2009, Al Dunbar wrote:



"Nex6" <Nex6@xxxxxxxxxxxxxxx> wrote in message news:alpine.WNT.2.00.0906091532310.6772@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Hi all,

I am trying to rewrite my logon scripts which are all in vbscript. the scripts are written in a framework model, eg: control script,hashtable script and subscripts which are for each group.

the hash table, has all the names, and server paths, and all the scripts use those names from the central hash table (via an include function) (this is so if server name changes i just change the path in the hash table)


this all works well, except, the function i am using for the rules in the control script causes alot of querrys to AD. as there are alot of groups.

In my experience, testing group membership is expensive, no matter how you try to do it.

so my thinking was have a function dump all the groups into an array,

How have you determined that this will be faster or result in fewer trips to the domain?

becuase the current product script, is based like so:

if ismember "groupname" then
obj.run "\\ad\sysvol\~\subscriptdept.vbs
end if

only alot of them... like about 50 or 60, so every querry is a call to AD. thats too much, i want/need to cut that down.

That is not vbscript code, so I cannot tell if "ismember" is a vbscript function or perhaps a resource kit executable...

For our logon script I developed a function that combined recursive calls to itself to deal with group nesting but it used ismember.exe to test membership in each group encountered. Once it determined whether or not user "X" was a member of group "Y", it kept that info in a dictionary object so the next time it had to test that same group it avoided the ismember.exe call.

I tried about seven different versions, each using a different "is this user a member of this group" logic, and picked the one that performed the best. In the process I found that the first use of ismember.exe takes the longest time, such that subsequent uses are a lot faster. I think that is because it also caches its results somehow.




pass the array to a select case and fire off the subscripts inside the case statement. (there are more the 60 groups is there a limit to case?

I am unaware of any limit to the number of cases in a select case block...

here is what i have:


/code

dim dataarray()
dim data
dim retrv
dim obj



set objFSO = CreateObject("Scripting.FileSystemObject")
set objTSout = objFSO.CreateTextFile(".\loglinfunction.txt", true)
set objTSout2 = objFSO.CreateTextFile(".\logoutfunction.txt", true)
set objTSout3 = objFSO.CreateTextFile(".\top.txt", true)
set objTSout4 = objFSO.CreateTextFile(".\logarrayfunction.txt", true)

objTSout.writeline retrv

what value are you expecting this statement to write into the file, given that retrv has yet to be assigned a value?

this is debug stuff, so I can see the vaules at that point in the script, infact all the writelines are just for debugging to help me see output.

I kind of guessed it was debug output. But the question remains: why display the value of a variable that has not yet been assigned any value? Is this perhaps because you have shown only a representative sample of your script?



retrv = checkgrp

what value are you expecting this will assign to retrv?

here is am trying to get the array into something i can use in the select case. I have been playing with it alot, so some things may be messy :)

So if you think that this will assign an array value to the variable, how do you think the case select statement is going go compare this array value (i.e. an array of individual values) with the literal string values such as "group name here"? IMHO, CASE SELECT, like IF, can only work with scalar values, not arrays.




'for each obj in retrv
Select Case retrv
Case "group name here" wscript.echo "ok"
Case "green" document.bgColor = "green"
Case "blue" document.bgColor = "blue"
'Case Else MsgBox "pick another color"
End Select

The above will do one of three actions depending on the value of retrv being either "group name here", "green", or "blue". If retrv is anything else, nothing will happen.


yup, nothing happens, which i know becuase i am outputing everything at each stage to files for me to look at.

But of course nothing happens. That is because retrv does NOT contain any of the three string values attached to the CASE statements.



When you run this, what happens? I expect nothing as noted in my comment just after the end function statement...

nothing, becuase the arrays data never leaves the for loop in the function.

That may be true. However, by not assigning ANY value to checkgrp in the function, you are guaranteeing that, should the function ever exit, it will return no information.



Also, where is the document object defined?

hunh?

You have a statement like this:

Case "green" document.bgColor = "green"

The only meaning I take from this is that a variable named "document " contains a reference to an object having a property called "bgColor. Since no value is assigned to this variable, the statement, if executed, will execute in error.

Now, such a variable could be created automatically in some environments, but a logon script is usually implemented as a .vbs or .wsf script where this is not the case.



'next


private function checkgrp()
'dim dataarray()
'dim data


On Error Resume Next
Set objADSysInfo = CreateObject("ADSystemInfo")
strUser = objADSysInfo.UserName
Set objUser = GetObject("LDAP://"; & strUser)
For Each strGroup in objUser.memberOf
Set objGroup = GetObject("LDAP://"; & strGroup)
'Wscript.Echo objGroup.CN
redim Preserve dataarray(data)

where does "data" get its value from?


below, i am trying to have a dynamic array, becuase this is polling group member ship and everyone will be different.

I understood what you were trying to do, incrementally increase the dimension of an array. But when that REDIM statement is executed, the variable called "data" *MUST* contain in integer value equal to the new size of the array. Your script does not assign any value to this variable.




dataarray(data) = objGroup.CN
retrv = dataarray(data)

Assigning a value from within a function to a global variable is not a good idea.

i know, i was trying diffeent things to get it to work, notice the commented out at the top of the function.

I understand "trying different things", but you should really restrict yourself to trying only one of them at a time. That said, I can think of no good reason to *EVER* assign a value directly from within a function to the global variable to which the result of the function is being assigned. If this is the type of thing you are trying, it leads me to believe that you have yet to get a good overall grasp on the language.





'wscript.echo dataarray(data)


'objTSout.writeline dataarray(data)
'objTSout.writeline checkgrp

Next




'objTSout2.writeline dataarray()
objTSout2.writeline retrv
objTSout4.writeline dataarray(data)

'wscript.echo strname


end function

Since no value has been assigned to the name of the function, the value returned has nothing to do with anything the function has done.


i tryed doing things like checkgrp = arrayname, but it still does not work. so i , after google and nothing, basicly am trying everything I can think of. but since i never really played with arrays that much, and passing data from an array in a function seems to be a black art in vbscript....

You don't want to pass data from an array in a function; you want to pass an entire array back to the calling routine from the function. No blackness to this art at all, here is a simple example:

a = "asdf"
wscript.echo typename(a)
wscript.echo vartype(a)
a = makearray()
wscript.echo typename(a)
wscript.echo vartype(a)

function makearray()
dim av(),ix
for ix = 0 to 3
redim av(ix)
av(ix) = ix
next
makearray = av
end function

Of course, there is a simpler way to do the same thing in this particular case. Just delete the function and replace this line:

a = makearray()

with this one:

a = array(0,1,2,3)

In your case, the difficulty is in figuring out what information to put into the array elements. Richard made some good suggestions in that direction.




wscript.echo "script has finished running"


/end code

Neither the intent nor the execution of the code is clear to me. Since it contains numerous errors, I am wondering why you think it is the function and select case statements themselves that are responsible rather than your code.



object, in the function get the array populted with the user who runs it, with all the groups. then, the select case, would be formated like so:

select case
case script_department.vbs
end case

Syntactically, this is incorrect, and doesn't come anywhere near what you actually want, which, as I understand you, might look more like this:

for each group in list_of_group_names
select case group ' not select case
case "finance" : include "script_finance.vbs" ' literal strings need to be quoted
case "HR" : include "script_HR.vbs"
case "IT" : include "script_IT.vbs"
end SELECT ' not end case
next

In English: for each group the user is a member of, execute the script associated.

If this is basically what you are doing, you might be able to get rid of the select case statement altogether. But this will require that the group names consist of only valid filename characters. Here's how:

for each group in list_of_group_names
vbsname = "script_" & group & ".vbs"
if FSO.fileexist( vbsname ) then
include vbsname
end if
next

Note: this assumes that FSO contains a file system object.

Alternately, you could have a dictionary object where the key is the group name (which could then be the DN or the sAMAccountName), and the value is the name of the associated script. Here's how:

set vbsnames = createobject("scripting.dictionaryobject")
vbsnames("dn=cn=dept\: Finance") = "\\finance_server\scripts\finance-logonscript.vbs"
vbsnames("dn=cn=IT guys") = "\\common_server\logonscripts\geeksRus.vbs"
etc...

for each group in list_of_group_names
if vbsnames( lcase(group) ).exist then
include vbsnames( lcase(group) )
end if
next

only like 60 cases. then those subscript, are the real login scripts for the users. and, those subscripts, i have an inlcude function the pulls a hashtable with everything they need to map all the drivers etc.


hope this clears it up some.

That is pretty much what I expected. One observation, though; I suspect you may have made this more complicated than really necessary.

/Al


.



Relevant Pages

  • Re: array within array
    ... playing around with the script below to get a feel for Perl. ... script below is incomplete and I'm doing an array within an array ... You are assigning the list from the file to a hash. ...
    (perl.beginners)
  • RE: array within array
    ... Subject: array within array ... On Monday 29 October 2007 06:42, Mike Tran wrote: ... playing around with the script below to get a feel for Perl. ... You are assigning the list from the file to a hash. ...
    (perl.beginners)
  • Re: string retrieval issue
    ... Chicago Bears|NFC North ... not writing the third element back to the array). ... You didn't include it in your script. ... Fear is the mind-killer. ...
    (comp.lang.perl.misc)
  • Re: even rows for checkbox forms with no splitting of boxes from values
    ... 'mod' on the array length with a denominator equal to the width of the row, ... State saving really depends on what the script is already doing. ... So I usually roll my own checkboxes. ... #this is to create an array with 25-50 strings 2-10 in length ...
    (comp.infosystems.www.authoring.cgi)
  • Re: settimeout needs alert() ???
    ... function slider { ... and use script to replace the src and title attributes. ... are downloaded completely. ... The usual strategy is to load all of the images in to an array of image ...
    (comp.lang.javascript)

Loading