4

I am using Ubuntu with WSL with a zsh/bash shell. My host OS is Windows 10. I already figured out how to mount a Windows external drive:

sudo mkdir /mnt/d
sudo mount -t drvfs D: /mnt/d

I rarely plug this drive in, so I'd like to automatically mount it when I do. It's fine if this occurs after I plug the drive in, then start a new WSL terminal.

I don't want to put this command in a .bashrc type of file because having to type in my password every time I open a terminal would be more trouble than it's worth, especially if 99% of the time, the command will fail anyway. Putting it in a bash script won't help either, because I'd run it so infrequently, by the time I need to use it, I'll forget I created it in the first place.

So, is there a way to mount an external drive when it becomes available in WSL?


I don't know if this is a good solution, but this tells you how to turn off the password request for sudo. This is the route I took: https://superuser.com/a/1492456/89165

Daniel Kaplan
  • 579
  • 8
  • 23

1 Answers1

4

It looks to me like this will need two different approachs:

  • First we need to handle the case when WSL starts up while the drive is already attached.
  • And we also need to handle the case when the drive is attached while WSL is already running.

Drive already attached when WSL starts

The first part should be pretty easy.

I don't want to put this command in a .bashrc type of file because having to type in my password every time I open a terminal

That's simple to overcome. Add the following to your ~/.bashrc instead:

wsl.exe -u root -e mount -t drvfs D: /mnt/d > /dev/null 2>&1

That will mount the drive if it's available. If not, it will silently fail.

Drive is attached while WSL is running

It's not easy, and it probably needs more error handling to be "robust", but I was able to get this to work by creating a PowerShell script to:

  • Register an action when a USB drive is attached
  • Run wsl -u root -e mount -t drvfs /mnt/<driveletter> <Drive> when the event fires.
$query = "select * from __InstanceCreationEvent within 5 where TargetInstance ISA 'Win32_LogicalDisk' and TargetInstance.DriveType = 2"

$action = {
    $drivePath = $event.SourceEventArgs.NewEvent.TargetInstance.Name
    $driveLetter = $drivePath.ToLower()[0]
    wsl -u root -e mount -t drvfs $drivePath /mnt/$driveLetter
}

Register-WmiEvent -Query $Query -Action $Action -SourceIdentifier USBFlashDriveWSLMount

Note that this needs to run in Windows PowerShell (rather than PowerShell Core) since it uses WMIEvent. I'm sure there's a PowerShell Core equivalent using CIM, but I haven't tried it that way yet.

If you run into a problem, check the output. From PowerShell:

Get-Job
# Get the Id of the job then
Receive-Job <job_id>

In theory, you can set this script to run at Windows Login via Task Scheduler, but I haven't tried it. I'm 80% confident it will work. You'll need to call it through the powershell command (not pwsh since it uses WMIEvent).

Note, there's also apparently a way to register the event listener permanently though CIM. I spent some time on this last week, but got rabbit-trailed when I followed some documentation that created a CIM class on my system that I couldn't get rid of. I may come back to it eventually, but hopefully this works for you as a Scheduled Task. I just didn't want to hold off posting until I got it "just right", because I might never finish it up.

NotTheDr01ds
  • 17,574
  • 4
  • 44
  • 81
  • Still on the first paragraph, but "And we also need to handle the case when the drive is attached while WSL is already running" isn't a requirement for me, just a nice to have. – Daniel Kaplan Aug 09 '22 at 21:11
  • @DanielKaplan Excellent - Then that should make it pretty easy! – NotTheDr01ds Aug 09 '22 at 21:12
  • @DanielKaplan And while I'm thinking about it (since I just answered another related question), see [this Ask Ubuntu answer](https://askubuntu.com/a/1422805/1165986) for a slight tweak on the `mount` command. – NotTheDr01ds Aug 09 '22 at 21:13
  • I just tried this and it didn't work. It errors, saying `User not found.` – Daniel Kaplan Aug 19 '22 at 04:55
  • @DanielKaplan Hmm - You mean the `wsl.exe -u root` part? What happens if you run `wsl -u root` without the rest of it? I would *expect* that to essentially be the same as `sudo -s`, but without requiring a password. – NotTheDr01ds Aug 19 '22 at 19:24
  • `➜ ~ wsl.exe -u root\n User not found.` FWIW, I'm running this in the ubuntu shell. – Daniel Kaplan Aug 22 '22 at 21:19
  • @DanielKaplan That's pretty odd. How about (when running inside Ubuntu) `wsl.exe -d $WSL_DISTRO_NAME -u $USER`? – NotTheDr01ds Aug 22 '22 at 23:27
  • That literally prints no output, but succeeds. The values of those variables are `Ubuntu` and the value of my `whoami`, respectively. The latter is different from "root". – Daniel Kaplan Aug 23 '22 at 02:24
  • @DanielKaplan Sorry, forgot to come back to this. Its sounding like you really may not have a root user in that instance (or it's named something else). Does `less /etc/passwd` show a `root:x:0:0 ...` (usually in the first position)? If not, is some other user else in there with a `0:0` in the third and fourth columns? – NotTheDr01ds Aug 30 '22 at 00:35
  • Yep, it's there like `root:x:0:0...` – Daniel Kaplan Aug 31 '22 at 02:32