This utility will allow you to look up user ID info on an NT domain.

To use it, first select your PDC(PrimaryDomainController) or BDC(BackupDomainController)
then type in the userid to pullup, or do a search by name.

If you find it useful, let me know.

{UPDATE on April 10, 2003 to work with new Win32API.inc}


Code:
#COMPILE EXE
#DIM ALL
#INCLUDE "win32api.inc"
#INCLUDE "LMACCESS.inc"

%FILE                                   = 500
%CHGPDC                                 = 510
%SEPARATOR_515                          = 515
%BUTCLOSE                               = 520
%BUTFNAME                               = 525
%HELP                                   = 600
%ABOUT                                  = 605
%FRAME1                                 = 100
%LABEL1                                 = 105
%TEXT1                                  = 110
%LISTBOX1                               = 125

DECLARE CALLBACK FUNCTION DLGPROC

GLOBAL hDlg    AS LONG    ' Dialog handle
GLOBAL hMenu0&
GLOBAL hMenu1&
GLOBAL hMenu2&

'=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
FUNCTION uniPtrToAnsi(BYVAL uniPtr AS LONG) AS STRING
  DIM i      AS LONG
  DIM sText  AS STRING
  i = lstrlenW(BYVAL uniPtr)     'get wide text length
  sText = PEEK$(uniPtr, i * 2)   'get wide text from memory
  FUNCTION = ACODE$(sText)       'return ascii text
END FUNCTION
'=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
FUNCTION Is_UserId_Found(BYVAL sUser AS STRING, BYVAL sDomainServer AS STRING) AS LONG
   LOCAL lRet           AS LONG
   LOCAL unizServerName AS STRING * 200
   LOCAL unizUserName   AS STRING * 100
   LOCAL UI             AS USER_INFO_3 PTR
   unizServerName = UCODE$(sDomainServer) + CHR$(0) + CHR$(0)
   unizUserName   = UCODE$(sUser) + CHR$(0) + CHR$(0)
   lRet = NetUserGetInfo(VARPTR(unizServerName),VARPTR(unizUserName),BYVAL 3, BYVAL VARPTR(UI))
   LISTBOX RESET hDlg, %LISTBOX1
   FUNCTION = (lRet = %NERR_SUCCESS)
   SELECT CASE lRet
      CASE 0   'worked...  found user in domain
         IF uniPtrToAnsi(@UI.usri3_full_name) <> "" THEN LISTBOX ADD hDlg, %LISTBOX1, "Name:" + $TAB + uniPtrToAnsi(@UI.usri3_full_name)
         IF uniPtrToAnsi(@UI.usri3_usr_comment) <> "" THEN LISTBOX ADD hDlg, %LISTBOX1, uniPtrToAnsi(@UI.usri3_usr_comment)
         IF uniPtrToAnsi(@UI.usri3_home_dir) <> "" THEN LISTBOX ADD hDlg, %LISTBOX1, "Home dir:" + $TAB + uniPtrToAnsi(@UI.usri3_home_dir)
         IF uniPtrToAnsi(@UI.usri3_profile) <> "" THEN LISTBOX ADD hDlg, %LISTBOX1, "Profile:" + $TAB + uniPtrToAnsi(@UI.usri3_profile)
         IF @UI.usri3_password_age > 86400 THEN
            LISTBOX ADD hDlg, %LISTBOX1, "Password is " + STR$(INT(@UI.usri3_password_age/86400)) + " day(s) old."
         ELSEIF @UI.usri3_password_age > 0 THEN
            LISTBOX ADD hDlg, %LISTBOX1, "Password is " + STR$(@UI.usri3_password_age) + " second(s) old."
         END IF
         IF (@UI.usri3_flags AND %UF_LOCKOUT) = %UF_LOCKOUT THEN LISTBOX ADD hDlg, %LISTBOX1, "*** Account is Locked Out!"
         IF (@UI.usri3_flags AND %UF_ACCOUNTDISABLE) = %UF_ACCOUNTDISABLE THEN LISTBOX ADD hDlg, %LISTBOX1, "*** Account is disabled!"
         IF (@UI.usri3_priv AND %USER_PRIV_ADMIN) = %USER_PRIV_ADMIN THEN LISTBOX ADD hDlg, %LISTBOX1, "User is a domain Administrator"
         IF (@UI.usri3_auth_flags AND %AF_OP_SERVER) = %AF_OP_SERVER THEN LISTBOX ADD hDlg, %LISTBOX1, "User is a server operator"
         IF (@UI.usri3_auth_flags AND %AF_OP_ACCOUNTS) = %AF_OP_ACCOUNTS THEN LISTBOX ADD hDlg, %LISTBOX1, "User is a accounts operator"
         IF (@UI.usri3_bad_pw_count > 0) AND @UI.usri3_bad_pw_count <> %MAXDWORD THEN LISTBOX ADD hDlg, %LISTBOX1, STR$(@UI.usri3_bad_pw_count) & " bad login attempts."
         IF (@UI.usri3_num_logons <> -1) THEN LISTBOX ADD hDlg, %LISTBOX1, "Logged in a total of " + STR$(@UI.usri3_num_logons) & " times on this PDC/BDC: " + sDomainServer
         IF (@UI.usri3_password_expired <> 0) THEN LISTBOX ADD hDlg, %LISTBOX1, "*** Password has expired!"
         IF uniPtrToAnsi(@UI.usri3_script_path) <> "" THEN LISTBOX ADD hDlg, %LISTBOX1, "Login Script:" + $TAB + uniPtrToAnsi(@UI.usri3_script_path)

      CASE 53, 2351   'domain server not found
         LISTBOX ADD hDlg, %LISTBOX1, "Error Invalid path to Domain server, should be entered like: \\S-STL-PDC1"
      CASE 2221 'user not in domain
         LISTBOX ADD hDlg, %LISTBOX1, "Warning: User " & sUser & " was not found on " & sDomainServer
      CASE 1909 'access deinied because your account is locked out/invalid
         LISTBOX ADD hDlg, %LISTBOX1, "Search denied!  Your account is locked/invalid on " & sDomainServer
      CASE ELSE
         LISTBOX ADD hDlg, %LISTBOX1, "Error while looking up user. ret=" & STR$(lRet)
   END SELECT
   CALL NetApiBufferFree(BYVAL VARPTR(UI))
