Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I've created about 50 user accounts on a Windows 2003 Server, and I'd like to copy those accounts to a new server, is this possible? I'm not using Active Directory.

Patrick

Edit 1 : Thanks for the answers, however I should have been more specific in my original question. I'd like to copy the user accounts and maintain the existing passwords. Also, I'd like to copy the accounts between two servers across the internet and firewalls. Is it possible to simply backup and restore user accounts?

share|improve this question
    
Patrick: I've dropped an edit onto my answer that might help you out. –  Evan Anderson Jun 30 '09 at 14:46

4 Answers 4

The command "net user" will display a list of all user accounts. If you run this an pipe the output to a file you can then edit the file to convert it to a script to create the accounts of the new server. use "net help user" to see how to create accounts from a batch file. You'll probably have to do some manual tweaking of the accounts after creating them, but it's still a time saver compared to using the GUI.

NB you won't be able to extract the old passwords. If you don't know what your users passwords are you'll have to set them all to some default value then change them one by one.

JR

John's post has just reminded me: there's an applet from MS called AddUsers that helps with this sort of thing. See http://support.microsoft.com/kb/199878 for the details.

share|improve this answer
    
Doesn't look like addusers will work on Windows Server 2003 .. –  tomjedrz Jun 30 '09 at 13:27
    
I've just tested addusers.exe (in a limited way) on Windows Server 2008 and it worked fine. I'd be very surprised if it doesn't work on Windows 2003 as it's just using the NetXXX functions in the Win32 API. –  John Rennie Jun 30 '09 at 14:37

Here's a VBscript program to copy local groups and user accounts from a source computer to a destination computer:

Option Explicit

Dim dictGroupsNotToCreate, dictPropertiesToCopy, dictUsersToIgnore, objNetwork
Dim colSourceGroups, colDestinationGroups, objSourceGroup, objDestinationGroup, objUser
Dim colSourceAccounts, colDestinationAccounts, objSourceUser, objDestinationUser, property

' Debugging
Const DEBUGGING = True

' Source and destination computers
Const SOURCE_COMPUTER = "PC00623"
Const DESTINATION_COMPUTER = "PC00619"

' Password to set on newly create user accounts
Const DEFAULT_PASSWORD = "rh1n0s!!!"

' Constants for comparison of accounts to ignore list
Const MATCH_EXACT = 1
Const MATCH_LEFT = 2

Set dictGroupsNotToCreate = CreateObject("Scripting.Dictionary")
dictGroupsNotToCreate.Add "Administrators", MATCH_EXACT
dictGroupsNotToCreate.Add "Backup Operators", MATCH_EXACT
dictGroupsNotToCreate.Add "Guests", MATCH_EXACT
dictGroupsNotToCreate.Add "Network Configuration Operators", MATCH_EXACT
dictGroupsNotToCreate.Add "Power Users", MATCH_EXACT
dictGroupsNotToCreate.Add "Remote Desktop Users", MATCH_EXACT
dictGroupsNotToCreate.Add "Replicator", MATCH_EXACT
dictGroupsNotToCreate.Add "Users", MATCH_EXACT
dictGroupsNotToCreate.Add "Debugger Users", MATCH_EXACT
dictGroupsNotToCreate.Add "HelpServicesGroup", MATCH_EXACT

' Properties of user accounts to copy
Set dictPropertiesToCopy = CreateObject("Scripting.Dictionary")
dictPropertiesToCopy.Add "Description", True
dictPropertiesToCopy.Add "FullName", True
dictPropertiesToCopy.Add "HomeDirDrive", True
dictPropertiesToCopy.Add "HomeDirectory", True
dictPropertiesToCopy.Add "LoginHours", True
dictPropertiesToCopy.Add "LoginScript", True
dictPropertiesToCopy.Add "Profile", True

' Accounts to ignore during copying
Set dictUsersToIgnore = CreateObject("Scripting.Dictionary")
dictUsersToIgnore.Add "SUPPORT_", MATCH_LEFT
dictUsersToIgnore.Add "IUSR_", MATCH_LEFT
dictUsersToIgnore.Add "IWAM_", MATCH_LEFT
dictUsersToIgnore.Add "Administrator", MATCH_EXACT
dictUsersToIgnore.Add "Guest", MATCH_EXACT
dictUsersToIgnore.Add "HelpAssistant", MATCH_EXACT
dictUsersToIgnore.Add "ASPNET", MATCH_EXACT

' Should this account be ignored
Function IgnoreObject(Name, dictNames)
    Dim strToIgnore

    IgnoreObject = False

    For Each strToIgnore in dictNames

    	' Match Exact
    	If (dictNames.Item(strToIgnore) = MATCH_EXACT) and (UCase(Name) = UCase(strToIgnore)) Then
    		IgnoreObject = True
    		Exit Function
    	End If

    	' Match left
    	If (dictNames.Item(strToIgnore) = MATCH_LEFT) and (Left(UCase(Name), Len(strToIgnore)) = UCase(strToIgnore)) Then
    		IgnoreObject = True
    		Exit Function
    	End If

    Next' strToIgnore
