-
1 - Install WSL(Ubuntu 20.04)
- 1.1 - Enable WSL feature on Windows
- 1.2 - Clear "Users must enter a user name and password to use this computer"
- 1.3 - winreboot
- 1.4 - WinRM Wait for Reboot
- 1.5 - Download WSL installer
- 1.6 - Install WSL install image
- 1.7 - Remove WSL install image
- 1.8 - WSL ubuntu install via scheduled task
- 1.9 - Wait 2 minutes to allow scheduled task completes
- 1.10 - WSL create normal user
- 1.11 - WSL allow sudo NOPASSWD
- 1.12 - WSL change default login to normal user via scheduled task
- 1.13 - Wait 40 seconds to allow scheduled task completes
- 2 - Configure WSL to Allow SSH
- 3 - Run Wake On Lan Script
Exported on 08-Oct-2021 10:53:39
Parameters
1 - Install WSL(Ubuntu 20.04)
For simplicity, we use WSL version 1.0, which is sufficient for running this Python script.
There is a 'ubuntu2004.exe install' step, which can't run successfully directly from Attune(which uses the WinRM protocol under the hood), as a workaround, we setup a Windows scheduled task to accomplish the task. Detailed info here
1.1 - Enable WSL feature on Windows
Same with select Windows Subsystem for Linux
in Turn Windows features on or off
dialog, which can be accessed through Control Panel
-> Uninstall or change a program
, it's on the left pane.
Using the norestart
(postpone restarting Windows, because we have other steps to do before restarting) argument results in exit code to 3010
other than the normal 0
.
Login as user {Windows User} on node {Windows Node}
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
1.2 - Clear "Users must enter a user name and password to use this computer"
Clear Users must enter a user name and password to use this computer
with registry. It's identical to do the setting in GUI with netplwiz.exe
.
A GUI session is needed to run ubuntu2004.exe
/ Add-WindowsCapability
, but in attended automation, it's assumed we don't have local access to the host, and using RDP to establish a GUI session usually asks the user to do interactions. So clear the Users must enter a user name and password to use this computer
setting and do a system restart, will guarantee that the host will boot with a GUI session logged in.
TODO: Remember the original state of this parameter, we should restore it after setting up WSL.
Login as user {Windows User} on node {Windows Node}
$RegPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
$DefaultUsername = "{windowsUser.user}"
$DefaultPassword = "{windowsUser.password}"
Set-ItemProperty $RegPath "AutoAdminLogon" -Value "1" -type String
Set-ItemProperty $RegPath "DefaultUsername" -Value "$DefaultUsername" -type String
Set-ItemProperty $RegPath "DefaultPassword" -Value "$DefaultPassword" -type String
1.3 - winreboot
Reboot the computer.
Login as user {Windows User} on node {Windows Node}
shutdown -r -t 0
1.4 - WinRM Wait for Reboot
WIN2019 needs 40 seconds Post Wait Time(although port is open, but the WinRM service is not in a ready state), less than this may result in error with the following steps.
on node {Windows Node}
1.5 - Download WSL installer
Download WSL appx installer from the official URL.
Login as user {Windows User} on node {Windows Node}
$DIR=Split-Path -Path {wslInstallerDownloadPath}
if (-not (Test-Path $DIR)) {
New-Item $DIR -ItemType Directory
}
if (-not (Test-Path {wslInstallerDownloadPath})) {
Invoke-WebRequest -Uri {wslInstallerDownloadUrl} -OutFile {wslInstallerDownloadPath}
}
1.6 - Install WSL install image
Install the appx package.
Login as user {Windows User} on node {Windows Node}
Add-AppxPackage -Path {wslInstallerDownloadPath}
1.7 - Remove WSL install image
Remove the appx package.
Login as user {Windows User} on node {Windows Node}
if (Test-Path {wslInstallerDownloadPath}) {
Remove-Item -Recurse {wslInstallerDownloadPath}
}
1.8 - WSL ubuntu install via scheduled task
After installing the appx, it is required to do a ubuntu2004.exe install
to make the WSL system usable. We can use wsl -l -v
to check the status of the newly installed WSL system.
If running ubuntu2004.exe
directly from WinRM, will get "A specified logon session does not exist. It may already have been terminated." error.
Tweak with Windows Task Scheduler, see https://gitlab.com/AttuneOps/attune/-/issues/21
Login as user {Windows User} on node {Windows Node}
# Make the task start running after 15 seconds
$ts = New-TimeSpan -Seconds 15
$Trigger = New-ScheduledTaskTrigger -Once -At ((Get-date) + $ts)
# We use the '--root' argument here to avoid the input prompt
$Action= New-ScheduledTaskAction -Execute "C:\Users\kinzlaw\AppData\Local\Microsoft\WindowsApps\ubuntu2004.exe" -Argument "install --root"
$setting = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries
Register-ScheduledTask -TaskName "WSL Ubuntu install" -Trigger $Trigger -Action $Action -Settings $setting -Force
1.9 - Wait 2 minutes to allow scheduled task completes
This is a simplified solution, the wiser method would be to continuously wait a short time period(say 1 second), check if ubuntu2004.exe has finished running.
2 minutes is an estimated value, and tested to work on an I5-8250u 2 core 4GB with SSD Windows virtual machine.
Login as user {Windows User} on node {Windows Node}
start-sleep 120
1.10 - WSL create normal user
Create a normal user for WSL, using credential in 'WSL User' Parameter.
From the host, we can use wsl
to issue command to the WSL system.
See doc for the meaning of {wslUser.user}
and {wslUser.password}
.
Login as user {Windows User} on node {Windows Node}
# create user account
wsl -u root useradd -m {wslUser.user}
wsl -u root sh -c "echo {wslUser.user}:{wslUser.password} | chpasswd" # wrapped in sh -c to get the pipe to work
wsl -u root chsh -s /bin/bash {wslUser.user}
wsl -u root usermod -aG adm,cdrom,sudo,dip,plugdev {wslUser.user}
1.11 - WSL allow sudo NOPASSWD
By default, sudo
will interactively ask the user to enter his password, which is unfriendly to unattended automation tasks. So we disable it with NOPASSWD
.
From the host, we can use bash
to issue command to the WSL system.
Login as user {Windows User} on node {Windows Node}
bash -c "echo '%sudo ALL=(ALL) NOPASSWD: ALL' | EDITOR='tee -a' visudo"
1.12 - WSL change default login to normal user via scheduled task
The ubuntu2004.exe install --root
we previously executed makes the WSL to use root
as default credential, which is unrecommended for Ubuntu. So after creating a normal user, we issue ubuntu2004.exe config --default-user {wslUser.user}
here to change the default login.
If running ubuntu2004.exe
directly from WinRM, will get "A specified logon session does not exist. It may already have been terminated." error.
Tweak with Windows Task Scheduler, see https://gitlab.com/AttuneOps/attune/-/issues/21
See doc for the meaning of {wslUser.user}
.
Login as user {Windows User} on node {Windows Node}
# Make the task start running after 15 seconds
$ts = New-TimeSpan -Seconds 15
$Trigger = New-ScheduledTaskTrigger -Once -At ((Get-date) + $ts)
$Action= New-ScheduledTaskAction -Execute "C:\Users\kinzlaw\AppData\Local\Microsoft\WindowsApps\ubuntu2004.exe" -Argument "config --default-user {wslUser.user}"
$setting = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries
Register-ScheduledTask -TaskName "WSL Ubuntu default user" -Trigger $Trigger -Action $Action -Settings $setting -Force
1.13 - Wait 40 seconds to allow scheduled task completes
This is a simplified solution, the wiser method would be to continuously wait a short time period(say 1 second), check if ubuntu2004.exe has finished running.
This task should finish within 1 or 2 seconds, so 40 seconds of wait is enough(the task is scheduled to run after 15 seconds).
Login as user {Windows User} on node {Windows Node}
start-sleep 40
2 - Configure WSL to Allow SSH
The WSL Ubuntu system's sshd service is not properly configured, so we do the configuration in this group step, to allow Attune to connect the Ubuntu via SSH.
Before SSH is configured, we can use bash
to issue command to the WSL system from the host.
2.1 - WSL reinstall OpenSSH Server
The openssh-server installed by default with WSL Ubuntu lacks some config files, reinstalling it helps creating the needed files.
Login as user {Windows User} on node {Windows Node}
bash -c "sudo apt remove openssh-server -y"
bash -c "sudo apt install openssh-server -y"
2.2 - Edit the sshd_config
After this step, we effectively have the following settings in /etc/ssh/sshd_config
# Allow login with password
PasswordAuthentication yes
# By default, we will lose the connection in several minutes of idle time
# So we change the following params to keep the connection alive
TCPKeepAlive yes
ClientAliveInterval 120
ClientAliveCountMax 720
Login as user {Windows User} on node {Windows Node}
bash -c "sudo sed -i `'/PasswordAuthentication no/c\PasswordAuthentication yes`' /etc/ssh/sshd_config"
# in case the parameter previously commented
bash -c "sudo sed -i `'/PasswordAuthentication yes/c\PasswordAuthentication yes`' /etc/ssh/sshd_config"
bash -c "sudo sed -i `'/TCPKeepAlive no/c\TCPKeepAlive yes`' /etc/ssh/sshd_config"
# in case the parameter previously commented
bash -c "sudo sed -i `'/TCPKeepAlive yes/c\TCPKeepAlive yes`' /etc/ssh/sshd_config"
bash -c "sudo sed -i `'/ClientAliveInterval [[:digit:]]\+/c\ClientAliveInterval 120`' /etc/ssh/sshd_config"
bash -c "sudo sed -i `'/ClientAliveCountMax [[:digit:]]\+/c\ClientAliveCountMax 720`' /etc/ssh/sshd_config"
2.3 - Restart OpenSSH Server
Restart the service for the new config files to take effect.
Login as user {Windows User} on node {Windows Node}
bash -c "sudo service ssh restart"
2.4 - WSL SSH Windows Firewall setup
Allow the TCP 22 port(SSH) to be connected.
Remember the Ubuntu is an WSL within the Windows, whose network is the same as the host system, so we create the firewall rule in Windows.
Login as user {Windows User} on node {Windows Node}
New-NetFirewallRule -DisplayName 'WSL SSH' `
-Name 'WSL SSH' `
-Profile Any `
-LocalPort 22 `
-Protocol TCP
2.5 - Automatically start OpenSSH Server on bootup
WSL isn't started automatically when the host system boot up, so we can't use Ubuntu's systemctl enable sshd
to do this.
Here we create a Windows scheduled task in the host system, using bash
to issue the sudo service ssh start
command, which is a usual command to manually startup a service.
Login as user {Windows User} on node {Windows Node}
# run this task every time the computer start up
$Trigger= New-ScheduledTaskTrigger -AtStartup
$principal = New-ScheduledTaskPrincipal -LogonType S4U -UserId '{windowsUser.user}'
$Action= New-ScheduledTaskAction -Execute "bash" -Argument "-c `'sudo service ssh start`'"
$setting = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries
Register-ScheduledTask -TaskName "SSH service start on bootup" -Trigger $Trigger -Principal $principal -Action $Action -Settings $setting -Force
3 - Run Wake On Lan Script
After preparing the WSL environment, now comes the real work we want to do -- WOL another PC.
Wake-on-LAN (WOL) is an Ethernet or Token Ring computer networking standard that allows a computer to be turned on or awakened by a network message.
Which means that a host(Target) is in power off, sleep, or hibernated state. If there is another device(usually another PC, raspberry pi, or even a router which supports running script/app) that is running 7x24, we can use that device to broadcast the Wake on Magic Packet to the LAN, the Target boots up when it sees the Wake on Magic Packet. This feature is useful to control devices remotely.
See this article on setting up WOL in BIOS and Windows.
3.1 - Add Python executable alternative
Attune's Python step depends on a python
executable resides on the host, but Ubuntu 20.04 comes with only a python3
, so we need to create a python
link for it.
Use update-alternatives --install
to create a normal python
executable link to the actual python3
.
This step needs a credential with Sudo to Root
set.
Login as user {WSL User With Sudo} on node {WSL Node}
if which python; then
: # python is found, nothing needs to be done
else
update-alternatives --install /usr/bin/python python /usr/bin/python3 1
fi
3.2 - Wake on Lan via WSL Python
Runs the WOL Python script inside WSL.
Please edit the values commented with TODO
to reflect the real situation.
Login as user {WSL User} on node {WSL Node}
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Wake on Lan
import socket
import struct
def WOL(macaddress):
if len(macaddress) == 12:
pass
elif len(macaddress) == 12 + 5:
sep = macaddress[2]
macaddress = macaddress.replace(sep, '')
else:
raise ValueError('Incorrect MAC address format')
data = ''.join(['FFFFFFFFFFFF', macaddress * 16])
send_data = b''
for i in range(0, len(data), 2):
byte_dat = struct.pack('B', int(data[i: i + 2], 16))
send_data = send_data + byte_dat
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
sock.bind(('{wslNode.ip}', 20000))
# TODO: change to the broadcast IP of your LAN
sock.sendto(send_data, ('192.168.31.255', 9))
sock.close()
if __name__ == '__main__':
# TODO: change to the MAC of the Target NIC
WOL('00:e0:b4:1d:01:f4')
Using Attune to install and configure WSL on Win10/Win2019, then running Wake on Lan python script via the newly installed WSL
This blueprint is used to boot another host in the LAN, through Wake on Lan. Before running the WOL python script, we need to install WSL on a Windows host, and setup the WSL to allow SSH connection. Then we can use Attune to SSH connect to the WSL(same as a Linux physical machine, or virtual machine), and run the python script there.
Tested on Windows 10/2019(WSL will be installed on this host), the WOL target's OS doesn't matter, it only depends on the NIC's BIOS supporting WOL feature, and of course, the target machine's power cord needs to be plugged in.
Explanation of Terms
The Windows Subsystem for Linux(WSL) lets developers run a GNU/Linux environment -- including most command-line tools, utilities, and applications -- directly on Windows, unmodified, without the overhead of a traditional virtual machine or dualboot setup. In this case, we'll install Ubuntu 20.04.
Wake-on-LAN (WOL) is an Ethernet or Token Ring computer networking standard that allows a computer to be turned on or awakened by a network message.
Which means that a host(Target) is in power off, sleep, or hibernated state. If there is another device(usually another PC, raspberry pi, or even a router which supports running script/app) that is running 7x24, we can use that device to broadcast the Wake on Magic Packet to the LAN, the Target boots up when it sees the Wake on Magic Packet. This feature is useful to control devices remotely.
See this article on setting up WOL in BIOS and Windows.
Known issues
Pre-Blueprint Attune setup