Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Help creating local user with script

12 views
Skip to first unread message

Lars Kofod Ibsen

unread,
Jan 20, 2004, 10:58:00 AM1/20/04
to
Hi

I'm a newbi to this scripting thing - I need a script that can create a
local user account with the following options set:

User name - of course ;-))
Full name
Description

User may change password = NO
Password Expire = Never
Password Change= Never

Can you guy's help me out please - I have to create 200-300 users so it
would be a great help and if it not to hard to do is it possible to make it
so you can use it with options (createusr Username password fullname) or
something like that.

I hope you can read my bad english.

Best regards
Lars Ibsen


Richard Mueller [MVP]

unread,
Jan 20, 2004, 4:03:16 PM1/20/04
to
Lars Kofod Ibsen wrote:

> I'm a newbi to this scripting thing - I need a script that can create a
> local user account with the following options set:
>
> User name - of course ;-))
> Full name
> Description
>
> User may change password = NO
> Password Expire = Never
> Password Change= Never
>
> Can you guy's help me out please - I have to create 200-300 users so it
> would be a great help and if it not to hard to do is it possible to make
it
> so you can use it with options (createusr Username password fullname) or
> something like that.

Hi,

I assume you aren't going to create that many users on one computer. If you
plan to create many users on each machine, then you might want to code a
program that reads the values from a text file, instead of passing the
values as parameters on the command line.

You must use the WinNT provider to create local user accounts. The example
VBScript program below accepts 4 parameters. They are username, password,
fullname, and description. Any values with spaces must be enclosed in quote.
The user object is created on the local machine. I hope this helps:

Option Explicit

Dim objComputer, objUser, strComputer
Dim strName, strPassword, strFullName, lngFlag
Dim strDescription, objNetwork

Const ADS_UF_PASSWD_CANT_CHANGE = &H40
Const ADS_UF_DONT_EXPIRE_PASSWD = &H10000

' Check for required arguments.
If Wscript.Arguments.Count <> 4 Then
Wscript.Echo "Error - Wrong number of arguments"
Wscript.Echo "Syntax:"
Wscript.Echo " cscript Create.vbs Name Password FullName Description"
Wscript.Echo "Values with spaces must be in quotes"
Wscript.Quit
End If

' Retrieve local computer name.
Set objNetwork = CreateObject("Wscript.Network")
strComputer = objNetwork.ComputerName

' Assign variables.
strName = Wscript.Arguments(0)
strPassword = Wscript.Arguments(1)
strFullName = Wscript.Arguments(2)
strDescription = Wscript.Arguments(3)

' Bind to local computer object.
Set objComputer = GetObject("WinNT://" & strComputer)

' Create local user.
On Error Resume Next
Err.Clear
Set objUser = objComputer.Create("user", strName)
If Err.Number <> 0 Then
' Error raised.
Err.Clear
On Error GoTo 0
Wscript.Echo "Unable to create user " & strName
Wscript.Quit
End If
On Error GoTo 0

' User created. Assign properties.
If strFullName <> "" Then
objUser.Put "FullName", strFullName
End If
If strDescription <> "" Then
objUser.Put "Description", strDescription
End If

' Save user object.
On Error Resume Next
Err.Clear
objUser.SetInfo
If Err.Number <> 0 Then
' Error raised.
Err.Clear
On Error GoTo 0
Wscript.Echo "Unable to save user " & strName
End If
On Error GoTo 0

' Set user flags.
lngFlag = objUser.Get("UserFlags")
' Set bit so user cannot change their password.
lngFlag = lngFlag Or ADS_UF_PASSWD_CANT_CHANGE
' Set bit so password never expires.
lngFlag = lngFlag Or ADS_UF_DONT_EXPIRE_PASSWD
objUser.Put "UserFlags", lngFlag

