Jump to content

Creating Users With '"' In The Password


Recommended Posts

I am creating standard local users on a large number of computers. I had it working great with an AutoIT script that created a CMD shell external command formatted and executed as follows:

$UserName = Fred
$Password = Wilma
$ExtCommand = 'NET USER ' & '"' & $UserName & ' "' & $Password & '" /ADD'
$ExitCode = RunWait(@ComSpec & ' /c ' & $ExtCommand, @TempDir, @SW_SHOW)

; Should run the follwing in the CMD shell:
;    NET USER "Fred" "Wilma" /ADD

The problem is that the place I get the passwords from requires complex passwords and generates some that contain double quotes. Having a double-quote in the password explodes the CMD shell execution of the NET USER command. If I type or cut-n-paste a password into the GUI local user manager (lusrmgr.msc) it can handle the double-quote, so it is not invalid for a password, just for the CMD shell to handle it. :mellow:

I know I can script the lusrmgr.msc GUI in AutoIT, but wanted to avoid that if possible.

Any great ideas on making this work? :)

Edit: fix typo per cdkid - thnx, but not related to problem...

Edited by PsaltyDS
Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Try this

$UserName = 'Fred'
$Password = 'Wilma'
$ExtCommand = 'NET USER ' & '"' & $UserName & ' "' & $Password & '" /ADD'
$ExitCode = RunWait(@ComSpec & ' /c ' & $ExtCommand, @TempDir, @SW_SHOW)

; Should run the follwing in the CMD shell:
;    NET USER "Fred" "Wilma" /ADD

That will allow for double quotes. Also, it's @ComSpec not @CommandSpec

~cdkid

Edited by cdkid
AutoIt Console written in C#. Write au3 code right at the console :D_FileWriteToLineWrite to a specific line in a file.My UDF Libraries: MySQL UDF Library version 1.6 MySQL Database UDF's for AutoItI have stopped updating the MySQL thread above, all future updates will be on my SVN. The svn location is:kan2.sytes.net/publicsvn/mysqlnote: This will still be available, but due to my new job, and school hours, am no longer developing this udf.My business: www.hirethebrain.com Hire The Brain HireTheBrain.com Computer Consulting, Design, Assembly and RepairOh no! I've commited Scriptocide!
Link to comment
Share on other sites

Try this

$UserName = 'Fred'
$Password = 'Wilma'
$ExtCommand = 'NET USER ' & '"' & $UserName & ' "' & $Password & '" /ADD'
$ExitCode = RunWait(@ComSpec & ' /c ' & $ExtCommand, @TempDir, @SW_SHOW)

; Should run the follwing in the CMD shell:
;    NET USER "Fred" "Wilma" /ADD

That will allow for double quotes. Also, it's @ComSpec not @CommandSpec

~cdkid

Sorry, I didn't post an example of the actual problem. My code above was working fine for passwords without a double-quote in them (@CommandSpec was a typo in my post, not the code). It fails with the double-quote contained in the password. To see the failing example change the password:

$Password = 'Wil"ma'

The double-quote in the middle of the password blows up the CMD shell. I am fully aware that this is Microsoft's problem in their crippled command line, not AuotIT's. Just looking for work-arounds.

Edited by PsaltyDS
Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

  • Moderators

Might not work, I don't know much in this area, but had you tried something like:

$Password = 'Wi"lma'
If StringInStr($Password, '"') Then $Password = StringReplace($Password, '"', '%22')
?

Nah, figured I'd test it.. doesn't work on mine. :)

Edit2:

Well, mine isn't blowing up using cdkid's example even with the 'double quote' in wi"lma. It sets it, and shows in the cmd.exe as wilma.

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

AHAH!!! EUREKA!!! Found it!!! :)

The answer to life, the universe, and everything is NOT 42, it's: AddUsers.exe!

AddUsers reads the user info and password from a CSV file. It might not mind the special characters in the passwords.

Edited by PsaltyDS
Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

  • Developers

here is a script that can do it using the COM object:

You can also add the user to a group and set other info..(currently commented)

