Learning ADSI - Part 2: Editing Users and Administering Groups

Introduction

When I started ASP, I tried reading a couple of phone directory-sized $50 books. Each of them was filled with samples that didn't make sense to me. I then found a Web site with simple ASP code samples, which I used to create some ASP pages. Today, when I look back at those pages, I'm truly embarrassed. When I revist those books, everything finally makes sense. But with ADSI, making sense simply means learning the syntax. How do you know the right syntax? Read this article, which covers how to edit an existing user and administer groups.

Caveat

Caveat

Please keep in mind that you are going to modify the basics of the Windows NT security model. You should be very alert when dealing with ADSI. Keep in mind that a simple mistype could mean reformatting and reinstalling your system. Don't do it on a operational machine! Please know that I have tried to make the following code as accurate as possible. Yet I can't guarantee their outcome. So please don't just copy and paste. I know it is very attractive, but it could cause you to spend the next couple of hours looking at a very appealing Windows installation screen.

EXTRA NOTE:
For those who read my first article, please heed the following. In that article I forgot one of the most important aspects of programming. The codes I provided could cause a memory leak since I forgot to cleanup the objects I used. So please add this to the codes in order to prevent this (The first article has been updated with this change).


Set Computer = nothing
Set User = nothing
Set Flags = nothing


Set Computer = nothing
Set User = nothing
Set Flags = nothing


Set Computer = nothing
Set User = nothing
Set Flags = nothing

Please keep in mind that you are going to modify the basics of the Windows NT security model. You should be very alert when dealing with ADSI. Keep in mind that a simple mistype could mean reformatting and reinstalling your system. Don't do it on a operational machine! Please know that I have tried to make the following code as accurate as possible. Yet I can't guarantee their outcome. So please don't just copy and paste. I know it is very attractive, but it could cause you to spend the next couple of hours looking at a very appealing Windows installation screen.

EXTRA NOTE:
For those who read my first article, please heed the following. In that article I forgot one of the most important aspects of programming. The codes I provided could cause a memory leak since I forgot to cleanup the objects I used. So please add this to the codes in order to prevent this (The first article has been updated with this change).


Set Computer = nothing
Set User = nothing
Set Flags = nothing


Set Computer = nothing
Set User = nothing
Set Flags = nothing


Set Computer = nothing
Set User = nothing
Set Flags = nothing

Please keep in mind that you are going to modify the basics of the Windows NT security model. You should be very alert when dealing with ADSI. Keep in mind that a simple mistype could mean reformatting and reinstalling your system. Don't do it on a operational machine! Please know that I have tried to make the following code as accurate as possible. Yet I can't guarantee their outcome. So please don't just copy and paste. I know it is very attractive, but it could cause you to spend the next couple of hours looking at a very appealing Windows installation screen.

EXTRA NOTE:
For those who read my first article, please heed the following. In that article I forgot one of the most important aspects of programming. The codes I provided could cause a memory leak since I forgot to cleanup the objects I used. So please add this to the codes in order to prevent this (The first article has been updated with this change).


Set Computer = nothing
Set User = nothing
Set Flags = nothing


Set Computer = nothing
Set User = nothing
Set Flags = nothing


Set Computer = nothing
Set User = nothing
Set Flags = nothing

Editing an Existing User

As I explained in my first article, every action performed here goes directly through the Windows SAM. In response to my first article, there were some questions on how to change the logon hours or the terminal server home path. Sorry, but I have to disappoint you . This , as well as some other vital functions, can't be changed by ADSI. Then again, ADSI does do a lot. In the upcoming articles we are going to dive into the IIS metabase. But before we do that, let's start with editing a user.

Renaming Users


<%
1.  RenameUser("MyDomain","MyUsername","MyNewUsername")
2.
3.   Sub RenameUser(strDomain,strOldUsername,strNewUsername)
4.     Dim Computer
5.     Dim User
6.     Dim MoveUser
7.    
8.     Set Computer = GetObject("WinNT://" & strDomain)
9.     Set User = GetObject("WinNT://" & strDomain & "/" & strOldUsername & ",user")
10.   Set MoveUser = Computer.MoveHere(User.ADsPath, strNewUsername)
11.
12.   Set Computer = nothing
13.   Set User = nothing
14.   Set MoveUser = nothing
15. End Sub
%>


<%
1.  RenameUser("MyDomain","MyUsername","MyNewUsername")
2.
3.   Sub RenameUser(strDomain,strOldUsername,strNewUsername)
4.     Dim Computer
5.     Dim User
6.     Dim MoveUser
7.    
8.     Set Computer = GetObject("WinNT://" & strDomain)
9.     Set User = GetObject("WinNT://" & strDomain & "/" & strOldUsername & ",user")
10.   Set MoveUser = Computer.MoveHere(User.ADsPath, strNewUsername)
11.
12.   Set Computer = nothing
13.   Set User = nothing
14.   Set MoveUser = nothing
15. End Sub
%>


<%
1.  RenameUser("MyDomain","MyUsername","MyNewUsername")
2.
3.   Sub RenameUser(strDomain,strOldUsername,strNewUsername)
4.     Dim Computer
5.     Dim User
6.     Dim MoveUser
7.    
8.     Set Computer = GetObject("WinNT://" & strDomain)
9.     Set User = GetObject("WinNT://" & strDomain & "/" & strOldUsername & ",user")
10.   Set MoveUser = Computer.MoveHere(User.ADsPath, strNewUsername)
11.
12.   Set Computer = nothing
13.   Set User = nothing
14.   Set MoveUser = nothing
15. End Sub
%>

There isn't much to explain. The computer just grabs all the information about a user (the user.ADsPath) and projects that to the new user, deleting the old.

Changing User-Properties


