Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to enumerate all properties and methods of unknown object?

6,305 views
Skip to first unread message

Charles Kerekes

unread,
Mar 6, 2001, 11:02:36 AM3/6/01
to
Hello,

Is there a way to enumerate all properties and methods of an object in
VBScript?

For instance, I am making some LDAP calls against AD and I'm able to
enumerate all attributes of objects. Some attributes are returned as a
VarType of vbObject. So this creates an object variable in my script, but I
am unable to get information out of it. I tried retrieving information by
guessing some properties like:

MyObject.Name
MyObject.Info
MyObject.Value

None of my guesses have worked so far. I always get an error saying that the
property or method is not supported. Is there a way that I could determine
all valid properties and methods? Thanks in advance.

Charlie


Dave Anderson

unread,
Mar 6, 2001, 11:12:06 AM3/6/01
to
Try this:

Dim attr
For Each attr In MyObject
Response.Write(attr & ": " & MyObject(attr) & "<BR>" & vbCr)
Next

"Charles Kerekes" <CKereke...@bigfoot.com> wrote in message
news:u9ZIFblpAHA.1912@tkmsftngp03...

--
Dave Anderson

Unsolicited commercial email will be read at a cost of $500 per message. Use
of this email address implies consent to these terms.


Mark_Pryor

unread,
Mar 6, 2001, 12:33:50 PM3/6/01
to
Hi, see below
Charles Kerekes wrote in message ...

>Hello,
>
>Is there a way to enumerate all properties and methods of an object in
>VBScript?
>
>For instance, I am making some LDAP calls against AD and I'm able to
>enumerate all attributes of objects. Some attributes are returned as a
>VarType of vbObject. So this creates an object variable in my script, but I

If the returned object is strongly typed, VarType() will return ( 9= vbObject ).
Instead use TypeName(). You can tell if there is strong typing or not.

>am unable to get information out of it. I tried retrieving information by
>guessing some properties like:
>
> MyObject.Name
> MyObject.Info
> MyObject.Value
>
>None of my guesses have worked so far. I always get an error saying that the
>property or method is not supported. Is there a way that I could determine
>all valid properties and methods? Thanks in advance.

Use the file Tlbinf32.dll to get the properties and methods.
The following is a VBScript run from WSH. You need the ProgID
TLI.TLIApplication.

'Tsk Objects and vars
dim oSch, tsk
set oSch = WScript.CreateObject("Scheduler.SchAgent")

oSch.TargetComputer = vbNullString
call oSch.Refresh

if oSch.Count = 0 then WScript.quit
set tsk = oSch.Job(1) 'strongly typed obj= "JOB"

WScript.echo "ObjType=" & TypeName( tsk ) & " " & "Count=" & Cstr(oSch.Count)

dim oTLI
set oTLI = WScript.CreateObject("TLI.TLIApplication")
dim oMI, sOut
for each oMI in oTLI.InterfaceInfoFromObject( tsk ).Members
sOut = sOut & oMI.Name & vbCrLf '& " = " & oMI.Value
Next

WScript.echo sOut
' end code

Hope this helps,
Mark Pryor
pgp KeyID: 0x1A966EC5
KeyHash MD5: F597 D012 5CB0 9D04 3D6B 931C C69E 1290

Charles Kerekes

unread,
Mar 6, 2001, 1:35:58 PM3/6/01
to
Dave,

Thanks but no go. I get an error on the For Each line saying that the object
does not support this property or method. Oh well, the search goes on.

Charlie


"Dave Anderson" <DaveAn...@myself.com> wrote in message
news:uzyszglpAHA.956@tkmsftngp03...

Charles Kerekes

unread,
Mar 6, 2001, 2:42:44 PM3/6/01
to
Mark,

Thank you for the sample code. Unfortunately, it did not work with my
object. The object does return VarType = 9 and TypeName = Object.

> for each oMI in oTLI.InterfaceInfoFromObject( tsk ).Members

When the script gets to the For Each oMI line, it gives the following error:

"Object doesn't support this action."

Any other suggestions?

--
Charlie
-----------------------------------------------------
I use PGP encryption for security and privacy.
PGP Key ID: 0xD5AFAD01
-----------------------------------------------------

"Mark_Pryor" <erlan...@hotmail.com> wrote in message
news:#ACPUPmpAHA.1492@tkmsftngp03...

Dave Anderson

unread,
Mar 6, 2001, 3:14:18 PM3/6/01
to
Try [for..in]...

