Page 1 of 1 1
Topic Options
#214242 - 2023-06-27 11:25 AM Kixtart Getobject Active Directory Issues
Robdutoit Offline
Hey THIS is FUN
***

Registered: 2012-03-27
Posts: 363
Loc: London, England
I spent around 10 hours on this yesterday and I still cannot understand why I cannot get this to work.

This is a bit of a complicated question as there are three parts to the question.

Question 1: Has a Kixtart update broken something?

The GetGroups Function - gives an Error in expression: this type of array not supported in expressions.

http://www.kixtart.org/forums/ubbthreads.php?ubb=showflat&Number=83438

I speak under correction, but if an UDF on the Kixtart is present, it has presumably been tested and working?

I have tried a couple of udf's similar to this one and got the same error message!

http://www.kixtart.org/forums/ubbthreads.php?ubb=showflat&Number=208912 This post highlights the problem as well. If I have understood what I have read correctly, either Kixtart or ldap is converting text to array or vice versa and you need to put a @crlf somewhere in the coding for udf's like GetGroups function. This I presume forces Kixtart to use a string instead of array I think.

Using the GetGroups function, I managed to modify the code to get rid of the array error message. But then I get a missing ) error message! I had the same result with another udf, getting rid of the array error message then resulted in a missing ) error message, despite the fact that there are no missing ) anywhere!

To me, this feels like a bug, given that a Kixtart UDF hosted on Kixtart, that presumably used to work no longer works, and given that the solution as shown in another post is to add a @crlf to break the line as it were!

A lot of of people seem to be having problems with this. It's not just me! Is this a Kixtart, Ldap or what? bug? Is

Question 2: What I was actually trying to do. How do I fix!

What I am trying to achieve (and so far cannot) is to lookup the list of Security Groups in a particular OU and then check if the currently logged on user is a member of any of those particular security groups and display the output to console.

I created this code to do this:

[code]
Function JobRole()

Dim $objADsPath, $obj, $userSecurityGroups

$objADsPath = GetObject("LDAP://OU=JobRole,DC=%Userdomain%,DC=internal")

$userSecurityGroups = $objADsPath.GetEx("member")

If @Error = 0
For Each $obj In $userSecurityGroups
If INGROUP(GetObject("LDAP://" + $obj).cn)
? "Job Role is: " + GetObject("LDAP://" + $obj).cn
EndIf
Next
Else
? "Error retrieving security groups: " + @Error
? "Error description: " + @SERROR
EndIf

EndFunction
/code]

Because I updated and changed this code so many times yesterday trying to get it to work, I can't guarantee it's accurate at the moment, but I have reached my limit.

The error message I get for this function (which I cannot resolve) is -Error description: com exception error "getex" (Active Directory - The directory property cannot be found in the cache.)

After hours of trying, I abandoned this script and started looking at the scripts on the Kixtart website, but then I kept running into this Error in expression: this type of array not supported in expressions. And when I manage to get rid of that message, I always end up with this stupid missing ) error message - which I can't fix.

My code doesn't work at all in the sense it returns nothing. The GetGroups Function does stop on the array not supported error, but it does at least correctly identify what groups the logged on user is in and displays the output. In my networks, I create a user and add them to a job role security group. Then I add that job role to other security groups which control access to mapped drives, printers etc. So I am quite happy to use the GetGroups function (providing I can fix the array message message and update to using LDAP instead of WinNT.

Question 3: Is there a better way than using Getobject LDAP?

95% of my kixtart scripts is checking and setting registry entries as well as using standard kixtart built in functions such as if ingroup etc. So I don't spend a lot of time, hardly any, working on LDAP queries or Getobject etc. However, I really struggled for hours yesterday using my own script as well as two scripts off Kixtart website and basically am going round in circles.

Is there a simpler and better way to get Kixtart to lookup a list of elements in active directory and do something with that information. I cannot believe how hard this is to do. Even Chatgpt could not fix the issue. I either cannot cache the result, or I get an error in array or I keep running into this missing ) problem! There has to be a simpler way?

Conclusion.

I don't mind how I get the information - using the GetGroups Function, my JobRole Function or some other Kixtart method. As long as it works and uses modern coding so LDAP instead of WinNT for example. As my network usually has a user added to one Security Group, it probably is better to go with that option because then it's easy to see if a user has been added to a group incorrectly if it shows all security groups. Would be nice to exclude domain users group from the results though!