' Save user object.
On Error Resume Next
Err.Clear
objUser.SetInfo
If Err.Number <> 0 Then
' Error raised.
Err.Clear
On Error GoTo 0
Wscript.Echo "Unable to save user " & strName
End If
On Error GoTo 0

' Set password.
If strPassword <> "" Then
On Error Resume Next
Err.Clear
objUser.SetPassword strPassword
If Err.Number <> 0 Then
' Error raised.
Err.Clear
On Error GoTo 0
Wscript.Echo "Unable to set password for " & strName
End If
On Error GoTo 0
End If

' Clean up.
Set objUser = Nothing
Set objComputer = Nothing

Wscript.Echo "Done"

--
Richard
Microsoft MVP Scripting and ADSI
HilltopLab web site - http://www.rlmueller.net
--


Torgeir Bakken (MVP)

unread,
Jan 20, 2004, 4:37:57 PM1/20/04
to
Lars Kofod Ibsen wrote:

> I'm a newbi to this scripting thing - I need a script that can create a
> local user account with the following options set:
>
> User name - of course ;-))
> Full name
> Description
>
> User may change password = NO
> Password Expire = Never
> Password Change= Never
>
> Can you guy's help me out please - I have to create 200-300 users so it
> would be a great help and if it not to hard to do is it possible to make it
> so you can use it with options (createusr Username password fullname) or
> something like that.

Hi

' Input parameters needed: username password fullname

' Script will also add the user to the group specified in the
' variable sGroupname ("user" in this example)

Set oArgs = WScript.Arguments
If oArgs.Count <> 3 Then
Wscript.Echo "Error: Wrong number of arguments!"
Wscript.Quit
End If

sNewUser = oArgs(0)
sPassw = oArgs(1)
sFullName = oArgs(2)

Const ADS_UF_DONT_EXPIRE_PASSWD = &h10000
Const ADS_UF_PASSWD_CANT_CHANGE = &H40

Set oWshNet = CreateObject("WScript.Network")
sComputerName = oWshNet.ComputerName

Set oComputer = GetObject("WinNT://" & sComputerName)
Set oUser = oComputer.Create("user", sNewUser)

oUser.SetPassword sPassw

' disable the line below if you have trouble
' and want to see the actual error
On Error Resume Next
' save (create) the user
oUser.Setinfo

' If user exists already, we get an error
If Err.Number = 0 Then
On Error Goto 0

oUser.Fullname = sFullName
oUser.Description = "Some description"

lngFlags = oUser.userFlags
lngFlags = lngFlags Or ADS_UF_PASSWD_CANT_CHANGE
lngFlags = lngFlags Or ADS_UF_DONT_EXPIRE_PASSWD
oUser.userFlags = lngFlags
oUser.Setinfo
Else
WScript.Echo "Error: Could not create user"
WScript.Quit
End If
On Error Goto 0


sGroupname = "Users"
' Add the user to the group
Set oGroup = GetObject("WinNT://" & sComputerName & "/" & sGroupname)

' Use error handling in case he is a member already
On Error Resume Next
oGroup.Add(oUser.ADsPath)
On Error Goto 0


--
torgeir
Microsoft MVP Scripting and WMI, Porsgrunn Norway
Administration scripting examples and an ONLINE version of the 1328 page
Scripting Guide: http://www.microsoft.com/technet/scriptcenter


Torgeir Bakken (MVP)

unread,
Jan 20, 2004, 5:27:07 PM1/20/04
to
Some notes inline...

"Richard Mueller [MVP]" wrote:

> (snip)


> ' Create local user.
> On Error Resume Next
> Err.Clear

Not important, but "On Error Resume Next" and "On Error Goto 0" are also an
implicit "Err.Clear", so a Err.Clear line after On Error Resume Next/Goto 0 is
redundant.


> Set objUser = objComputer.Create("user", strName)
> If Err.Number <> 0 Then

