The Ops Community ⚙️

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

Posted on • Updated 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 Author

added mapping for root user

Collapse
 
kaiwalter profile image
Kai Walter Author

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