I ran into the same problem: Windows 10 wsl2 Ubuntu Linux isn't working in background, if I have wsl console session closed. I found my way around.
It looks like this post/question has many views, but no up2date solutions, so I post it here.
Please criticize my solution, I am definitely not a Windows guy, I am on the Linux side, so had to learn things digging into this.
My goals reached: I can simply press computer reset button, after Windows 10 boots, I get wsl Ubuntu Linux automatically started in background, with running services accessible via network through Windows box IP.
So I got 2 following things explained here:
- How to configure Windows 10 startup properly, adding my script into Windows startup.
- Commands from my script explained:
- start Ubuntu Linux wsl2;
- configure access to Linux services from network;
- make Linux services running in background.
Configuring Startup
I use Task Scheduler to start it at system startup, in this way it start even before anybody is logged into Windows.
I have the task created in the following way:
- General:
- Run whether user is logged on or not;
- Run with highest privileges;
- Triggers:
- Actions:
- Start a program:
- Program/script: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
- Add arguments: C:\Users\MY-USERNAME\bin\UStartup.cmd
The script
The full path is C:\Users\MY-USERNAME\bin\UStartup.cmd
You can change it, just make sure that configuring startup using Task Scheduler, you specify the correct path there.
The script does the following things:
- it starts Ubuntu Linux wsl2 at Windows startup even before anybody logs into computer;
- it automatically detects Ubuntu Linux internal virtual IP and configures forwarding of pre-defined by you ports, so you can access Linux services from network going to Windows box external IP (for example you can log into linux via ssh and/or access linux web server via web from local network);
- it forces Ubuntu Linux wsl2 working in background, even if you do not have any wsl console open.
The full script
echo %date%-%time% > %TEMP%\UStartup.log 2>&1
PowerShell -Command "Set-ExecutionPolicy Unrestricted" >> %TEMP%\UStartup.log 2>&1
PowerShell wsl -d Ubuntu "/usr/bin/sudo /root/startup.sh" >$null 2>&1
PowerShell wsl -l -v >> %TEMP%\UStartup.log 2>&1
PowerShell "$A = (wsl -- sh -c 'hostname -I | cut -d\ -f1'); echo \"[$A]\"; netsh interface portproxy add v4tov4 listenport=8080 listenaddress=0.0.0.0 connectport=8080 connectaddress=$A; netsh interface portproxy show all" >> %TEMP%\UStartup.log 2>&1
Start "%APPDATA%\Microsoft\Windows\Start Menu\Programs\Windows PowerShell" wsl tmux new-session -s test >> %TEMP%\UStartup.log 2>&1
PowerShell sleep 3 >> %TEMP%\UStartup.log 2>&1
PowerShell "$A = (tasklist|Select-String 'wsl.exe'|Select-String 'Console'|%%{($_ -split '\s+')[1]}); echo \"[$A]\"; Stop-Process -Id $A" >> %TEMP%\UStartup.log 2>&1
echo %date%-%time% >> %TEMP%\UStartup.log 2>&1
Hope it may help to somebody!
Now script commands quick explanations, part by part
PART 1: Starting wsl2 Ubuntu Linux
1.1. Clear log file and print date/time to the log file (not needed for functionality, it is just nice to have date/time in log):
echo %date%-%time% > %TEMP%\UStartup.log 2>&1
1.2. Change Execution Policies to get rid of restrictions:
PowerShell -Command "Set-ExecutionPolicy Unrestricted" >> %TEMP%\UStartup.log 2>&1
1.3. Start wsl:
PowerShell wsl -d Ubuntu "/usr/bin/sudo /root/startup.sh" >$null 2>&1
I configured inside of Linux sudo, to allow execute "sudo /root/startup.sh" as root to start cron service and also some extra services, but it is up to you, you can skip sudo part and simply just start wsl.
Also I redirected output to /dev/null, because it looks ugly, anyway it is logged inside of Linux wsl.
1.4. Print list of all wsl systems I got on my box, Ubuntu should be shown as running there, because it was just started (not needed for functionality, it is just nice to have extra info in log):
PowerShell wsl -l -v >> %TEMP%\UStartup.log 2>&1
PART 2: Configuring ports redirect from Windows IP to wsl2 Ubuntu Linux
2.1. Retrieve currently assigned Ubuntu Linux wsl2 IP address and get Windows box port forwarding configured, also print current ports forwarding info:
PowerShell "$A = (wsl -- sh -c 'hostname -I | cut -d\ -f1'); echo \"[$A]\"; netsh interface portproxy add v4tov4 listenport=8080 listenaddress=0.0.0.0 connectport=8080 connectaddress=$A; netsh interface portproxy show all" >> %TEMP%\UStartup.log 2>&1
echo %date%-%time% >> %TEMP%\UStartup.log 2>&1
In this example I have the following configured: if somebody opens in his browser my windows box ip port 8080, he is going to access Ubuntu Linux wsl2 box port 8080.
If you have Linux sshd enabled and want it accessible, add another such a line with '22' instead of '8080' in 2 places replaced.
PART 2: Making wsl2 Ubuntu Linux services running in background
3.1. Start wsl session with a new tmux console session open:
Start "%APPDATA%\Microsoft\Windows\Start Menu\Programs\Windows PowerShell" wsl tmux new-session -s test >> %TEMP%\UStartup.log 2>&1
Actually it opens a new "Windows Powershell" window with active wsl console on your screen. You cannot see it, if you not logged in, but if you run the script manually (do not forget about elevated privileges), you will see it.
3.2. Wait for 3 seconds (command #1) and after kill "Windows Powershell" window (command #2), leaving tmux console session active:
PowerShell sleep 3 >> %TEMP%\UStartup.log 2>&1
PowerShell "$A = (tasklist|Select-String 'wsl.exe'|Select-String 'Console'|%%{($_ -split '\s+')[1]}); echo \"[$A]\"; Stop-Process -Id $A" >> %TEMP%\UStartup.log 2>&1
We search for process 'wsl.exe' for "Windows Powershell", there should be no others such processes during system startup. But if you run it manually - be aware: you do not want another wsl.exe have running.
3.3. Print date/time to log file (not needed for functionality, it is just nice to have date/time in log):
echo %date%-%time% >> %TEMP%\UStartup.log 2>&1