There is no point in doing an error test here, because the instruction above
will never err. It is first when a .SetInfo instruction is done that any errors
will show up (because it is then all the user properties is evaluated.


> (snip put of FullName/Description)


>
> ' Save user object.
> On Error Resume Next
> Err.Clear
> objUser.SetInfo

Note that if a complex password policy is set, this .SetInfo will err. To avoid
that, always do the "objUser.SetPassword strPassword" instruction before the
first .SetInfo


> (snip)


>
> ' Set password.
> If strPassword <> "" Then
> On Error Resume Next
> Err.Clear
> objUser.SetPassword strPassword

I think a "objUser.SetInfo" line is needed here...


> If Err.Number <> 0 Then
> ' Error raised.
> Err.Clear
> On Error GoTo 0
> Wscript.Echo "Unable to set password for " & strName
> End If
> On Error GoTo 0
> End If
>
> ' Clean up.
> Set objUser = Nothing
> Set objComputer = Nothing
>
> Wscript.Echo "Done"

I took the liberty to rewrite your script based on the comments above (and also
put the "UserFlags" setting part into a "Else" so the script wouldn't try to set
them even if the user couldn't be saved in the first place):


Option Explicit

' Create local user.


Set objUser = objComputer.Create("user", strName)

' User created. Set password.
objUser.SetPassword strPassword

' Assign properties.


If strFullName <> "" Then
objUser.Put "FullName", strFullName
End If
If strDescription <> "" Then
objUser.Put "Description", strDescription
End If

' Save user object.
On Error Resume Next

objUser.SetInfo
If Err.Number <> 0 Then
' Error raised.

On Error GoTo 0
Wscript.Echo "Unable to create user " & strName

Else


On Error GoTo 0
' Set user flags.
lngFlag = objUser.Get("UserFlags")
' Set bit so user cannot change their password.
lngFlag = lngFlag Or ADS_UF_PASSWD_CANT_CHANGE
' Set bit so password never expires.
lngFlag = lngFlag Or ADS_UF_DONT_EXPIRE_PASSWD
objUser.Put "UserFlags", lngFlag

' Save user object.
On Error Resume Next

objUser.SetInfo
If Err.Number <> 0 Then
' Error raised.

On Error GoTo 0
Wscript.Echo "Unable to save user's UserFlags" & strName


End If
On Error GoTo 0
End If

' Clean up.
Set objUser = Nothing
Set objComputer = Nothing

Wscript.Echo "Done"

--

Lars Kofod Ibsen

unread,
Jan 21, 2004, 4:11:06 AM1/21/04
to
Thanks for the scripts - they work like a dream.

regards
Lars Ibsen
"Torgeir Bakken (MVP)" <Torgeir.B...@hydro.com> wrote in message
news:400D9FB5...@hydro.com...

scott

unread,
Jan 21, 2004, 4:40:18 AM1/21/04
to
Nice script!
What would i need to change to set No Expiry on the Password for existing
accounts?

Regards,
Scott.

"Torgeir Bakken (MVP)" <Torgeir.B...@hydro.com> wrote in message

news:400DAB3A...@hydro.com...

Richard Mueller [MVP]

unread,
Jan 21, 2004, 12:09:28 PM1/21/04
to
Torgeir,

Thanks for the comments. I very much appreciate it. Comments inline below.

"Torgeir Bakken (MVP)" <Torgeir.B...@hydro.com> wrote in message
news:400DAB3A...@hydro.com...

> Some notes inline...
>
> "Richard Mueller [MVP]" wrote:
>
> > (snip)
> > ' Create local user.
> > On Error Resume Next
> > Err.Clear
>
> Not important, but "On Error Resume Next" and "On Error Goto 0" are also
an
> implicit "Err.Clear", so a Err.Clear line after On Error Resume Next/Goto
0 is
> redundant.

I didn't know this, but testing proves you correct. I developed the habit of
using "Err.Clear" after "On Error" statements from Tim Hill's "Windows
Script Host".

> > Set objUser = objComputer.Create("user", strName)
> > If Err.Number <> 0 Then
>
> There is no point in doing an error test here, because the instruction
above
> will never err. It is first when a .SetInfo instruction is done that any
errors
> will show up (because it is then all the user properties is evaluated.

I believe you are correct. I thought an invalid value for strName would
raise an error (invalid characters for example), but testing proves this
isn't
the case. No matter how illegal the name, the error is only raised when
SetInfo if called.

> > (snip put of FullName/Description)
> >
> > ' Save user object.
> > On Error Resume Next
> > Err.Clear
> > objUser.SetInfo
>
> Note that if a complex password policy is set, this .SetInfo will err. To
avoid
> that, always do the "objUser.SetPassword strPassword" instruction before
the
> first .SetInfo

I was going to disagree, but testing proves you correct again (at least for
local accounts). Sources, such as Thomas Eck's "Windows NT/2000 ADSI
Scripting for System Administration" state "SetPassword is an immediate
operation. The account must exist before attempting any password
manipulation function calls". Now, however, I find in "Microsoft Windows
2000 Scripting Guide" that this only applies to domain accounts. This text
says "A password cannot be assigned until after you use the SetInfo method
to commit a user account to Active Directory." But in a Note, it says "In
contrast to Active Directory accounts, strict password policy configured for
local user accounts on Windows 2000 nondomain controllers requires that
SetPassword be called prior to SetInfo". At least I don't have to revise my
code to create domain accounts.

> > (snip)
> >
> > ' Set password.
> > If strPassword <> "" Then
> > On Error Resume Next
> > Err.Clear
> > objUser.SetPassword strPassword
>
> I think a "objUser.SetInfo" line is needed here...

When creating domain accounts in Active Directory, the SetPassword method
operates directly on the user object in AD. A call to SetInfo is not
required. For local accounts, SetInfo is required if any attributes are
modified. I'm not sure about after a SetPassword, but it can't hurt.

> > If Err.Number <> 0 Then
> > ' Error raised.
> > Err.Clear
> > On Error GoTo 0
> > Wscript.Echo "Unable to set password for " & strName
> > End If
> > On Error GoTo 0
> > End If
> >
> > ' Clean up.
> > Set objUser = Nothing
> > Set objComputer = Nothing
> >
> > Wscript.Echo "Done"
>
> I took the liberty to rewrite your script based on the comments above (and
also
> put the "UserFlags" setting part into a "Else" so the script wouldn't try
to set
> them even if the user couldn't be saved in the first place):

You are right. I attempted to modify "UserFlags" even if the account could
not be created.

Once again, I have learned things in the newsgroups I probably would have
never learned on my own.

Richard Mueller [MVP]

unread,
Jan 21, 2004, 12:48:47 PM1/21/04
to
Scott wrote:

> Nice script!
> What would i need to change to set No Expiry on the Password for existing
> accounts?

Hi,

The procedure (for a local user account) would be to bind to the user object
using the WinNT provider, retrieve the value of the "UserFlags" attribute,
"Or" this value with the bit mask for ADS_UF_DONT_EXPIRE_PASSWD (which sets
the bit), write the new value back to the object, and save the object by
calling the SetInfo method. For example, assuming the account is on the
local computer, the program below prompts for the user name. It only sets
the bit if it is not already set. You "And" "UserFlags" with the bit mask to
test if it is set (any result other than zero means the bit is set):

Option Explicit

Dim objUser, strComputer
Dim strName, lngFlag
Dim objNetwork

Const ADS_UF_DONT_EXPIRE_PASSWD = &H10000

strName = InputBox("Enter the username to set password never expires")

' Retrieve local computer name.
Set objNetwork = CreateObject("Wscript.Network")
strComputer = objNetwork.ComputerName

' Bind to local user.
On Error GoTo 0
Set objUser = GetObject("WinNT://" & strComputer & "/" & strName & ",user")
If Err.Number <> 0 Then


Err.Clear
On Error GoTo 0

Wscript.Echo "User " & strName & " not found"
Wscript.Quit


End If
On Error GoTo 0

' Test user flags for password never expire.


lngFlag = objUser.Get("UserFlags")

If (lngFlag And ADS_UF_DONT_EXPIRE_PASSWD) = 0 Then
' Bit not set, so set the bit.


lngFlag = lngFlag Or ADS_UF_DONT_EXPIRE_PASSWD
objUser.Put "UserFlags", lngFlag
' Save user object.
On Error Resume Next
objUser.SetInfo
If Err.Number <> 0 Then
' Error raised.
On Error GoTo 0
Wscript.Echo "Unable to save user's UserFlags " & strName

Else
On Error GoTo 0

Wscript.Echo "Password set to never expire for " & strName


End If
On Error GoTo 0

Else
Wscript.Echo "User already has password never expires"
End If

' Clean up.
Set objUser = Nothing

Wscript.Echo "Done"

To do this for all local accounts, you can enumerate the user objects in a
loop and operate on each as above. For example, the snippet below loops
through all users accounts on the local machine.

Set objComputer = GetObject("WinNT://" & strComputer)

objComputer.Filter = Array("user")
For Each objUser In objComputer
' Set password never expires bit for each user.
Next

Michael Harris \(MVP\)

unread,
Jan 21, 2004, 8:58:46 PM1/21/04
to
> Once again, I have learned things in the newsgroups I probably would
> have never learned on my own.


I'd say that 90% of what I have learned about scripting since I started way
back in 1998 has come from either research for answering NG questions or
reading the many excellent (and often creative) examples posted by others...

The rest has come from surfing the documentation, snooping typelibs with
object browsers, and experimentation (read as: a *lot* of trial and
error!!!)...

--
Michael Harris
Microsoft.MVP.Scripting

scott

unread,
Jan 22, 2004, 4:40:33 AM1/22/04
to
Very helpful again. Thank very much!

"Richard Mueller [MVP]" <rlmuelle...@ameritech.NOSPAM.net> wrote in
message news:%23lZcbdE...@tk2msftngp13.phx.gbl...

Al Dunbar [MS-MVP]

unread,
Jan 22, 2004, 2:34:55 PM1/22/04
to

"Richard Mueller [MVP]" <rlmuelle...@ameritech.NOSPAM.net> wrote in
message news:eAMScHE4...@TK2MSFTNGP12.phx.gbl...

> Torgeir,
>
> Thanks for the comments. I very much appreciate it. Comments inline below.
>
> "Torgeir Bakken (MVP)" <Torgeir.B...@hydro.com> wrote in message
> news:400DAB3A...@hydro.com...

<snip>

> > > Set objUser = objComputer.Create("user", strName)
> > > If Err.Number <> 0 Then
> >
> > There is no point in doing an error test here, because the instruction
> above
> > will never err. It is first when a .SetInfo instruction is done that any
> errors
> > will show up (because it is then all the user properties is evaluated.
>
> I believe you are correct. I thought an invalid value for strName would
> raise an error (invalid characters for example), but testing proves this
> isn't
> the case. No matter how illegal the name, the error is only raised when
> SetInfo if called.

Sometimes it is possible to know whether or not it is possible for a
statement to err - sometimes not. Better to assume it might than to spend a
lot of time testing all of the possibilities...

<snip>

> > I took the liberty to rewrite your script based on the comments above
(and
> also
> > put the "UserFlags" setting part into a "Else" so the script wouldn't
try
> to set
> > them even if the user couldn't be saved in the first place):
>
> You are right. I attempted to modify "UserFlags" even if the account could
> not be created.
>
> Once again, I have learned things in the newsgroups I probably would have
> never learned on my own.

Well, if Richard is still learning this stuff, I will feel much better the
next time I find I had some of it wrong. ;-)

/Al


0 new messages