<%
1.   ChangeUser("MyUser","MyDomain","MyFullname","MyDescription","MyOldPass"
      ," MyNewPass"
2.
3.   Sub ChangeUser(strUser,strDomain,strFullname,strDesc,strOldPassword, 
4.                              strNewPassword)
5.     Dim User
6.     Set User = GetObject("WinNT://" & strDomain & "/" & strUser & ",user")
7.     User.Fullname = strDesc
8.     User.Description = strDesc
9.     User.ChangePassword(strOldPassword,strNewPassword)
10.   User.Setinfo
11.   Set User = nothing
12. End Sub
%>


<%
1.   ChangeUser("MyUser","MyDomain","MyFullname","MyDescription","MyOldPass"
      ," MyNewPass"
2.
3.   Sub ChangeUser(strUser,strDomain,strFullname,strDesc,strOldPassword, 
4.                              strNewPassword)
5.     Dim User
6.     Set User = GetObject("WinNT://" & strDomain & "/" & strUser & ",user")
7.     User.Fullname = strDesc
8.     User.Description = strDesc
9.     User.ChangePassword(strOldPassword,strNewPassword)
10.   User.Setinfo
11.   Set User = nothing
12. End Sub
%>


<%
1.   ChangeUser("MyUser","MyDomain","MyFullname","MyDescription","MyOldPass"
      ," MyNewPass"
2.
3.   Sub ChangeUser(strUser,strDomain,strFullname,strDesc,strOldPassword, 
4.                              strNewPassword)
5.     Dim User
6.     Set User = GetObject("WinNT://" & strDomain & "/" & strUser & ",user")
7.     User.Fullname = strDesc
8.     User.Description = strDesc
9.     User.ChangePassword(strOldPassword,strNewPassword)
10.   User.Setinfo
11.   Set User = nothing
12. End Sub
%>

In the above code we changed some basic elements of a user account. It isn't that different from adding a user. The only thing difference is the way a password is changed. Because of security reasons you can only change a password by providing the old password. The outcome of this subroutine is very simple. The user "MyUser" now has "MyFullname","MyDescription", and "MyNewpass" as a fullname, description and password. The next part is a bit harder since we are going into Hex/Decimal codes with the User-Flags. Again the code looks a lot like the code I used in my first article, but with one difference. Because we are now changing the user settings we use XOR instead of OR when dealing with userflags.

Changing Specific User Boundaries


<%

1.  UserFlags "newuser","mydomain",0,False,True,True,True
2. 
3.    Sub UserFlags(strUser,strDomain,strPassexpires,strNochange,strNoexpire, & _        
                               strDisable,strLocked)
4.      Dim User
5.      Dim Flags
6.
7.      Set User = Getobject("WinNT://" & strDomain & "/" & strUser & ",user")
8.      Flags = User.Get("UserFlags")
9.
10.    User.put "PasswordExpired",strPassexpires
11.    User.Accountdisabled = strDisable
12.    if strNochange = "true" then 
13.      User.put "UserFlags", Flags OR &H00040
14.    End if
15.    If strNoexpire = "true" then
16.      User.put "Userflags", flags OR &H10000
17.    end if
18.    User.IsAccountLocked = strLocked
19.
20.    Set User = nothing
21. End sub

%>


<%

1.  UserFlags "newuser","mydomain",0,False,True,True,True
2. 
3.    Sub UserFlags(strUser,strDomain,strPassexpires,strNochange,strNoexpire, & _        
                               strDisable,strLocked)
4.      Dim User
5.      Dim Flags
6.
7.      Set User = Getobject("WinNT://" & strDomain & "/" & strUser & ",user")
8.      Flags = User.Get("UserFlags")
9.
10.    User.put "PasswordExpired",strPassexpires
11.    User.Accountdisabled = strDisable
12.    if strNochange = "true" then 
13.      User.put "UserFlags", Flags OR &H00040
14.    End if
15.    If strNoexpire = "true" then
16.      User.put "Userflags", flags OR &H10000
17.    end if
18.    User.IsAccountLocked = strLocked
19.
20.    Set User = nothing
21. End sub

%>


<%

1.  UserFlags "newuser","mydomain",0,False,True,True,True
2. 
3.    Sub UserFlags(strUser,strDomain,strPassexpires,strNochange,strNoexpire, & _        
                               strDisable,strLocked)
4.      Dim User
5.      Dim Flags
6.
7.      Set User = Getobject("WinNT://" & strDomain & "/" & strUser & ",user")
8.      Flags = User.Get("UserFlags")
9.
10.    User.put "PasswordExpired",strPassexpires
11.    User.Accountdisabled = strDisable
12.    if strNochange = "true" then 
13.      User.put "UserFlags", Flags OR &H00040
14.    End if
15.    If strNoexpire = "true" then
16.      User.put "Userflags", flags OR &H10000
17.    end if
18.    User.IsAccountLocked = strLocked
19.
20.    Set User = nothing
21. End sub

%>

I'm not going to explain this code since it is an almost exact copy of the coding in the first article. Please make sure that you use XOR to change a userflag and OR to initially set it. The following part is a direct copy since nothing has changed. In order to change the logon script, profile path, etc., we use the same code as we used to initially set it.

<%

1.    userconfig "newuser","mydomain","c:/myprofiles/","myscript.cmd","c:/","z:/", & _
                         #mm/dd/yyyy#,"true"
2.
3.    sub userconfig(strUser,strDomain,strProfile,strScript,strHomedir, & _
                               strHomedirdrive,strAccountexpire,strPassrequired)
4.      Dim User
5.      Dim Flags
6.
7.      Set User = Getobject("WinNT://" & strDomain & "/" & strUser & ",user")
8.      
9.      User.Profile = strProfile
10.    User.LoginScript = strScript
11.    User.Homedirectory = strHomedir
12.    User.Put("HomeDirDrive"),strHomedirdrive
13.    User.AccountExpirationDate = strAccountexpire
14.    User.Passwordrequired = strPassrequired
15.
16.  end sub

%>

Now we edited the same information that we applied to the computer in the previous article. After doing this we might as well remove the user we created, leaving us with nothing.

Removing Users


<%
1.  DelUser("MyDomain","MyUsername",)
2.
3.   Sub DelUser(strDomain,strUsername)
4.     Dim Computer
5.    
6.     Set Computer = GetObject("WinNT://" & strDomain)
7.     Computer.Delete("User", strUsername)
8.     Set Computer = nothing
9.   End Sub
%>


<%
1.  DelUser("MyDomain","MyUsername",)
2.
3.   Sub DelUser(strDomain,strUsername)
4.     Dim Computer
5.    
6.     Set Computer = GetObject("WinNT://" & strDomain)
7.     Computer.Delete("User", strUsername)
8.     Set Computer = nothing
9.   End Sub
%>


<%
1.  DelUser("MyDomain","MyUsername",)
2.
3.   Sub DelUser(strDomain,strUsername)
4.     Dim Computer
5.    
6.     Set Computer = GetObject("WinNT://" & strDomain)
7.     Computer.Delete("User", strUsername)
8.     Set Computer = nothing
9.   End Sub
%>

In the next article I will provide codes on how to query specific user information. For now we are going to order our thousands of users by making groups.

As I explained in my first article, every action performed here goes directly through the Windows SAM. In response to my first article, there were some questions on how to change the logon hours or the terminal server home path. Sorry, but I have to disappoint you . This , as well as some other vital functions, can't be changed by ADSI. Then again, ADSI does do a lot. In the upcoming articles we are going to dive into the IIS metabase. But before we do that, let's start with editing a user.

Renaming Users


<%
1.  RenameUser("MyDomain","MyUsername","MyNewUsername")
2.
3.   Sub RenameUser(strDomain,strOldUsername,strNewUsername)
4.     Dim Computer
5.     Dim User
6.     Dim MoveUser
7.    
8.     Set Computer = GetObject("WinNT://" & strDomain)
9.     Set User = GetObject("WinNT://" & strDomain & "/" & strOldUsername & ",user")
10.   Set MoveUser = Computer.MoveHere(User.ADsPath, strNewUsername)
11.
12.   Set Computer = nothing
13.   Set User = nothing
14.   Set MoveUser = nothing
15. End Sub
%>


<%
1.  RenameUser("MyDomain","MyUsername","MyNewUsername")
2.
3.   Sub RenameUser(strDomain,strOldUsername,strNewUsername)
4.     Dim Computer
5.     Dim User
6.     Dim MoveUser
7.    
8.     Set Computer = GetObject("WinNT://" & strDomain)
9.     Set User = GetObject("WinNT://" & strDomain & "/" & strOldUsername & ",user")
10.   Set MoveUser = Computer.MoveHere(User.ADsPath, strNewUsername)
11.
12.   Set Computer = nothing
13.   Set User = nothing
14.   Set MoveUser = nothing
15. End Sub
%>


<%
1.  RenameUser("MyDomain","MyUsername","MyNewUsername")
2.
3.   Sub RenameUser(strDomain,strOldUsername,strNewUsername)
4.     Dim Computer
5.     Dim User
6.     Dim MoveUser
7.    
8.     Set Computer = GetObject("WinNT://" & strDomain)
9.     Set User = GetObject("WinNT://" & strDomain & "/" & strOldUsername & ",user")
10.   Set MoveUser = Computer.MoveHere(User.ADsPath, strNewUsername)
11.
12.   Set Computer = nothing
13.   Set User = nothing
14.   Set MoveUser = nothing
15. End Sub
%>

There isn't much to explain. The computer just grabs all the information about a user (the user.ADsPath) and projects that to the new user, deleting the old.

Changing User-Properties


<%
1.   ChangeUser("MyUser","MyDomain","MyFullname","MyDescription","MyOldPass"
      ," MyNewPass"
2.
3.   Sub ChangeUser(strUser,strDomain,strFullname,strDesc,strOldPassword, 
4.                              strNewPassword)
5.     Dim User
6.     Set User = GetObject("WinNT://" & strDomain & "/" & strUser & ",user")
7.     User.Fullname = strDesc
8.     User.Description = strDesc
9.     User.ChangePassword(strOldPassword,strNewPassword)
10.   User.Setinfo
11.   Set User = nothing
12. End Sub
%>


<%
1.   ChangeUser("MyUser","MyDomain","MyFullname","MyDescription","MyOldPass"
      ," MyNewPass"
2.
3.   Sub ChangeUser(strUser,strDomain,strFullname,strDesc,strOldPassword, 
4.                              strNewPassword)
5.     Dim User
6.     Set User = GetObject("WinNT://" & strDomain & "/" & strUser & ",user")
7.     User.Fullname = strDesc
8.     User.Description = strDesc
9.     User.ChangePassword(strOldPassword,strNewPassword)
10.   User.Setinfo
11.   Set User = nothing
12. End Sub
%>


<%
1.   ChangeUser("MyUser","MyDomain","MyFullname","MyDescription","MyOldPass"
      ," MyNewPass"
2.
3.   Sub ChangeUser(strUser,strDomain,strFullname,strDesc,strOldPassword, 
4.                              strNewPassword)
5.     Dim User
6.     Set User = GetObject("WinNT://" & strDomain & "/" & strUser & ",user")
7.     User.Fullname = strDesc
8.     User.Description = strDesc
9.     User.ChangePassword(strOldPassword,strNewPassword)
10.   User.Setinfo
11.   Set User = nothing
12. End Sub
%>

In the above code we changed some basic elements of a user account. It isn't that different from adding a user. The only thing difference is the way a password is changed. Because of security reasons you can only change a password by providing the old password. The outcome of this subroutine is very simple. The user "MyUser" now has "MyFullname","MyDescription", and "MyNewpass" as a fullname, description and password. The next part is a bit harder since we are going into Hex/Decimal codes with the User-Flags. Again the code looks a lot like the code I used in my first article, but with one difference. Because we are now changing the user settings we use XOR instead of OR when dealing with userflags.

Changing Specific User Boundaries


<%

1.  UserFlags "newuser","mydomain",0,False,True,True,True
2. 
3.    Sub UserFlags(strUser,strDomain,strPassexpires,strNochange,strNoexpire, & _        
                               strDisable,strLocked)
4.      Dim User
5.      Dim Flags
6.
7.      Set User = Getobject("WinNT://" & strDomain & "/" & strUser & ",user")
8.      Flags = User.Get("UserFlags")
9.
10.    User.put "PasswordExpired",strPassexpires
11.    User.Accountdisabled = strDisable
12.    if strNochange = "true" then 
13.      User.put "UserFlags", Flags OR &H00040
14.    End if
15.    If strNoexpire = "true" then
16.      User.put "Userflags", flags OR &H10000
17.    end if
18.    User.IsAccountLocked = strLocked
19.
20.    Set User = nothing
21. End sub

%>


<%

1.  UserFlags "newuser","mydomain",0,False,True,True,True
2. 
3.    Sub UserFlags(strUser,strDomain,strPassexpires,strNochange,strNoexpire, & _        
                               strDisable,strLocked)
4.      Dim User
5.      Dim Flags
6.
7.      Set User = Getobject("WinNT://" & strDomain & "/" & strUser & ",user")
8.      Flags = User.Get("UserFlags")
9.
10.    User.put "PasswordExpired",strPassexpires
11.    User.Accountdisabled = strDisable
12.    if strNochange = "true" then 
13.      User.put "UserFlags", Flags OR &H00040
14.    End if
15.    If strNoexpire = "true" then
16.      User.put "Userflags", flags OR &H10000
17.    end if
18.    User.IsAccountLocked = strLocked
19.
20.    Set User = nothing
21. End sub

%>


<%

1.  UserFlags "newuser","mydomain",0,False,True,True,True
2. 
3.    Sub UserFlags(strUser,strDomain,strPassexpires,strNochange,strNoexpire, & _        
                               strDisable,strLocked)
4.      Dim User
5.      Dim Flags
6.
7.      Set User = Getobject("WinNT://" & strDomain & "/" & strUser & ",user")
8.      Flags = User.Get("UserFlags")
9.
10.    User.put "PasswordExpired",strPassexpires
11.    User.Accountdisabled = strDisable
12.    if strNochange = "true" then 
13.      User.put "UserFlags", Flags OR &H00040
14.    End if
15.    If strNoexpire = "true" then
16.      User.put "Userflags", flags OR &H10000
17.    end if
18.    User.IsAccountLocked = strLocked
19.
20.    Set User = nothing
21. End sub

%>

I'm not going to explain this code since it is an almost exact copy of the coding in the first article. Please make sure that you use XOR to change a userflag and OR to initially set it. The following part is a direct copy since nothing has changed. In order to change the logon script, profile path, etc., we use the same code as we used to initially set it.

<%

1.    userconfig "newuser","mydomain","c:/myprofiles/","myscript.cmd","c:/","z:/", & _
                         #mm/dd/yyyy#,"true"
2.
3.    sub userconfig(strUser,strDomain,strProfile,strScript,strHomedir, & _
                               strHomedirdrive,strAccountexpire,strPassrequired)
4.      Dim User
5.      Dim Flags
6.
7.      Set User = Getobject("WinNT://" & strDomain & "/" & strUser & ",user")
8.      
9.      User.Profile = strProfile
10.    User.LoginScript = strScript
11.    User.Homedirectory = strHomedir
12.    User.Put("HomeDirDrive"),strHomedirdrive
13.    User.AccountExpirationDate = strAccountexpire
14.    User.Passwordrequired = strPassrequired
15.
16.  end sub

%>

Now we edited the same information that we applied to the computer in the previous article. After doing this we might as well remove the user we created, leaving us with nothing.

Removing Users


<%
1.  DelUser("MyDomain","MyUsername",)
2.
3.   Sub DelUser(strDomain,strUsername)
4.     Dim Computer
5.    
6.     Set Computer = GetObject("WinNT://" & strDomain)
7.     Computer.Delete("User", strUsername)
8.     Set Computer = nothing
9.   End Sub
%>


<%
1.  DelUser("MyDomain","MyUsername",)
2.
3.   Sub DelUser(strDomain,strUsername)
4.     Dim Computer
5.    
6.     Set Computer = GetObject("WinNT://" & strDomain)
7.     Computer.Delete("User", strUsername)
8.     Set Computer = nothing
9.   End Sub
%>


<%
1.  DelUser("MyDomain","MyUsername",)
2.
3.   Sub DelUser(strDomain,strUsername)
4.     Dim Computer
5.    
6.     Set Computer = GetObject("WinNT://" & strDomain)
7.     Computer.Delete("User", strUsername)
8.     Set Computer = nothing
9.   End Sub
%>

In the next article I will provide codes on how to query specific user information. For now we are going to order our thousands of users by making groups.

As I explained in my first article, every action performed here goes directly through the Windows SAM. In response to my first article, there were some questions on how to change the logon hours or the terminal server home path. Sorry, but I have to disappoint you . This , as well as some other vital functions, can't be changed by ADSI. Then again, ADSI does do a lot. In the upcoming articles we are going to dive into the IIS metabase. But before we do that, let's start with editing a user.

Renaming Users


<%
1.  RenameUser("MyDomain","MyUsername","MyNewUsername")
2.
3.   Sub RenameUser(strDomain,strOldUsername,strNewUsername)
4.     Dim Computer
5.     Dim User
6.     Dim MoveUser
7.    
8.     Set Computer = GetObject("WinNT://" & strDomain)
9.     Set User = GetObject("WinNT://" & strDomain & "/" & strOldUsername & ",user")
10.   Set MoveUser = Computer.MoveHere(User.ADsPath, strNewUsername)
11.
12.   Set Computer = nothing
13.   Set User = nothing
14.   Set MoveUser = nothing
15. End Sub
%>


<%
1.  RenameUser("MyDomain","MyUsername","MyNewUsername")
2.
3.   Sub RenameUser(strDomain,strOldUsername,strNewUsername)
4.     Dim Computer
5.     Dim User
6.     Dim MoveUser
7.    
8.     Set Computer = GetObject("WinNT://" & strDomain)
9.     Set User = GetObject("WinNT://" & strDomain & "/" & strOldUsername & ",user")
10.   Set MoveUser = Computer.MoveHere(User.ADsPath, strNewUsername)
11.
12.   Set Computer = nothing
13.   Set User = nothing
14.   Set MoveUser = nothing
15. End Sub
%>


<%
1.  RenameUser("MyDomain","MyUsername","MyNewUsername")
2.
3.   Sub RenameUser(strDomain,strOldUsername,strNewUsername)
4.     Dim Computer
5.     Dim User
6.     Dim MoveUser
7.    
8.     Set Computer = GetObject("WinNT://" & strDomain)
9.     Set User = GetObject("WinNT://" & strDomain & "/" & strOldUsername & ",user")
10.   Set MoveUser = Computer.MoveHere(User.ADsPath, strNewUsername)
11.
12.   Set Computer = nothing
13.   Set User = nothing
14.   Set MoveUser = nothing
15. End Sub
%>

There isn't much to explain. The computer just grabs all the information about a user (the user.ADsPath) and projects that to the new user, deleting the old.

Changing User-Properties


<%
1.   ChangeUser("MyUser","MyDomain","MyFullname","MyDescription","MyOldPass"
      ," MyNewPass"
2.
3.   Sub ChangeUser(strUser,strDomain,strFullname,strDesc,strOldPassword, 
4.                              strNewPassword)
5.     Dim User
6.     Set User = GetObject("WinNT://" & strDomain & "/" & strUser & ",user")
7.     User.Fullname = strDesc
8.     User.Description = strDesc
9.     User.ChangePassword(strOldPassword,strNewPassword)
10.   User.Setinfo
11.   Set User = nothing
12. End Sub
%>


<%
1.   ChangeUser("MyUser","MyDomain","MyFullname","MyDescription","MyOldPass"
      ," MyNewPass"
2.
3.   Sub ChangeUser(strUser,strDomain,strFullname,strDesc,strOldPassword, 
4.                              strNewPassword)
5.     Dim User
6.     Set User = GetObject("WinNT://" & strDomain & "/" & strUser & ",user")
7.     User.Fullname = strDesc
8.     User.Description = strDesc
9.     User.ChangePassword(strOldPassword,strNewPassword)
10.   User.Setinfo
11.   Set User = nothing
12. End Sub
%>


<%
1.   ChangeUser("MyUser","MyDomain","MyFullname","MyDescription","MyOldPass"
      ," MyNewPass"
2.
3.   Sub ChangeUser(strUser,strDomain,strFullname,strDesc,strOldPassword, 
4.                              strNewPassword)
5.     Dim User
6.     Set User = GetObject("WinNT://" & strDomain & "/" & strUser & ",user")
7.     User.Fullname = strDesc
8.     User.Description = strDesc
9.     User.ChangePassword(strOldPassword,strNewPassword)
10.   User.Setinfo
11.   Set User = nothing
12. End Sub
%>

In the above code we changed some basic elements of a user account. It isn't that different from adding a user. The only thing difference is the way a password is changed. Because of security reasons you can only change a password by providing the old password. The outcome of this subroutine is very simple. The user "MyUser" now has "MyFullname","MyDescription", and "MyNewpass" as a fullname, description and password. The next part is a bit harder since we are going into Hex/Decimal codes with the User-Flags. Again the code looks a lot like the code I used in my first article, but with one difference. Because we are now changing the user settings we use XOR instead of OR when dealing with userflags.

Changing Specific User Boundaries


<%

1.  UserFlags "newuser","mydomain",0,False,True,True,True
2. 
3.    Sub UserFlags(strUser,strDomain,strPassexpires,strNochange,strNoexpire, & _        
                               strDisable,strLocked)
4.      Dim User
5.      Dim Flags
6.
7.      Set User = Getobject("WinNT://" & strDomain & "/" & strUser & ",user")
8.      Flags = User.Get("UserFlags")
9.
10.    User.put "PasswordExpired",strPassexpires
11.    User.Accountdisabled = strDisable
12.    if strNochange = "true" then 
13.      User.put "UserFlags", Flags OR &H00040
14.    End if
15.    If strNoexpire = "true" then
16.      User.put "Userflags", flags OR &H10000
17.    end if
18.    User.IsAccountLocked = strLocked
19.
20.    Set User = nothing
21. End sub

%>


<%

1.  UserFlags "newuser","mydomain",0,False,True,True,True
2. 
3.    Sub UserFlags(strUser,strDomain,strPassexpires,strNochange,strNoexpire, & _        
                               strDisable,strLocked)
4.      Dim User
5.      Dim Flags
6.
7.      Set User = Getobject("WinNT://" & strDomain & "/" & strUser & ",user")
8.      Flags = User.Get("UserFlags")
9.
10.    User.put "PasswordExpired",strPassexpires
11.    User.Accountdisabled = strDisable
12.    if strNochange = "true" then 
13.      User.put "UserFlags", Flags OR &H00040
14.    End if
15.    If strNoexpire = "true" then
16.      User.put "Userflags", flags OR &H10000
17.    end if
18.    User.IsAccountLocked = strLocked
19.
20.    Set User = nothing
21. End sub

%>


<%

1.  UserFlags "newuser","mydomain",0,False,True,True,True
2. 
3.    Sub UserFlags(strUser,strDomain,strPassexpires,strNochange,strNoexpire, & _        
                               strDisable,strLocked)
4.      Dim User
5.      Dim Flags
6.
7.      Set User = Getobject("WinNT://" & strDomain & "/" & strUser & ",user")
8.      Flags = User.Get("UserFlags")
9.
10.    User.put "PasswordExpired",strPassexpires
11.    User.Accountdisabled = strDisable
12.    if strNochange = "true" then 
13.      User.put "UserFlags", Flags OR &H00040
14.    End if
15.    If strNoexpire = "true" then
16.      User.put "Userflags", flags OR &H10000
17.    end if
18.    User.IsAccountLocked = strLocked
19.
20.    Set User = nothing
21. End sub

%>

I'm not going to explain this code since it is an almost exact copy of the coding in the first article. Please make sure that you use XOR to change a userflag and OR to initially set it. The following part is a direct copy since nothing has changed. In order to change the logon script, profile path, etc., we use the same code as we used to initially set it.

<%

1.    userconfig "newuser","mydomain","c:/myprofiles/","myscript.cmd","c:/","z:/", & _
                         #mm/dd/yyyy#,"true"
2.
3.    sub userconfig(strUser,strDomain,strProfile,strScript,strHomedir, & _
                               strHomedirdrive,strAccountexpire,strPassrequired)
4.      Dim User
5.      Dim Flags
6.
7.      Set User = Getobject("WinNT://" & strDomain & "/" & strUser & ",user")
8.      
9.      User.Profile = strProfile
10.    User.LoginScript = strScript
11.    User.Homedirectory = strHomedir
12.    User.Put("HomeDirDrive"),strHomedirdrive
13.    User.AccountExpirationDate = strAccountexpire
14.    User.Passwordrequired = strPassrequired
15.
16.  end sub

%>

Now we edited the same information that we applied to the computer in the previous article. After doing this we might as well remove the user we created, leaving us with nothing.

Removing Users


<%
1.  DelUser("MyDomain","MyUsername",)
2.
3.   Sub DelUser(strDomain,strUsername)
4.     Dim Computer
5.    
6.     Set Computer = GetObject("WinNT://" & strDomain)
7.     Computer.Delete("User", strUsername)
8.     Set Computer = nothing
9.   End Sub
%>


<%
1.  DelUser("MyDomain","MyUsername",)
2.
3.   Sub DelUser(strDomain,strUsername)
4.     Dim Computer
5.    
6.     Set Computer = GetObject("WinNT://" & strDomain)
7.     Computer.Delete("User", strUsername)
8.     Set Computer = nothing
9.   End Sub
%>


<%
1.  DelUser("MyDomain","MyUsername",)
2.
3.   Sub DelUser(strDomain,strUsername)
4.     Dim Computer
5.    
6.     Set Computer = GetObject("WinNT://" & strDomain)
7.     Computer.Delete("User", strUsername)
8.     Set Computer = nothing
9.   End Sub
%>

In the next article I will provide codes on how to query specific user information. For now we are going to order our thousands of users by making groups.

Creating, Editing and Populating Groups

Groups are made to make the life of system administrators a bit easier. By creating groups you don't have to give folder rights to each specific user. You only have to give folder rights to the group. With ADSI and some good old DOS programming we can automate both.

Creating a Group


<%
1.    '//Creating a local group
2.    AddLocalGroup("MyDomain", "MyGroup")
3.  
4.    Sub AddLocalGroup(strDomain,strGroupname)
5.      Dim Computer
6.      Dim Group
7.
8.      Set Computer = GetObject("WinNT://" & strDomain)
9.      Set Group = Computer.Create("Group", strGroupname)
10.    Group.Put "groupType", 4
11.    Group.Setinfo
12.
13.    Set Computer = nothing
14.    Set Group = nothing
15.  End Sub
16.  '//End Creating a local group
%>

<%
1.    '//Creating a global group
2.    AddGlobalGroup("MyDomain","MyGroup")
3.
4.    Sub AddGlobalGroup(strDomain,strGroupname)
5.      Dim Computer
6.      Dim Group
7.  
8.      Set Computer = GetObject("WinNT://" & strDomain)
9.      Set Group = Computer.Create("Group", strGroupname)
10.    Group.Put "groupType", 2
11.    Group.Setinfo
12. 
13.    Set Computer = nothing
14.    Set Group = nothing
15.  End Sub
16.  '//End Creating a global group
%>


<%
1.    '//Creating a local group
2.    AddLocalGroup("MyDomain", "MyGroup")
3.  
4.    Sub AddLocalGroup(strDomain,strGroupname)
5.      Dim Computer
6.      Dim Group
7.
8.      Set Computer = GetObject("WinNT://" & strDomain)
9.      Set Group = Computer.Create("Group", strGroupname)
10.    Group.Put "groupType", 4
11.    Group.Setinfo
12.
13.    Set Computer = nothing
14.    Set Group = nothing
15.  End Sub
16.  '//End Creating a local group
%>

<%
1.    '//Creating a global group
2.    AddGlobalGroup("MyDomain","MyGroup")
3.
4.    Sub AddGlobalGroup(strDomain,strGroupname)
5.      Dim Computer
6.      Dim Group
7.  
8.      Set Computer = GetObject("WinNT://" & strDomain)
9.      Set Group = Computer.Create("Group", strGroupname)
10.    Group.Put "groupType", 2
11.    Group.Setinfo
12. 
13.    Set Computer = nothing
14.    Set Group = nothing
15.  End Sub
16.  '//End Creating a global group
%>


<%
1.    '//Creating a local group
2.    AddLocalGroup("MyDomain", "MyGroup")
3.  
4.    Sub AddLocalGroup(strDomain,strGroupname)
5.      Dim Computer
6.      Dim Group
7.
8.      Set Computer = GetObject("WinNT://" & strDomain)
9.      Set Group = Computer.Create("Group", strGroupname)
10.    Group.Put "groupType", 4
11.    Group.Setinfo
12.
13.    Set Computer = nothing
14.    Set Group = nothing
15.  End Sub
16.  '//End Creating a local group
%>

<%
1.    '//Creating a global group
2.    AddGlobalGroup("MyDomain","MyGroup")
3.
4.    Sub AddGlobalGroup(strDomain,strGroupname)
5.      Dim Computer
6.      Dim Group
7.  
8.      Set Computer = GetObject("WinNT://" & strDomain)
9.      Set Group = Computer.Create("Group", strGroupname)
10.    Group.Put "groupType", 2
11.    Group.Setinfo
12. 
13.    Set Computer = nothing
14.    Set Group = nothing
15.  End Sub
16.  '//End Creating a global group
%>

You may have noticed that in the first code sample the grouptype is 4, and in the second it is 2. The grouptype defines if the group is a local group, or a global group. Local groups are created to make independent groups on a workstation, and global groups are made for the whole domain. By default ADSI creates a Global group, so if you want to make a group without thinking, use the second sample and remove the Group.Put "groupType", 2 part.

Adding Users to a Group


<%
1.    AddUserToGroup("MyDomain","MyUsername","MyGroup")
2.
3.    Sub AddUserToGroup(strDomain,strUsername,strGroupname)
4.      Dim User
5.      Dim Group
6.
7.      Set User = GetObject("WinNT://" & strDomain & "/" & strUsername & ",user")
8.      Set Group = GetObject("WinNT://" & strDomain & "/" & strGroupname & 
                                               ",group")
9.      Group.Add(User.ADsPath)
10.    Group.Setinfo
11.
12.    Set User = nothing
13.    Set Group = nothing
14.  End Sub
%>


<%
1.    AddUserToGroup("MyDomain","MyUsername","MyGroup")
2.
3.    Sub AddUserToGroup(strDomain,strUsername,strGroupname)
4.      Dim User
5.      Dim Group
6.
7.      Set User = GetObject("WinNT://" & strDomain & "/" & strUsername & ",user")
8.      Set Group = GetObject("WinNT://" & strDomain & "/" & strGroupname & 
                                               ",group")
9.      Group.Add(User.ADsPath)
10.    Group.Setinfo
11.
12.    Set User = nothing
13.    Set Group = nothing
14.  End Sub
%>


<%
1.    AddUserToGroup("MyDomain","MyUsername","MyGroup")
2.
3.    Sub AddUserToGroup(strDomain,strUsername,strGroupname)
4.      Dim User
5.      Dim Group
6.
7.      Set User = GetObject("WinNT://" & strDomain & "/" & strUsername & ",user")
8.      Set Group = GetObject("WinNT://" & strDomain & "/" & strGroupname & 
                                               ",group")
9.      Group.Add(User.ADsPath)
10.    Group.Setinfo
11.
12.    Set User = nothing
13.    Set Group = nothing
14.  End Sub
%>

Removing Users from a Group

<%
1.    DelUserFromGroup("MyDomain","MyUsername","MyGroup")
2.
3.    Sub DelUserFromGroup (strDomain,strUsername,strGroupname)
4.      Dim User
5.      Dim Group
6.
7.      Set User = GetObject("WinNT://" & strDomain & "/" & strUsername & ",user")
8.      Set Group = GetObject("WinNT://" & strDomain & "/" & strGroupname & 
                                               ",group")
9.      Group.Remove(User.ADsPath)
10.    Group.Setinfo
11.
12.    Set User = nothing
13.    Set Group = nothing
14.  End Sub
%>

Editing the Group Description Field

<%
1.    EditGroup("MyDomain","MyGroup","MyDescription")
2.
3.    Sub EditGroup (strDomain,strGroupname,strGroupDesc)
4.      Dim Group
5.
6.      Set Group = GetObject("WinNT://" & strDomain & "/" & strGroupname & 
                                               ",group")
7.      Group.Description = strGroupDesc
8.      Group.Setinfo
9.
10.    Set Group = nothing
11.  End Sub
%>

Maybe some of you missed my explanation here. But I couldn't think of anything to comment on. The creation of a group doesn't involve difficult pieces of coding. Frankly, the only thing that is different between adding and removing a user in a group is the words "add" and "remove". There is nothing as easy as making new groups; you just have to know the syntax. So that is what I've provided here. Let's cleanup our little experiment by removing the group.

Removing a Group


<%
1.  DelGroup("MyDomain","MyGroup",)
2.
3.   Sub DelGroup(strDomain,strGroupname)
4.     Dim Computer
5.     Set Computer = GetObject("WinNT://" & strDomain)
6.     Computer.Delete("Group", strGroupname)
7.     Set Computer = nothing
8.   End Sub
%>


<%
1.  DelGroup("MyDomain","MyGroup",)
2.
3.   Sub DelGroup(strDomain,strGroupname)
4.     Dim Computer
5.     Set Computer = GetObject("WinNT://" & strDomain)
6.     Computer.Delete("Group", strGroupname)
7.     Set Computer = nothing
8.   End Sub
%>


<%
1.  DelGroup("MyDomain","MyGroup",)
2.
3.   Sub DelGroup(strDomain,strGroupname)
4.     Dim Computer
5.     Set Computer = GetObject("WinNT://" & strDomain)
6.     Computer.Delete("Group", strGroupname)
7.     Set Computer = nothing
8.   End Sub
%>

That is all there is to say about groups in the ADSI. So now for the special bonus: Automatically changing the Folder Rights. After creating a group, or a user, you can automatically set the folder rights by using old fashion DOS methods. Every Windows server has a little program called cacls.exe. This program changes the user rights on folders. You can just run it by using Windows Scripting, but then you will get stuck. Why? Because the cacls.exe is waiting for confirmation. In order to do this you should pipe a Y to the cacls.exe, forcing it to accept the new settings.

<%
1.    ChangeFolderSettings("c:/myfolder","Myuser","C")
2.
3.    Sub ChangeFolderSettings(strFolderPath,strUser,strPermission)
4.      Dim caclscommand
5.      Dim whs
6.      Dim whsRun
7.
8.      Caclscommand = "cmd /c echo y| CACLS " & strFolderPath
9.      Caclscommand = Caclscommand & " /E /C /G " & strUser & ":" & strPermission
10.
11.    Set whs = server.createobject("WScript.Shell")
12.    Set whsRun = whs.run(Caclscommand, 0, True)
13.
14.    Set whsrun = nothing
15.    Set whs = nothing
16.  End Sub
%>

The code creates a commandline that is executed in by the Windows Script Host. In that commandline I specify a few different things:

1. "cmd /c echo"
2. "y| CACLS"
3. & strFolderPath & " /E /C"
4. "/G " & strUser & ":" & strPermission

The first thing I do is open a command window and pointing out that I want to see the what's happening. After that I pipe the letter Y to the CACLS.exe by using the y| symbol. By piping Y, I avoid the "Are you Sure" question. Then I give the name of the folder (or file) I want to edit, followed by /E and /C. The /E says that I want to edit the user rights. Without the /E the rights will be overwritten. The /C says that the code should continue even if an error occurs. The last part is where I grant to user strUser (this can also be a group) a specific right. In the example I use C. But there are more rights:

- R (read only)
- W (write only)
- C (change (read/write))
- F (Full Control)

Please note that if you want to change the rights of a user you have to use "/P " & strUser & ":" & strPermission

I'm going to end with some answers to questions I received concerning my previous article. Hope you enjoyed it, and happy programming.

Groups are made to make the life of system administrators a bit easier. By creating groups you don't have to give folder rights to each specific user. You only have to give folder rights to the group. With ADSI and some good old DOS programming we can automate both.

Creating a Group


<%
1.    '//Creating a local group
2.    AddLocalGroup("MyDomain", "MyGroup")
3.  
4.    Sub AddLocalGroup(strDomain,strGroupname)
5.      Dim Computer
6.      Dim Group
7.
8.      Set Computer = GetObject("WinNT://" & strDomain)
9.      Set Group = Computer.Create("Group", strGroupname)
10.    Group.Put "groupType", 4
11.    Group.Setinfo
12.
13.    Set Computer = nothing
14.    Set Group = nothing
15.  End Sub
16.  '//End Creating a local group
%>

<%
1.    '//Creating a global group
2.    AddGlobalGroup("MyDomain","MyGroup")
3.
4.    Sub AddGlobalGroup(strDomain,strGroupname)
5.      Dim Computer
6.      Dim Group
7.  
8.      Set Computer = GetObject("WinNT://" & strDomain)
9.      Set Group = Computer.Create("Group", strGroupname)
10.    Group.Put "groupType", 2
11.    Group.Setinfo
12. 
13.    Set Computer = nothing
14.    Set Group = nothing
15.  End Sub
16.  '//End Creating a global group
%>


<%
1.    '//Creating a local group
2.    AddLocalGroup("MyDomain", "MyGroup")
3.  
4.    Sub AddLocalGroup(strDomain,strGroupname)
5.      Dim Computer
6.      Dim Group
7.
8.      Set Computer = GetObject("WinNT://" & strDomain)
9.      Set Group = Computer.Create("Group", strGroupname)
10.    Group.Put "groupType", 4
11.    Group.Setinfo
12.
13.    Set Computer = nothing
14.    Set Group = nothing
15.  End Sub
16.  '//End Creating a local group
%>

<%
1.    '//Creating a global group
2.    AddGlobalGroup("MyDomain","MyGroup")
3.
4.    Sub AddGlobalGroup(strDomain,strGroupname)
5.      Dim Computer
6.      Dim Group
7.  
8.      Set Computer = GetObject("WinNT://" & strDomain)
9.      Set Group = Computer.Create("Group", strGroupname)
10.    Group.Put "groupType", 2
11.    Group.Setinfo
12. 
13.    Set Computer = nothing
14.    Set Group = nothing
15.  End Sub
16.  '//End Creating a global group
%>


<%
1.    '//Creating a local group
2.    AddLocalGroup("MyDomain", "MyGroup")
3.  
4.    Sub AddLocalGroup(strDomain,strGroupname)
5.      Dim Computer
6.      Dim Group
7.
8.      Set Computer = GetObject("WinNT://" & strDomain)
9.      Set Group = Computer.Create("Group", strGroupname)
10.    Group.Put "groupType", 4
11.    Group.Setinfo
12.
13.    Set Computer = nothing
14.    Set Group = nothing
15.  End Sub
16.  '//End Creating a local group
%>

<%
1.    '//Creating a global group
2.    AddGlobalGroup("MyDomain","MyGroup")
3.
4.    Sub AddGlobalGroup(strDomain,strGroupname)
5.      Dim Computer
6.      Dim Group
7.  
8.      Set Computer = GetObject("WinNT://" & strDomain)
9.      Set Group = Computer.Create("Group", strGroupname)
10.    Group.Put "groupType", 2
11.    Group.Setinfo
12. 
13.    Set Computer = nothing
14.    Set Group = nothing
15.  End Sub
16.  '//End Creating a global group
%>

You may have noticed that in the first code sample the grouptype is 4, and in the second it is 2. The grouptype defines if the group is a local group, or a global group. Local groups are created to make independent groups on a workstation, and global groups are made for the whole domain. By default ADSI creates a Global group, so if you want to make a group without thinking, use the second sample and remove the Group.Put "groupType", 2 part.

Adding Users to a Group


<%
1.    AddUserToGroup("MyDomain","MyUsername","MyGroup")
2.
3.    Sub AddUserToGroup(strDomain,strUsername,strGroupname)
4.      Dim User
5.      Dim Group
6.
7.      Set User = GetObject("WinNT://" & strDomain & "/" & strUsername & ",user")
8.      Set Group = GetObject("WinNT://" & strDomain & "/" & strGroupname & 
                                               ",group")
9.      Group.Add(User.ADsPath)
10.    Group.Setinfo
11.
12.    Set User = nothing
13.    Set Group = nothing
14.  End Sub
%>


<%
1.    AddUserToGroup("MyDomain","MyUsername","MyGroup")
2.
3.    Sub AddUserToGroup(strDomain,strUsername,strGroupname)
4.      Dim User
5.      Dim Group
6.
7.      Set User = GetObject("WinNT://" & strDomain & "/" & strUsername & ",user")
8.      Set Group = GetObject("WinNT://" & strDomain & "/" & strGroupname & 
                                               ",group")
9.      Group.Add(User.ADsPath)
10.    Group.Setinfo
11.
12.    Set User = nothing
13.    Set Group = nothing
14.  End Sub
%>


<%
1.    AddUserToGroup("MyDomain","MyUsername","MyGroup")
2.
3.    Sub AddUserToGroup(strDomain,strUsername,strGroupname)
4.      Dim User
5.      Dim Group
6.
7.      Set User = GetObject("WinNT://" & strDomain & "/" & strUsername & ",user")
8.      Set Group = GetObject("WinNT://" & strDomain & "/" & strGroupname & 
                                               ",group")
9.      Group.Add(User.ADsPath)
10.    Group.Setinfo
11.
12.    Set User = nothing
13.    Set Group = nothing
14.  End Sub
%>

Removing Users from a Group

<%
1.    DelUserFromGroup("MyDomain","MyUsername","MyGroup")
2.
3.    Sub DelUserFromGroup (strDomain,strUsername,strGroupname)
4.      Dim User
5.      Dim Group
6.
7.      Set User = GetObject("WinNT://" & strDomain & "/" & strUsername & ",user")
8.      Set Group = GetObject("WinNT://" & strDomain & "/" & strGroupname & 
                                               ",group")
9.      Group.Remove(User.ADsPath)
10.    Group.Setinfo
11.
12.    Set User = nothing
13.    Set Group = nothing
14.  End Sub
%>

Editing the Group Description Field

<%
1.    EditGroup("MyDomain","MyGroup","MyDescription")
2.
3.    Sub EditGroup (strDomain,strGroupname,strGroupDesc)
4.      Dim Group
5.
6.      Set Group = GetObject("WinNT://" & strDomain & "/" & strGroupname & 
                                               ",group")
7.      Group.Description = strGroupDesc
8.      Group.Setinfo
9.
10.    Set Group = nothing
11.  End Sub
%>

Maybe some of you missed my explanation here. But I couldn't think of anything to comment on. The creation of a group doesn't involve difficult pieces of coding. Frankly, the only thing that is different between adding and removing a user in a group is the words "add" and "remove". There is nothing as easy as making new groups; you just have to know the syntax. So that is what I've provided here. Let's cleanup our little experiment by removing the group.

Removing a Group


<%
1.  DelGroup("MyDomain","MyGroup",)
2.
3.   Sub DelGroup(strDomain,strGroupname)
4.     Dim Computer
5.     Set Computer = GetObject("WinNT://" & strDomain)
6.     Computer.Delete("Group", strGroupname)
7.     Set Computer = nothing
8.   End Sub
%>


<%
1.  DelGroup("MyDomain","MyGroup",)
2.
3.   Sub DelGroup(strDomain,strGroupname)
4.     Dim Computer
5.     Set Computer = GetObject("WinNT://" & strDomain)
6.     Computer.Delete("Group", strGroupname)
7.     Set Computer = nothing
8.   End Sub
%>


<%
1.  DelGroup("MyDomain","MyGroup",)
2.
3.   Sub DelGroup(strDomain,strGroupname)
4.     Dim Computer
5.     Set Computer = GetObject("WinNT://" & strDomain)
6.     Computer.Delete("Group", strGroupname)
7.     Set Computer = nothing
8.   End Sub
%>

That is all there is to say about groups in the ADSI. So now for the special bonus: Automatically changing the Folder Rights. After creating a group, or a user, you can automatically set the folder rights by using old fashion DOS methods. Every Windows server has a little program called cacls.exe. This program changes the user rights on folders. You can just run it by using Windows Scripting, but then you will get stuck. Why? Because the cacls.exe is waiting for confirmation. In order to do this you should pipe a Y to the cacls.exe, forcing it to accept the new settings.

<%
1.    ChangeFolderSettings("c:/myfolder","Myuser","C")
2.
3.    Sub ChangeFolderSettings(strFolderPath,strUser,strPermission)
4.      Dim caclscommand
5.      Dim whs
6.      Dim whsRun
7.
8.      Caclscommand = "cmd /c echo y| CACLS " & strFolderPath
9.      Caclscommand = Caclscommand & " /E /C /G " & strUser & ":" & strPermission
10.
11.    Set whs = server.createobject("WScript.Shell")
12.    Set whsRun = whs.run(Caclscommand, 0, True)
13.
14.    Set whsrun = nothing
15.    Set whs = nothing
16.  End Sub
%>

The code creates a commandline that is executed in by the Windows Script Host. In that commandline I specify a few different things:

1. "cmd /c echo"
2. "y| CACLS"
3. & strFolderPath & " /E /C"
4. "/G " & strUser & ":" & strPermission

The first thing I do is open a command window and pointing out that I want to see the what's happening. After that I pipe the letter Y to the CACLS.exe by using the y| symbol. By piping Y, I avoid the "Are you Sure" question. Then I give the name of the folder (or file) I want to edit, followed by /E and /C. The /E says that I want to edit the user rights. Without the /E the rights will be overwritten. The /C says that the code should continue even if an error occurs. The last part is where I grant to user strUser (this can also be a group) a specific right. In the example I use C. But there are more rights:

- R (read only)
- W (write only)
- C (change (read/write))
- F (Full Control)

Please note that if you want to change the rights of a user you have to use "/P " & strUser & ":" & strPermission

I'm going to end with some answers to questions I received concerning my previous article. Hope you enjoyed it, and happy programming.

Groups are made to make the life of system administrators a bit easier. By creating groups you don't have to give folder rights to each specific user. You only have to give folder rights to the group. With ADSI and some good old DOS programming we can automate both.

Creating a Group


<%
1.    '//Creating a local group
2.    AddLocalGroup("MyDomain", "MyGroup")
3.  
4.    Sub AddLocalGroup(strDomain,strGroupname)
5.      Dim Computer
6.      Dim Group
7.
8.      Set Computer = GetObject("WinNT://" & strDomain)
9.      Set Group = Computer.Create("Group", strGroupname)
10.    Group.Put "groupType", 4
11.    Group.Setinfo
12.
13.    Set Computer = nothing
14.    Set Group = nothing
15.  End Sub
16.  '//End Creating a local group
%>

<%
1.    '//Creating a global group
2.    AddGlobalGroup("MyDomain","MyGroup")
3.
4.    Sub AddGlobalGroup(strDomain,strGroupname)
5.      Dim Computer
6.      Dim Group
7.  
8.      Set Computer = GetObject("WinNT://" & strDomain)
9.      Set Group = Computer.Create("Group", strGroupname)
10.    Group.Put "groupType", 2
11.    Group.Setinfo
12. 
13.    Set Computer = nothing
14.    Set Group = nothing
15.  End Sub
16.  '//End Creating a global group
%>


<%
1.    '//Creating a local group
2.    AddLocalGroup("MyDomain", "MyGroup")
3.  
4.    Sub AddLocalGroup(strDomain,strGroupname)
5.      Dim Computer
6.      Dim Group
7.
8.      Set Computer = GetObject("WinNT://" & strDomain)
9.      Set Group = Computer.Create("Group", strGroupname)
10.    Group.Put "groupType", 4
11.    Group.Setinfo
12.
13.    Set Computer = nothing
14.    Set Group = nothing
15.  End Sub
16.  '//End Creating a local group
%>

<%
1.    '//Creating a global group
2.    AddGlobalGroup("MyDomain","MyGroup")
3.
4.    Sub AddGlobalGroup(strDomain,strGroupname)
5.      Dim Computer
6.      Dim Group
7.  
8.      Set Computer = GetObject("WinNT://" & strDomain)
9.      Set Group = Computer.Create("Group", strGroupname)
10.    Group.Put "groupType", 2
11.    Group.Setinfo
12. 
13.    Set Computer = nothing
14.    Set Group = nothing
15.  End Sub
16.  '//End Creating a global group
%>


<%
1.    '//Creating a local group
2.    AddLocalGroup("MyDomain", "MyGroup")
3.  
4.    Sub AddLocalGroup(strDomain,strGroupname)
5.      Dim Computer
6.      Dim Group
7.
8.      Set Computer = GetObject("WinNT://" & strDomain)
9.      Set Group = Computer.Create("Group", strGroupname)
10.    Group.Put "groupType", 4
11.    Group.Setinfo
12.
13.    Set Computer = nothing
14.    Set Group = nothing
15.  End Sub
16.  '//End Creating a local group
%>

<%
1.    '//Creating a global group
2.    AddGlobalGroup("MyDomain","MyGroup")
3.
4.    Sub AddGlobalGroup(strDomain,strGroupname)
5.      Dim Computer
6.      Dim Group
7.  
8.      Set Computer = GetObject("WinNT://" & strDomain)
9.      Set Group = Computer.Create("Group", strGroupname)
10.    Group.Put "groupType", 2
11.    Group.Setinfo
12. 
13.    Set Computer = nothing
14.    Set Group = nothing
15.  End Sub
16.  '//End Creating a global group
%>

You may have noticed that in the first code sample the grouptype is 4, and in the second it is 2. The grouptype defines if the group is a local group, or a global group. Local groups are created to make independent groups on a workstation, and global groups are made for the whole domain. By default ADSI creates a Global group, so if you want to make a group without thinking, use the second sample and remove the Group.Put "groupType", 2 part.

Adding Users to a Group


<%
1.    AddUserToGroup("MyDomain","MyUsername","MyGroup")
2.
3.    Sub AddUserToGroup(strDomain,strUsername,strGroupname)
4.      Dim User
5.      Dim Group
6.
7.      Set User = GetObject("WinNT://" & strDomain & "/" & strUsername & ",user")
8.      Set Group = GetObject("WinNT://" & strDomain & "/" & strGroupname & 
                                               ",group")
9.      Group.Add(User.ADsPath)
10.    Group.Setinfo
11.
12.    Set User = nothing
13.    Set Group = nothing
14.  End Sub
%>


<%
1.    AddUserToGroup("MyDomain","MyUsername","MyGroup")
2.
3.    Sub AddUserToGroup(strDomain,strUsername,strGroupname)
4.      Dim User
5.      Dim Group
6.
7.      Set User = GetObject("WinNT://" & strDomain & "/" & strUsername & ",user")
8.      Set Group = GetObject("WinNT://" & strDomain & "/" & strGroupname & 
                                               ",group")
9.      Group.Add(User.ADsPath)
10.    Group.Setinfo
11.
12.    Set User = nothing
13.    Set Group = nothing
14.  End Sub
%>


<%
1.    AddUserToGroup("MyDomain","MyUsername","MyGroup")
2.
3.    Sub AddUserToGroup(strDomain,strUsername,strGroupname)
4.      Dim User
5.      Dim Group
6.
7.      Set User = GetObject("WinNT://" & strDomain & "/" & strUsername & ",user")
8.      Set Group = GetObject("WinNT://" & strDomain & "/" & strGroupname & 
                                               ",group")
9.      Group.Add(User.ADsPath)
10.    Group.Setinfo
11.
12.    Set User = nothing
13.    Set Group = nothing
14.  End Sub
%>

Removing Users from a Group

<%
1.    DelUserFromGroup("MyDomain","MyUsername","MyGroup")
2.
3.    Sub DelUserFromGroup (strDomain,strUsername,strGroupname)
4.      Dim User
5.      Dim Group
6.
7.      Set User = GetObject("WinNT://" & strDomain & "/" & strUsername & ",user")
8.      Set Group = GetObject("WinNT://" & strDomain & "/" & strGroupname & 
                                               ",group")
9.      Group.Remove(User.ADsPath)
10.    Group.Setinfo
11.
12.    Set User = nothing
13.    Set Group = nothing
14.  End Sub
%>

Editing the Group Description Field

<%
1.    EditGroup("MyDomain","MyGroup","MyDescription")
2.
3.    Sub EditGroup (strDomain,strGroupname,strGroupDesc)
4.      Dim Group
5.
6.      Set Group = GetObject("WinNT://" & strDomain & "/" & strGroupname & 
                                               ",group")
7.      Group.Description = strGroupDesc
8.      Group.Setinfo
9.
10.    Set Group = nothing
11.  End Sub
%>

Maybe some of you missed my explanation here. But I couldn't think of anything to comment on. The creation of a group doesn't involve difficult pieces of coding. Frankly, the only thing that is different between adding and removing a user in a group is the words "add" and "remove". There is nothing as easy as making new groups; you just have to know the syntax. So that is what I've provided here. Let's cleanup our little experiment by removing the group.

Removing a Group


<%
1.  DelGroup("MyDomain","MyGroup",)
2.
3.   Sub DelGroup(strDomain,strGroupname)
4.     Dim Computer
5.     Set Computer = GetObject("WinNT://" & strDomain)
6.     Computer.Delete("Group", strGroupname)
7.     Set Computer = nothing
8.   End Sub
%>


<%
1.  DelGroup("MyDomain","MyGroup",)
2.
3.   Sub DelGroup(strDomain,strGroupname)
4.     Dim Computer
5.     Set Computer = GetObject("WinNT://" & strDomain)
6.     Computer.Delete("Group", strGroupname)
7.     Set Computer = nothing
8.   End Sub
%>


<%
1.  DelGroup("MyDomain","MyGroup",)
2.
3.   Sub DelGroup(strDomain,strGroupname)
4.     Dim Computer
5.     Set Computer = GetObject("WinNT://" & strDomain)
6.     Computer.Delete("Group", strGroupname)
7.     Set Computer = nothing
8.   End Sub
%>

That is all there is to say about groups in the ADSI. So now for the special bonus: Automatically changing the Folder Rights. After creating a group, or a user, you can automatically set the folder rights by using old fashion DOS methods. Every Windows server has a little program called cacls.exe. This program changes the user rights on folders. You can just run it by using Windows Scripting, but then you will get stuck. Why? Because the cacls.exe is waiting for confirmation. In order to do this you should pipe a Y to the cacls.exe, forcing it to accept the new settings.

<%
1.    ChangeFolderSettings("c:/myfolder","Myuser","C")
2.
3.    Sub ChangeFolderSettings(strFolderPath,strUser,strPermission)
4.      Dim caclscommand
5.      Dim whs
6.      Dim whsRun
7.
8.      Caclscommand = "cmd /c echo y| CACLS " & strFolderPath
9.      Caclscommand = Caclscommand & " /E /C /G " & strUser & ":" & strPermission
10.
11.    Set whs = server.createobject("WScript.Shell")
12.    Set whsRun = whs.run(Caclscommand, 0, True)
13.
14.    Set whsrun = nothing
15.    Set whs = nothing
16.  End Sub
%>

The code creates a commandline that is executed in by the Windows Script Host. In that commandline I specify a few different things:

1. "cmd /c echo"
2. "y| CACLS"
3. & strFolderPath & " /E /C"
4. "/G " & strUser & ":" & strPermission

The first thing I do is open a command window and pointing out that I want to see the what's happening. After that I pipe the letter Y to the CACLS.exe by using the y| symbol. By piping Y, I avoid the "Are you Sure" question. Then I give the name of the folder (or file) I want to edit, followed by /E and /C. The /E says that I want to edit the user rights. Without the /E the rights will be overwritten. The /C says that the code should continue even if an error occurs. The last part is where I grant to user strUser (this can also be a group) a specific right. In the example I use C. But there are more rights:

- R (read only)
- W (write only)
- C (change (read/write))
- F (Full Control)

Please note that if you want to change the rights of a user you have to use "/P " & strUser & ":" & strPermission

I'm going to end with some answers to questions I received concerning my previous article. Hope you enjoyed it, and happy programming.

FAQ

Q: I can't set the AccountExpirationDate
A: This could be because the user has the "Password Never Expires" toggled on. If so, the account won't expire, and therefore ADSI isn't able to set it.

Q: I get a "General Access Denied Error" when I apply the codes
A: The server will only allow changes to be made to the SAM using an Administrator username and password. So the IUSR_machinename (IIS anonymous account) isn't allowed to execute the codes. Make sure that you toggle off the anonymous access in IIS, and let people login using a valid Administrator account.

Q: Can I Automatically create an exchange Mail account?
A: Yes you can, but I will handle that later.

Q: can I set the Terminal Services Properties using ADSI.
A: No you can't. ADSI can't set the terminal services properties, as well as it can't change logon hours.

Beside these questions, there were some question about LDAP. This article doesn't involve LDAP; it just refers to the ADSI language. If you do have question about LDAP, you can e-mail me. I'm not really good at it, but I can help to figure out a solution.

Q: I can't set the AccountExpirationDate
A: This could be because the user has the "Password Never Expires" toggled on. If so, the account won't expire, and therefore ADSI isn't able to set it.

Q: I get a "General Access Denied Error" when I apply the codes
A: The server will only allow changes to be made to the SAM using an Administrator username and password. So the IUSR_machinename (IIS anonymous account) isn't allowed to execute the codes. Make sure that you toggle off the anonymous access in IIS, and let people login using a valid Administrator account.

Q: Can I Automatically create an exchange Mail account?
A: Yes you can, but I will handle that later.

Q: can I set the Terminal Services Properties using ADSI.
A: No you can't. ADSI can't set the terminal services properties, as well as it can't change logon hours.

Beside these questions, there were some question about LDAP. This article doesn't involve LDAP; it just refers to the ADSI language. If you do have question about LDAP, you can e-mail me. I'm not really good at it, but I can help to figure out a solution.

Q: I can't set the AccountExpirationDate
A: This could be because the user has the "Password Never Expires" toggled on. If so, the account won't expire, and therefore ADSI isn't able to set it.

Q: I get a "General Access Denied Error" when I apply the codes
A: The server will only allow changes to be made to the SAM using an Administrator username and password. So the IUSR_machinename (IIS anonymous account) isn't allowed to execute the codes. Make sure that you toggle off the anonymous access in IIS, and let people login using a valid Administrator account.

Q: Can I Automatically create an exchange Mail account?
A: Yes you can, but I will handle that later.

Q: can I set the Terminal Services Properties using ADSI.
A: No you can't. ADSI can't set the terminal services properties, as well as it can't change logon hours.

Beside these questions, there were some question about LDAP. This article doesn't involve LDAP; it just refers to the ADSI language. If you do have question about LDAP, you can e-mail me. I'm not really good at it, but I can help to figure out a solution.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值