<SCRIPT LANGUAGE="JScript" RUNAT="server">
for (var x in myObject)
Response.Write(x.item() + ": " + myObject(x.item()) + "<BR>\n")
</SCRIPT>

or an Enumerator in JScript...

<SCRIPT LANGUAGE="JScript" RUNAT="server">
var e = new Enumerator(myObject)
for (; !e.atEnd(); e.moveNext())
Response.Write(e.item() + ": " + myObject(e.item()) + "<BR>\n")
</SCRIPT>


Just remember order of execution when declaring variables and functions:
<%@ Language=JScript %>
1. <SCRIPT LANGUAGE="VBScript" RUNAT="server">
2. <% Inline JScript %>
3. <SCRIPT LANGUAGE="JScript" RUNAT="server">

<%@ Language=VBScript %>
1. <SCRIPT LANGUAGE="JScript" RUNAT="server">
2. <% Inline VBScript %>
3. <SCRIPT LANGUAGE="VBScript" RUNAT="server">

"Charles Kerekes" <CKereke...@bigfoot.com> wrote in message

news:OzUoxwmpAHA.864@tkmsftngp04...

Dave Anderson

unread,
Mar 6, 2001, 3:21:20 PM3/6/01
to
Correction on the (for..in) syntax:

<SCRIPT LANGUAGE="JScript" RUNAT="server">
for (var x in myObject)

Response.Write(x + ": " + myObject[x] + "<BR>\n")
</SCRIPT>


"Dave Anderson" <DaveAn...@myself.com> wrote in message

news:O12GJonpAHA.1564@tkmsftngp04...

Tom Jones

unread,
Mar 6, 2001, 3:41:11 PM3/6/01
to
The way AD is setup is that each instance of an object has the properties
that correspond to an object definition (or a schema).

So, basically you'd want to grab the schema of the object in question and
iterate through the properties defined as either mandatory or optional for
that schema.

Here's a short VBScript sample.

Dim objADObject
Dim objSchema
Dim strPropertyName

'Replace <My Computer Name> with your computer name or another WinNT or
LDAP/ADSI qualifier.
Set objADObject = GetObject("WinNT://<My Computer Name>")
Set objSchema = GetObject(objADObject.Schema)

For Each strPropertyName In objSchema.MandatoryProperties
MsgBox strPropertyName & " = " & objADObject.Get(strPropertyName)
Next

For Each strPropertyName In objSchema.OptionalProperties
MsgBox strPropertyName & " = " & objADObject.Get(strPropertyName)
Next

Set objSchema = Nothing
Set objADObject = Nothing


Also, for a free reference, check out:

Chapter 9: Interacting with Directories via ADSI
http://www.vb2themax.com/HtmlDoc.asp?Table=Books&ID=1100

"Charles Kerekes" <CKereke...@bigfoot.com> wrote in message

news:u9ZIFblpAHA.1912@tkmsftngp03...

Charles Kerekes

unread,
Mar 6, 2001, 4:23:35 PM3/6/01
to
Tom,

Thanks for the code.

> Set objADObject = GetObject("WinNT://<My Computer Name>")

I replaced above line with:

Set objADObject =
GetObject("LDAP://cn=administrator,cn=users,dc=MyDomain,dc=pvt")

The For loop went through and started displaying the attributes and their
values, until it hit the ntSecurityDescriptor. It failed on the following
line:

> MsgBox strPropertyName & " = " & objADObject.Get(strPropertyName)

It gave the following error:

"800A01B6 - Object doesn't support this property or method"

So the question remains -- what format is ntSecurityDescriptor in and how do
I get the information out of it. I know from my other scripts that this
attribute has a VarType = 9 (Object).

Thanks again for your help. If you have other suggestions I would appreciate
them.

--
Charlie
-----------------------------------------------------
I use PGP encryption for security and privacy.
PGP Key ID: 0xD5AFAD01
-----------------------------------------------------

"Tom Jones" <ekin...@hotmail.com> wrote in message
news:#rAHB3npAHA.684@tkmsftngp03...

Charles Kerekes

unread,
Mar 6, 2001, 4:31:31 PM3/6/01
to
Thanks again, Dave. This time it tells me that the object is not a
collection. This one has me stumped!

--
Charlie
-----------------------------------------------------
I use PGP encryption for security and privacy.
PGP Key ID: 0xD5AFAD01
-----------------------------------------------------

"Dave Anderson" <DaveAn...@myself.com> wrote in message
news:OTqoFsnpAHA.2244@tkmsftngp05...

