# Updating the Vista password hint via command line



## scrfix (May 3, 2009)

Does anyone know of a command or method of updating the Vista Password Hint via the command line?

I can accomplish this in XP (supposedly. I have not tested the theory yet) but Vista saves its password hints encrypted in the SAM file.

I would prefer to accomplish this in a batch format however am open to other methods if they are available from the command line without having to confirm in a GUI. I need this to be accomplished in the Vista environment just like if you went to change password and updated the hint.

Thanks,


----------



## TheOutcaste (Aug 8, 2007)

It can be done in a batch file, but it won't be easy.


 Can only be done from an Elevated Prompt
 You need the Original Account name or the SID for the account you wish to change.
Just need the last part of the SID:
S-1-5-21-1234567890-1234567890-1234567890-*1000*
 The new password hint must be converted to a hexadecimal Unicode value.
You create a scheduled task to run under the System account, that will call a batch file to check the registry and make the changes. So you'll have to wait up to a minute for the file to run.
If the Username (or display name) contain any special characters, or Unicode characters not supported in the Command Prompt, you'll have to use the SID to change the Hint -- and the Hint can't contain any special characters
You can get the Original account name for the current user from the Username variable, but if you want to change the hint for a different account, you'll have to do it the hard way.

If you don't know for sure if you have the original name, you need to enumerate each name under this key:
HKLM\SAM\SAM\Domains\Account\Users\Names
Convert it to a hexadecimal Unicode string, then search the V value under it's corresponding Key in this tree:
HKLM\SAM\SAM\Domains\Account\Users
For that string, then check to see if it has a Display name that matches.
I've found where the length of the Original name and the Display name are stored, but haven't found how they indicate the start of the name. I suspect they parse the key using the length of each item, so it doesn't actually have a pointer. The ones I checked all started between 0x180 and 0x1A0, so you would start searching at position 700 or so.

For example, I create an account named TheOutcaste. I change it to MyOutcaste
To find the original name, I first convert MyOutcaste to 4D0079004F007500740063006100730074006500.
I read each key under HKLM\SAM\SAM\Domains\Account\Users\Names to get the name, and the Account number, and convert the name to a hexadecimal Unicode string
So I'll eventually find the Name TheOutcaste.
I have to convert TheOutcaste to
5400680065004F0075007400630061007300740065000000
The Name key tells me it's account 1000, so it's key is 000003E8
Search the V value under HKLM\SAM\SAM\Domains\Account\Users\000003E8 for the above Unicode value, then see if it's immediately followed by the Display name I'm looking for:
4D0079004F007500740063006100730074006500
If it's there, I can change the UserPasswordHint value under the HKLM\SAM\SAM\Domains\Account\Users\000003E8 to the New value.
If the New value is "This is new" I'd replace it with this:
540068006900730020006900730020006e0065007700.

You'll need to use a file to return the status of the change, and have the first batch file wait for that file to be created.

And to run the file under the system account, you'd use this:

```
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: cpsystem.cmd
:: Start Command Prompt under System account in one minute from now
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Setlocal
Set hour=%time:~,2%
Set minH=%time:~3,1%
Set /a minl=%time:~4,1%+1
If %minl% GTR 9 Set minl=0& Set /a minh=minh+1
If %minh% GTR 5 Set MinH=0& Set /a hour=hour+1
If %hour% GTR 23 Set hour=0
at %hour%:%minh%%minl% cmd.exe /C C:\Scripts\test.cmd TypeofData "UserName|SID|DisplayName" "newhint"
```
Test.cmd is the file to run under the System account.
TypeofData would be a flag to indicate if the next value is a Username, SID, or DisplayName
I haven't yet tested passing variables, so that might need some tweaking.

Another option would be to include subinacl.exe, which let's you change Registry permissions. Run it to save the current permissions, add the Administrator account, granting R/W access to the SAM key, make the changes, the restore the permissions.

Now if only I could get a batch file to mow the grass...


----------



## scrfix (May 3, 2009)

Ok,

First of all. Wow. I searched everywhere for any type of answer on this. Thank You. Could Microsoft have made this any more difficult?

A little more detail about what I am doing so we can narrow this down.
1. I only need to change the current active user's password hint.
2. I can overwrite the elevated command prompt so that it does not ask by changing ConsentPromptBehaviorAdmin to 0.
3. I would like to accomplish this without having to restart the computer so whichever is easier, converting everything to hex unicode or utilizing subinacl.exe.

I was actually looking into utilizing subinacl.exe for other items however I have never utilized it so do not have the first clue on what it can actually do.

About the SAM entries in the registry. I do not have anything past HKLM/SAM/SAM There are no folders or entries past that.

Why will it take a full minute? I can run the password hint in a separate batch while I am working on my other items and maintenance of the computers.

Knowing the above, do you feel the best solution is to go with subinacl.exe OR to convert the current username and work from there?

Batch file to mow the grass. Yeah that would be nice.


----------



## TheOutcaste (Aug 8, 2007)

scrfix said:


> 1. I only need to change the current active user's password hint.
> 2. I can overwrite the elevated command prompt so that it does not ask by changing ConsentPromptBehaviorAdmin to 0.
> 3. I would like to accomplish this without having to restart the computer so whichever is easier, converting everything to hex unicode or utilizing subinacl.exe.


1. That makes it much easier. You can get the correct username from the %username% variable. Then just get the Account number, convert the New passphrase, and change it.
2. Haven't tried that, but that should do it. Not sure if it will work from a Standard account though. Not sure if a Standard account is allowed to run the AT command.
3. Either way the entry is in hexadecimal and unicode.



scrfix said:


> I was actually looking into utilizing subinacl.exe for other items however I have never utilized it so do not have the first clue on what it can actually do.


 I barely know how to use it myself. It got tons of options. Just haven't used it enough to do much without the instructions in one hand.



scrfix said:


> About the SAM entries in the registry. I do not have anything past HKLM/SAM/SAM There are no folders or entries past that.


Right click the 2nd SAM, click permissions, then add your account. Full control if you want to change anything, read only is fine just to look. Then when done looking just remove your account from the permissions.



scrfix said:


> Why will it take a full minute? I can run the password hint in a separate batch while I am working on my other items and maintenance of the computers.


You have to schedule the 2nd batch to run with the AT command. Soonest you can schedule is *Now + 1 minute*, so it will take anywhere from 1-60 seconds to start. Don't have to wait for it to finish, but should create and check a results file to make sure there were no errors. More for if you are having to search to find the Account name from the Display name, and it didn't find a match for some reason. Just changing the Current Account shouldn't be a problem, unless registry permissions are messed up. But in that case it probably wouldn't let you log in, so it's not likely.


----------



## scrfix (May 3, 2009)

I tried looking up AT command and could only find old 1997 modem commands and other sorts. What exactly is an AT command and what do I use to perform one?

So, if I have to right click and add permissions to be able to see those in the registry then how do you change the permissions in the registry through batch if I am going to have to repeat this. Is this the part you were talking about utilizing subinacl.exe?

Why couldn't microsoft just leave it easy and keep it in the registry in plain text like xp? It's a password hint. It doesn't need to be encrypted.


----------