But I would also like to know if there is some kind of bug!

Top
#214243 - 2023-06-27 03:13 PM Re: Kixtart Getobject Active Directory Issues [Re: Robdutoit]
Allen Administrator Offline
KiX Supporter
*****

Registered: 2003-04-19
Posts: 4549
Loc: USA
I haven't had time to fully read through your post or do any re-testing, but I did want to point you in the direction of using a UDF that uses the more current LDAP object instead of WINNT object.

GetADUserGroups -
http://www.kixtart.org/forums/ubbthreads.php?ubb=showflat&Number=198609#Post198609

How to use UDFs -
http://www.kixtart.org/forums/ubbthreads.php?ubb=showflat&Number=81943#Post81943

The rest of the UDFs are here -
http://www.kixtart.org/forums/ubbthreads.php?ubb=postlist&Board=7&page=1

Top
#214246 - 2023-06-27 08:42 PM Re: Kixtart Getobject Active Directory Issues [Re: Robdutoit]
ShaneEP Moderator Offline
MM club member
*****

Registered: 2002-11-29
Posts: 2125
Loc: Tulsa, OK
You're referencing a UDF that was originally posted in 2002. If Howard posted it, I can pretty much assure you it worked at the time. But lots has changed since then. Most of the usual contributors aren't as active anymore. And I doubt they are going through and re-testing UDFs from 21 years ago, when they are on.
Top
#214247 - 2023-06-27 10:42 PM Re: Kixtart Getobject Active Directory Issues [Re: ShaneEP]
Robdutoit Offline
Hey THIS is FUN
***

Registered: 2012-03-27
Posts: 363
Loc: London, England
Thanks. I will have a look tomorrow at the GetAdUserGroups to see if that will work for me! Or whenever I have energy to back to that.

I don't believe it is the Winnt issue - although I would prefer to use LDAP. I updated the code to use LDAP and it made zero difference. In point of fact, Howard's udf actually does get the security groups the user is a member of, so the script actually is working just stopping with an error.

I appreciate the age of the script does make it possible that the issue is changes over time. However, I think the post that I linked to and Lonkero's explanation would suggest as wider issue than any specific script.

I will update when I come back to this.

Top
#214249 - 2023-06-28 12:53 AM (NA) Re: Kixtart Getobject Active Directory Issues [Re: Robdutoit]
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4396
Loc: New Jersey
Not only from 2002, but a UDF that doesn't follow current standards. UDFs should operate silently and return values. Given the age and that Active Directory had substantial changes starting with Server 2003, using the WINNT object may no longer work fully.

The LDAPQuery function can do what you need and works with current standards. It is, however, somewhat challenging to use. I wrote GetLDAPData() as a front-end to the LDAPQuery function making it easy to use.
 Code:
; Get a list of group names from the OU
$aData = GetLDAPData('Group', , $OU_DN, 'BASE')
; Enumerate the array and check for user match - GroupMember, GroupMembers, GetObjectDN, and GetOBjectOU are all helpful functions


Most of the AD-related functions available on my website were written when I was working on large AD consolidation and migration projects. Pulling user, ou, group, and other data had to work reliably and with large (20K objects) datasets. These were written around 2013-2016 and would be my go-to over anything written 21 years ago. Also - as we use Kix intensively, most of the functions in my library are maintained and kept current - updating when required. My website updates directly from my dev library, so it's far more current than anything posted on KORG.
_________________________
Actually I am a Rocket Scientist! \:D

Top
#214250 - 2023-06-28 01:27 PM (NA) Re: Kixtart Getobject Active Directory Issues [Re: Glenn Barnas]
Robdutoit Offline
Hey THIS is FUN
***

Registered: 2012-03-27
Posts: 363
Loc: London, England
Allen, I have tested your GetADUserGroups Function and it comes up with the exact same error message - Error in expression: this type of array not supported in expressions.

ChatGTP said:

The error "this type of array not supported in expressions" typically occurs in KiXtart when trying to use an array directly in an expression. KiXtart does not allow direct array usage in expressions, such as passing an array as a function parameter or using an array as an index. To resolve this issue, you can modify the getADUserGroups function to return a string representation of the array instead of the array itself. To fix the issue.