Tom Jones

unread,
Mar 6, 2001, 5:18:05 PM3/6/01
to
ntSecurityDescriptor is of type IADsSecurityDescriptor. Instead of
VarType(...) try TypeName(...) on the errant property value, which should
return "IADsSecurityDescriptor". To find out which properties/methods
IADsSecurityDescriptor supports, checkout MSDN:
http://msdn.microsoft.com/library/psdk/adsi/if_sec_9s4y.htm

"Charles Kerekes" < > wrote in message

news:eSbtbOopAHA.1752@tkmsftngp03...

Michael Harris

unread,
Mar 6, 2001, 10:43:30 PM3/6/01
to
Here'a an example that uses the WinNT provider. Once you have the ADS object the rest is the
same...

vDomainUser = InputBox("Enter domainname/username",,"domainname/username")

if Trim(vDomainUser) = "" then WScript.quit
if Instr(1,vDomainUser,"/") = 0 then WScript.quit

Set oUser = GetObject("WinNT://" & vDomainUser & ",USER")
oUser.GetInfo

on error resume next

s = s & "Class: " _
& oUser.Class & vbCrLf
s = s & "Name: " _
& oUser.Name & vbCrLf
s = s & "PasswordExpirationDate: " _
& oUser.PasswordExpirationDate & vbCrLf
s = s & "IsAccountLocked: " _
& oUser.IsAccountLocked & vbCrLf
s = s & "==========================" & vbCrLf

for i = 1 to oUser.PropertyCount
set prop = oUser.Next
val = oUser.Get(prop.name)
if typename(val) = "Byte()" then
s = s & prop.name & "=" & ByteArray(val) & vbCRLF
elseif isnull(val) then
s = s & prop.name & "=null" & vbCRLF
else
s = s & prop.name & "=" & oUser.Get(prop.name) & vbCRLF
end if
next

msgbox s

function ByteArray(bar)
dim dl,s,n
dl = ""
s = ""
for n = 1 to lenb(bar)
s = s & dl & right("0" & hex(ascb(midb(bar,n,1))),2)
dl = ","
next
ByteArray = s
end function

--
Michael Harris
Microsoft.MVP.Scripting
--
mik...@mvps.org
Please do not email questions - post them to the newsgroup instead.
--

"Charles Kerekes" <CKereke...@bigfoot.com> wrote in message

news:eSbtbOopAHA.1752@tkmsftngp03...

Charles Kerekes

unread,
Mar 7, 2001, 9:33:30 AM3/7/01
to
Michael,

Thanks for the code, but it's still not working for me. The code you gave
works great for AD object attributes. The problem is that I am able to
retrieve all attributes except the Object types. Let me also say that I'm
not only looking at user objects but any AD object type.

I am pasting my code below. It is a script that queries any AD object and
returns all attributes.

Let me exlain the problem. Firt, lets start by assuming that we execute the
script with the following command line to query the Administrator user
object in AD:

cscript AdoAttributes.vbs /s:MyServer.MyDomain.com /dn:"cn=administrator,
cn=users,dc=MyDomain,dc=com" /ao:Y /type:Y

In the Main sub I successfully bind to the user object. Then I call the
adEnumerateAttributes function and it correctly enumerates all attribute
names for this object. In my case it retrieves 34 attributes.

Now we want to read the value of each attribute. This is done by the
adGetAttributeValues function. Everything works great except the code after
the "Case vbObject" line. One of the many Object-type attributes is
nTSecurityDescriptor. If I already know the structure of this object, I can
easily read the values. In the code below I put some debugging code where I
read the Control, Group, Owner, etc. attributes of this object and it works
fine. However, I do not want to manually specify each attribute for all
object types. I want to dynamically determine these attribute names and
display their values. Are these even called attributes? Maybe I'm using the
wrong term.

So, your sample code works great against the AD object, but at the second
level (Object attribute of an AD object), it does not work. One of the
problems I see is that the Object attribute (i.e. nTSecurityDescriptor) does
not have it's own PropertyCount attribute. How else can the number and names
of Object-type properties be determined?

I hope I didn't ramble on too long. Does it make sense what I'm trying to
do?


--
Charlie
-----------------------------------------------------
I use PGP encryption for security and privacy.
PGP Key ID: 0xD5AFAD01
-----------------------------------------------------

