Article Image

I’ve run zsh with Oh-my-zsh on my Mac for a couple of years and have preferred that environment over my Cmder setup on Windows. I’m also a big fan of Cmder but I’m very happy to now be able to run more or less the same configuration of my terminal on Mac and Windows, thanks to WSL.

This is how I’ve configured the Windows Terminal with bash zsh.

Ubuntu on WSL

Windows Subsystem on Linux is an optional component for Windows 10. Follow the instructions to install it. Essentially it’s just a matter of executing the follow ing powershell statement,

Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux

and then installing the Linux distro of choice from the Microsoft Store. In terms of Linux distro, I’m using Ubuntu 18.04


Now when Ubuntu is installed, you should be able to type bash in cmd to launch bash.

So, what about zsh? Zsh is another shell to be used instead of bash. Don’t ask me about the nitty gritty details here but as I understand it, zsh is considered to be more customizable, allowing you to adapt it to your workflow in more detail.

Several years ago I found the post How to get an awesome looking terminal on Mac OS X. In there Jakob shows how to configure zsh. And, that’s basically the reason why I jumped on zsh and been using it ever since.

Install zsh with the command

sudo apt-get install zsh

Oh My Zsh is a framework for managing your zsh configuration (thems, plugins etc). Install it with the following command

sh -c "$(curl -fsSL"

Open the ~/.zshrc file and add desired plugins and set the theme. I’m currently using the git and history plugins and the default theme “robbyrussel”.

plugins=(git history history-substing-search)

To run zsh you have to start it from bash using the command zsh. But, that’s not how we want it. We still have to launch bash from Windows though but we can configure bash to launch zsh at start up. Add the below lines to ~/.bashrc.

# Launch Zsh
if [ -t 1 ]; then
exec zsh

Windows Terminal

Install the new Windows Terminal. I installed the version from the Microsoft Store but, it’s also available on Github

Now, add a new profile to Windows Terminal to be able to directly launch zsh. Profiles and other customizations of the Terminal is currently done in profiles.json

    "acrylicOpacity": 1,
    "closeOnExit": true,
    "colorScheme": "Solarized Dark Tweak",
    "commandline": "bash",
    "cursorColor": "#FFFFFF",
    "cursorShape": "bar",
    "fontFace": "Menlo for Powerline",
    "fontSize": 11,
    "guid": "{2DFCF2E7-1697-4471-860B-39C3AFC4685F}",
    "historySize": 9001,
    "icon": "ms-appx:///ProfileIcons/{0caa0dad-35be-5f56-a8ff-afceeeaa6101}.png",
    "name": "zsh",
    "padding": "0, 0, 0, 0",
    "snapOnInput": true,
    "startingDirectory": "%USERPROFILE%",
    "useAcrylic": false

Solarized Dark

As you can see in the above profile, I’ve a slightly tweaked Solarized Dark color scheme. I’ve popped the blues a bit to add some more contrast Again, profiles.json.

    "background": "#18333d",
    "black": "#073642",
    "blue": "#00e5e5",
    "brightBlack": "#666666",
    "brightBlue": "#839496",
    "brightCyan": "#00e5e5",
    "brightGreen": "#586e75",
    "brightPurple": "#6c71c4",
    "brightRed": "#cb4b16",
    "brightWhite": "#fdf6e3",
    "brightYellow": "#657b83",
    "cyan": "#00a6b2",
    "foreground": "#708284",
    "green": "#18333d",
    "name": "Solarized Dark Tweak",
    "purple": "#d33682",
    "red": "#cb4b16",
    "white": "#eee8d5",
    "yellow": "#b58900"

To have as similar colors both in the Terminal and in VS Code, I’ve also tweaked the VS Code defaults for the Solarized Dark theme. Add these overrides in your user settings , settings.json

"workbench.colorCustomizations": {
        "[Solarized Dark]": {
            "editor.foreground": "#708284",
            "editor.background": "#18333d",
            "terminal.ansiBrightGreen": "#586e75",
            "terminal.ansiGreen": "#18333d",
            "terminal.ansiCyan": "#00a6b2",
            "terminal.ansiBrightCyan": "#00e5e5",
            "terminal.ansiBrightBlue": "#839496",
            "terminal.ansiBlue": "#00e5e5"

    "editor.fontFamily": "Menlo for Powerline",
    "editor.fontSize": 14,
    "editor.tokenColorCustomizations": {
        "[Solarized Dark]": {
            "comments": "#839496",
            "functions": "#00e5e5",
            //"keywords": "#586e75",
            "types": "#586e75",
            "strings": "#00e5e5",
            "numbers": "#d33682",
            //"variables": "#d33682",
            "textMateRules": [
                    "scope": [
                        "", "",
                        "meta.definition.method", "",
                    "settings": {
                        "foreground": "#00e5e5",
                    "scope": [
                    "settings": {
                        "foreground": "#d33682",

.NET Core

If you want to do .NET Core development from zsh you also need to install it in your Linux environment.

wget -q -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo add-apt-repository universe
sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install dotnet-sdk-2.2

If everything was installed correctly you should now be able to run


Authenticating with Azure Repos

Generate a ssh key and add the public key to your account in Azure Repos

Execute the below statements to generate new keys and copy the public key to the Windows clipboard - ready to be added to Azure Repos

ssh-keygen -C "myemail@domain.local"
cat ~/.ssh/ | clip.exe

(Notice that WSL can call into Windows executables - clip.exe, to interact with the Windows clipboard from Linux)

Authenticating with Azure Artifacts

If you’re building .NET Core apps and libraries changes are that you’re using Azure Artifacts to manage your internal package feed(s). Unfortunatly it has it’s own way of authenticating users and not relying on the ssh keys in your Repos configuration. Luckilly the team has built a credentials provider.

Grab the shell script below and execute it to install the credentials provider

To trigger the credentials provider, run dotnet with the –interactive switch. That’ll ask you to authenticate and cache your token (or credentials)

dotnet restore --interactive
Blog Logo

Christofer Löf