#214242 - 2023-06-27 11:25 AM
Kixtart Getobject Active Directory Issues
|
Robdutoit
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
|
|
|
|
#214249 - 2023-06-28 12:53 AM
(NA) Re: Kixtart Getobject Active Directory Issues
[Re: Robdutoit]
|
Glenn Barnas
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. ; 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!
|
Top
|
|
|
|
#214250 - 2023-06-28 01:27 PM
(NA) Re: Kixtart Getobject Active Directory Issues
[Re: Glenn Barnas]
|
Robdutoit
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
; 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
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
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
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
|
|
|
|
#214253 - 2023-06-28 05:39 PM
(NA) Re: Kixtart Getobject Active Directory Issues
[Re: Glenn Barnas]
|
ShaneEP
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.
$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
|
|
|
|
Moderator: Jochen, Allen, Radimus, Glenn Barnas, ShaneEP, Ruud van Velsen, Arend_, Mart
|
0 registered
and 686 anonymous users online.
|
|
|