| Platform SDK: Active Directory, ADSI, and Directory Services |
The following script enumerates all users on a member server or Windows 2000 Professional:
Dim cont As IADsContainer
'Example: Enumerating all local users on member server or workstation
'''''''''''''''''''''''''''''''''''''''
'Parse the arguments
'''''''''''''''''''''''''''''''''''''''
sComputer = InputBox("This script lists the users on a member server or workstation." & vbCrLf & vbCrLf & "Specify the computer name:")
If sComputer = "" Then
Exit Sub
End If
'''''''''''''''''''''''''''''''''''''''
'Bind to the computer
'''''''''''''''''''''''''''''''''''''''
'Note that this sample uses the logged-on user's context
'To specify a user account other than the user account under
'which your application is running, use IADsOpenDSObject.
Set cont = GetObject("WinNT://" & sComputer & ",computer")
If (Err.Number <> 0) Then
BailOnFailure Err.Number, "on GetObject method"
End If
'''''''''''''''''''''''''''''''''''''''
'Filter to view only user objects
'''''''''''''''''''''''''''''''''''''''
cont.Filter = Array("User")
If (Err.Number <> 0) Then
BailOnFailure Err.Number, "on IADsContainer::Filter method"
End If
strText = ""
intIndex = 0
intNumDisplay = 0
cmember = 0
'Maximum number of users to list on a msgbox.
MAX_DISPLAY = 20
'''''''''''''''''''''''''''''''''''''''
'Get each user
'''''''''''''''''''''''''''''''''''''''
For Each user In cont
intIndex = intIndex + 1
'Get the name
strText = strText & vbCrLf & Right(" " & intIndex, 4) & " " & user.Name
intNumDisplay = intNumDisplay + 1
'Display in msgbox if there are MAX_DISPLAY users to display
If intNumDisplay >= MAX_DISPLAY Then
Call show_users(strText, sComputer)
strText = ""
intNumDisplay = 0
End If
'Reset the count of members within the current group
cmember = 0
Next
Call show_users(strText, sComputer)
'''''''''''''''''''''''''''''''''''''''
'Display subroutines
'''''''''''''''''''''''''''''''''''''''
Sub show_users(strText, strName)
MsgBox strText, vbInformation, "Users on " & strName
End Sub
Sub BailOnFailure(ErrNum, ErrText) strText = "Error 0x" & Hex(ErrNum) & " " & ErrText
MsgBox strText, vbInformation, "ADSI Error"
WScript.Quit
End Sub
The following code fragment contains a function that enumerates all objects of a specified class (such as user) and displays the members contained in each object on a member server or Windows 2000 Professional:
////////////////////////////////////////////////////////////////////////////////////////////////////
/* ListObjectsWithWinNtProvider() - Uses the WinNT provider to list children based on a filter
Returns S_OK on success
Parameters
LPWSTR pwszComputer - Computer to list
LPWSTR pwszClass - Filter for listing
LPWSTR pwszUSER = NULL - User Name for ADsOpenObject() binding- If NOT passed - Bind Though ADsGetObject()
LPWSTR pwszPASS = NULL - Password for ADsOpenObject() binding- If NOT passed - Bind Though ADsGetObject()
*/
HRESULT ListObjectsWithWinNtProvider(LPWSTR pwszComputer,LPWSTR pwszClass, LPWSTR pwszUSER = NULL, LPWSTR pwszPASS = NULL)
{
HRESULT hr;
LPWSTR pwszBindingString = NULL;
IADsContainer * pIADsCont = NULL;
// Allocate a String for Binding.. This should definitely be big enough..
pwszBindingString = new WCHAR[(wcslen(gbsComputer) *2) + 20];
swprintf(pwszBindingString,L"WinNT://%s,computer",pwszComputer);
// Make sure either NO user is passed - or BOTH user and password are passed
assert(!pwszUSER || (pwszUSER && pwszPASS));
// Bind to the container passed
// If USER and PASS passed in, use ADsOpenObject()
if (pwszUSER)
hr = ADsOpenObject( pwszBindingString,
pwszUSER,
pwszPASS,
ADS_SECURE_AUTHENTICATION,
IID_IADsContainer,
(void**) &pIADsCont);
else
hr = ADsGetObject( pwszBindingString, IID_IADsContainer,(void **)&pIADsCont);
if (SUCCEEDED(hr))
{
VARIANT vFilter;
VariantInit(&vFilter);
LPWSTR pwszFilter = pwszClass;
// Build a Variant of array type, using the filter passed
hr = ADsBuildVarArrayStr(&pwszFilter, 1, &vFilter);
if (SUCCEEDED(hr))
{
// Set the filter for the results of the Enum
hr = pIADsCont->put_Filter(vFilter);
if (SUCCEEDED(hr))
{
IEnumVARIANT * pEnumVariant = NULL; // Ptr to the IEnumVariant Interface
VARIANT Variant; // Variant for retrieving data
ULONG ulElementsFetched; // Number of elements fetched
// Builds an enumerator interface- this will be used
// to enumerate the objects contained in the IADsContainer
hr = ADsBuildEnumerator(pIADsCont,&pEnumVariant);
// While no errors- Loop through and print the data
while (SUCCEEDED(hr) && hr != S_FALSE)
{
// Object comes back as a VARIANT holding an IDispatch *
hr = ADsEnumerateNext(pEnumVariant,1,&Variant,&ulElementsFetched);
if (hr != S_FALSE)
{
assert(HAS_BIT_STYLE(Variant.vt,VT_DISPATCH));
IDispatch *pDispatch = NULL;
IADs *pIADs= NULL;
pDispatch = Variant.pdispVal;
// QI the Variant's IDispatch * for the IADs interface
hr = pDispatch->QueryInterface(IID_IADs,(VOID **) &pIADs) ;
if (SUCCEEDED(hr))
{
// Print some information about the object
BSTR bsResult;
pIADs->get_Name(&bsResult);
wprintf(L" NAME: %s\n",(LPOLESTR) bsResult);
SysFreeString(bsResult);
pIADs->get_ADsPath(&bsResult);
wprintf(L" ADSPATH: %s\n",(LPOLESTR) bsResult);
SysFreeString(bsResult);
puts("------------------------------------------------------");
pIADs->Release();
pIADs = NULL;
}
}
}
// Since the hr from iteration was lost, free
// the interface if the ptr is != NULL
if (pEnumVariant)
{
pEnumVariant->Release();
pEnumVariant = NULL;
}
VariantClear(&Variant);
}
}
VariantClear(&vFilter);
}
delete [] pwszBindingString;
pwszBindingString = NULL;
return hr;
}