----- AdoAttributes.vbs -----
'===========================================================================
========
' DESCRIPTION: Script queries all attributes of an AD object and displays
values.
'
' AUTHOR: Charles Kerekes, NewData Strategies
'
'===========================================================================
========


'===========================================================================
========
'= VERSION HISTORY
=
'===========================================================================
========
' Date Ini Ver Comment
'===========================================================================
========
' 03/05/2001 VSE 0.00 File created at 8:38am with Visual SlickEdit.
'---------------------------------------------------------------------------
--------
' 03/05/2001 CK 0.01 Initial version.
'---------------------------------------------------------------------------
--------
' 03/07/2001 CK 0.02 Working on the Object-type attribure.
'===========================================================================
========


Option Explicit

'===========================================================================
===
'===========================================================================
===
' CONSTANT DEFINITIONS
'---------------------------------------------------------------------------
---
' Miscellaneous
'---------------------------------------------------------------------------
---
Const Version = 0.02 ' Script or application version
Const dBUG = False ' True to turn on debuging
Const ARG_COUNT = 2 ' Minimum number of arguments expected.
'===========================================================================
===


'---------------------------------------------------------------------------
---
' File System
'---------------------------------------------------------------------------
---
Const fsoForReading = 1
'===========================================================================
===


'===========================================================================
===
'===========================================================================
===
' GLOBAL VARIABLE DECLARATIONS
'---------------------------------------------------------------------------
---
Dim args() ' holds command line arguments
Dim ExecGlb ' Allows return of value from an Execute process.
Dim fso ' object variable for instance of FileSystemObject
Dim iCount ' Generic counter integer
Dim Q ' Double quote character
Dim rc ' miscellaneous return codes
Dim sErrMsg ' Error messages for display to user
Dim sMsg ' generic message string
Dim X ' Generic counter used in FOR statements

' Active Directory Related
Dim oObject ' Object to be queried, used to bind.
Dim sAttributes() ' Contains all object attributes

' Command line parameters
Dim parmS ' Holds AD server name
Dim parmDN ' Holds DN of object to query.
Dim parmAO ' Y if we want attribute names only, N if we also want
values.
Dim parmType ' Y to show the data type of each attribute.
'===========================================================================
===


'===========================================================================
===
'===========================================================================
===
' VARIABLE ASSIGNMENTS
'===========================================================================
===
Q = Chr (34) '
Double-quote character
'---------------------------------------------------------------------------
---
Set fso = CreateObject("Scripting.FileSystemObject") ' Create
top level file system object to be used by all other file objects
'===========================================================================
===


Call Main


'===========================================================================
===
'===========================================================================
===
' MAIN()
'===========================================================================
===
Sub Main()

' Process the command line parameters or show usage syntax.
Call ProcessParms

' Bind to the AD object.
On Error Resume Next
Echo ""
Echo "Attempting to bind: " & parmDN
Echo ""
Set oObject = GetObject("LDAP://" & parmDN)
If Err.Number <> 0 Then
Echo ""
Echo "*** ERROR: Unable to bind to AD object. You may not have proper
permissions."
Echo "Error from GetOjbect: " & Err.Number & " - " & Err.Description
Echo "Aborting..."
Echo ""
WScript.Quit
End If
On Error Goto 0

' Show some values of attribute
Echo "Bound to object: " & oObject.Get("distinguishedName")
' Some optional attributes may not be set. In that case ignore and
continue.
If dBug Then
On Error Resume Next
Echo " - Description: " & oObject.Get("description")
Echo " - Managed By : " & oObject.Get("managedBy")
On Error Goto 0
Echo " - Created : " & oObject.Get("WhenCreated")
End If

' Enumerate object attributes
rc = adEnumerateAttributes(oObject)

' Read attribute values
If rc > 0 Then
rc = adGetAttributeValues(oObject)
End If

End Sub

' *** ------------------------------------------------ ***
Function CheckForBadArgs(byref args())
' Sample code from Clonepr.vbs
' Walks thru the array searching for any non-empty element. If at least one
' is found, then return non-zero. Otherwise return 0.

sErrMsg = ""

CheckForBadArgs = 0

dim i
for i = 0 to UBound(args)
if Len(args(i)) > 0 then
CheckForBadArgs = 1

' If this is first error, firt populate sErrMsg with header
If sErrMsg = "" Then
sErrMsg = vbNewLine
sErrMsg = sErrMsg & "ERROR - The following arguments are
invalid:" & vbNewLine
sErrMsg = sErrMsg &
"--------------------------------------------" & vbNewLine
End If

