The Ops Community ⚙️

Cover image for PowerShell script to setup SSH folder on WSL
Kai Walter
Kai Walter

Posted on • Edited on

PowerShell script to setup SSH folder on WSL

I created this script for me to quickly copy my .ssh environment from my Windows system to a WSL distribution and to do a basic Git setup.

It is based on the feature that WSL 2 exposes a distributions filesystem as \\wsl.localhost\{distribution name} e.g. \\wsl.localhost\Ubuntu.

[CmdletBinding()]
param (
    [string] $distroName = "Ubuntu",
    [string] $userName = "mymysticuser"
)

# --------------------------------------------------------------------------------
# INIT

$sshFolder = Join-Path $HOME ".ssh"
$userPath = "\home\$userName"
if($userName -eq "root") {
    $userPath = "\root"
}
$targetHome = "\\wsl.localhost\$distroName\$userPath"

if (!(Test-Path $targetHome)) {
    $targetHome = "\\wsl$\$distroName\$userPath"
    if (!(Test-Path $targetHome)) {
        throw $("Home folder $targetHome not found")
    }
}

$targetHomeSsh = Join-Path $targetHome ".ssh"

# --------------------------------------------------------------------------------
# BASIC .ssh SETUP

if (!(Test-Path $targetHomeSsh)) {
    Write-Host "creating $targetHomeSsh"
    New-Item -Path $targetHomeSsh -ItemType Directory
}

Write-Host "generating /home/$userName/.ssh/config"

$targetConfig = Get-Content $(Join-Path $sshFolder "config") -Raw
$targetConfig.Replace("\r\n","`n").Replace("\r","") | Set-Content $(Join-Path $targetHomeSsh "config") -NoNewline

# --------------------------------------------------------------------------------
# COPY .ssh FILES

Write-Host "copying SSH files to $targetHomeSsh"
$sshFiles = Get-ChildItem -Path $sshFolder | ? { $_.Name -notmatch "(config|known_hosts|authorized_keys)" }

foreach ($sshFile in $sshFiles) {
    if (!(Test-Path $(Join-Path $targetHomeSsh $sshFile.Name))) {
        Write-Host ".. copying" $sshFile.FullName $($connection + ":/home/" + $userName + "/.ssh/")
        Copy-Item -Path $sshFile.FullName -Destination $targetHomeSsh
        if ($sshFile.Name -match "\.pub$") {
            $mode = "644"
        }
        else {
            $mode = "600"
        }
        wsl -d $distroName -- chmod $mode ~/.ssh/$($sshFile.Name)
    }
}

# --------------------------------------------------------------------------------
# PROCESS GIT 

$jobs = @{}

$jobs["01 - configuring SSH/GIT"] = @(
    "chmod 700 ~/.ssh",
    "chmod 644 ~/.ssh/config",
    "if [ ! -e ~/.ssh/known_hosts ]; then ssh-keyscan -H github.com > ~/.ssh/known_hosts; fi"
)

$jobs["02 - cloning script repo"] = @(
    "if [ ! -d ~/scripts ]; then git clone git@github.com:KaiWalter/bash-scripts.git ~/scripts; fi"
)

$jobs["03 - dotfiles"] = @(
    "if [ ! -d ~/.dotfiles.git ]; then git clone --bare git@github.com:KaiWalter/dotfiles.git ~/.dotfiles.git; fi",
    "echo `".dotfiles.git`" >> ~/.gitignore",
    "git --git-dir=`$HOME/.dotfiles.git/ --work-tree=`$HOME/ checkout"
)

$jobs["04 - cloning project repos"] = @(
    "if [ ! -d ~/src ]; then mkdir -p ~/src; fi",
    "if [ ! -d ~/src/message-distribution ]; then git clone git@github.com:KaiWalter/message-distribution.git ~/src/message-distribution; fi"
)

foreach ($kv in ($jobs.GetEnumerator() | Sort-Object Key)) {
    Write-Host $kv.Key
    foreach ($step in $kv.Value) {
        $argumentList = $("-d $distroName -- " + $step).Split(" ")
        Start-Process "wsl.exe" -ArgumentList $argumentList -NoNewWindow -Wait
    }
}
Enter fullscreen mode Exit fullscreen mode

I do no adaptations to .zshrc or .bashrc during the dotfiles setup, as these files are then checked out from the repository

Top comments (2)

Collapse
 
kaiwalter profile image
Kai Walter •

added fallback UNC \wsl$ for older WSL/Windows versions

Collapse
 
kaiwalter profile image
Kai Walter •

added mapping for root user