## scrfix (May 3, 2009)

I downloaded subinacl.exe and went to the .htm file.
It says the following:
*System Requirements*

The following are the system requirements for SubInACL: 

Windows XP Professional or Windows Server 2003 operating system
Before I waste what will ultimately be your time and mine and anyone reading this thread on this, not that anyone but myself will ever want to change the Vista password hint via the command line... lol Will this run for windows Vista?

There is absolutely NO documentation anywhere including the Microsoft website on this subject. How do you even know this information?


----------



## scrfix (May 3, 2009)

ok.

Thanks to Jerry, we now have our steps to accomplish this task. This is a little bit confusing for me as I am going in to uncharted territory and as I understand everything that you have written, I am confused about certain aspects of it. I am going to presume from what I have read that subinacl.exe does not work in Vista properly so there is no sense is wasting your time or anyone else's going that route. Let's go the hard way. If you find differently, please let me know.

1. Can only be done from an Elevated Prompt
*Response: This step has been accomplished*

2. You need the Original Account name or the SID for the account you wish to change.
Just need the last part of the SID:
S-1-5-21-1234567890-1234567890-1234567890-1000 
*Response: Where do I get this information from?*

3. The new password hint must be converted to a hexadecimal Unicode value.
*Response: What can I use to perform this task?*

4. You create a scheduled task to run under the System account, that will call a batch file to check the registry and make the changes. So you'll have to wait up to a minute for the file to run.
*Response: Although, I have not completed this task before, I have done a lot of studying on this particular portion of creating tasks. This should be fairly straight forward. Is this what you were calling an AT command?*

*Notes:* If the Username (or display name) contain any special characters, or Unicode characters not supported in the Command Prompt, you'll have to use the SID to change the Hint -- and the Hint can't contain any special characters.

You can get the Original account name for the current user from the Username variable, but if you want to change the hint for a different account, you'll have to do it the hard way.
*Response: If the people have changed their username would the %username% variable not just display the username they changed it to and not their original account name?*

*This only needs to be done for the current user running the script.*

5. If you don't know for sure if you have the original name, you need to enumerate each name under this key:
HKLM\SAM\SAM\Domains\Account\Users\Names
*Response: This statement now becomes null and void because we are using the %username% variable, correct?*

*If that is not a correct presumption then that means that I have to change the permissions inside that registry entry so that I can add the current user to be able to view and change and view that entry above. How do I accomplish this? I know that I can take ownership. I don't know how to add the permissions via the command line.*

*I am presuming by enumerate you mean list each name under that key. This would be done with the dreaded FOR statement dun dun dun... (in walks death stage right.)*

6. Convert it to a hexadecimal Unicode string, then search the V value under it's corresponding Key in this tree:
HKLM\SAM\SAM\Domains\Account\Users
*Response: You state convert it to a hexidecimal unicode string. Which item? If I am listing all of the values above, which one do I convert?*
*Is this statement now null and void since I just need to change the hint for the current user and we can use the %username% variable or is this still necessary?*

7. For that string, then check to see if it has a Display name that matches.
*Response: What are we matching it up against?*

Notes: I've found where the length of the Original name and the Display name are stored, but haven't found how they indicate the start of the name. I suspect they parse the key using the length of each item, so it doesn't actually have a pointer. The ones I checked all started between 0x180 and 0x1A0, so you would start searching at position 700 or so.
*Response: Completely Lost Here. I understood everything up to this point with questions. I do not understand this statement.*

Note 1: For example, I create an account named TheOutcaste. I change it to MyOutcaste
*Response: Ok, you went to the GUI, created an account named TheOutcaste, signed in to that account and then changed the name to MyOutcaste.*

Note 2: To find the original name, I first convert MyOutcaste to 4D0079004F007500740063006100730074006500.
*Response: How did you convert this?*

Note 3: I read each key under HKLM\SAM\SAM\Domains\Account\Users\Names to get the name, and the Account number, and convert the name to a hexadecimal Unicode string
So I'll eventually find the Name TheOutcaste.
*Response: How did you accomplish this?*
*How did you get past the fact that you need to change the security permissions to be able to even see past HKLM/SAM/SAM?*

Note 4: I have to convert TheOutcaste to
5400680065004F0075007400630061007300740065000000
*Response: How did you accomplish this?*

Note 5: The Name key tells me it's account 1000, so it's key is 000003E8
*Response: Where did we get 1000? How are you able to tell this? Where did 000003E8 come from?*

Note 6: Search the V value under HKLM\SAM\SAM\Domains\Account\Users\000003E8 for the above Unicode value, then see if it's immediately followed by the Display name I'm looking for:
4D0079004F007500740063006100730074006500
*Response: When you state V value, do you mean the /v REG_SZValue or DWordNameHere? If so, which V value am I searching for?*

*The display name meaning the %username% variable we were looking for and stored earlier, correct?*

Note 7: If it's there, I can change the UserPasswordHint value under the HKLM\SAM\SAM\Domains\Account\Users\000003E8 to the New value.
If the New value is "This is new" I'd replace it with this:
540068006900730020006900730020006e0065007700.
*Response: If it is not there then what?*
*How did you convert the "This is new" to 540068006900730020006900730020006e0065007700?*

Note 8: You'll need to use a file to return the status of the change, and have the first batch file wait for that file to be created.
*Response: Why do I need a separate file?*
*Does it matter what type of file?*
*Would I utilize the delay command in order to wait for this file or is there a better way?*

*Code Provided:* 
And to run the file under the system account, you'd use this:


```
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: cpsystem.cmd
:: Start Command Prompt under System account in one minute from now
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Setlocal
Set hour=%time:~,2%
Set minH=%time:~3,1%
Set /a minl=%time:~4,1%+1
If %minl% GTR 9 Set minl=0& Set /a minh=minh+1
If %minh% GTR 5 Set MinH=0& Set /a hour=hour+1
If %hour% GTR 23 Set hour=0
at %hour%:%minh%%minl% cmd.exe /C C:\Scripts\test.cmd TypeofData "UserName|SID|DisplayName" "newhint"
```
Test.cmd is the file to run under the System account.
TypeofData would be a flag to indicate if the next value is a Username, SID, or DisplayName
I haven't yet tested passing variables, so that might need some tweaking.
*Response: Okay, is this the AT command that you were talking about?*
*I am not sure what this is actually for or how to utilize it. However it is at the end of this track so I am going to come back to this one later. Perhaps by then I will understand why we need this.*


----------



## Squashman (Apr 4, 2003)

```
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

H:\>at /?
The AT command schedules commands and programs to run on a computer at
a specified time and date. The Schedule service must be running to use
the AT command.

AT [\\computername] [ [id] [/DELETE] | /DELETE [/YES]]
AT [\\computername] time [/INTERACTIVE]
    [ /EVERY:date[,...] | /NEXT:date[,...]] "command"

\\computername     Specifies a remote computer. Commands are scheduled on the
                   local computer if this parameter is omitted.
id                 Is an identification number assigned to a scheduled
                   command.
/delete            Cancels a scheduled command. If id is omitted, all the
                   scheduled commands on the computer are canceled.
/yes               Used with cancel all jobs command when no further
                   confirmation is desired.
time               Specifies the time when command is to run.
/interactive       Allows the job to interact with the desktop of the user
                   who is logged on at the time the job runs.
/every:date[,...]  Runs the command on each specified day(s) of the week or
                   month. If date is omitted, the current day of the month
                   is assumed.
/next:date[,...]   Runs the specified command on the next occurrence of the
                   day (for example, next Thursday).  If date is omitted, the
                   current day of the month is assumed.
"command"          Is the Windows NT command, or batch program to be run.


H:\>
```