' Add bad argument to error message
sErrMsg = sErrMsg & " " & args(i) & vbNewLine

end if
next

' Display the error messasge
Echo sErrMsg

End Function


' *** ------------------------------------------------ ***
Function adEnumerateAttributes(adObject)
' Enumerate all attributes for the AD object. Store in sAttributes() array.

Dim PropCount
Dim ObjProp

' Retrieve information from object
adObject.GetInfo
PropCount = adObject.PropertyCount
If dBUG Then Echo "PropertyCount: " & PropCount

' Retrieve each property (attribute) into array
ReDim sAttributes(PropCount - 1)
For X = 0 To PropCount - 1
Set ObjProp = adObject.Next
sAttributes(X) = ObjProp.Name
If dBUG Then Echo "Property #" & X & ": " & sAttributes(X)
Next

' Return total property count
adEnumerateAttributes = PropCount

' Clear variables
Set ObjProp = Nothing

End Function


' *** ------------------------------------------------ ***
Function adGetAttributeValues(adObject)
' Retrieve values of attributes. Attribute names have been stored
' in the sAttributes() array by the adEnumerateAttributes procedure.

Dim CurAttr ' Object containing current attribute
Dim AttrVal ' Holds attribute value in original format
Dim AttrValStr ' String format of attribute value
Dim AttrType ' Hold value to indicate the attribute data type
Dim AttrTypeName ' Hold name of attribute type, for display.
Dim AttrArray ' Holds array-type attribute values before being
converted to string.
Dim AttrByte ' Holds byte array type attribute values.
Dim AttrDate ' Holds date and time values
Dim AttrObject ' Hold an object type value.
Dim Y
Dim ExecStr ' String to pass to Execute statement
Dim ShowType ' If /type=Y specified, show dat type.
Dim Temp
Dim HexStr ' Hold hex string value as we format it.

Echo ""
For X = 0 to UBound(sAttributes)

' Initialize variables.
AttrVal = ""

' Explicitly load current attribute into cache because some LDAP
servers
' do not return all attributes. This also allows us to use the
' adObject.Get method so we don't have to use the Execute statement.
Call adObject.GetInfoEx(Array(sAttributes(X)),0)

' Get the variable type
'** DON'T NEED TO USE EXECUTE, USE .Get METHOD INSTEAD.
'** ' We need to use the Execute statement to assemble the object
command line.
'** Execute "AttrType = VarType(adObject." & sAttributes(X) & ")"
'** Execute "AttrTypeName = TypeName(adObject." & sAttributes(X) & ")"
AttrType = VarType(adObject.Get(sAttributes(X)))
AttrTypeName = TypeName(adObject.Get(sAttributes(X)))

' Determine if we need to show the variable type based on command line
parameters.
ShowType = ""
If parmType = "Y" Then
ShowType = "[" & AttrTypeName & "]"
End If

' We process the attribute value, based on its type
Select Case AttrType

Case vbArray + vbVariant
' Array of variants.

'Echo "Case Array - " & sAttributes(X)

' Need to reset array in case it has been used by a previous
attribute.
ReDim AttrArray(0)

'ExecStr = "AttrArray = adObject." & sAttributes(X)
'Execute ExecStr
AttrArray = adObject.Get(sAttributes(X))

For Y = 0 to UBound(AttrArray)
Echo sAttributes(X) & "(" & Y & ")" & ShowType & ": " &
AttrArray(Y)
Next

Case vbArray + vbByte
' Byte array

' Need to reset array in case it has been used by a previous
attribute.
ReDim AttrArray(0)
ReDim AttrByte(0)


'ExecStr = "AttrByte = adObject." & sAttributes(X)
'Execute ExecStr
AttrByte = adObject.Get(sAttributes(X))

Temp = ""

For Y = 1 to LenB(AttrByte) Step 1

HexStr = Hex(AscB(MidB(AttrByte,Y,1)))
' Leading 0's are dropped by Hex function above. We add it
back.
' We need the padding for now because our function supports
fixed
' length SID's only.
If Len(HexStr)=1 Then HexStr="0" & HexStr
Temp = Temp & HexStr

Next

' So far we have a raw dump of the byte data in hex format. We
need to rearrange
' hex pairs for attributes we are aware of.
Select Case sAttributes(X)
Case "objectGUID"
Temp = FormatGUID(Temp)

Case "objectSid"
Temp = FormatSID(Temp)

End Select

