Windows 10 setup, if not slipstreamed (or automated), will try to trick you into establishing a Microsoft account. If you dodged it (by disconnecting from internet and have it try to set up a local account), you are still required to set up an account OTHER than “Administrator” (built-in account) itself and the built-in administrator account is disabled out of the box. Microsoft consider administrator account (in Linux world, root) bad practices so they are eager to make it difficult for you to do it the old fashioned way (like in Windows 2000, NT 4 and before).
I was able to fight this with NTlite, but even NTlite does not account for all scenarios, and I’ve devised a little scripting to have it do exactly what I wanted (use built-in admin account and ask user to establish the password for it) out of the box.
In NTlite, to enable the built-in administrator account, you’ll have to click the “Add local account” button at the ribbon (menu) bar:
then check “Enable built-in Administrator using this account”. Here’s where I run into a bunch of dilemma because of the unspoken rules (implied behavior in NTLite by doing this):
- If you enter a password for the account, NTLite will record it in your .xml file for the Presets which is littered in NTLite’s program folder. You don’t really want your administrator in plain text anywhere! This will also make the installation image non-generic that other people cannot benefit from it.
- If you do not enter a password, it’ll be treated as a blank password, which in Windows 10, if you have an account with a blank password, the system will log you on automatically! It’s also dangerous to have a blank password for administrator by default, forget that you need to change the password and walk away with it!
- If you do not ‘create’ the ‘Administrator’ account with the password, whether it’s blank of user-defined (which is weird because the built-in administrator account is already there, just disabled) with NTLite (and just activate it with
net user administrator /active:yes
in post-setup commands), Windows setup will force you to make a user account because you will have no active accounts available until AFTER setup (if you choose to enable the built-in admin account afterwards). This design choice makes sense because I’ve screwed up before without activating the built-in admin account at the end as a script and got locked out and had to use a recovery disk to enable the built-in admin account, but painful to those who know what they are doing! - Technically you can choose to suppress any prompts and risk screwing up the output image like I did locking myself out by having no active accounts in the slipstreamed configuration. This is done by enabling “SkipMachineOOBE”, however I choose to set it to false because I want automatic Windows update at the end:
With a blank built-in administrator password established above by NTLite, Windows will boot automatically into Administrator account without prompts for passwords. I’ve looked up many methods to force Windows to ask the user to establish the password during or right after installation, and here’s a few paths I explored that didn’t work
- account password expiration: the number of days to expire is shared across all accounts
- “User must change password at next login” do not have simple commands to change the property either with “net user” or “wmic”. Nearly every property can be controlled with “net user” or “wmic” except this one, which has to go through Powershell to access ‘PasswordExpired’ property (wmic and net user have things like whether the password CAN expire, not whether they expired already)
I also tried to put this password change command at the post-setup script
net user administrator *
(the * at the end means asking the user for input instead of exposing the password as part of the command), but it seems like Windows setup get stuck quietly waiting for the user interaction which did not pop up.
The final idea I came up with is to ask for the user to change the password on first login (which the system will automatically do with a blank password). I thought of using ‘RunOnce’ in registry but the problem is that when ‘RunOnce’ executes is not predictable.
So I chose to inject a cmd/batch script in the user Startup folder which self-destructs after the first run. But this is not as easy as one might think because NTlite do not allow you to inject arbitrary files. You can give scripts for NTlite to run, but not tell NTlite to inject a file to certain folders.
What I came up with is a CMD script that spits out another text file at the said startup folder, call it makeSelfDestructScript_promptChangeAdminPW.cmd and have put it in the post-setup queue in NTLite:
Here’s the script:
@echo off SET outputBatchFile="%systemdrive%\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\promptChangeAdminPW.cmd" echo @echo off > %outputBatchFile% echo echo PLEASE CHANGE ADMINISTRATOR PASSWORD! >> %outputBatchFile% echo net user administrator * >> %outputBatchFile% echo echo PRESS ANY KEY AND THE THE FILE WILL SELF DESTRUCT >> %outputBatchFile% echo pause >> %outputBatchFile% echo del "%%~f0" >> %outputBatchFile%
A few concepts/techniques is involved to come up with the script above
- %appdata% is not used because I don’t know if Windows PE is mounted to Administrator account already at this point. Since NTLite does not have the option to relocate the User or AppData folder, I always know that the folder is always at:
%systemdrive%\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\promptChangeAdminPW.cmd
I took care to use %systemdrive% instead of C:\ because people could choose other drive letter to install Windows that coexists with other OS and the installed partition might not be always take the first drive letter. - There are techniques to have echo command interpret newlines, but so far it’s very messy and it makes the code unreadable. Instead I do one echo at a time except I use ‘append output redirection >>’ in subsequent lines.
- I added a pause so that if you mistyped during confirm-password (which the change will fail), at least you get a chance to see the text response, which you can choose to abort the script and avoid the self-destruct or just let it self-destruct and press CTRL-ALT-DEL and change password later on your own without the CMD script.
%~f0
is the variable for the filename of the script itself, I have to escape the % character by %%.- Avoid misinterpreting spaces in filenames as delimiters with double quotes
The generated script promptChangeAdminPW.cmd
at startup folder will look like this:
@echo off echo PLEASE CHANGE ADMINISTRATOR PASSWORD! net user administrator * echo PRESS ANY KEY AND THE THE FILE WILL SELF DESTRUCT pause del "%~f0"