Replace $getADUserGroups=$array with $getADUserGroups = $groupString and add the following code above $GetADUserGroups = $groupString

 Code:
; Convert array to string representation
    $groupString = ""
	?
    for $j = 0 to UBound($array) - 1
      $groupString = $groupString + $array[$j] + ","
    next
    $groupString = Left($groupString, Len($groupString) - 1)


This fixes the issue and confirms two points. The error message occurs regardless of whether one is using LDAP or WinNT, so this is not the issue. I agree that coding put onto the Kixtart UDF forums years ago would have worked. Obviously, something has changed with either Kixtart or how servers return LDAP or WinNT information so that Kixtart now requires you to return a string representation of the array. I suspect, in the past, the LDAP or WinNT information returned the information as a string so Kixtart didn’t have to convert to a string. I say this, because the problem doesn’t seem to be limited to Kixtart. Other people using other languages report the same problem. So I suspect how servers return the information has changed rather than programming languages.

As the getADUserGroups UDF is your UDF, you are more than welcome to update the coding accordingly. I have tested it and it now works when using the Convert array to string representation coding and substituting $getADUserGroups=$array with $getADUserGroups = $groupString. Basically all the functions in the Kixtart UDF will probably need to be updated to convert the arrays to strings?

I am going to have another look at the GetGroups UDF and see if I can fix that one as well. There are two reasons for this. The GetGroups function is a lot less coding and a lot easier to understand. The getADUserGroups UDF is much harder to follow what is going on and I don’t think all that coding is necessary given that GetGroups does work and is way shorter. I just need to add the Convert array to string representation and change WinNT to LDAP to get it to work. I will work on that now and post the updates shortly – if I can get it to work!

Glenn, what is the difference between GetLDAPData and a function that uses $oAccount=getobject("WinNT://$Domain/$Account,user") or $objRootDSE = GetObject("LDAP://RootDSE")?

Top
#214251 - 2023-06-28 03:41 PM Re: (NA) Re: Kixtart Getobject Active Directory Issues [Re: Glenn Barnas]
Robdutoit Offline
Hey THIS is FUN
***

Registered: 2012-03-27
Posts: 363
Loc: London, England
I have done some more work looking at the GetGroups Function by Howard.

Original GetGroups Function
 Code:
Function GetGroups($Domain, $Account, optional $Suppress)

   ; Group Types
   ; ADS_GROUP_TYPE_GLOBAL_GROUP        = 0x00000002,
   ; ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP  = 0x00000004,
   ; ADS_GROUP_TYPE_LOCAL_GROUP         = 0x00000004,
   ; ADS_GROUP_TYPE_UNIVERSAL_GROUP     = 0x00000008,
   ; ADS_GROUP_TYPE_SECURITY_ENABLED    = 0x80000000

   ; 

   Dim $Groups[1,0], $i, $x, $Type[8]
   $Type[2] = "GLOBAL_GROUP"
   $Type[4] = "LOCAL_GROUP"
   $Type[8] = "UNIVERSAL_GROUP"
   $oAccount=getobject("WinNT://$Domain/$Account,user")

   $x = -1
   For Each $group In $oAccount.Groups
      $x = $x + 1
      ReDim Preserve $Groups[1,$x]
      ; Class is always 'Group'
      ; $class = $group.Class
      $Groups[0,$x] = $group.Name
      $Groups[1,$x] = $Type[$group.groupType]
   Next

   $GetGroups = $Groups
   if not $Suppress
      $x = ubound($Groups,2)
      ? $Domain + "\" + $Account + " is a member of " + ($x+1) + " groups."
      For $i=0 to $x
         ? "    '" + $Groups[0,$i] + "'  (" + $Groups[1,$i] + ")"
      Next
   Endif
EndFunction


Now Working GetGroups Function

 Code:

Function GetGroups($Domain, $Account, Optional $Suppress)
   Dim $Groups[1, 0], $i, $x
   $oAccount = GetObject("WinNT://$Domain/$Account,user")
   $x = -1
   For Each $group In $oAccount.Groups
      $x = $x + 1
      ReDim Preserve $Groups[1, $x]
      $Groups[0, $x] = $group.Name
   Next

  ; Convert array to string representation
   $groupString = ""
   For $i = 0 To UBound($Groups, 2) - 1
      $groupString = $groupString + $Groups[0, $i] + ","
   Next
   $groupString = Left($groupString, Len($groupString) - 1)

   $GetGroups = $groupString
   If Not $Suppress
      $x = UBound($Groups, 2)
      ?$Domain + "\" + $Account + " is a member of " + ($x + 1) + " groups."
      For $i = 0 To $x - 1
         ?"    '" + $Groups[0, $i] + "'"
      Next
   EndIf
EndFunction


I have removed the:

; ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP = 0x00000004,
; ADS_GROUP_TYPE_LOCAL_GROUP = 0x00000004,
; ADS_GROUP_TYPE_UNIVERSAL_GROUP = 0x00000008,
; ADS_GROUP_TYPE_SECURITY_ENABLED = 0x80000000

because most people only use Global Security Groups. I have also removed the Type variable as not relevant here and deleted the extra bit that was on this line ?" '" + $Groups[0, $i] + "'".

I have also added the Convert array to string representation part of the coding.

I am pleased to report that this function is now working too. Once again, it is clear that we need to convert arrays to strings in Kixtart now. The old way doesn't work.

So I have fixed two of the functions on KORG!

I have tried and unfortunately failed to use LDAP in this function. I just cannot get it to return any groups using LDAP no no matter what changes are made to this script. So I have left this as WinNT because at least this works.

I am not sure if maybe Chatgpt could be used in the near future to scan all the user functions submitted on Kixtart website to convert arrays to strings or what the official position that Kixtart will want to take regarding all the udf's that no longer work because of this issue. Most of the coding probably still works, apart from this specific aspect. Having said that, at the moment Chatgpt is able to convert arrays to strings, but even between myself and chatgpt we just can't get some functions using WinNT to use LDAP to work properly. So the free version of Chatgpt is not ready for this task yet. Don't know about the paid for version which I understand is much more advanced. I just highlight this an option to automagically update the UDF's on the KORG using AI as nobody will have the time or interest in manually updating these UDFS. AI is a much better solution to this problem as the task is very specific.

Or failing that, I would recommend adding a note to the main UDF's function page (and highly visible) to make users aware that if they want to use any UDFS with WinNT or LDAP arrays - those arrays need to be converted into strings.

I am going to see if I can trim your script Allen. It works well, but I am sure the coding can be reduced! Will update on this later.

Top
#214252 - 2023-06-28 03:55 PM (NA) Re: Kixtart Getobject Active Directory Issues [Re: Robdutoit]
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4396
Loc: New Jersey
That's a key reason we don't use ChatGPT for production coding - that's very inefficient. It also is building a string with a delimiter and then removing the final delimiter. A much better method would be
 Code:
$Delim = ''
For Each $Elem in $aArray
  $String = $String + $Delim + $Elem
  $Delim = ','
Next
$String @CRLF
However, this is what most experienced coders would do:
 Code:
$aArray = Function(args..)
'DEBUG - Array data contains: Join($aArray, ' | ') ; or use @CRLF delimiter for 1 val per line
When we're debugging/developing apps and want to visualize the data being returned from functions, we use the DispResult() function. Pass it a variable and it figures out what KIND of variable it is and displays the type and value - simple ITEM, ARRAY, or 2-D ARRAY values are supported. The version on my website doesn't support COMPOUND ARRAY types, but those are not commonly used.

DispResult function: https://www.barnas.us/Downloads/Kixlib/DispResult.kxf.htm

The bottom line is that you are trying to directly display a value that is being returned as an array. You need to read the headers of the UDF to determine what is being returned and process it appropriately. GetGroups indicates it returns a 2-dimension array. GetADUserGroups also reports that it returns an array. If you don't know what kind of data is being returned or defined in a variable, the VarType() and VarTypeName() functions can help.

Also - public UDFs are "black boxes" and meant to be used as published. Removing code can break functionality, and - in essence - you are creating a NEW function and should thus give it a new name and header. Failing to do that will cause the rest of us to waste time troubleshooting something we believe to be a standard when it isn't. This isn't the first time we've had a discussion about understanding the data you are working with..