END FUNCTION
'=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
FUNCTION Get_Groups(BYVAL sUser AS STRING, BYVAL sDomainServer AS STRING) AS LONG
   LOCAL lRet           AS LONG
   LOCAL unizServerName AS STRING * 200
   LOCAL unizUserName   AS STRING * 100
   LOCAL GI             AS DWORD  ' holds pointer to system buffer
   LOCAL GItmp          AS GROUP_INFO_0 PTR
   LOCAL dNumRead       AS DWORD
   LOCAL dMaxLen        AS DWORD
   LOCAL dTotalEntries  AS DWORD
   LOCAL iCounter       AS DWORD
   unizServerName = UCODE$(sDomainServer) + CHR$(0) + CHR$(0)
   unizUserName   = UCODE$(sUser) + CHR$(0) + CHR$(0)
   dMaxLen = %MAXDWORD
   lRet = NetUserGetGroups(VARPTR(unizServerName),VARPTR(unizUserName),BYVAL 0, BYVAL VARPTR(GI), dMaxLen, dNumRead, dTotalEntries)
   FUNCTION = lRet
   SELECT CASE lRet
      CASE 0   'worked...  found user in domain
         'msgbox "Total groups = " + str$(dNumRead),,"test"
         FOR iCounter = 0 TO dNumRead -1
            GItmp = GI + (iCounter * 4)  'move pointer to next array (4 bytes in a dword)
            IF @GItmp.grpi0_name <> 0 THEN IF uniPtrToAnsi (@GItmp.grpi0_name) <> "" THEN LISTBOX ADD hDlg, %LISTBOX1, "In Group:  " + uniPtrToAnsi (@GItmp.grpi0_name)
         NEXT iCounter
   END SELECT
   CALL NetApiBufferFree(BYVAL VARPTR(GI))
