Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

In Window 10 with WSL installed, a Task Scheduler task setup to run at Startup/Logon which intiates a PowerShell script which executes the bash command fails. #3829

Closed
rabicherian opened this issue Feb 7, 2019 · 18 comments
Labels

Comments

@rabicherian
Copy link

rabicherian commented Feb 7, 2019

Please fill out the below information:

  • Your Windows build number: (Type ver at a Windows Command Prompt)
    Microsoft Windows [Version 10.0.17763.253]

  • What you're doing and what's happening:
    In Window 10 with WSL installed, a Task Scheduler task setup to run at Startup/Logon which intiates a PowerShell script which executes the bash command fails.
    This is the PowerShell script:

#power shell file saved as autostartsshd.ps1
bash -c 'sudo service ssh start'

Note: Running this with powershell as Administrator works fine. If fails only when run as a task via TaskScheduler

  • What's wrong / what should be happening instead:
    But running from Task Scheduler at log on throws this error:

bash : The term 'bash' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At D:\ssh_startup\autostartsshd.ps1:2 char:1

  • bash -c 'sudo service ssh start'
  •   + CategoryInfo          : ObjectNotFound: (bash:String) [], CommandNotFoundException
      + FullyQualifiedErrorId : CommandNotFoundException
    
    

Note the reason it cannot find bash is that bash.exe is found only in the 32 bit version (c:\Windows\System32\bash.exe) and it looks like the path for TaskScheduler does not include 32bit libraries by default in Windows?

  • Workaround:
    Create a symlink to 32bit bash.exe in SysWOW64
PS C:\Windows\system32> cd ..\SysWOW64\
PS C:\Windows\SysWOW64>  New-Item -ItemType SymbolicLink -Name bash.exe -Target c:\Windows\System32\bash.exe

Now the TaskScheduler task executes successfully and the ssh service is started as instructed.

Can this PATH issue be fixed in a future release, so that this unnecessary workaround can be avoided?

@craigloewen-msft
Copy link
Member

Could you try replacing:
bash -c 'sudo service ssh start'

With:
wsl sudo service ssh start

And see if that fixes the issue for you?

We'll also look into the startup PATH behavior for bash.exe :)

@benhillis
Copy link
Member

What about fully qualifying the path to bash.exe or wsl.exe (c:\Windows\System32\bash.exe).

@rabicherian
Copy link
Author

rabicherian commented Feb 8, 2019

@mscraigloewen @benhillis thanks for the quick response
I tried your suggestions, here are my findings
NOTE: All these succeed with PowerShell but fail when task is executed at Startup/login

Case 1: using wsl instead of bash

#power shell file using wsl : saved as autostartsshd.ps1
wsl sudo service ssh start

At task startup, this is the error thrown by the script:

wsl : The term 'wsl' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the
spelling of the name, or if a path was included, verify that the path is correct and try again.
At D:\ssh_startup\autostartsshd.ps1:3 char:1

  • wsl sudo service ssh start
  •   + CategoryInfo          : ObjectNotFound: (wsl:String) [], CommandNotFoundException
      + FullyQualifiedErrorId : CommandNotFoundException
    

Case 2: using full path of exe(c:\Windows\System32\wsl.exe)

#power shell file using c:\Windows\System32\wsl.exe :saved as autostartsshd.ps1
c:\Windows\System32\wsl.exe sudo service ssh start

At task startup, this is the error thrown by the script:

The term 'c:\Windows\System32\wsl.exe' is not recognized as the name of a cmdlet,
function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the
path is correct and try again.
At D:\ssh_startup\autostartsshd.ps1:3 char:1

  • c:\Windows\System32\wsl.exe sudo service ssh start
  •   + CategoryInfo          : ObjectNotFound: (c:\Windows\System32\wsl.exe:String) [], CommandNotFoundException
      + FullyQualifiedErrorId : CommandNotFoundException
    

Note 1 : mentioning full path of bash exe(c:\Windows\System32\bash.exe) after removing symlink also failed at task startup even though it went through in PowerShell
To remove the bash sym-link
(Get-Item C:\Windows\SysWOW64\bash.exe).Delete()

Note 2: Mentioning path like this also failed at task startup even though this too successfully went throught with PowerShell.
c:\Windows\System32\wsl