Edited by Glenn Barnas (2023-06-28 04:00 PM)
_________________________
Actually I am a Rocket Scientist! \:D

Top
#214253 - 2023-06-28 05:39 PM (NA) Re: Kixtart Getobject Active Directory Issues [Re: Glenn Barnas]
ShaneEP Moderator Offline
MM club member
*****

Registered: 2002-11-29
Posts: 2125
Loc: Tulsa, OK
Ok, I finally actually tested the original UDF, and it works fine for me. My guess is, you are incorrectly accessing the multiple dimension array that is returned, which is what is causing your errors. Nothing is wrong with the UDF itself.

STOP BELIEVEING CHATGPT KNOWS HOW TO PROGRAM IN KIX. It's a good source for information, but can only do so much. It led you down a rabbit hole you never needed to go down.

 Code:
$dom = "DOMAIN"
$acct = "USER"

$groups = GetGroups($dom, $acct)

For $i = 0 to UBound($groups, 0)
	? $groups[0,$i]
Next

get $


Edited by ShaneEP (2023-06-28 05:39 PM)

Top
#214254 - 2023-06-28 06:07 PM (NA) Re: Kixtart Getobject Active Directory Issues [Re: Glenn Barnas]
Robdutoit Offline
Hey THIS is FUN
***

Registered: 2012-03-27
Posts: 363
Loc: London, England
Interesting bit about building a string with a delimiter and then removing the final delimiter. I will have to look and see how that works for me! I didn't say Chatgpt was efficient. It has potential, but I would definitely not rely on it. It needs to be constantly checked and repeatedly uses coding that is not supported by Kixtart!

OMG - I have just tested your line
$aArray = Function(args..)

and found the root of all my sorrows! I have just checked with Chatgpt and it also at one point along the dialogue said to do that, but I did not see it or understand at the time. It had got me completely on the wrong track! You are absolutely right. There is nothing wrong with the actual functions themselves!

I can see why I got this horribly wrong. All my coding in my scripts to date is in the format

Function(args). I have never done it like below:
$Variable = Function(args..). Didn't even know that was supported!

This is the first time (since using Kixtart) that I have ever used an array! Never needed to use an array before! I will have to investigate to see if arrays are the only exception to the rule of Functions (args) in the context that I use them in, so I don't make this mistake in the future with something else.

Irritating thing is that Chatgpt did at some point raise this as the solution, but only after extensive editing of the function itself. Which is what makes using Chatgpt such a double edged sword! I have learnt a lot about coding since using Chatgpt, but it obviously is not ready to teach me coding!

Never occurred to me that the problem was with code calling the function itself!

Thank you for picking up what the actual problem was! At least I now have a much better understanding of WinNT, LDAP and arrays due to spending 2 days on the issue lol!

Much appreciated. Everything is working. Tested all UDFS and it does what it says on the tin!

Top
#214258 - 2023-06-30 11:04 PM (NA) Re: Kixtart Getobject Active Directory Issues [Re: Robdutoit]
ShaneEP Moderator Offline
MM club member
*****

Registered: 2002-11-29
Posts: 2125
Loc: Tulsa, OK
Glad it worked out in the end. And always good when you learn in the process. Good luck on your continued KiXventures.
Top
#214260 - 2023-07-01 10:21 AM (NA) Re: Kixtart Getobject Active Directory Issues [Re: ShaneEP]
Robdutoit Offline
Hey THIS is FUN
***

Registered: 2012-03-27
Posts: 363
Loc: London, England
I do have a much better understanding of getobject, WinNT, LDAP and arrays now thanks to all that time spent on it. So it's not wasted time in that sense.
Top
Page 1 of 1 1


Moderator:  Jochen, Allen, Radimus, Glenn Barnas, ShaneEP, Ruud van Velsen, Arend_, Mart 
Hop to:
Shout Box

Who's Online
0 registered and 686 anonymous users online.
Newest Members
Timothy, Jojo67, MaikSimon, kvn317, kixtarts2025
17874 Registered Users

Generated in 0.143 seconds in which 0.105 seconds were spent on a total of 13 queries. Zlib compression enabled.

Search the board with:
superb Board Search
or try with google:
Google
Web kixtart.org