; Init objects
$UserName = 'Fred'
$Password = 'Wil"ma'
$oMyError = ObjEvent("AutoIt.Error","MyErrFunc"); Install a custom error handler 
$strComputer = @ComputerName
$colAccounts = ObjGet("WinNT://" & $strComputer & "")
;$objGroup = ObjGet("WinNT://" & $strComputer & "/Users,group")
; Read in lines of text until the EOF is reached
$objUser = $colAccounts.Create("user", $UserName)
$objUser.SetPassword ($Password)
;$objUser.Put ("sn", $SirName)
;$objUser.Put ("givenName", $GivenName)
;$objUser.Put ("displayName", $SirName & ", " & $GivenName)
$objUser.SetInfo
;Add User to group 
;$objGroup.Add($objUser.ADsPath)
;
;
; This is my custom error handler 
Func MyErrFunc() 
   $HexNumber=hex($oMyError.number,8) 
   Msgbox(0,"","We intercepted a COM Error !" & @CRLF & _
                "Number is: " & $HexNumber & @CRLF & _
                "Linenbr is: " & $oMyError.scriptline  & @CRLF & _
                "Description is: " & $oMyError.description  & @CRLF & _
                "Windescription is: " & $oMyError.windescription ) 

   SetError(1); something to check for when this function returns 
Endfunc
Edited by JdeB

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

  • Moderators

That's cool Jdeb... but my password isn't setting this way at all? (The username is though).

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • Developers

That's cool Jdeb... but my password isn't setting this way at all? (The username is though).

Works fine for me... do you have some sort of policy on what passwords are allowed ?

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

here is a script that can do it using the COM object:

You can also add the user to a group and set other info..(currently commented)

CODE
; Init objects

$UserName = 'Fred'

$Password = 'Wil"ma'

$oMyError = ObjEvent("AutoIt.Error","MyErrFunc"); Install a custom error handler

$strComputer = @ComputerName

$colAccounts = ObjGet("WinNT://" & $strComputer & "")

;$objGroup = ObjGet("WinNT://" & $strComputer & "/Users,group")

; Read in lines of text until the EOF is reached

$objUser = $colAccounts.Create("user", $UserName)

$objUser.SetPassword ($Password)

;$objUser.Put ("sn", $SirName)

;$objUser.Put ("givenName", $GivenName)

;$objUser.Put ("displayName", $SirName & ", " & $GivenName)

$objUser.SetInfo

;Add User to group

;$objGroup.Add($objUser.ADsPath)

;

;

; This is my custom error handler

Func MyErrFunc()

$HexNumber=hex($oMyError.number,8)

Msgbox(0,"","We intercepted a COM Error !" & @CRLF & _

"Number is: " & $HexNumber & @CRLF & _

"Linenbr is: " & $oMyError.scriptline & @CRLF & _

"Description is: " & $oMyError.description & @CRLF & _

"Windescription is: " & $oMyError.windescription )

SetError(1); something to check for when this function returns

Endfunc

Cool! Thanks, JdeB! :mellow:

I never would have gone there. Obj calls are still over my head to write, but I have used several from this board with minor tweaks to fit into my scripts. One day I'll get edumacated... :)

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Works fine for me... do you have some sort of policy on what passwords are allowed ?

That's probably the problem. The 'Wil"ma' password will not meet windows complex password requirements. It was just an easy example for the post. The password lists I get that started this thread are generated by an randomizer script and look like:

User1: XErhk2kj8"9a!90k4)&^75djohf#$
User2: XreS58~o0(&49klgfOl"vfrye?5<2

:)

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

  • Moderators

Works fine for me... do you have some sort of policy on what passwords are allowed ?

No, I was able to add the original with Run, but not with COM. Tad weird, but I don't need this type of thing in the near future anyway, so no big deal!! :) ...

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

here is a script that can do it using the COM object:

You can also add the user to a group and set other info..(currently commented)

CODE
; Init objects

$UserName = 'Fred'

$Password = 'Wil"ma'

$oMyError = ObjEvent("AutoIt.Error","MyErrFunc"); Install a custom error handler

$strComputer = @ComputerName

$colAccounts = ObjGet("WinNT://" & $strComputer & "")

;$objGroup = ObjGet("WinNT://" & $strComputer & "/Users,group")

; Read in lines of text until the EOF is reached

$objUser = $colAccounts.Create("user", $UserName)

$objUser.SetPassword ($Password)

;$objUser.Put ("sn", $SirName)

;$objUser.Put ("givenName", $GivenName)

;$objUser.Put ("displayName", $SirName & ", " & $GivenName)

$objUser.SetInfo

;Add User to group

;$objGroup.Add($objUser.ADsPath)

;

;

; This is my custom error handler

Func MyErrFunc()

$HexNumber=hex($oMyError.number,8)

Msgbox(0,"","We intercepted a COM Error !" & @CRLF & _

"Number is: " & $HexNumber & @CRLF & _

"Linenbr is: " & $oMyError.scriptline & @CRLF & _

"Description is: " & $oMyError.description & @CRLF & _

"Windescription is: " & $oMyError.windescription )

SetError(1); something to check for when this function returns