END FUNCTION
'=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
FUNCTION Find_Name(BYVAL sName AS STRING, BYVAL sDomainServer AS STRING) AS LONG
   LOCAL lRet           AS LONG
   LOCAL unizServerName AS STRING * 200
   LOCAL NDU            AS DWORD
   LOCAL NDUtmp         AS NET_DISPLAY_USER PTR
   LOCAL dNumRead       AS DWORD
   LOCAL dMaxLen        AS DWORD
   LOCAL iCounter       AS DWORD
   LOCAL iIndex         AS DWORD
   LOCAL iOldIndex      AS DWORD
   CONTROL DISABLE  hDlg, %IDOK
   CONTROL DISABLE  hDlg, %BUTCLOSE
   CONTROL DISABLE  hDlg, %BUTFNAME
   MENU SET STATE hMenu0&, 1, %MF_DISABLED
   unizServerName = UCODE$(sDomainServer) + CHR$(0) + CHR$(0)
   dMaxLen = %MAXDWORD - 1
   sName = UCASE$(sName)
   iIndex = 0
   iOldIndex = 1
   DO
      lRet = NetQueryDisplayInformation(VARPTR(unizServerName),BYVAL 1, iIndex, 1000, dMaxLen, dNumRead, NDU)
      SELECT CASE lRet
         CASE 5
            LISTBOX ADD hDlg, %LISTBOX1, "Search denied!  Your account is locked/invalid on " & sDomainServer
            EXIT LOOP
         CASE 0, 234   'worked...  found user in domain
            IF dNumRead > 0 THEN
               NDUtmp = NDU
               FOR iCounter = 0 TO dNumRead -1
                  NDUtmp = NDU + (iCounter * 24)  'move pointer to next array (4 bytes in a dword)
                  IF @NDUtmp.usri1_full_name <> 0 THEN 'valid pointer
                     IF INSTR(UCASE$(uniPtrToAnsi(@NDUtmp.usri1_full_name)),sName) THEN LISTBOX ADD hDlg, %LISTBOX1, "Found:  " + uniPtrToAnsi(@NDUtmp.usri1_full_name) + $TAB + "UserId =" + $TAB + uniPtrToAnsi(@NDUtmp.usri1_name)
                     iIndex = @NDUtmp.usri1_next_index
                  END IF
               NEXT iCounter
            END IF
         CASE %ERROR_MORE_DATA
         CASE ELSE
            LISTBOX ADD hDlg, %LISTBOX1, "Warning!  Error during lookup. Ret=" & STR$(lRet)
      END SELECT
      DIALOG DOEVENTS
      CALL NetApiBufferFree(BYVAL NDU)
      IF iOldIndex = iIndex THEN EXIT LOOP
      iOldIndex = iIndex
   LOOP WHILE (lRet = %ERROR_MORE_DATA) AND (dNumRead > 0)
   CONTROL ENABLE  hDlg, %IDOK
   CONTROL ENABLE  hDlg, %BUTCLOSE
   CONTROL ENABLE  hDlg, %BUTFNAME
   MENU SET STATE hMenu0&, 1, %MF_ENABLED
   LISTBOX ADD hDlg, %LISTBOX1, "Done.   Double-click each item for more info."
   CONTROL SEND hDlg, %LISTBOX1, %LB_GETCOUNT,0,0 TO lRet
   CONTROL SEND hDlg, %LISTBOX1, %LB_SETCURSEL, lRet -1, 0