End Function

Set objNetwork = CreateObject("Wscript.Network")

' Get groups on source computer and loop through them, copying as necessary
Set colSourceGroups = GetObject("WinNT://" & SOURCE_COMPUTER)
Set colDestinationGroups = GetObject("WinNT://" & DESTINATION_COMPUTER)
colSourceGroups.Filter = Array("group")

For Each objSourceGroup in colSourceGroups

    If IgnoreObject(objSourceGroup.Name, dictGroupsNotToCreate) = False then
    	If (DEBUGGING) Then WScript.Echo "Creating Group: " & objSourceGroup.Name
    	Set objDestinationGroup = colDestinationGroups.Create("group", objSourceGroup.Name)
    	objDestinationGroup.Put "Description", objSourceGroup.Get("Description")
    	objDestinationGroup.SetInfo
    Else
    	If (DEBUGGING) Then WScript.Echo "Ignoring Group: " & objSourceGroup.Name
    End If
Next ' objSourceGroup

' Get accounts on source computer and loop through them, copying as necessary
Set colSourceAccounts = GetObject("WinNT://" & SOURCE_COMPUTER)
set colDestinationAccounts = GetObject("WinNT://" & DESTINATION_COMPUTER)
colSourceAccounts.Filter = Array("user")
For Each objSourceUser In colSourceAccounts

    If IgnoreObject(objSourceUser.Name, dictUsersToIgnore) = False Then
    	If (DEBUGGING) Then WScript.Echo "Copying account: " & objSourceUser.Name

    	On Error Resume Next

    	Set objDestinationUser = colDestinationAccounts.Create("user", objSourceUser.Name)
    	objDestinationUser.SetPassword DEFAULT_PASSWORD
    	objDestinationUser.SetInfo

    	' Copy properties from source user to destination user
    	For Each property in dictPropertiesToCopy
    		If (DEBUGGING) then WScript.Echo "   Copying property " & property & " (" &  objSourceUser.Get(property) & ")"
    		objDestinationUser.Put property, objSourceUser.Get(property)
    		objDestinationUser.SetInfo
    	Next ' property

    	' Put user into destination groups
    	For Each objSourceGroup In colSourceGroups
    		For Each objUser In objSourceGroup.Members
    			If UCase(objUser.Name) = Ucase(objSourceUser.Name) Then 
    				If (DEBUGGING) Then WScript.Echo "Adding user " & objSourceUser.Name & " to group " & objSourceGroup.Name
    				Set objDestinationGroup = GetObject("WinNT://" & DESTINATION_COMPUTER & "/" & objSourceGroup.Name & ",group")
    				objDestinationGroup.Add(objDestinationUser.aDSPath)
    			Else
    				If (DEBUGGING) Then WScript.Echo "User " & objSourceUser.Name & " is not a member of group " & objSourceGroup.Name
    			End If
    		Next ' objUser
    	Next 'objSourceGroup

    Else
    	If (DEBUGGING) Then WScript.Echo "Ignoring account: " & objSourceUser.Name
    End If
Next ' objSourceUser

A quick tour:

  • Set the SOURCE_COMPUTER and DESTINATION_COMPUTER names
  • Set the DEFAULT_PASSWORD (which will be assigned to the newly created user accounts)
  • Add any local group names that should not be created on the destination computer to the dictGroupsNotToCreate list. MATCH_EXACT means that the name of the group is matched exactly. MATCH_LEFT means that only the leftmost portion of the group name will be matched (i.e. imagine that the name match has a "*" after it).
  • Add any local user names that should not be created on the destination computer to the dictUsersToIgnore LIST. MATCH_EXACT and MATCH_LEFT have the same meanings as with the dictGroupsNotToCreate list (i.e. "IUSR_" with MATCH_LEFT means that any user account starting with "IUSR_" will not be created on the destination computer).

You must execute this script with credentials that have rights to create accounts on the destination computer.

The properties copied for user accounts, by default, are listed in the dictPropertiesToCopy list. I chose the most common properties.

The script has been tested fairly well, but I haven't used it in a production environment. It makes NO changes to the source server, so you can run it w/o fear of damaging your source server.

(No, the group population algorith isn't effiicent in the slightest. If that bothers you then you know enough already to re-implement it better... >smile<)

share|improve this answer
    
That's a pretty awesome script, thanks! Would this work over the internet? Lets assume the two servers are hosted by different providers? –  Patrick J Collins Jul 9 '09 at 10:22
    
As long as the rights ports are open for RPC, you're properly authenticated to the computers, and you have good name resolution it ought to work on Windows computers "anywhere". –  Evan Anderson Jul 9 '09 at 11:51

In days gone by I used a command line utility from Microsoft that allowed you to dump the accounts, complete with password hashes, to a text faile which could then be imported on another machine. Unfortunately, I can't remember its name.

share|improve this answer

You might give moveuser from the 2003 Resource Kit a try. Reading through, it appears to be designed to move a user between domains, but I can google up references to it being used for local -> domain moves. Makes me wonder if a local-to-local is possible, too.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.