----------



## scrfix (May 3, 2009)

Squashman,

Thanks. I did not know about the AT command. I was studying the schtasks command.

Are they the same thing?
Is one more effecient and more powerful than the other?
Which one would you suggest utilizing?
Is AT supported in XP as well to schedule tasks?


----------



## Squashman (Apr 4, 2003)

Squashman said:


> ```
> Microsoft Windows XP [Version 5.1.2600]
> (C) Copyright 1985-2001 Microsoft Corp.
> 
> ...





scrfix said:


> Is AT supported in XP as well to schedule tasks?


----------



## TheOutcaste (Aug 8, 2007)

scrfix said:


> I tried looking up AT command and could only find old 1997 modem commands and other sorts. What exactly is an AT command and what do I use to perform one?
> 
> So, if I have to right click and add permissions to be able to see those in the registry then how do you change the permissions in the registry through batch if I am going to have to repeat this. Is this the part you were talking about utilizing subinacl.exe?
> 
> Why couldn't microsoft just leave it easy and keep it in the registry in plain text like xp? It's a password hint. It doesn't need to be encrypted.


AT /? in a command prompt, which Squashman has posted.
Note that the /interactive switch does not work in Vista
On XP, *Start | Help and Support*, search for *command line reference*.
Vista help doesn't have this, but does find links to the online guides:
XP Command-line reference A-Z
Server 2008/Vista Command-line reference A-Z
Note: AT is not in the list in the right pane, but is in the tree in the left pane.

AT is the original NT Task Scheduler, before they had a GUI interface. Let's you tell the PC "At this time do this command". Guess they couldn't think of a fancy name so just named it AT
Tasks scheduled with the AT command run under the System account. The System already has full access to those keys, so no need to change permissions.
You can see the difference on an XP system.


Open Regedit, navigate to HKLM\SAM\SAM
It will appear empty
close regedit
Run the following and wait for a Command prompt window to open
Note the Title shows Windows\system32\svchost.exe
Type Set
Note there is no USERNAME variable and UserProfile points to C:\Documents and Settings\NetworkService
Type Regedit and navigate to the above key. You'll have full access.


```
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: cpsystem.cmd
:: Start Command Prompt under System account in one minute from now
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Setlocal
Set hour=%time:~,2%
Set minH=%time:~3,1%
Set /a minl=%time:~4,1%+1
If %minl% GTR 9 Set minl=0& Set /a minh=minh+1
If %minh% GTR 5 Set MinH=0& Set /a hour=hour+1
If %hour% GTR 23 Set hour=0
at %hour%:%minh%%minl% /interactive cmd.exe
```
This won't work on Vista as they've blocked the /interactive feature:* Warning: Due to security enhancements, this task will run at the time
expected but not interactively.
Use schtasks.exe utility if interactive task is required ('schtasks /?'
for details).*​If you have Task Manager open, set to show processes from all users, you'll see a *cmd.exe* process start, running under the user *System*. But no window will appear as that's not allowed any more. But you can still run batch files and will have full access to things users accounts normally don't.

Another difference. On XP, unless you specify */every* or */next* with multiple dates, the command is deleted after it runs. On Vista, it is not deleted. So would need to capture the job number so it can be deleted when done, just in case the PC has a task scheduled with the AT command they want to keep, or check first to see if any AT jobs exist
Tasks created with AT are named *ATX*, with *X* an incrementing number.


----------



## TheOutcaste (Aug 8, 2007)

2. The SID can be read from the ProfileList key in the registry. Have to know the Original Account name to get the proper SID though.
3. Check each character in the string against a string of all characters to get an index number.
The Letter A is Ascii 65 or 0x41. In Unicode it would be 0x0041. It's stored in the registry low byte first, so it would be seen as 4100.
This following code just checks for A-Z. You'd have to check for lowercase and any special characters like punctuation or accented characters like é but this is the basic process. This will work for the characters in the Terminal Font, but won't work with other characters like this: **
This is entered with ALT+0158 and it's unicode value is 017E.
I can enter  in the batch file in notepad++ and it displays correctly, but when typed to the screen in the command prompt it shows differently. The Command Prompt uses the Terminal font; that character displays as ALT+158, which is different than ALT+0158.
Entering ALT+0158 at a Set /P prompt shows the character as a z, but it can't be found.
You can use the Character Map utility (Accessories\SystemTools) to see what characters are usable.

```
SetLocal EnableDelayedExpansion
Set _Str=MYNAME
Set _Alphabet=ABCDEFGHIJKLMNOPQRSTUVWXYZ
Set _Hex=0123456789ABCDEF
Set _Pos=0
Set _UniStr=
:_Convert
Set _Index=-1
:_Loop
Set /A _Index+=1
If "!_Str:~%_Pos%,1!"=="" Goto _Done
If Not "!_Str:~%_Pos%,1!"=="!_Alphabet:~%_Index%,1!" Goto _Loop
Set /A _Index=_Index+65
Set /A _H1=_Index/16
Set /A _H2=_Index-_H1*16
Set _UniStr=%_UniStr%!_Hex:~%_H1%,1!!_Hex:~%_H2%,1!00
Set /A _Pos+=1
Goto _Convert
:_Done
Echo String=%_Str%
Echo Converted String is %_UniStr%
```
I've got a routine that I think works for all characters except %. The % has to be entered twice. Still testing...

4. Yes, create the task using the AT command, not schtasks
The %Username% variable shows the account name, not the Display name (See Screenshot 1)
5. Yes, just need the %username% variable
Don't have to change permissions, the AT task runs under the System account which already has the needed permissions.
However, Vista does let you easily change this. If you open the Task Scheduler (*Administrative Tools | Task Scheduler*), click *Action | AT Service Account Configuration*, this let's you change it so it runs under a User Account instead of the System Account. Not likely on a home system, but it's possible on a workplace PC that this has been changed to increase security.
Yes, our friend the For loop. It will still be needed to read the account ID number so we can find the correct key that holds the password hint for this account.

For the rest, it's not needed if we are just changing the current users hint.
If you haven't actually seen the Keys in the SAM tree it's hard to follow.
See screenshot#2
The Default value for my account

```
HKEY_LOCAL_MACHINE\SAM\SAM\Domains\Account\Users\Names\TheOutcaste
```
shows a Type of 0x3e8
When read using Reg Query it will be shown as 1000 (0x3E8=1000)
Convert the 1000 back to hex (3E8) and pad with zeros to get the key name for the account here:

```
HKEY_LOCAL_MACHINE\SAM\SAM\Domains\Account\Users
```
Screenshot 3 shows the 000003E8 key, with the *UserPasswordHint* value and the *V* key I was talking about.
Doesn't matter if the *UserPasswordHint* doesn't exist, we are just going to add/replace it with a reg add command with the new hint (converted of course) as the data.

As the file that does this change is running under the System account, and is not allowed to interact with the user, you can't pass variables back; you have to save them in a file, which the main file can then read. The file can be named anything, but will be a text file. All it needs is a success/fail line so we know if an error occurred. You can also output all errors to this file if desired.
Couple ways to wait for it to finish.
Check to see if the result file has been created. This would only work if it's created as the last step, not for capturing errors. Can always use two files, one for errors and one for pass/fail.
Check to see if the CMD.EXE process running under the System account has ended using Tasklist and capturing the output.(Another For loop)
* tasklist /FI "IMAGENAME eq CMD.EXE" /FI "SESSIONNAME eq SERVICES"*
You'd want to use a delay so it doesn't hog the CPU checking. Don't know how long the task would take, but shouldn't be too long, especially if the main batch does all the prep work of converting the new hint string. Then all the 2nd batch has to do is read the account key, convert the number to the hex key name and make the change, report pass/fail, and exit.
Should be just a few seconds.
When done, would then need to delete the task it created. Best to capture the output of the AT command to get the ID number. (Another For loop)


----------



## scrfix (May 3, 2009)

I discovered today that changing the behavior prevents the annoying UAC do you want to do this from showing up however does not elevate command lines. The command line prompts are still without elevation so that means that we will have to turn UAC off which will need a reboot of the computer. Grrr.

Unless there is a different method?


----------



## Squashman (Apr 4, 2003)

I wonder if an Encrypted RunAS program would work? Have never tested them on Vista.


----------



## scrfix (May 3, 2009)

I did not look up an Encrypted RanAs however I did look up RunAs on Google (Search was opening an elevated command prompt from a command prompt) and other people have attempted it and they get an error.

I did not attempt it myself.


----------



## Squashman (Apr 4, 2003)

So you don't want the user to have to click the Continue button when the UAC box pops up?


----------



## scrfix (May 3, 2009)

My ultimate goal is to be able to change the password hint from the command line in Vista.

Now in order to accomplish this we need an elevated command prompt. This is where the problem lies.

I was going to utilize the ConsentPromptBehaviorAdmin registry entry which works perfectly on anything GUI however it does not open up an Administrative Command Prompt so therefore this is no longer an option.

The goal here would be to open an elevated command prompt without having to turn off UAC so that I can utilize the above entry to disable UAC without rebooting the computer and open an elevated command prompt to change the password hint.


----------



## Squashman (Apr 4, 2003)

Well from this link:
http://www.winhelponline.com/articles/185/1/VBScripts-and-UAC-elevation.html
It looks like you can wrap your batch file inside a Vbscript but it will still prompt for UAC and the user would have to click continue.


```
Set objShell = CreateObject("Shell.Application")
Set FSO = CreateObject("Scripting.FileSystemObject")
strPath = FSO.GetParentFolderName (WScript.ScriptFullName)
If FSO.FileExists(strPath & "\Hint.bat") Then
     objShell.ShellExecute "cmd.exe", _ 
        "/c " & Chr(34) & strPath & "\Hint.bat" & Chr(34), "", "runas", 1