END FUNCTION
'=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
CALLBACK FUNCTION DLGPROC
   LOCAL iRet           AS LONG
   LOCAL sUser          AS STRING
   LOCAL sName          AS STRING
   LOCAL sText          AS STRING
   STATIC sDomainServer AS STRING
   LOCAL zBuffer        AS ASCIIZ * %MAX_PATH
   SELECT CASE CBMSG
      CASE %WM_INITDIALOG
         iRet = GetProfileString("MANer" & CHR$(0), "DomainSrv" & CHR$(0), "\\S-STL-PDC1" & CHR$(0), zBuffer, BYVAL %MAX_PATH) ' Get default settings from Win.ini..
         sDomainServer = TRIM$(zBuffer,CHR$(0,23))
      CASE %WM_CLOSE
         CALL WriteProfileString("MANer", "DomainSrv", sDomainServer & CHR$(0))       'store in win.ini
      CASE %WM_COMMAND
         SELECT CASE CBCTL
            CASE  %IDOK
               IF CBCTLMSG=%BN_CLICKED THEN
                  CONTROL GET TEXT hDlg, %TEXT1 TO sUser
                  IF LEN(sUser) > 1 THEN
                     IF Is_UserId_Found(sUser, sDomainServer) THEN
                        CALL Get_Groups(sUser, sDomainServer)
                     END IF
                  END IF
               END IF
            CASE  %CHGPDC
               IF CBCTLMSG=%BN_CLICKED THEN
                  DO
                     sText = INPUTBOX$("Enter a new PDC or BDC." + $CRLF + $CRLF + "Example:   \\s-stl-pdc1","Enter Domain Controller",sDomainServer)
                  LOOP UNTIL LEFT$(sText,2) = "\\" OR sText = ""
                  IF LEFT$(sText,2) = "\\" THEN sDomainServer = sText
               END IF
            CASE  %LISTBOX1
               IF CBCTLMSG=%LBN_SELCHANGE THEN
                  LISTBOX GET TEXT hDlg, %LISTBOX1 TO sText                   'get listbox text
                  IF PARSE$(sText,$TAB,2) = "UserId =" THEN
                     sUser = PARSE$(sText,$TAB,3)
                     CONTROL SET TEXT hDlg, %TEXT1, sUser
                  END IF
               END IF
               IF CBCTLMSG=%LBN_DBLCLK THEN
                  LISTBOX GET TEXT hDlg, %LISTBOX1 TO sText                   'get listbox text
                  IF PARSE$(sText,$TAB,2) = "UserId =" THEN
                     sUser = PARSE$(sText,$TAB,3)
                     CONTROL SET TEXT hDlg, %TEXT1, sUser
                     IF Is_UserId_Found(sUser, sDomainServer) THEN
                        CALL Get_Groups(sUser, sDomainServer)
                     END IF
                  END IF
               END IF
            CASE  %BUTFNAME
               IF CBCTLMSG=%BN_CLICKED THEN
                  CONTROL GET TEXT hDlg, %TEXT1 TO sUser
                  sName = INPUTBOX$("Name to search for?" + $CRLF + $CRLF + "Note: You can search on any part of the name or use partial names like:" + $CRLF _
                                    + " " + $DQ + "smi" + $DQ + " would find Smith, Smiley, GoldSmith, etc.","Name to find?",sUser)
                  LISTBOX RESET hDlg, %LISTBOX1
                  IF sName <> "" THEN
                     LISTBOX ADD hDlg, %LISTBOX1, "Searching for " & sName
                     CALL Find_Name(sName, sDomainServer)
                  END IF
               END IF
            CASE  %ABOUT
               MSGBOX "This utility will query the PDC/BDC for user information. " + $CRLF + $CRLF _
                     + "TO USE:" + $CRLF + $CRLF _
                     + "1.) Type in the user id." + $CRLF + $CRLF _
                     + "2.) Click on the LookUp button.  " + $CRLF _
                     + "     or Click on the Find by Name button.  " + $CRLF + $CRLF  + $CRLF _
                     + "Note: Some of the information is stored on each PDC/BDC and may not reflect" + $CRLF _
                     + "       the largest total. (days_old,total_logins)  These items will indicate" + $CRLF _
                     + "       they are totals on that PDC/BDC" _
                     ,%MB_ICONINFORMATION,"IDLOOKUP    Ver 2.3    By William Burns"
            CASE  %BUTCLOSE
                  DIALOG END hDlg
            CASE ELSE
         END SELECT
      CASE ELSE
   END SELECT
