IMPORTANT EDIT: PLEASE IGNORE ALL THE BELOW RUBBISH.

There’s a much better way, and I’ve coded up a helper for it; please see here.

END OF IMPORTANT EDIT

Herewith, the happily short total of the black arts and incantations needed to get systemd up and running happily on WSL 2.

First, disabling stuff. Because systemd controls everything on a Linux system, and while I don’t know that it will break things if you run a complete Linux startup inside WSL, I didn’t feel like taking the chance. Besides, most of us don’t want systemd to run absolutely everything anyway.

So go to /etc/systemd/system. Create the wsl.target file with the following contents:

[Unit] Description=WSL System Conflicts=multi-user.target graphical.target rescue.target AllowIsolate=yes

This ensures, in conjunction with the –system-unit switch used below, that when systemd starts up, it will only start the units which your new target wants; currently, none of them.

Second, enabling stuff.

Now create a directory under /etc/systemd/system named wsl.target.wants. In this directory, later, we’ll place symbolic links to the services we want systemd to run. (We can’t use the enable command for all of these, as some are statically defined – see system documentation for details.) At the moment, go ahead and create a symlink in this directory to /lib/systemd/system/dbus.service, since systemd requires dbus to function. Don’t add anything else now – get systemd up and running before you get fancy, m’kay?

Third, starting systemd, WSL-side. To do this cleanly, you’ll need the daemonize(1) utility installed; on Debian, this means

sudo apt install daemonize

Create the file systemd-start in the /usr/bin directory, with the following contents:

#!/bin/sh mkdir /sys/fs/cgroup/systemd mount -t cgroup -o none,name=systemd cgroup /sys/fs/cgroup/systemd daemonize /lib/systemd/systemd --system --system-unit=wsl.target

And make it executable.

Basically, systemd expects its cgroup to be all set up when it runs, so you need to do this manually before starting it.

Now, if you don’t mind starting systemd manually when you need it, this is all you need; just manually invoke systemd-start when you want it.

If you’d prefer it to start automatically, on the other hand, you’ve got two options. Both of them are much more convenient if you don’t need to type your password again, so you can optionally run visudo, and add the following line to /etc/sudoers, substituting your username as appropriate:

username ALL=(root) NOPASSWD: /usr/bin/systemd-start

Then, if you want it to start with your WSL session, you can fire it up when you open a console: edit your .bash_login to include the following lines:

if ps -ef | grep -v grep | grep systemd ; then echo "systemd already started" else echo "systemd not running, starting..." sudo /usr/bin/systemd-start fi

Myself, I prefer to have it start automatically when I log in, so I have the following batch file, wsl-startup.cmd:

@echo off wsl sudo /usr/bin/systemd-start net use l: \\wsl$\Debian /persistent:no

Which both fires up systemd and maps a drive for convenient access to my in-WSL files. I then configure this in Task Scheduler to be automatically run when I log in.

Hope this works for you!

EDIT: There are two build-in systemd services which are triggered automatically and which will fail (one because dbus is not yet ready; the other because systemd is not running as pid 1) and cause systemctl status et. al. to indicate that your system is in a degraded state. To prevent this, run the following two commands:

sudo ln -s /dev/null /etc/systemd/system/systemd-update-utmp.service sudo ln -s /dev/null /etc/systemd/system/systemd-journal-flush.service