Endfunc

If I might bother you for a clarification... :mellow:

Are there objects in there for "Full Name" and "Description"? Using NET USER from the CMD shell, these would be added by:

/FULLNAME:"John Q. Public" /COMMENT:"This is a public user"

I don't think sir name, given name, and display name from Active Directory are equivelent to Fullname and Description for a local user??? :)

I ran it like this and got errors from those three:

; Init objects
$UserName = 'Fred'
$Password = 'Wi123l"ma!'
$SirName = 'Public'
$GivenName = 'John Q.'
$oMyError = ObjEvent("AutoIt.Error", "MyErrFunc"); Install a custom error handler
$strComputer = @ComputerName
$colAccounts = ObjGet("WinNT://" & $strComputer & "")
;$objGroup = ObjGet("WinNT://" & $strComputer & "/Users,group")
; Read in lines of text until the EOF is reached
$objUser = $colAccounts.Create ("user", $UserName)
$objUser.SetPassword ($Password)
$objUser.Put ("sn", $SirName)
$objUser.Put ("givenName", $GivenName)
$objUser.Put ("displayName", $SirName & ", " & $GivenName)
$objUser.SetInfo
;Add User to group
;$objGroup.Add($objUser.ADsPath)

; This is my custom error handler
Func MyErrFunc()
    $HexNumber = Hex($oMyError.number, 8)
    MsgBox(0, "", "We intercepted a COM Error !" & @CRLF & _
            "Number is: " & $HexNumber & @CRLF & _
            "Linenbr is: " & $oMyError.scriptline & @CRLF & _
            "Description is: " & $oMyError.description & @CRLF & _
            "Windescription is: " & $oMyError.windescription)
    SetError(1); something to check for when this function returns
EndFunc  ;==>MyErrFunc
Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

  • Developers

If I might bother you for a clarification... :mellow:

Are there objects in there for "Full Name" and "Description"? Using NET USER from the CMD shell, these would be added by:

/FULLNAME:"John Q. Public" /COMMENT:"This is a public user"

I don't think sir name, given name, and display name from Active Directory are equivelent to Fullname and Description for a local user??? :)

yea you are right... just tried it and this works locally:

; Init objects
$UserName = 'Fred'
$Password = 'Wil"ma'
$oMyError = ObjEvent("AutoIt.Error","MyErrFunc"); Install a custom error handler 
$strComputer = @ComputerName
$colAccounts = ObjGet("WinNT://" & $strComputer & "")
;$objGroup = ObjGet("WinNT://" & $strComputer & "/Users,group")
; Read in lines of text until the EOF is reached
$objUser = $colAccounts.Create("user", $UserName)
$objUser.SetPassword ($Password)
$objUser.Put ("Fullname", "Test User")
$objUser.Put ("Description", "Test User description")
$objUser.SetInfo

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

yea you are right... just tried it and this works locally:

; Init objects
$UserName = 'Fred'
$Password = 'Wil"ma'
$oMyError = ObjEvent("AutoIt.Error","MyErrFunc"); Install a custom error handler 
$strComputer = @ComputerName
$colAccounts = ObjGet("WinNT://" & $strComputer & "")
;$objGroup = ObjGet("WinNT://" & $strComputer & "/Users,group")
; Read in lines of text until the EOF is reached
$objUser = $colAccounts.Create("user", $UserName)
$objUser.SetPassword ($Password)
$objUser.Put ("Fullname", "Test User")
$objUser.Put ("Description", "Test User description")
$objUser.SetInfo
You officialy rock! Thanks!

:):o:mellow::>:)

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

That's probably the problem. The 'Wil"ma' password will not meet windows complex password requirements. It was just an easy example for the post. The password lists I get that started this thread are generated by an randomizer script and look like:

User1: XErhk2kj8"9a!90k4)&^75djohf#$
User2: XreS58~o0(&49klgfOl"vfrye?5<2

:)

You are attempting to create invalid passwords. These are special characters that @Comspec treats differently to the rest.

The special characters that require quotes are:

<space>

&()[]{}^=;!'+,`~

Link to comment
Share on other sites

You are attempting to create invalid passwords. These are special characters that @Comspec treats differently to the rest.

You are right, of course, about @ComSpec. But the requirement to use these passwords remains. I had no problem whith putting double-quotes around the complex passwords using @ComSpec, but there is one case that does not handle, which is a double-quote in the password itself. Still have no fix for that within @ComSpec, but don't need it anymore, either. :)

With the resource kit, you can use AddUsers.exe and read the parameters from a .CSV file. The only complication there is if there is a comma in the password! :)