Else
     MsgBox "Hint.bat not found"
End If
```
I can't test this right now as I am not at home. See what it does for you.


----------



## scrfix (May 3, 2009)

I am in the same boat. I am onsite at a clients right now. I will be back home around midnight. I can try it then. The clicking OK might be an issue. I am attempting to do this without any interaction but will see if I can utilize that. Perhaps I can automate the click.


----------



## scrfix (May 3, 2009)

Okay,

Here is what I decided to do about that. There are a ton of optimization settings in the computer that I personally set for these computers.

I will build a bat file that optimizes those settings and also turns off UAC. When I do that I will disable that stupid security warning telling you that UAC is turned off. I can then set a scheduled task to run an exe one time upon startup of the computer. This will be the real BAT file that can change the Vista Hint to what I want along with a ton of other items. When the computer reboots, it will then run that file.


----------



## TheOutcaste (Aug 8, 2007)

Squashman said:


> Well from this link:
> http://www.winhelponline.com/articles/185/1/VBScripts-and-UAC-elevation.html
> It looks like you can wrap your batch file inside a Vbscript but it will still prompt for UAC and the user would have to click continue.


Nice find! My Googlefoo must have been on vacation yesterday.
I did come up with pretty much the same thing though, a bit more generalized so you can pass the batch file name and a command line using variables.
And if you set *ConsentPromptBehaviorAdmin* to 0, you don't have to click Continue, it will just run elevated.

```
Set objShell = CreateObject("Shell.Application")
Set objWSShell = WScript.CreateObject("WScript.Shell")
Set objWSProcessEnv = objWSShell.Environment("PROCESS")