Echo sAttributes(X) & ShowType & ": " & Temp

Case vbBoolean, vbInteger, vbLong
' Numeric values, including boolean

'Execute "AttrVal = adObject." & sAttributes(X)
AttrVal = adObject.Get(sAttributes(X))
Echo sAttributes(X) & ShowType & ": " & AttrVal

Case vbDate, vbString, vbVariant
' String and date values

'Execute "AttrVal = adObject." & sAttributes(X)
AttrVal = adObject.Get(sAttributes(X))
Echo sAttributes(X) & ShowType & ": " & AttrVal

Case vbObject
' Objects

' DEBUG BEGIN. This IF statement is here to debug only. We don't
want to limit
' this case to nTSecurityDescriptor only. We want to process any
Object-type
' attribute. I am limiting it fow now to debug since I already
know the attributes
' of the nTSecurityDescriptor object.
If sAttributes(X) = "nTSecurityDescriptor" Then

Echo "AttrObject = adObject.Get(" & sAttributes(X) & ")"
Set AttrObject = adObject.Get(sAttributes(X))

'MsgBox TypeName(AttrObject)
'rc = GetObjectMembers(AttrObject)
'Echo AttrObject.Count

' This works becaus the AD object has the PropertyCount field.
We really don't need
' this line because we already got the property count in an
earlier procedure. Test only.
Echo "oObject.PropertyCount: " & oObject.PropertyCount

' This does not work because the object returned in AttrObject
(which is an attribure of oObject)
' does not have a PropertyCount attribute.
Echo "PropertyCount: " & AttrObject.PropertyCount

'
Echo sAttributes(X) & ShowType & ": " & AttrObject.Control
Echo sAttributes(X) & ShowType & ": " & AttrObject.Group
Echo sAttributes(X) & ShowType & ": " &
AttrObject.GroupDefaulted
Echo sAttributes(X) & ShowType & ": " & AttrObject.Owner
Echo sAttributes(X) & ShowType & ": " &
AttrObject.OwnerDefaulted
Echo sAttributes(X) & ShowType & ": " & AttrObject.Revision
'Echo sAttributes(X) & ShowType & ": " &
AttrObject.DiscretionaryAcl
Echo sAttributes(X) & ShowType & ": " & AttrObject.DaclDefaulted
'Echo sAttributes(X) & ShowType & ": " & AttrObject.SystemAcl

'Set AttrObject = adObject.Get(sAttributes(X))
'Echo sAttributes(X) & ShowType & ": " & AttrObject.desc

' DEBUG END
End If

Case Else
' All other attribute types not supported.

Echo sAttributes(X) & ShowType & ": <* Data type of '" &
AttrTypeName & "' unsupported by script. *>"

End Select

Next

End Function


' *** ------------------------------------------------ ***
Sub Echo(byref message)
wscript.echo message
End Sub


' *** ------------------------------------------------ ***
Function FormatGUID(sGuid)
' Rearrange hex string into proper format for GUID

If Len(sGuid)<> 32 Then
' We were expecting 32 bytes of data. Return string inchanged.
'Echo "FormatGUID length: " & Len(sGuid) & ". Left string unchanged."
FormatGUID = sGuid
Exit Function
End If

'Rotate first 4 pairs
FormatGUID = Mid(sGuid,7,2) & Mid(sGuid,5,2) & Mid(sGuid,3,2) &
Mid(sGuid,1,2) & "-"

'Rotate next two pairs
FormatGUID = FormatGUID & Mid(sGuid,11,2) & Mid(sGuid,9,2) & "-"

'Rotate next two pairs
FormatGUID = FormatGUID & Mid(sGuid,15,2) & Mid(sGuid,13,2) & "-"

'Next two pairds do NOT rotate
FormatGUID = FormatGUID & Mid(sGuid,17,2) & Mid(sGuid,19,2) & "-"

'Rotate final 6 pairs
FormatGUID = FormatGUID & Mid(sGuid,21,2) & Mid(sGuid,23,2) &
Mid(sGuid,25,2) & Mid(sGuid,27,2) & Mid(sGuid,29,2) & Mid(sGuid,31,2)

End Function

' *** ------------------------------------------------ ***
Function FormatSID(sSid)
' Rearrange hex string into proper format for SID
'
' NOTE: There is an API function ConvertSidToStringSid to do this for us,
but
' VBScript does not support API declares so I had to write this
function.
'
' WARNING: Since we are unable to use the ConvertSidToStringSid API call,
this function
' -------- will not be able to format all SID's. Here we took the most
common format
' where the SID data is 56 bytes long and format it. All others we
return
' as raw hex data, appended with <UNFORMATTED>.