What JdeB gave me was a direct call to the Win32 API for user management, if I understand it correctly. Haven't finished testing, but that appears to work for all complex passwords on first blush. :mellow:

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Nice, but what happens if you use Runas at the commandline or use Runas inside Explorer, then your complex usage will not be accepted. Just to say, do not paint yourself into a corner.

The only task in this case is to create local users that will run certain services. These passwords will not be passed to any commandlines, where they would fail for any other command the same as they fail for NET USER. The password files come down from on high, and I have no say in their content, other than they have to be valid passwords for the service accounts. When the service itself is set up, the script will paste the complex password into the "Run service as:" box via the GUI.

:)

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

yea you are right... just tried it and this works locally:

CODE
; Init objects

$UserName = 'Fred'

$Password = 'Wil"ma'

$oMyError = ObjEvent("AutoIt.Error","MyErrFunc"); Install a custom error handler

$strComputer = @ComputerName

$colAccounts = ObjGet("WinNT://" & $strComputer & "")

;$objGroup = ObjGet("WinNT://" & $strComputer & "/Users,group")

; Read in lines of text until the EOF is reached

$objUser = $colAccounts.Create("user", $UserName)

$objUser.SetPassword ($Password)

$objUser.Put ("Fullname", "Test User")

$objUser.Put ("Description", "Test User description")

$objUser.SetInfo

This is how my experimental function wound up. I would appreciate your opinion if the @Error handling is correct. Then function returns 1 for success, 0 for fail, but COM errors from the handler only set @error to 1, if I understand this correctly. So the If statement at the end handles the return code based on @error:

; ========================================================
;   _Add_LocalUser function
; ========================================================
; Call with:  _Add_LocalUser($sNewUsrName, $sNewUsrPass, $sNewUsrFull, $sNewUsrDesc) where:
;   $sNewUsrName = UserName to add
;   $sNewUsrPass = New user's password
;   $sNewUsrFull = (optional) User's full name
;   $sNewUsrDesc = (optional) User's description (comment)
; Returns 1 for success, 0 for fail
Func _Add_LocalUser($sNewUsrName, $sNewUsrPass, $sNewUsrFull = "", $sNewUsrDesc = "")
; Init COM objects
    $oMyError = ObjEvent("AutoIt.Error", "MyErrFunc"); Install a custom error handler
    $strComputer = @ComputerName
    $colAccounts = ObjGet("WinNT://" & $strComputer & "")
; Create user
    $objUser = $colAccounts.Create ("user", $sNewUsrName)
    $objUser.SetPassword ($sNewUsrPass)
    $objUser.Put ("Fullname", $sNewUsrFull)
    $objUser.Put ("Description", $sNewUsrDesc)
    $objUser.SetInfo
    If @error Then
        Return 0
    Else
        Return 1
    EndIf
EndFunc;==>_Add_LocalUser

; Custom COM object error handler
Func ComErrFunc()
    $HexNumber = Hex($oMyError.number, 8)
    MsgBox(16, "AutoIT Error", "AutoIT intercepted a COM Error!" & @CRLF & _
            "Number is: " & $HexNumber & @CRLF & _
            "Linenbr is: " & $oMyError.scriptline & @CRLF & _
            "Description is: " & $oMyError.description & @CRLF & _
            "Windescription is: " & $oMyError.windescription)
    SetError(1); something to check for when this function returns
EndFunc;==>ComErrFunc

Thanks. :)

P.S. Is there some reason the @ComputerName macro should not be used directly? Like this:

$colAccounts = ObjGet("WinNT://" & @ComputerName & "")
Edited by PsaltyDS
Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

  • Developers

This is how my experimental function wound up. I would appreciate your opinion if the @Error handling is correct. Then function returns 1 for success, 0 for fail, but COM errors from the handler only set @error to 1, if I understand this correctly. So the If statement at the end handles the return code based on @error:

I would change the Error handler that it doesn't show a msgbox in case of errors to enable you to run it in batch..:

; Custom COM object error handler
Func ComErrFunc()
    Local $HexNumber = Hex($oMyError.number, 8)
    ConsoleWrite("COM Error!  Number is: " & $HexNumber & "Linenbr is: " & $oMyError.scriptline & _
            "Description is: " & $oMyError.description & "Windescription is: " & $oMyError.windescription)
    SetError(1); something to check for when this function returns
EndFunc;==>ComErrFunc

P.S. Is there some reason the @ComputerName macro should not be used directly? Like this:

$colAccounts = ObjGet("WinNT://" & @ComputerName & "")
No reason really.. this is the same..

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...