END FUNCTION
'=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
FUNCTION PBMAIN
   DIALOG NEW 0, "Find User ID info      - by William Burns", 0, 0,  240,  177, _
      %WS_POPUP OR %DS_MODALFRAME OR %WS_CAPTION OR %WS_MINIMIZEBOX OR %WS_SYSMENU OR %DS_CENTER, 0 TO hDlg
   MENU NEW BAR TO hMenu0&
   MENU NEW POPUP TO hMenu1&
   MENU ADD POPUP, hMenu0& ,"&File", hMenu1&, %MF_ENABLED
   MENU ADD STRING, hMenu1&, "&LookUp userid info",  %IDOK, %MF_ENABLED
   MENU ADD STRING, hMenu1&, "&Find userid by name", %BUTFNAME, %MF_ENABLED
   MENU ADD STRING, hMenu1&, "&Change PDC/BDC",  %CHGPDC, %MF_ENABLED
   MENU ADD STRING, hMenu1&, "-",  %SEPARATOR_515, %MF_ENABLED
   MENU ADD STRING, hMenu1&, "E&xit",  %BUTCLOSE, %MF_ENABLED
   MENU NEW POPUP TO hMenu2&
   MENU ADD POPUP, hMenu0& ,"&Help", hMenu2&, %MF_ENABLED
   MENU ADD STRING, hMenu2&, "&About",  %ABOUT, %MF_ENABLED
   MENU ATTACH hMenu0&, hDlg
   CONTROL ADD FRAME, hDlg,  %FRAME1,  "User Information", 3, 42, 235, 121, %WS_CHILD OR %WS_VISIBLE OR %BS_GROUPBOX, %WS_EX_TRANSPARENT
   CONTROL ADD LABEL, hDlg,  %LABEL1,  "Enter the UserID to find:", 3, 7, 83, 12, %WS_CHILD OR %WS_VISIBLE OR %SS_CENTER
   CONTROL ADD TEXTBOX, hDlg,  %TEXT1,  "", 85, 5, 83, 12, %WS_CHILD OR %WS_VISIBLE OR %ES_AUTOHSCROLL OR %WS_TABSTOP, %WS_EX_CLIENTEDGE
   CONTROL ADD "Button", hDlg,  %IDOK,  "&LookUp", 179, 5, 53, 15, %WS_CHILD OR %WS_VISIBLE OR %BS_PUSHBUTTON OR %WS_TABSTOP
   CONTROL ADD "Button", hDlg,  %BUTCLOSE,  "&Close", 179, 25, 53, 15, %WS_CHILD OR %WS_VISIBLE OR %BS_PUSHBUTTON OR %WS_TABSTOP
   CONTROL ADD "Button", hDlg,  %BUTFNAME,  "Find by Name", 8, 25, 53, 15, %WS_CHILD OR %WS_VISIBLE OR %BS_PUSHBUTTON OR %WS_TABSTOP
   CONTROL ADD LISTBOX, hDlg,  %LISTBOX1, , 8, 52, 224, 106, %WS_CHILD OR %WS_VISIBLE OR %LBS_NOTIFY OR %LBS_NOINTEGRALHEIGHT OR %WS_VSCROLL OR %WS_TABSTOP OR %LBS_USETABSTOPS, %WS_EX_CLIENTEDGE
   DIALOG SHOW MODAL hDlg , CALL DLGPROC
END FUNCTION
'=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
------------------
"I haven't lost my mind... its backed up on tape... I think??"



[This message has been edited by William Burns (edited April 10, 2003).]