Dim Segments(5)
Dim i

If Len(sSid)<> 56 Then
' We were expecting 56 bytes of data. Append string with <UNFORMATTED>
and return.
Echo "FormatSID length: " & Len(sSid) & ". Unable to format."
FormatSID = "<UNFORMATTED> " & sSid
Exit Function
End If

If Mid(sSID,1,24) <> "010500000000000515000000" Then
' These numbers should be present in all SID's that we know how to
format. They represent "S-15"
' If not found, append string with <UNFORMATTED> and return.
Echo "*** FormatSID: First 24 characters are not
'010500000000000515000000'"
FormatSID = "<UNFORMATTED> " & sSid
Exit Function
End If

'First 24 characters are always the same, make up first two segments
Segments(0) = "S"
Segments(1) = "15"

'Rotate the first 4 pairs
Segments(2) = Mid(sSid,31,2) & Mid(sSid,29,2) & Mid(sSid,27,2) &
Mid(sSid,25,2)

'Rotate the next 4 pairs
Segments(3) = Mid(sSid,39,2) & Mid(sSid,37,2) & Mid(sSid,35,2) &
Mid(sSid,33,2)

'Rotate the next 4 pairs
Segments(4) = Mid(sSid,47,2) & Mid(sSid,45,2) & Mid(sSid,43,2) &
Mid(sSid,41,2)

'Rotate last two pairs.
Segments(5) = Mid(sSid,51,2) & Mid(sSid,49,2)

'Drop leading 0's from each segment
For i = 0 To 5
If Mid(Segments(i),1,1) = "0" Then Segments(i)= Mid(Segments(i),2)
Next

'Join segments and return to calling procedure
FormatSID = Join(Segments,"-")

End Function


' *** ------------------------------------------------ ***
Function GetArgValue(argName, args())
' Smaple code from Clonepr.vbs
' Searches for and returns the value of a command line argument of the form
' /argName:value from the supplied array. Erases the entry in the array so
' that only untouched entries remain.

dim a
dim v
dim argNameLength
dim x
dim argCount
dim fullArgName

fullArgName = "/" & argName & ":"
argCount = Ubound(args)

' Get the length of the argname we are looking for
argNameLength = Len(fullArgName)
GetArgValue = "" ' default to nothing

for x = 0 To argCount
if Len(args(x)) >= argNameLength then

a = Mid(args(x), 1, argNameLength)
if UCase(a) = UCase(fullArgName) then

' erase it so we can look for unknown args later
v = args(x)
args(x) = ""

if Len(v) > argNameLength then
GetArgValue = Mid(v, argNameLength + 1)
exit function
else
GetArgValue = ""
exit function
end if
end if
end if
next

End Function


' *** ------------------------------------------------ ***
Function GetObjectMembers(oObject)
' TEST CODE ONLY!!!
' From sample posted to newsgroup by Mark Pryor, modified to fit our needs.
' This function relies on the Tlbinf32.dll which is freely distributable.
' Copied Tlbinf32.dll to %windir%\system32 and resigtered with regsvr32.exe

Echo ""
Echo "Running GetObjectMembers procedure ..."

'Dim tliTypeLibInfo as TLI.TypeLibInfo
'Set tliTypeLibInfo = New TypLibInfo
'tliTypeLibInfo.ContainingFile = "tlbinf32.dll"

dim oTLI
set oTLI = WScript.CreateObject("TLI.TLIApplication")
dim oMI, sOut

for each oMI in oTLI.InterfaceInfoFromObject(oObject).Members
'sOut = sOut & oMI.Name & vbCrLf '& " = " & oMI.Value
Echo oMI.Name
Next
'For Each oMI in oObject
' Echo oMI & " - " & oObject(oMI.Item())
'Next

Echo sOut
Echo ""

End Function


' *** ------------------------------------------------ ***
Sub PrintUsageAndQuit

Dim f
Dim UsageText

' Build usage syntax file from script name. Assume same directory as
script.
Dim UsageName
'UsageName = fso.GetParentFolderName(WScript.ScriptFullName) & "\" &
WScript.ScriptName & " - Usage.txt"
UsageName = WScript.ScriptFullName & " - Usage.txt"

' Open the usage syntax file.
Set f = fso.OpenTextFile(UsageName, fsoForReading)