The only thing that worked is with the WORKAROUND when symlinks are created.

PS C:\Windows\system32> cd ..\SysWOW64\
PS C:\Windows\SysWOW64> New-Item -ItemType SymbolicLink -Name wsl.exe -Target C:\Windows\System32\wsl.exe

Now Case 1 went through at Task Start up.

CONCLUSION:
In Window 10, Task Scheduler for tasks executed at Start Up/Logon do not include C:\Windows\System32 in the PATH. As a result PowerShell Scripts which use CLIs/Utilities like bash, wsl etc. fail.

IMO this make a case for a fix.
Agree?

@0xbadfca11
Copy link

It looks like looking at system32 folder from a 32-bit application.
Does C:\Windows\sysnative\wsl.exe work ?

@rabicherian
Copy link
Author

rabicherian commented Feb 8, 2019

Looking at Case 2 failure above (when I tried full path 'c:\Windows\System32\wsl.exe) and it failed at task startup, it is clear that specifing C:\Windows\sysnative\wsl.exe will also fail with

The term 'C:\Windows\sysnative\wsl.exe' is not recognized as the name of a cmdlet error
Also Note:

>dir c:\Windows\sysnative\wsl.exe
The system cannot find the file specified.

So this will fail with PowerShell execution too

@DHowett
Copy link
Member

DHowett commented Feb 10, 2019

It’s not entirely clear that it’ll fail: sysnative is an escape route for 32-bit processes to access the native System32 directory (which on 64-bit windows actually contains 64-bit binaries.)

Since it looks like the task being scheduled is launched with filesystem redirection turned on, and perhaps even in 32-bit mode itself, sysnative should work.

The issue isn’t exactly that system32 isn’t in the path; it’s that system32 is redirected to syswow64 for a 32-bit process.

@rabicherian
Copy link
Author

rabicherian commented Feb 11, 2019

@0xbadfca11 My apologies

I tried with C:\Windows\sysnative\wsl.exe after removing the symlink to wsl
(Get-Item C:\Windows\SysWOW64\bash.exe).Delete()

My PowerShell script now looks like

#power shell file - using sysnative to access wsl
C:\Windows\sysnative\wsl.exe sudo service ssh start

On startup, task gets executed without error and ssh service does get started.

Thank you. Learnt something about sysnative as well. Thanks @DHowett

@rodrymbo
Copy link

Another workaround might be to use the distro-named .exe, which is probably in a "normal" directory. For example, ubuntu1804.exe can start scripts on its command line (rith appropriate syntax), is usually on the Path, and doesn't require the sysnative trick to work, I don't think, usually. Your distro may vary.

@rabicherian
Copy link
Author

@rodrymbo
Confirming that using named distro exe to launch works, Specifically I am using Ubuntu 18.04 LTS.
This works:

#power shell file - using native distro exe to access WSL
ubuntu1804.exe run "sudo service ssh start"

Thank you.

@rabicherian
Copy link
Author

One correction for all these workarounds.
These work only with Task Scheduler Tasks triggered at Log On of Users,

  • SysNative wsl run C:\Windows\sysnative\wsl.exe ...
  • Native Distro Exe e.g. ubuntu1804.exe run "..."
  • After wsl symlink creation in SysWOW64 wsl ...

None of these workarounds work on a Task Scheduler Tasks triggered On System Startup.

Could Anyone suggest a work around that will work at System Start Up, and not for just for Logged In User?

@Phoenyx33
Copy link

Is it possible to start ubuntu1804.exe without it displaying a window? If so it might be possible to install and run a service that would execute the command and arguments. Something like the cygrun command from Cygwin.

@rodrymbo
Copy link

rodrymbo commented May 19, 2019

I've not been able to get ubuntu1804 to run from task manager in the "whether user is logged on or not" context. But since this is a desktop machine, I just use an "only when user logged in" context, which works just fine and accomplishes almost the same thing. (Takes some testing to make sure it is doing what you want.)

It would be nice to have it run as a true service, but there are plenty of complications to consider. One is that it still needs to run in some (Windows) user context, so if not yours, you'd need to create one and install a distro for it. The other is that, once the background task or daemon starts, the Windows system context tends to be frozen, so, for example, if you mount a drive after that, the background process won't see the new drive.

On to "start without displaying a window":

One of the first things I did when I first started using WSL was work up a way to start WSL without leaving a window lying around. The first thing I did was use vbscript, which has the

CreateObject("WScript.Shell").Run command, 0, False

syntax, where the 0 means hide the window and False is in the "wait on return" position. You may need to fiddle with it to get it to work the way you want. Once it is working, the "hide window" switch makes sure there is no window kicking around.

As with most such things, just because I got it working many months ago doesn't mean it is still the best way to do it, but since it works, I'm still using it. :P

The ubuntu1804.exe run <scriptname> works as long as you remember to use the linux (wslpath) format for the full path for scriptname.

You can probably use one of the commands to start a process in the background from a bash script; thus the script can exit (closing the window) but the process will still keep running in the background. It didn't used to work that way, but it works much better now.

It might take some trial and error to get it working the way you want, but of course once you find a vbs script you can run from wscript (or a bash script you can run from ubuntu1804.exe and ignore the window that opens then closes again) you can put it into Task Scheduler.

@ghost
Copy link

ghost commented Jun 8, 2020

I am in the same scenario with powershell script to start WSL with SSH in task scheduler. I tried wsl symlink and SysNative wsl workarounds but none of them works when scheduled for login or just on-demand run... I am using WSL2 and opensuse though.

With the symlink workaround, my powershell script looks like below
$command = "wsl.exe sudo /usr/sbin/sshd;exit"
iex "& $command"
If I manually ran this scipt in powershell, it works.

With the Sysnative wsl workaround (symlink removed), my powershell script looks like below
$command = "C:\Windows\sysnative\wsl.exe sudo /usr/sbin/sshd;exit"
iex "& $command"

@chx
Copy link

chx commented Nov 15, 2021

I am fairly certain the problem really is #2979

This is a duplicate of microsoft/winget-cli#1011 and also https://stackoverflow.com/q/65770661/308851

I have tried to set up the task to run as the user WSL is installed under but that's obviously (?) a no go because you'd need to store the user password. (And I am in an AD and I can't even get to the password prompt but w/e.)

The only way would be to install WSL somehow under SYSTEM using the steps under https://docs.microsoft.com/en-us/windows/wsl/install-on-server however after downloading and extracting and using PsExec.exe -sid ubuntu2004.exe I get an access denied like the one in #4487 . It's entirely possible the elevated user doesn't have the directories WSL needs.

I give up and will run my script on login.

@enachi
Copy link

enachi commented Dec 20, 2022

Try with non-store version of WSL 2

add a new SchTask
run as: your_current_account
run whether user is logged on or not
trigger : at system startup + delay 2 mins
example:
action: program: wsl, argument: -u root -e sudo service ssh --full-restart

this works with only with WSL inside version. new WSL store version breaks this #9231

@jsquyres
Copy link

jsquyres commented Jan 3, 2023

Try with non-store version of WSL 2

@enachi Can you describe how to install a non-store version of WSL2? Thanks!

@rewgs
Copy link

rewgs commented Sep 14, 2023

I tried everything in this thread to get WSL2 to run at startup via the Task Scheduler, and nothing worked. However, I was able to get WSL2 to run at startup without the Task Scheduler by doing the following:

I wrote a script called run-wsl.ps1 as follows:

$wslJob = Start-Job -ScriptBlock { C:\Windows\System32\wsl.exe `
	--distribution Ubuntu `
	--user myUser `
	--exec tmux new-session -s main -d ` # This line isn't necessary; it's just an example of executing something in WSL
}
$wslJob | Wait-Job

I then placed a shortcut to run-wsl.ps1 in shell:startup and set it to run Minimized.

Works like a charm, albeit after a ~5 second delay or so on my machine. The minimized PowerShell window disappears once the WSL process is successfully kicked off, so this meets my criteria for running WSL totally in the "background" at startup.

To be clear, I installed Ubuntu via Microsoft Store, as I'm running Tailscale in WSL and thus much prefer having the ability to start it via systemd.

Copy link
Contributor

This issue has been automatically closed since it has not had any activity for the past year. If you're still experiencing this issue please re-file this as a new issue or feature request.

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests