Platform SDK: Active Directory, ADSI, and Directory Services

Example Code for Creating a User

[C++]

The following code snippet contains a function that creates a user with only the essential properties explicitly set (cn, sAMAccountType) and returns an IDirectoryObject pointer to the new user object:

////////////////////////////////////////////////////////////////////////////////////////////////////
/*  CreateUser()   - Function for creating a basic User
    
    Parameters
 
        IDirectoryObject *pDirObject    -   Parent Directory Object for the new User
        LPWSTR pwCommonName             -   Common Name for the new User
        IDirectoryObject ** ppDirObjRet -   Pointer to the Pointer which will receive the new User
*/
HRESULT CreateUser(IDirectoryObject *pDirObject, LPWSTR pwCommonName,LPWSTR pwSamAcctName,IDirectoryObject ** ppDirObjRet)
{
    assert(pDirObject);
    if (wcslen(pwSamAcctName) >20)
    {
        MessageBox(NULL,L"SamAccountName CANNOT be bigger than 20 characters",L"Error: CreateSimpleUser()",MB_ICONSTOP);
        assert(0);
        return E_FAIL;
    }
 
    HRESULT    hr;
    ADSVALUE   sAMValue;
    ADSVALUE   classValue;
    LPDISPATCH pDisp;
    WCHAR       pwCommonNameFull[1024];
    
    ADS_ATTR_INFO  attrInfo[] = 
    {  
       { L"objectClass", ADS_ATTR_UPDATE, 
                           ADSTYPE_CASE_IGNORE_STRING, &classValue, 1 },
       {L"sAMAccountName", ADS_ATTR_UPDATE, 
                           ADSTYPE_CASE_IGNORE_STRING, &sAMValue, 1},
    };
 
    DWORD dwAttrs = sizeof(attrInfo)/sizeof(ADS_ATTR_INFO); 
    classValue.dwType = ADSTYPE_CASE_IGNORE_STRING;
    classValue.CaseIgnoreString = L"User";
 
    sAMValue.dwType=ADSTYPE_CASE_IGNORE_STRING;
    sAMValue.CaseIgnoreString = pwSamAcctName;
 
    wsprintfW(pwCommonNameFull,L"CN=%s",pwCommonName);
 
    hr = pDirObject->CreateDSObject( pwCommonNameFull,  attrInfo, 
                                dwAttrs, &pDisp );
    if (SUCCEEDED(hr))
    {
        hr = pDisp->QueryInterface(IID_IDirectoryObject,(void**) ppDirObjRet);
 
        pDisp->Release();
        pDisp = NULL;
    }
    return hr;
}
[Visual Basic]

The following code snippet creates a user with only the essential properties explicitly set (cn, sAMAccountType) and displays the properties of the new user:

Dim IADsRootDSE As IADs

sComputer = InputBox("This creates a user in a Windows 2000 domain." & vbCrLf & vbCrLf & "Specify the domain name or the name of a domain controller in the domain. (for example, MyDomain.development.microsoft.com ):")
sContainer = InputBox("Specify the name of the container where you want to create the user : (for example, CN=Users,DC=MyDomain,DC=Development,DC=microsoft,DC=com")
sUser = InputBox("Specify the name of the user to create: (for example, Bob )")

If sUser = "" Then
  MsgBox "No user name was specified. You must specify a user name."
  Exit Sub
End If

If sComputer = "" Then
  On Error GoTo 0
  MsgBox "No computer or domain was specified. Script will use the current user's domain " & WshNetwork.UserDomain & "."
  Exit Sub
Else
  sPrefix = "LDAP://" & sComputer & "/"
End If

If sContainer = "" Then
  WScript.Echo "No container was specified. Script will use the Users container in the specified domain."
  Set IADsRootDSE = GetObject(sPrefix & "rootDSE")
  If (Err.Number <> 0) Then
     BailOnFailure Err.Number, "on GetObject method"
  End If
  sDomain = IADsRootDSE.Get("defaultNamingContext")
  If (Err.Number <> 0) Then
     BailOnFailure Err.Number, "on Get method"
  End If
  sContainerDN = "cn=Users," + sDomain
Else
  sContainerDN = sContainer
End If

'''''''''''''''''''''''''''''''''''''''
'Bind to the container
'''''''''''''''''''''''''''''''''''''''
Set cont = GetObject(sPrefix & sContainerDN)
If (Err.Number <> 0) Then
  BailOnFailure Err.Number, "on GetObject method"
End If
'''''''''''''''''''''''''''''''''''''''
'Add the user
'''''''''''''''''''''''''''''''''''''''
Set user = cont.Create("user", "cn=" & sUser)
If (Err.Number <> 0) Then
  BailOnFailure Err.Number, "on Create method"
End If
user.put "samAccountName", sUser
If (Err.Number <> 0) Then
  BailOnFailure Err.Number, "on Put samAccountName method"
End If
user.SetInfo
If (Err.Number <> 0) Then
  BailOnFailure Err.Number, "on SetInfo method"
End If
strText = "The user " & sUser & " was successfully added."
strText = strText & vbCrLf & "The user has the following properties:"
'Refresh the property cache
user.GetInfo
'zz Count = user.PropertyCount
If (Err.Number <> 0) Then
  BailOnFailure Err.Number, "on PropertyCount method"
End If
strText = strText & "Number of properties: " & Count

For cprop = 1 To Count
  Set v = user.Next()
  If IsNull(v) Then
    Exit For
  End If
  strText = strText & vbCrLf & cprop & ") " & v.Name & " (" & v.ADsType & ") "
Next
show_items strText, sComputer
strText = "User operational attributes"
user.GetInfoEx Array("canonicalName", "allowedAttributes", "allowedAttributesEffective"), 0
  strText = strText & vbCrLf & "Canonical Name:" & user.Get("canonicalName")
If (Err.Number <> 0) Then
  BailOnFailure Err.Number, "on Get method"
End If
show_items strText, sComputer

cattr = 0
strText = "Attributes Allowed"
attr = user.GetEx("allowedAttributes")
For Each attrval In attr
  cattr = cattr + 1
Next
strText = strText & vbCrLf & cattr
show_items strText, sComputer

cattr = 0
strText = "Attributes Effective"
attr = user.GetEx("allowedAttributesEffective")
For Each attrval In attr
  cattr = cattr + 1
Next
strText = strText & vbCrLf & cattr
show_items strText, sComputer
'''''''''''''''''''''''''''''''''''''''
'Display subroutines
'''''''''''''''''''''''''''''''''''''''
Sub show_items(strText, strName)
    MsgBox strText, vbInformation, "Create User on " & strName
End Sub
 
Sub BailOnFailure(ErrNum, ErrText)    strText = "Error 0x" & Hex(ErrNum) & " " & ErrText
    MsgBox strText, vbInformation, "ADSI Error"
    WScript.Quit
End Sub