' Read entire file
UsageText = f.ReadAll
f.Close

' Replace variables in text
UsageText = Replace(UsageText,"%ScriptName%",WScript.ScriptName)
UsageText = Replace(UsageText,"%Version%",Version)

' Display text
wscript.echo UsageText

Echo "For easier reading, open the following file:"
Echo " """ & UsageName & """"

wscript.quit(0)

End Sub


' *** ------------------------------------------------ ***
Sub ProcessParms()

' If less args than minimum were passed, show usage.
If wscript.arguments.count < ARG_COUNT then
Call PrintUsageAndQuit
End If

' Copy the command-line arguments for parsing
Redim args(0)
args(0) = ""
dim i
for i = 0 to wscript.arguments.count - 1
Redim Preserve args(i)
args(i) = wscript.arguments.item(i)
next

'Read command line arguments
parmS = GetArgValue("s", args)
parmDN = GetArgValue("dn", args)
parmAO = UCase(GetArgValue("ao", args))
parmType = UCase(GetArgValue("type", args))

'Set default values
If parmType = "" Then parmType = "N"
If parmAO = "" Then parmAO = "N"


' DEBUG - Echo out parameters
If dBUG Then
Echo ""
Echo "Parameters:"
Echo "parmS: """ & parmS & """"
Echo "parmDN: """ & parmDN & """"
Echo "parmAO: """ & parmAO & """"
Echo "parmType: """ & parmType & """"
End If

' Ensure the user did not pass any unrecognized command-line arguments
If CheckForBadArgs(args) Then Call PrintUsageAndQuit

End Sub

' /// END OF SCRIPT ///


------ AdoAttributes.vbs - Usage.txt -----
The "%ScriptName%" VBScript queries all attributes of an
Active Directory object and displays its velues.
(Script version %Version%)

----------------------------------------------------------------
- USAGE SYNTAX: -
----------------------------------------------------------------
cscript %ScriptName% /s:<AD server name> /dn:<DN of object>
[/ao:y|N] [/type:y|N]


PARAMETERS:
----------------------------------------------------------------
/s - Name of AD server to query.
/dn - Distinguished name of object to query.
/ao - Show Attributes Only. Defaults to No to show attribute
name and values.
/type - Display attribute data type. Defaults to No.


EXAMPLES:
----------------------------------------------------------------
NOTE: All samples must be entered on a single line. Line breaks
below are for clarity only.
----------------------------------------------------------------

Query abject attributes, show values:
cscript %ScriptName% /s:w2klab00001.fritolay.pvt /dn:"cn=administrator,
cn=users,dc=MyDomain,dc=com"


Query abject attributes, do NOT show values:
cscript %ScriptName% /s:w2klab00001.fritolay.pvt /dn:"cn=administrator,
cn=users,dc=MyDomain,dc=com" /ao:Y

Dave Anderson

unread,
Mar 7, 2001, 8:19:36 PM3/7/01
to
"Charles Kerekes" wrote:
>
> [this error follows an attempt to enumerate propertites]

>
> "800A01B6 - Object doesn't support this property or method"

If memory serves me correctly, I saw similar results with an object that had
write-only properties (example: CDONTS.NewMail.Cc is write-only, and
therefore attempts to use it in string concatenation fail).

Michael Harris

unread,
Mar 7, 2001, 9:36:15 PM3/7/01
to
Well, you're *way* beyond me <vbg> - I've only dabbled in ADSI with the WinNT provider...

You might have better luck posting in the

microsoft.public.adsi.general
microsoft.public.active.directory.interfaces
microsoft.public.win2000.active_directory

newsgroups.

--
Michael Harris
Microsoft.MVP.Scripting
--
mik...@mvps.org
Please do not email questions - post them to the newsgroup instead.
--

"Charles Kerekes" <CKereke...@bigfoot.com> wrote in message

news:ufLY7NxpAHA.1580@tkmsftngp04...

Charles Kerekes

unread,
Mar 8, 2001, 9:03:51 AM3/8/01
to
Michael,

Thanks for trying.

--
Charlie
-----------------------------------------------------
I use PGP encryption for security and privacy.
PGP Key ID: 0xD5AFAD01
-----------------------------------------------------

"Michael Harris" <mik...@mvps.org> wrote in message
news:eGqXNi3pAHA.844@tkmsftngp05...


> Well, you're *way* beyond me <vbg> - I've only dabbled in ADSI with the
WinNT provider...

<snip>


0 new messages