The ADSI WinNT provider allows you to
communicate to a Windows NT® 4.0 directory. Since Windows 2000 maintains backward compatibility, you
can also communicate with Windows® 2000 machines using WinNT. However, we recommend
that you use the LDAP provider to communicate with Windows 2000 domain controllers. For the Windows 2000
standalone server and Professional Edition, you must use the WinNT provider to access the
directory.
WinNT supports local and remote
accounts, services, computers, security management and other functionalities. With ADSI extensions,
you'll be able to extend the functionality. For more information on ADSI extensions, click
here.
Requirements
- Install ADSI. To download the runtime, visit
http://www.microsoft.com/adsi on
Windows NT 4.0 or Windows 95. Note: If you have Windows 2000 machine,
you don't need to install ADSI. ADSI is a built-in component for Windows 2000.
- You must have a Windows NT 4.0 or Windows 2000 or higher to connect
to. The client and server may be on the same machine.
How do I...
Bind
Manage
Users
You can the source code for these tasks in the
\\samples\WinNT\User directory.
Manage
a Group
You can the source code for these tasks in the
\\samples\WinNT\Group directory.
Manage
a Computer
You can the source code for these tasks in the
\\samples\WinNT\Computer directory.
Manage
Printers
You can the source code for these tasks in the
\\samples\WinNT\PrintQueue
directory.
Manage
Files
Binding
to a Windows NT 4.0 Domain Directory
You must supply the Windows NT 4.0 domain name.
ADSI will transparently connect to one of the domain controllers.
'--- Binding to a domain
domainName = "INDEPENDENCE"
userName = "Administrator"
password = "password"
'--- Binding to a domain as a currently logged on user
Set dom = GetObject("WinNT://" & domainName)
'--- Enumerating an object in a domain
For Each obj In dom
Debug.Print obj.Name & " (" & obj.Class & ")"
Next
'--- Binding to a domain with alternate credentials
Set dso = GetObject("WinNT:")
Set dom = dso.OpenDSObject("WinNT://" & domainName, userName, password,
ADS_SECURE_AUTHENTICATION)
'--- Enumerating the object in a domain
For Each obj In dom
Debug.Print obj.Name & " (" & obj.Class & ")"
Next
Back to top.
Binding to
a Windows NT 4.0 Local Directory on a Machine
'--- Binding to a computer
computerName = "ADSI"
userName = "Administrator"
password = "password"
'--- Binding to a computer as a currently logged on user
Set com = GetObject("WinNT://" & computerName & ",computer")
'- Enumerate object in a computer
For Each obj In com
Debug.Print obj.Name & " (" & obj.Class & ")"
Next
'--- Binding to a computer with alternate credentials
Set dso = GetObject("WinNT:")
Set com = dso.OpenDSObject("WinNT://" & computerName &
",computer", userName, password, ADS_SECURE_AUTHENTICATION)
'--- Enumerating an object in a computer
For Each obj In com
Debug.Print obj.Name
Next
Back to top.
Creating
a User
domainName = "INDEPENDENCE"
'--- Binding to a domain as currently logged on user
Set dom = GetObject("WinNT://" & domainName)
'--- Creating a user
Set usr = dom.Create("user", "JSmith")
usr.SetInfo
Back to top.
Changing
the User's Full Name and Description
Set usr =
GetObject("WinNT://INDEPENDENCE/jsmith,user")
usr.FullName = "John Smith"
usr.Description = "DSys WOSD Program Manager"
usr.SetInfo
Back to top.
Changing
the User's Password
A user may change his/her own password, but not others.
Administrators have privileges to change any user's password. ChangePassword
requires an old password and the user must already exist in the directory, while SetPassword
does not. Both functions do not require SetInfo to commit the changes.
'--- Changing the password
Set usr = GetObject("WinNT://INDEPENDENCE/jsmith,user")
usr.ChangePassword "secret", "password"
Back to top.
Setting
the User's Password
Administrators may reset the user password.
'--- Setting the password
Set usr = GetObject("WinNT://INDEPENDENCE/jsmith,user")
usr.SetPassword "secret"
Back to top.
Setting
the User's Password Expiration Date
The password expiration date is a
calculated field. The value is computed as follows:
- If the user's "Password Never
Expires" (UF_DONT_EXPIRE_PASSWD) f lag is set, then there's no need to
compute an expiration date. The user password is valid.
- If the user's flag is not set, then it
computes the difference between when the password was last set and current time.
- If the difference is greater or equal to
the MaxPasswordAge found in the domain object, then the user's password is expired.
- If the difference is less than
MaxPasswordAge, then the user's password expiration date = user's password last set +
MaxPasswordAge.
To get the user's password expiration date:
To set user's password expiration date,
you set MaxPasswordAge in the domain object. Note that this will affect all users since
the password expiration date is a calculated field from the domain object.
expInDay = 60&
expInSec = expInDay * (3600& * 24&)
Set dom = GetObject("WinNT://INDEPENDENCE")
dom.Put "MaxPasswordAge", CLng(expInSec)
dom.SetInfo
Back to top.
Making
a User Change the Password at Next Logon
Set usr = GetObject("WinNT://INDEPENDENCE/jsmith,user")
usr.Put "PasswordExpired", CLng(1)
usr.SetInfo
'--- Clear this flag so that the user does not have to change the
password at next logon.
usr.Put "PasswordExpired", CLng(0)
usr.SetInfo
Back to top.
Preventing
the User from Changing the Password
Set usr = GetObject("WinNT://INDEPENDENCE/jsmith,user")
usr.Put "userFlags", usr.Get("UserFlags") Or ADS_UF_PASSWD_CANT_CHANGE
usr.SetInfo
'--- To clear this flag, use Xor and allow the user to change his/her password.
usr.Put "userFlags", usr.Get("UserFlags") Xor ADS_UF_PASSWD_CANT_CHANGE
usr.SetInfo
Back to top.
Preventing
the User's Password from Expiring
Set usr = GetObject("WinNT://INDEPENDENCE/jsmith,user")
usr.Put "userFlags", usr.Get("UserFlags") Or UF_DONT_EXPIRE_PASSWD
usr.SetInfo
'--- To clear this flag, use XOr.
usr.Put "userFlags", usr.Get("UserFlags") Xor UF_DONT_EXPIRE_PASSWD
usr.SetInfo
Back to top.
Disabling
the User's Account
Set usr = GetObject("WinNT://INDEPENDENCE/jsmith,user")
usr.AccountDisabled = True
'Disabled the account
usr.SetInfo
usr.AccountDisabled = False
'Enabled the account
usr.SetInfo
Back to top.
Setting
the User's Account Expiration Date
Set usr = GetObject("WinNT://INDEPENDENCE/jsmith,user")
'--Set a user account expiration 90 days from now.
usr.AccountExpirationDate = Now() + 90
usr.SetInfo
'--- To set the account expiration to NEVER (default).
usr.AccountExpirationDate = "01/01/1970"
usr.SetInfo
Back to top.
Unlocking
the User's Account
You can read the value of account lockout,
and you can set the lockout to FALSE (not locked), but you can't
lock the user's account. Only the system
can set the account lockout to TRUE.
'--- Unlocking the user's account
Set usr = GetObject("WinNT://INDEPENDENCE/jsmith,user)
usr.IsAccountLocked = False
usr.SetInfo
Back to top.
Setting
the User's Home Directory and Home Drive Directory
Set usr = GetObject("WinNT://INDEPENDENCE/jsmith,user")
usr.HomeDirectory = "UserHomeDirHere"
usr.HomeDirDrive = "HomeDirDriveHere"
usr.SetInfo
Back to top.
Setting
the User's Login Script
Set usr = GetObject("WinNT://INDEPENDENCE/jsmith,user")
usr.LoginScript = "LoginScriptHere"
usr.SetInfo
Back to top.
Getting
the User's Primary Group
Set usr = GetObject("WinNT://INDEPENDENCE/jsmith,user")
grpPrimaryID = usr.Get("PrimaryGroupID")
Back to top.
Getting the
User's SID (Security ID)
Set usr = GetObject("WinNT://INDEPENDENCE/jsmith,user")
sid = usr.Get("objectSID")
For Each element In sid
Debug.Print Hex(element)
Next
Back to top.
Getting
groups a user belongs to
Set usr = GetObject("WinNT://INDEPENDENCE/jsmith,user")
For each grp in usr.Groups
Debug.Print grp.Name
Next
Back to top.
Renaming
a User
Renaming a user is similar to renaming an object.
Set dom = GetObject("WinNT://INDEPENDENCE")
Set usr = dom.MoveHere("WinNT://INDEPENDENCE/jsmith,user", "jjohnson")
usr.FullName = "Jane Johnson"
usr.SetInfo
Back to top.
Deleting a
User
Deleting a user is similar to deleting an object.
Set dom = GetObject("WinNT://INDEPENDENCE")
dom.Delete "user", "jjohnson"
Back to top.
Creating
a Group
This code snippet shows how to create a local group in a domain.
Set dom = GetObject("WinNT://INDEPENDENCE")
Set grp = dom.Create("group", "DSys")
grp.Put "groupType", ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP
grp.Description = "Distributed System Group"
grp.SetInfo
This shows how to create a global group in a domain.
Set dom = GetObject("WinNT://INDEPENDENCE")
Set grp = dom.Create("group", "PM")
grp.Put "groupType", ADS_GROUP_TYPE_GLOBAL_GROUP
grp.Description = "Program Managers"
grp.SetInfo
And finally, this snippet shows how to create a local group in a computer.
Set comp = GetObject("WinNT://SEATTLE,computer")
Set grp = comp.Create("group", "TheSmiths")
grp.Put "groupType", ADS_GROUP_TYPE_LOCAL_GROUP
grp.Description = "The Smiths Family Member"
grp.SetInfo
Back to top.
Adding
a User to a Group
'--- Adding a user in a
local domain or global group.
Set grp = GetObject("WinNT://INDEPENDENCE/DSys,group")
grp.Add ("WinNT://INDEPENDENCE/JSmith")
'--- Adding a user in a
local group in a computer.
Set comp = GetObject("WinNT://SEATTLE,computer")
Set grp = comp.GetObject("group", "TheSmiths")
grp.Add ("WinNT://INDEPENDENCE/JSmith")
Back to top.
Adding a
Group to a Group
A global group can be added to a local group in a
Windows NT 4.0 domain. Note that in the Windows 2000 domain environment, you can nest a
group.
Set grp = GetObject("WinNT://INDEPENDENCE/DSys,group")
grp.Add ("WinNT://INDEPENDENCE/PM,group")
Back to top.
Enumerating
Group in a Domain or Computer
'--- Enumerating groups in a domain.
Set dom = GetObject("WinNT://INDEPENDENCE")
dom.Filter = Array("Group")
'--- Enumerating a local group.
Debug.Print "Local Groups---"
For Each grp In dom
If (grp.GroupType = ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP) Then
Debug.Print grp.Name
End If
Next
'--- Enumerating a global group.
Debug.Print "Global Groups---"
For Each grp In dom
If (grp.GroupType = ADS_GROUP_TYPE_GLOBAL_GROUP) Then
Debug.Print grp.Name
End If
Next
'--- Enumerating groups in a computer.
Set comp = GetObject("WinNT://SEATTLE,computer")
comp.Filter = Array("Group")
'A local group consists of all groups in a computer
Debug.Print "Groups:"
For Each grp In comp
Debug.Print grp.Name
Next
Back to top.
Enumerating
Group Membership
Local groups may contain global groups.
Set grp = GetObject("WinNT://INDEPENDENCE/DSys,group")
For Each member In grp.Members
Debug.Print member.Name & " (" & member.Class
& ")"
'Global group memberships may also be enumerated.
If (member.Class = "Group") Then
For Each obj In
member.Members
Debug.Print " " & obj.Name & " (" & obj.Class &
")"
Next
End If
Next
Back to top.
Removing
a Member from Group
Set grp = GetObject("WinNT://INDEPENDENCE/PM,group")
grp.Remove ("WinNT://INDEPENDENCE/ChristyH")
Back to top.
Finding
Out if a User or Group is a Member of a Group
Set grp = GetObject("WinNT://INDEPENDENCE/DSys,group")
If (grp.IsMember("WinNT://INDEPENDENCE/JSmith")) Then
Debug.Print "Yes"
Else
Debug.Print "No"
End If
Back to top.
Connecting
to a Computer
Set comp = GetObject("WinNT://INDEPENDENCE/SEATTLE,computer")
Debug.Print comp.Division
Debug.Print comp.OperatingSystem
Debug.Print comp.OperatingSystemVersion
Debug.Print comp.Owner
Debug.Print comp.Processor
Debug.Print comp.ProcessorCount
Back to top.
Enumerating
Services in a Computer
Set comp = GetObject("WinNT://INDEPENDENCE/SEATTLE,computer")
comp.Filter = Array("Service")
For Each svc In comp
Debug.Print svc.Name & " " & svc.DisplayName
Next
Back to top.
Displaying
the Service's Properties
This code snippet shows how to display a service's properties,
as defined in winnt.h.
Const SERVICE_BOOT_START = &H0
Const SERVICE_SYSTEM_START = &H1
Const SERVICE_AUTO_START = &H2
Const SERVICE_DEMAND_START = &H3
Const SERVICE_DISABLED = &H4
'--- Error control type
Const SERVICE_ERROR_IGNORE = &H0
Const SERVICE_ERROR_NORMAL = &H1
Const SERVICE_ERROR_SEVERE = &H2
Const SERVICE_ERROR_CRITICAL = &H3
Const SERVICE_KERNEL_DRIVER = &H1
Const SERVICE_FILE_SYSTEM_DRIVER = &H2
Const SERVICE_ADAPTER = &H4
Const SERVICE_RECOGNIZER_DRIVER = &H8
Const SERVICE_DRIVER = &HB
Const SERVICE_WIN32_OWN_PROCESS = &H10
Const SERVICE_WIN32_SHARE_PROCESS = &H20
Const SERVICE_WIN32 = &H30
Const SERVICE_INTERACTIVE_PROCESS = &H100
Set comp = GetObject("WinNT://SEATTLE,computer")
Set svc = comp.GetObject("Service", "Browser")
Debug.Print "Display Name: " & svc.DisplayName
Debug.Print "Order Group: " & svc.LoadOrderGroup
Debug.Print "Host Name: " & svc.HostComputer
s = "Startup: "
Select Case svc.StartType
Case SERVICE_BOOT_START
s = s + "Boot Start"
Case SERVICE_SYSTEM_START
s = s + "System Start"
Case SERVICE_AUTO_START
s = s + "Automatic"
Case SERVICE_DEMAND_START
s = s + "Manual"
Case SERVICE_DISABLED
s = s + "Disabled"
Case Else
s = s + "Unknown"
End Select
Debug.Print s
'Dependencies
Debug.Print "Dependencies: "
For Each dpc In svc.Dependencies
Debug.Print " " & dpc
Next
'Service Type
s = "Service Type: "
Select Case svc.ServiceType
Case SERVICE_KERNEL_DRIVER
s = s + "Kernel Driver"
Case SERVICE_FILE_SYSTEM_DRIVER
s = s + "File System Driver"
Case SERVICE_ADAPTER
s = s + "Adapter"
Case SERVICE_RECOGNIZER_DRIVER
s = s + "Recognizer Driver"
Case SERVICE_WIN32_OWN_PROCESS
s = s + "Win32 Process"
Case SERVICE_WIN32_SHARE_PROCESS
s = s + "Win32 Share Process"
Case SERVICE_WIN32
s = s + "Win32"
Case SERVICE_INTERACTIVE_PROCESS
s = s + "Interactive Process"
End Select
Debug.Print s
'Error Control
s = "Error Control: "
Select Case svc.ErrorControl
Case SERVICE_ERROR_IGNORE
s = s + "Service ignores error"
Case SERVICE_ERROR_NORMAL
s = s + "No Error"
Case SERVICE_ERROR_SEVERE
s = s + "Severe error"
Case SERVICE_ERROR_CRITICAL
s = s + "Critical error"
Case Else
s = s + "Unknown"
End Select
Debug.Print s
Back to top.
Stopping,
Starting, and Pausing a Service
Set comp = GetObject("WinNT://SEATTLE,computer")
Set svcOp = comp.GetObject("Service", "Browser")
'Stopping a service.
svcOp.Stop
'Starting a service.
svcOp.Start
'Pausing a service.
svcOp.Pause
Back to top.
Enumerating
File Shares in a Computer
Set comp = GetObject("WinNT://SEATTLE,computer")
Set svc = GetObject(comp.ADsPath & "/" & "LanmanServer")
For Each fileShare In svc
Debug.Print fileShare.Name & " " & " " &
fileShare.CurrentUserCount & " " & fileShare.Path
Next
Back to top.
Creating
a File Share in a Computer
Set comp = GetObject("WinNT://SEATTLE,computer")
Set svc = GetObject(comp.ADsPath & "/" & "LanmanServer")
Set fileShare = svc.Create("FileShare", "public")
fileShare.Path = "c:\public"
fileShare.SetInfo
Back to top.
Deleting
a File Share
Set comp = GetObject("WinNT://SEATTLE,computer")
Set svc = GetObject(comp.ADsPath & "/" & "LanmanServer")
svc.Delete "FileShare", "public"
Back to top.
Enumerating
Sessions in a Computer
Dim fileSvc As IADsFileService
Dim session As IADsSession
Set comp = GetObject("WinNT://SEATTLE,computer")
Set fileSvc = GetObject(comp.ADsPath & "/" & "LanmanServer")
For Each session In fileSvc.Sessions
Debug.Print session.Name & " " &
session.ConnectTime
Next
Back to top.
Enumerating
Resources in a Computer
Set comp = GetObject("WinNT://SEATTLE,computer")
Set fileSvc = GetObject(comp.ADsPath & "/" & "LanmanServer")
For Each resource In fileSvc.Resources
Debug.Print resource.Name & " - " & resource.User
Next
Back to top.
Creating
a Machine Account
machinename = "mymachine"
Set oProv = GetObject("WinNT:")
Set oTarg = oProv.OpenDSObject("WinNT://myDomain", "domain\user","password",ADS_SECURE_AUTHENTICATION)
Set oComp = oTarg.Create("computer", machinename)
oComp.SetInfo
'--- Rebind as a user and set the
initial password.
Set oCompUser = GetObject("WinNT://domain/" & machinename
"$,user")
sPwd = machinename
sPwd = StrConv(sPwd, vbLowerCase)
oCompUser.SetPassword sPwd
oCompUser.SetInfo
Back to top.
Setting
File Share Security
Setting file share security is supported
in the ADSI Resource Tool Kit.
Back to top.
Setting File
security
Setting file security is supported in the
ADSI Resource Tool Kit.
Back to top.
Enumerating
Print Queues in a Computer
computerName = "MSPRINT44"
printQueueName = "CORPF"
Set comp = GetObject("WinNT://" & computerName & ",computer")
comp.Filter = Array("PrintQueue")
'--- Enumerating a Printer in a computer.
For Each printQueue In comp
s = printQueue.Name & " " & printQueue.Description & " ("
& printQueue.PrinterPath & ")"
'Debug.Print printQueue.status
'--- QI the PrintQueueOperations (this is optional step in VB/VBScript).
Set printQOps = printQueue
s = s & "Status: " & GetPrintStatus(printQueue.status)
Debug.Print s ' Report the printQueue and Printer status
Next
You can find the source code for this example
at \\samples\WinNT\PrintQueue.
Back to top.
Listing Print
Jobs in a Queue
Dim printQueue As IADsPrintQueue
Dim printQOps As IADsPrintQueueOperations
Dim printJob As IADsPrintJob
Dim printJobOps As IADsPrintJobOperations
'--- Bind to a printer queue.
Set comp = GetObject("WinNT://" & computerName & ",computer")
Set printQueue = comp.GetObject("PrintQueue", printQueueName)
'--- Get print queue characteristics.
Debug.Print printQueue.Name & " " & printQueue.Description & "
(" & printQueue.PrinterPath & ")"
Debug.Print s
'--- Switch to print queue operation.
Set printQOps = printQueue
Debug.Print "Status: " & GetPrintStatus(printQueue.status)
'--- Get print jobs for this specific queue.
Debug.Print "--- Jobs in the queue ----- "
For Each printJob In printQOps.PrintJobs
Debug.Print printJob.Description & " " & printJob.User & "
" & printJob.Priority
Set printJobOps = printJob
Debug.Print "Page printed: " & printJobOps.PagesPrinted & "Page(s)
" & GetJobStatus(printJobOps.status)
Debug.Print "-----"
Next
You can find the source code for this example
at \\samples\WinNT\PrintQueue.
Back to top.
|