StrApplication = objWSProcessEnv("_Cmd")
StrCmdLine = objWSProcessEnv("_CmdLine")
'WScript.Echo "Cmd is " & StrApplication
'WScript.Echo "CmdLine is " & StrCmdLine
objShell.ShellExecute strApplication, strCmdLine, "", "runas"
```
You can also set the file to run hidden, minimized, or normal, (plus a few others) but haven't added that yet.
So right now I have the Main batch file that sets some variables, sets *ConsentPromptBehaviorAdmin* to 0, calls the script to run a 2nd batch file elevated. The 2nd batch then uses AT to schedule a 3rd batch file to run that will be able to access the registry and change the hint. The 2nd batch waits for the 3rd to finish, then deletes the AT job that was created.

I've finally gotten a batch routine that will convert any character from space to ~ to it's ASCII value, including the special characters that cause so much trouble in batch files.
Just need to finish the decimal to hex conversion to convert the new hint string and to get the proper key name from the SAM database.
Then just need to create the script and the 2nd and 3rd batch files on the fly so you'll still have just one file. And if created on the fly, won't need to pass variables

Also found another way to do this. If you call a shortcut that has been set to Run as Administrator from the Command Prompt, it uses the GUI to get consent, so setting *ConsentPromptBehaviorAdmin* to 0 will let it run elevated without prompting.

Found one method to create shortcuts using an INF file (at least for XP, but should work for Vista), but don't know how to set the *Run As Administrator* setting. So you would have to create a shortcut first, then copy it along with the batch file. If you change the target of the shortcut to use variables, you can copy the shortcut to any system, set the variables, and run most anything elevated.


----------



## scrfix (May 3, 2009)

Did I say you guys were good? Hell, you guys are brilliant. I did not have a chance to test that. I got in around 2am this morning and now am out to another appointment. Hopefully I will have time to test it tomorrow.

I say again, could Microsoft have made this any harder?

*Updated*
I found that run as administrator in the advanced as well. I looked for where that is located but could not find it however I did not search tremedously hard as I was working at clients locations all day just like I will be today. Another come back at 2am day again.

I was actually writing that in and then I saw the post from Squashman so I ended up erasing it because I figured that was probably a better avenue to pursue. However if I can do the shortcut and do that from the same bat file without having to send variables back and forth between files, that would be wonderful.

I just found this however have not attempted it yet. I have to head off to work. Not sure if this helps at all however it creates a context menu and adds the Open as administrator in the right click menu. Not sure if that can be used or not.
http://www.walkernews.net/2007/05/21/open-command-prompt-here-with-elevated-privilege/

I am not sure if the following is an additional program that needs to be installed or if he is talking about an actual command prompt:
http://code.kliu.org/cmdopen/faq.html
How do I disable the "Open Elevated Command Prompt" menu item?The "Open Elevated Command Prompt" menu item is visible only if your version of Windows supports UAC and UAC is enabled.This menu item can be manually disabled and hidden with a registry key; to set this key, run the following command from a command prompt:reg add "HKCU\Software\CmdOpen" /v "NoUAC" /t REG_DWORD /d 1To undo this and restore the menu item, run the command again with the 1 changed to a 0. This is a per-user setting; to make this a machine-wide setting, use HKLM instead of HKCU.

I am looking for a guy in a forum that gave us an awesome code and I didn't realize I had my history states only set to 20. This is code that at the time, I didn't think would work however put together with what we have found, it would be perfect. It has something to do with runas adminsitrator %1, etc etc with the command prompt.

I cannot find it. I will keep looking when I come back. I did find this in a comment section of another website however if it helps:
http://www.howtogeek.com/howto/windows-vista/use-command-prompt-here-in-windows-vista/
To open a command prompt with admin rights (i.e. "as administrator"), just change the "cmd.exe /k %L" portion to "cmd.exe /s /k %L"
You can create all sorts of shell extensions this way. I use Process Explorer (the Sysinternals tool) and show the column "command line" which shows the full path and commandline args used for what ever process you want to duplicate.
Of course, regarding the command prompt with "run as admin" rights, there's the built-in shift-right-click method, but I personally prefer adding the 2nd shell extension so I don't HAVE to use both hands (i.e. the shift key). Whom ever said that "necessity is the mother of all invention" hasn't got a handle on reality yet and figured out that laziness is the mother of all invention.









Thank You,


----------



## scrfix (May 3, 2009)

I worked all weekend and was not available to look this over. I am going to try to look this over this week.

I could not find that code I was looking for to post. I searched and searched and searched. No go.


----------



## scrfix (May 3, 2009)

Jerry, Squashman,

Does it not make sense that if we can do this for the right click, we should be able to do this for the command prompt?

http://www.winhelponline.com/articl...elevated-Command-Prompt-in-Windows-Vista.html

How would we accomplish this for the command prompt? This seems a much simpler method of getting an elevated command prompt.


----------



## scrfix (May 3, 2009)

I found this as well done in power shell. It is a little more than the vbwrap however just thought I would post it here: 
Source: http://www.vistax64.com/powershell/213927-elevation-command-line.html


```
#requires -version 2.0
function global:Sudo {
## In order to use this, you have to
## Create a "Scheduled Task" named "Elevated powershell.exe" to run
## PowerShell -Command "exit"
## The scheduled task must be set to "Run with highest privileges"
## NOTE: THIS IS A [URL="http://www.vistax64.com/#"][COLOR=#3676a2][COLOR=#3676a2 !important][FONT=verdana][COLOR=#3676a2 !important][FONT=verdana]SECURITY [/FONT][/FONT][/COLOR][FONT=verdana][COLOR=#3676a2 !important][FONT=verdana]RISK[/FONT][/color][/FONT][/color][/color][/URL].
## You should at least set it to run only when you're logged on
## I also do NOT set it to run "Hidden" so I always know.
######################################################################
##### You could create that with a script: [URL="http://poshcode.org/907"][COLOR=#3676a2]http://poshcode.org/907[/COLOR][/URL]
## New-ElevatedTask $((gcm PowerShell | ls).FullName) `
## '-Command "exit"' -TaskName "Elevated PowerShell"
######################################################################
[CmdletBinding()]
Param(
[Parameter(ValueFromRemainingArguments=$true)]
$command=$(Read-Host "You must specify a command")
)
 
$SchTasks = ls ([Environment]::GetFolderPath("System")) schtasks.exe
$SchTasks = $SchTasks.FullName
$TaskName = '"Elevated PowerShell"'
 
$AllProfile = Join-Path $(Split-Path $Profile) "Profile.ps1"
$OutputXml = Join-Path $(Split-Path $Profile) "SudoOutput.psxml"
$OutputErr = Join-Path $(Split-Path $Profile) "SudoOutput.err"
$command = $($command -join " ") + " 2> $OutputErr |
Export-CliXml $OutputXml"
 
$donecheck = {
Get-WinEvent -LogName Microsoft-Windows-TaskScheduler/Operational `
-FilterXPath "*[System[TimeCreated[timediff(@SystemTime) <= 2500]]
and EventData[@Name='TaskSuccessEvent'
and Data[@Name='TaskName']='\Elevated PowerShell']]" `
-ErrorAction "SilentlyContinue"
}
 
 
## Append our command to the end of the profile script ...
## But make sure we remove any sig block at the end first
$script = gc $AllProfile
 
Set-Content $AllProfile @"
$(($script -notmatch "^\s*#") -join "`n")
Remove-Item $OutputXml -ErrorAction "SilentlyContinue"
Write-Host "$Command" -Fore Cyan
$Command
"@
 
$result = &$SchTasks /Run /TN $TaskName
if($result -notmatch "^SUCCESS") {
Write-Error $result
} else {
while(!(&$donecheck)) { sleep 1 }
}
 
$ErrorActionPreference = "SilentlyContinue"
Import-CliXml $OutputXml
 
Write-Warning $(@(Get-Content $OutputErr) -join "`n")
Remove-Item $OutputXml
Remove-Item $OutputErr
 
Set-Content $AllProfile $script
 
}
```
I also found the following script for powershell. Is powershell installed by default in Vista?


```
function sudo ([string]$file, [string]$arguments) {
$psi = new-object System.Diagnostics.ProcessStartInfo $file;
$psi.Arguments = $arguments;
$psi.Verb = "runas";
$psi.WorkingDirectory = get-location;
[System.Diagnostics.Process]::Start($psi);
}

