Out of the box, Ubuntu cannot resolve hostnames announced by Windows out of the box.
The internet had many solutions from ditching NETBIOS (winbind, wins) but it involves replacing systemd-resolved with the old NetworkManager (systemd-resolved was an extra level of indirection to break VPN ties), which I illustrated in this now deprecated blog post.
Having router assign host names you specify often included a local domain name (must not choose one that conflicts with the internet) such as local or lan. So the computers are accessed in the format of myPC.local or myPC.lan depending on the local domain name you picked. However, it doesn’t take advantage of the hostname announced by Windows computers.
I decided to give the NETBIOS service a second research today and found the missing link to the common solution of installing winbind and adding wins entry to host search order in /etc/nsswitch.conf (you can put it at the end or earlier if you want). I put it at the end as I wanted it to be the last resort
hosts: files {a bunch of things depending on your system} wins
Of course having a wins entry in the hosts search order involves installing winbind make sure the winbind service is running
sudo apt install winbind
The missing piece is editing /etc/samba/smb.conf to inject a name resolve order list after installing samba and winbind:
name resolve order = wins lmhosts bcast
You will need to install samba package first if you haven’t already installed it (for sharing folders with Windows)
sudo apt install samba
The post said the name resolve order section was commented out, but in newer version of samba, the line is simply non-existent. You’ll have to add it somewhere in /etc/samba/smb.conf, I chose to put it right at the beginning of [global] section.
Restart the services after editing to reflect the changes and you can start pinging!
sudo systemctl restart nmbd smbd winbind
So in the process above (installing samba and winbind and editing nsswitch.conf), you’ve also enabled linux to announce its hostname to Windows, which I’ve discussed in this blog post.
So to summarize the concepts,
You need to install winbind to add wins to host search list in nsswitch.conf, but it doesn’t do you anything yet!
Once you installed samba, your linux computer start announcing its hostname to Windows computers
To be able to use the hostnames announced by Windows, i.e. the other direction, you’ll need to add the name resolve order line to smb.conf (samba config file) and restart samba and winbind.
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"
Basically Windows is making a diary of every single folder/filenames you’ve visited in chronological order. Just learned about something called ShellBag while using NTlite to slipstream Windows. WTF!
Parents can run a scan with ShellBag Analyzer in their family computer and see what their teenager has been up to!
Everybody should first disable this feature by running this registry settings (or manually creating the DWORD entry and set it to 1) which you can download and execute below:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell]
"BagMRU Size"=dword:00000001