NTlite – Slipstream Windows 10 with Administrator Account only

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" 

Loading

Getting Remote Desktop Server to work on Cinnamon Desktop

xrdp+xorg is a huge pain in the butt as it does not account for variations in systems properly (or automatically) so often it breaks out of the box.

First of all, if you are using cinnamon (including Ubuntu Cinnamon Remix, I suspect it is the same for Linux Mint too), you will run into this shit after successfully logging in:

login - "oh no something has gone wrong" after clean install of 19.10 LVM  and making changes - Ask Ubuntu

This is a GNOME session crash. The information on the web points to some other modes of failure in ArchLinux and the like. That’s not the reason. By going through my own notes on xrdp, I noticed the gut of /etc/xrdp/startwm.sh is to call the executable script /etc/X11/Xsession:

test -x /etc/X11/Xsession && exec /etc/X11/Xsession
exec /bin/sh /etc/X11/Xsession

However /etc/X11/Xsession in term plough through a bunch of scripts in /etc/X11/Xsession.d folder and one step was to look for the executable script ~/.xsession, which is not established by default! For some reason the Xsession scripts can figure out the local desktop environment but not when it’s launched through xrdp!

So the solution is to make an executable script ~/.xsession with just one call to cinnamon-session and that’s it!

I initially thought the call was just ‘cinnamon’ because the most popular answer in the Stack Exchange page suggested writing to ~/.Xclients but this redirection was now obsolete and they use ~/.xsession instead:

but when I did that, the desktop loads but there are no icon and the theme colors are way off. The answer was buried here in a comment in one of the answers:

If you want this behavior to be universal across all user (don’t have to establish the ~/.xsession for each user), and is ok with hard-coding to stick to Cinnamon desktop for everybody including local users (i.e. no redirection script to figure out based on context and conditional config files), you can just replace the last two lines of /etc/xrdp/startwm.sh, which calls /etc/X11/Xsession, with simply cinnamon-session.

Geeze! Why does every basic feature in Windows has to turn into a freaking research project in Linux. I’ve wasted so many hours compiling XRDP from scratch from the author’s webpage thinking it’d solve the problem because he had many tutorials for a lot of cases that xrdp breaks out of the box. Turns out they didn’t matter: it’s just that xrdp couldn’t figure out the right desktop environment so it crashed after loggint in through xorg!

Loading

Linux WTF – KDE on Ubuntu and how to get rid of it.

I had quite a bit of trouble getting Cinnamon to work with xrdp (Remote Desktop Protocol for Linux) to work and was misguided to try out other Desktop environments such as KDE. I couldn’t be more displeased about how unfinished and poorly integrated KDE is.

Linux, no matter how good the programmers are with the core code with multiple people’s scrutiny, never had a proper QA team to take care of integration. Linux in 2022 is still like assembling a PC in the 1990s: I’d be super lucky if everything worked out at the first try after very careful planning and knowing every step of the way. There’s always something that just breaks out of the box for the most obvious use cases.

First I installed the ‘kde-full’ package, chose sddm, and rebooted to find out my 4k screen was covered by a giant freaking on screen keyboard:

Fedora 29 graphical login screen (sddm) displays only virtual keyboard -  Unix & Linux Stack Exchange

What the fuck? It’s trying to be smart-ass accommodating handheld devices yet it’s not smart enough to figure that it’s a desktop computer with a keyboard, so it ended up with shitty out of the box behavior that nobody wants under any circumstances!

After I clicked the bottom down keyboard icon to close to the damn on screen keyboard, it keeps popping up as I set the focus to the edit box to type my password so I have to close it again. Aargh!

Once I get into the plasma desktop, the window designed looked like BeOS so I think I cannot accept anything less than Cinnamon for now, so I wanted out. I thought just removing the same ‘kde-full’ package will put me back to where I was, but hell no! I’m still stuck with that ugly and confusing welcome screen and my software menu was cluttered with a boatload of KDE default apps that I do not want!

After a bit of digging around, I’m not the only one perplexed by this behavior. Turns out there’s a lot of clean up the uninstaller didn’t do! That’s why Windows has installer instead of package managers. One size does not fit it all. Installing something just to find out that uninstalling it immediately right after doesn’t put you back to where you were is deeply frustrating.

I adapted his tutorial uninstalling KDE with Ubuntu Cinnamon Remix:

# The desktop is still not removed even if you did "sudo apt remove kde-full"
sudo apt remove plasma-desktop --autoremove
# Default apps the came with KDE and plasma desktop are still there
sudo apt-get remove kde* --autoremove
sudo apt-get remove plasma* --autoremove
# This will give you a menu to pick the old splash screen (it's called plymouth)
sudo update-alternatives --config default.plymouth

# Reflect changes in early startup scripts (initramfas) and boot loader (grub)
sudo update-initramfs -u
sudo update-grub
# Stop and remove SDDM service to get back the old lockscreen
sudo systemctl disable sddm
# Note that you might be thrown out to text mode when you stop SDDM
# Switch to other virtual consoles (e.g. Ctrl+Alt+F2) and run startx to get to the GUI
sudo systemctl stop sddm
# Delete SDDM
sudo apt-get remove --auto-remove sddm
# Clean up SDDM
sudo apt-get purge --auto-remove sddm

# Message in SDDM removal suggests reconfiguring lightdm
# (lightdm is Cinnamon's default greeter)
# Don't need to systemctl enable/start, that's for GDM3
sudo dpkg-reconfigure lightdm

# Reboot
reboot

Loading

Qemu/KVM Command Line Notes

The executable kvm is an alias for (symbolic link to) qemu-system-x86_64

KVM is the type 1 hypervisor which can be used by QEMU for speed

-accel kvm is the newer way of saying –enable-kvm

CPU host pass-through for speed

-cpu host

Select boot device (c for HDD, d for cd-rom)

-boot d

Attach IDE optical drive (only one allowed, more needs to me mapped with -drive)

-cdrom {iso file or device file}

SPICE (rdp-like protocol to control virtual machine through IP) recommends qxl video driver

-vga qxl

-spice port={default is 3001},password={cannot start with numbers or it’ll be treated as boolean as it’d be interpreted as numeric}

Base HDD/SSD drive: discard=unmap means TRIM for SSD, can add it as a virtio device for speed ONLY AFTER the guest virtio drivers are installed:

-drive file={VHD or drive image file},discard=unmap[,if=virtio]

Speedup by skipping precision clock catchup (HPET)

-no-hpet

Use base=localtime to correct for Linux and Window’s difference in interpreting host RTC’s timezone (Linux assumes that hardware time is UTC+0 while Windows assumed it’s your local time)

-rtc base=localtime,clock=host

Loading

Ubuntu Cinnamon Remix notes

Fix annoying bash colors

Folders (di) color ($LS_COLOR) are dark blue by default which is hard to read on a default dark background (also default): edit ~/.bashrc and add this to the last line to change folder colors to change it to bold (1) light blue (94)

LS_COLORS=$LS_COLORS:'di=1;94:' ; export LS_COLORS

The default prompt ($PS1) also contains the directory (\w), which is also in dark blue (34) but bold (1) by default. Look for the line right below the $color_prompt flag section and change the color ([\033[<STYLE>;<COLOR>m]) modified before \w from bold dark blue (01;34) to bold light blue (01;94)

if [ "$color_prompt" = yes ]; then 
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;94m\]\w\[\033[00m\]\$ '

Loading