usage:
sudo notepad
sudo secpol.msc
```


----------



## scrfix (May 3, 2009)

I found another program as well called Elevate. It even comes with the source code.

With ConsentPromptBehaviorAdmin sent to 0 and calling this program, it takes approximately 49 seconds to open a new window with administrative privileges.

What I don't know is if we can utilize this to run the program to change the Vista Hint.

http://www.wintellect.com/CS/blogs/...e-a-process-at-the-command-line-in-vista.aspx

Extremely easy Elevate -k cmd.exe

If we do the following:
Elevate -k cmd title admin

It opens immediately. I believe this will work for elevation.

Jerry, will this work for your idea?
How can we utilize this program since it opens a new window with the administrative command line. I wonder if I can utilize this to open an elevated command prompt from the batch itself or the compiled batch somehow?


----------



## TheOutcaste (Aug 8, 2007)

scrfix said:


> With ConsentPromptBehaviorAdmin sent to 0 and calling this program, it takes approximately 49 seconds to open a new window with administrative privileges.


Wow, that's pretty slow. The VBScript takes about 2.5 seconds to open an elevated command prompt and start a batch file.

I've got this working now, just need to get the Ascii to hex conversion working properly for all printable characters. I finally got it working for the special characters !"%&><and ^, converting to decimal, just need to organize it a bit and add the hex conversion.


----------



## scrfix (May 3, 2009)

It was only 49 seconds because I was using the cmd.exe in the command. As soon as I changed that to:

Elevate -k cmd title admin

everything worked instantly.

I just didn't know if we could then continue to utilize this however I had some thoughts.

I create a bat that calls the program as such Elevate -k mybatfile.bat. This should elevate that particular bat file into an elevated command prompt window. Have not tested it however or viewed what adverse or undesired effects this would have.


----------



## TheOutcaste (Aug 8, 2007)

That should work, same as the script Squashman posted and the one I did. They all use ShellExecute with the RunAs verb.

The following seems to be working finally. I'm not sure if you can copy and paste because of the special characters is the Ascii to Hex routine. I've got it working with all printable characters from the command prompt, from space to *~* (32-126) and the extended characters (128-255) (Entered in a prompt using ALT+XXX).
There's room to speed up the conversion by checking lower case characters first (I suspect lower case characters will be more common) and punctuation and extended characters last. Or do that part in a VBScript as it has a built in ASC function.
Example Times per character:
space - .01-.03 seconds
Capital A - .15 seconds
Capital *Z* - .25 seconds
Lower case *z* - .40 seconds.

It's all one file, it creates the other three files then deletes them when finished.
Double click the file, it will prompt for the new hint. It will then disable the UAC prompt if it's enabled, so you do have to click continue just once to do that, then it can be left to it's own devices.
After it finishes whatever other processing you add, it checks to make sure the hint has been changed, then resets the UAC behavior to it's previous state and deletes the files it created (comment line 87 to keep the files).
The Prompt window that creates the scheduled task is displayed so you can see what it's doing. It can be hidden (or minimized) by changing line 66 to use *vHidden* (or *vMin*) instead of *vNormal*

```
@Echo Off
Setlocal
:: Define variables for VBScript
Set _Cmd=%ComSpec%
Set _vHidden=0
Set _vNormal=1
Set _vMin=2
:: Define variables needed for converting the hint
Set _H1=0123456789ABCDEF
Call :_Define _alphabet
:: File names to use. Can use same folder as Main (%~dp0), or a temp folder, spaces OK
:: These use the batchfile name as a base (%~dpn0
Set _AsAdmin=%~dpn0Elevate.vbs
Set _CreateAT=%~dpn0Schedule.cmd
Set _SetHint=%~dpn0ChangeHint.cmd
Set _StatFile=%~dpn0StatusMessage.txt
Set _ErrFile=%~dpn0ErrorFlag.txt
:: Name of user whose hint we will set
Set _User=%Username%
:: Uncomment the next line to test with a non-existant name
::Set _User=Invalid Username
:: Get New Password Hint
:_AskHint
Set _Hint=
Set /P _Hint=Enter New Password Hint for %_User%: 
If Not Defined _Hint Goto _AskHint
:: Create the VBScript that will let us Run As Admin
Call :_MakeFile0
:: Turn Off UAC. First get current Admim Approval setting, if already off, don't need to change it.
:: Get Current Consent Prompt setting
Set _AAMKey=HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System
Set _AAMValue=ConsentPromptBehaviorAdmin
For /F "Tokens=3 skip=1" %%I In ('Reg Query "%_AAMKey%" /V %_AAMValue%') Do Set /A _CurCPBA=%%I
If %_CurCPBA%==0x0 Goto _AAMSet
Set _CmdLine=/S /C "Reg Add "%_AAMKey%" /V %_AAMValue% /T REG_DWORD /D 0 /F"
Set _vShow=%_vHidden%
:: Must wait for User to click Continue, or the next file that needs elevation may start too soon
Start /W WScript //nologo "%_AsAdmin%"
:_AAMSet
:: Convert the password hint to hex format
SetLocal DisableDelayedExpansion
Set i=0
Set _NewHint=
:_ConvertLoop
Call Set _AscTmp="%%_Hint:~%i%,1%%
If ^%_AscTmp:~1,1%]==^"] Set _vAscHex=22&Goto:_ConvertWrite
If "%_AscTmp:~1,1%"=="" Goto _ConvertDone
If ^%_AscTmp:~1,1%==^%% Set _vAscHex=25&Goto:_ConvertWrite
If ^%_AscTmp:~1,1%==^^ Set _vAscHex=5E&Goto:_ConvertWrite
Call :_ASC "%_AscTmp:~1,1%" _vAscHex
:_ConvertWrite
Set _NewHint=%_NewHint%%_vAscHex%00
Set /A i+=1
Goto _ConvertLoop
:_ConvertDone
EndLocal&Set _NewHint=%_NewHint%
:: Delete the error flag file if it exists, then create the two files
:: MakeFile1 creates the file that will change the hint.
:: It runs in a hidden System Session so it will have access to the SAM key
:: MakeFile2 creates the scheduler file that will use AT to schedule the Hidden system task
If Exist "%_StatFile%" Del "%_StatFile%"
Call :_MakeFile1
Call :_MakeFile2
Set _CmdLine=/S /C ""%_CreateAT%" "%_SetHint%" "%_User%""
:: Use _vHidden if you want to hide the scheduler window
Set _vShow=%_vNormal%
Start WScript //nologo "%_AsAdmin%"
:: More stuff can go here to be done while waiting for the scheduled task to run.
::
:: When all is done, check to see if the Hint hgas been changed.
:: The file %_StatFile% will exist if it's done
:: Check if PW Hint was changed without error
:_CkStatus
ping 1.0.0.0 -n 1 -w 1000>Nul
If NOT Exist "%_StatFile%" Goto _CkStatus
:: Wait one second just in case the file has just been created, but not yet written to
ping 1.0.0.0 -n 1 -w 1000>Nul
Type "%_StatFile%
:: Reset previous ConsentPrompt setting if it wasn't 0
If %_CurCPBA%==0x0 Goto _Cleanup
Set _CmdLine=/S /C "Reg Add "%_AAMKey%" /V %_AAMValue% /T REG_DWORD /D %_CurCPBA% /F"
Set _vShow=%_vHidden%
:: Need to wait here or you might delete the script before it runs
Start /W WScript //nologo "%_AsAdmin%"
:_Cleanup
:: Delete the created files
For %%I In ("%_SetHint%" "%_CreateAT%" "%_StatFile%" "%_ErrFile%" "%_AsAdmin%") Do If Exist %%I Del %%I /F /Q
Goto :EOF
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Subroutines
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:_MakeFile0
:: Create WSH Script File to run CMD as Admin
>"%_AsAdmin%" Echo.Set objShell = CreateObject("Shell.Application")
>>"%_AsAdmin%" Echo.Set objWSShell = WScript.CreateObject("WScript.Shell")
>>"%_AsAdmin%" Echo.Set objWSProcessEnv = objWSShell.Environment("PROCESS")
>>"%_AsAdmin%" Echo.StrApplication = objWSProcessEnv("_Cmd")
>>"%_AsAdmin%" Echo.StrCmdLine = objWSProcessEnv("_CmdLine")
>>"%_AsAdmin%" Echo.vWindow = objWSProcessEnv("_vShow")
>>"%_AsAdmin%" Echo.Select Case vWindow
>>"%_AsAdmin%" Echo.  Case 0
>>"%_AsAdmin%" Echo.    vShow = 0
>>"%_AsAdmin%" Echo.  Case 1
>>"%_AsAdmin%" Echo.    vShow = 1
>>"%_AsAdmin%" Echo.  Case 2
>>"%_AsAdmin%" Echo.    vShow = 2
>>"%_AsAdmin%" Echo.  Case 3
>>"%_AsAdmin%" Echo.    vShow = 3
>>"%_AsAdmin%" Echo.  Case Else
>>"%_AsAdmin%" Echo.    vShow = 0
>>"%_AsAdmin%" Echo.End Select
>>"%_AsAdmin%" Echo.objShell.ShellExecute strApplication, strCmdLine, "", "runas", vShow
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:_MakeFile1
:: Create File to change the Hint
SetLocal DisableDelayedExpansion
>"%_SetHint%" Echo.SetLocal EnableDelayedExpansion
>>"%_SetHint%" Echo.Set _User=%%~1
>>"%_SetHint%" Echo.Set _ID=
>>"%_SetHint%" Echo.For /F "Tokens=3 Skip=1 Delims=() " %%%%I In ('Reg Query "HKLM\SAM\SAM\Domains\Account\Users\Names\%%_User%%" /ve /z') Do Set _ID=%%%%I
>>"%_SetHint%" Echo.If Defined _ID Goto _ConvertID
>>"%_SetHint%" Echo.^>"%_ErrFile%" Echo.User Name "%%_User%%" was not found. Unable to change Password Hint
>>"%_SetHint%" Echo.EndLocal
>>"%_SetHint%" Echo.Goto :EOF
>>"%_SetHint%" Echo.:_ConvertID
>>"%_SetHint%" Echo.Set _H1=0123456789ABCDEF
>>"%_SetHint%" Echo.Set /a _n0=%%_ID%%/268435456
>>"%_SetHint%" Echo.Set /a _n1=%%_ID%%%%%%268435456/16777216
>>"%_SetHint%" Echo.Set /a _n2=%%_ID%%%%%%268435456%%%%16777216/1048576
>>"%_SetHint%" Echo.Set /a _n3=%%_ID%%%%%%268435456%%%%16777216%%%%1048576/65536
>>"%_SetHint%" Echo.Set /a _n4=%%_ID%%%%%%268435456%%%%16777216%%%%1048576%%%%65536/4096
>>"%_SetHint%" Echo.Set /a _n5=%%_ID%%%%%%268435456%%%%16777216%%%%1048576%%%%65536%%%%4096/256
>>"%_SetHint%" Echo.Set /a _n6=%%_ID%%%%%%268435456%%%%16777216%%%%1048576%%%%65536%%%%4096%%%%256/16
>>"%_SetHint%" Echo.Set /a _n7=%%_ID%%%%%%268435456%%%%16777216%%%%1048576%%%%65536%%%%4096%%%%256%%%%16
>>"%_SetHint%" Echo.Set _H0=!_H1:~%%_n0%%,1!!_H1:~%%_n1%%,1!!_H1:~%%_n2%%,1!!_H1:~%%_n3%%,1!!_H1:~%%_n4%%,1!!_H1:~%%_n5%%,1!!_H1:~%%_n6%%,1!!_H1:~%%_n7%%,1!
>>"%_SetHint%" Echo.Reg Add "HKLM\SAM\SAM\Domains\Account\Users\%%_H0%%" /V UserPasswordHint /T REG_BINARY /D %_NewHint% /F
>>"%_SetHint%" Echo.EndLocal
EndLocal&Goto :EOF
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:_MakeFile2
:: Create the file to schedule the task to change the hint
>"%_CreateAT%" Echo.SetLocal
>>"%_CreateAT%" Echo.Set _SetHint=%%~s1
>>"%_CreateAT%" Echo.Set _User=%%~2
>>"%_CreateAT%" Echo.Set _Delay=1
>>"%_CreateAT%" Echo.Set _Time=%%time%%
>>"%_CreateAT%" Echo.Set _Hour=%%_Time:~,2%%
>>"%_CreateAT%" Echo.Set _minH=%%_Time:~3,1%%
>>"%_CreateAT%" Echo.Set _sec=%%_Time:~6,2%%
>>"%_CreateAT%" Echo.If %%_sec%% GEQ 58 Set _Delay=2
>>"%_CreateAT%" Echo.Set /a _minL=%%_Time:~4,1%%+_Delay
>>"%_CreateAT%" Echo.If %%_minL%% GTR 9 Set /a _minL=_minL-10^& Set /a _minH=_minH+1
>>"%_CreateAT%" Echo.If %%_minH%% GTR 5 Set _minH=0^& Set /a _Hour=_Hour+1
>>"%_CreateAT%" Echo.If %%_Hour%% GTR 23 Set _Hour=0
>>"%_CreateAT%" Echo.If Exist "%_ErrFile%" Del "%_ErrFile%"
>>"%_CreateAT%" Echo.For /F "Tokens=2 Delims==" %%%%I In ('AT %%_Hour%%:%%_minH%%%%_minL%% /interactive %ComSpec% /S /C %%_SetHint%% "%%_User%%"') Do Set /A _JobID=%%%%I
>>"%_CreateAT%" Echo.:_Wait
>>"%_CreateAT%" Echo.Set _JobRun=
>>"%_CreateAT%" Echo.ping 1.0.0.0 -n 1 -w 5000^>Nul
>>"%_CreateAT%" Echo.For /F "Tokens=1 Skip=2" %%%%I In ('AT %%_JobID%%') Do @Set /A _JobRun=%%%%I
>>"%_CreateAT%" Echo.If Defined _JobRun Goto _Wait
>>"%_CreateAT%" Echo.AT %%_JobID%% /Delete
>>"%_CreateAT%" Echo.If Exist "%_ErrFile%" (
>>"%_CreateAT%" Echo.^>"%_StatFile%" Type "%_ErrFile%"
>>"%_CreateAT%" Echo.) Else (
>>"%_CreateAT%" Echo.^>"%_StatFile%" Echo.Password Hint has been changed
>>"%_CreateAT%" Echo.)
>>"%_CreateAT%" Echo.Endlocal
Goto:EOF
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:_Define
:: Define the Ascii string. The extended characters will not appear the same in notepad as in the command prompt
SetLocal DisableDelayedExpansion
Set _alphabet= !"#$%%&'()*+,-./0123456789:;<=>[email protected][\]^_`abcdefghijklmnopqrstuvwxyz{|}~  ¡¢£¤¥¦§¨©ª«¬*®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ"
EndLocal&Set %1=^%_alphabet%&Goto :EOF
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:_ASC
:: Convert passed character to it's hex ascii value
:: can't pass %, ", or ^ to this function.
SetLocal EnableDelayedExpansion
Set j=0
:_ASC_Loop
Set _ASCTest=^!_alphabet:~%j%,1!
If ^%_ASCTest%==^%~1 Set /A _var=j+32& Goto _ASC_END
If %j% GEQ 287 Set _var=0& Goto _ASC_END
Set /A j+=1
Goto _ASC_Loop
:_ASC_END
Set /a _n0=%_var%%%256/16
Set /a _n1=%_var%%%16
Set _var=!_H1:~%_n0%,1!!_H1:~%_n1%,1!
EndLocal&Set %2=%_var%&Goto :EOF
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
```


----------



## scrfix (May 3, 2009)

OMG!!! All just to change the stupid hint in Vista... lol

Thank You.

Damn... I will start breaking this down probably this weekend.


----------



## Squashman (Apr 4, 2003)

Not worth it if you ask me. Why do you want to do this anyways.


----------



## TheOutcaste (Aug 8, 2007)

The hardest part of all that is converting the text to the hexadecimal format that is in the registry for that key. It just dawned on me that the only reason for that is because the current type is REG_BINARY.
If you make it a string (REG_SZ) no conversion is needed, and it seems to work just fine. No guarantees that changing the type won't have some effect down the road, though I can't think of any reason the type would matter. The type chosen for a key is more for the convenience of the application that will read it than anything else.

So the whole converting part isn't really needed, but at least I got an ASC function that works with anything now.

Using the User Accounts Control Panel to change the hint just changes it back to a REG_BINARY format.

EDIT: Though thinking further, you'd be back to having trouble with the special characters.


----------



## TheOutcaste (Aug 8, 2007)

Turns out a bunch of IF statements are much faster for checking and converting the entered characters. Plus you can easily tweak it to check characters in any order, say lower case first.
Entering all 233 characters from ASC(32) to ASC(255) in sequence, it's 520% faster (97.8 seconds down to 18.8).
For the line *The Quick Brown Fox Jumped Over the Lazy DOGG!!!&* it's 815% faster (9.62 seconds down to 1.18).
Version 0.2 attached.


----------



## scrfix (May 3, 2009)

Squashman,

To answer your question. I have a client that has a workgroup of computers. That client has me change the passwords on all of those computers every month and every time an employee leaves. These computers include both XP Home computers to Vista Basic computers so not all of them have secpol.msc with them to set password changes every so often.

They are not on a server so I cannot set changes that way either.

So I wrote a script that would change the passwords to predesignated passwords every month and left the list with the owner of the business so I would not need to be called for this.

However then I was still getting called for what the passwords were when the owner was not around so I came up with utilizing the password hint to tell them what their password was and then having them change the hint after they log in.

This is where it started.

Jerry,

I will test Version 0.2 as soon as I get back to that client which will probably not be for another couple of weeks. Thank you again. I will mark this as solved.


----------



## Squashman (Apr 4, 2003)

Umm, you can force them to change their passwords with a registry setting. So why bother doing it for them.
http://support.microsoft.com/kb/555540

They actually need you to change a password when an employee leaves? Are they that incompetent. If so, I am moving down by you so that I can have a cake walk job like you.


----------



## scrfix (May 3, 2009)

I was not aware that it could be forced on those operating systems within the registry. I searched and searched and could not find anything on that. Everything came back as it cannot be done on XP Home, so I went the other route instead.

You have got to be kidding me. I looked everywhere for anything like that. That is definitely a thousand times easier but could not find it hence setting up the scripts. Everything I searched all of the forums came back and said, sorry you cannot do that. That is not available in XP Home. Cannot accomplish that.

net user %username% %password% worked absolutely fantastic.
Even the registry entry for XP worked flawlessly and then came Vista! Dun Dun Dun.... started searching and searching and searching and nothing, nothing, nothing. 

Ha Ha Ha Ha! Yes. I have a ton of jobs where the clients absolutely refuse to do anything on their computers without my say so, even Windows updates. That is not all of my jobs, those are just a select few. When it comes to computers, I will do anything they want as long as they are paying me and it is legal.


----------



## TheOutcaste (Aug 8, 2007)

You can use *Net Accounts* from the CP to set the following for all accounts:
Minimum password age - prevents them from repeatedly changing the password to get around the password history limit.
Maximum password age
Minimum password length
Password History (UniquePW) - Number of unique passwords before one can be repeated.
I haven't tested this on XP Home or Vista Basic/Home as I haven't gotten around to creating a VM with those yet, but it should work. If not, you'll have to add the settings to the registry.

The *User must change password at next logon* setting is in the SAM tree, so setting that would be about the same complexity as changing the Hint. Though if you are going to put the password in the hint, you should set this so they don't forget to change it as the hint is visible to everyone. This setting will force them to change the password, but doesn't afford the opportunity to change the hint.

I don't see the use of this though, as this changes the hint for the Current User -- which means they are already logged on and don't need it. You'd need to be able to change the hint for a user that is not logged on, which would involve determining the true account name, or having a list of account names for each PC already encoded in the file so you know which hint key to change.
Plus, the hint would have to be typed in, meaning they have to already know the password to use this. You could put the passwords in a file, but if it's readable to the script, whomever is running the script can read the file. Unless you are going to pre-encode them as unicode strings, but that's not that hard to figure out. And every time a password is changed, the file would have to be updated.

And since running the script requires either being logged in to an Admin account, or knowing an Admin password, that person could just go in and change the password for an account if they don't know it. Just hope they have exported their encryption keys, and/or have set up a recovery agent, because changing the password in that manner will make encrypted files unaccessible if they can't import the encryption key.


----------



## scrfix (May 3, 2009)

Jerry,

I just attempted to utilize the code. UAC still comes up upon executing the code. If UAC is already turned on, it denies access to the registry so I cannot set consentpromptbehavioradmin to 0 before running it via the command prompt.

Any ideas?


----------



## scrfix (May 3, 2009)

I think I may have found a way to get around the very first UAC prompt and how we can turn it off.

http://cybernetnews.com/helpful-tip-disable-uac-for-a-program-in-vista/

This guy uses the schtasks to get around it. He sets them up to get around the prompt.

I am wondering if we can set up a schtasks to run the reg command to set consentpromptbehavioradmin to 0 and then run the rest of the batch?

I have not tested this yet and probably will not be able to tonight. I will not be near a computer for the next 4 days or so unless of course I take my laptop on vacation with me. 

Just an idea from searching. Sounds feasible.


----------



## TheOutcaste (Aug 8, 2007)

TheOutcaste said:


> Double click the file, it will prompt for the new hint. It will then disable the UAC prompt if it's enabled, *so you do have to click continue just once* to do that, then it can be left to it's own devices.


If UAC is enabled you will have one prompt so that you can disable UAC.
You can manually edit the registry, which requires an OK on a UAC prompt to run Regedit.
You can install the Elevate Me context entry you linked, which requires an OK on a UAC prompt to install, then requires you to right click and choose elevate me to run an item. Don't know if this would let a Limited User run the file though, which could be a security risk.
You can just run the batch file, which requires an OK on a UAC prompt.
You can create a scheduled task on each PC to run the batch file, which requires an OK on a UAC prompt to start the Task Scheduler.

There is no way around it if UAC is enabled.
If that's the first part of the batch file, you start it, click OK on the UAC prompt, then the file can do everything else.


----------

