Making the windows terminal great again

Once again my employeer forces me to work from an inferior platform, so what are my options to get the best possible working environment? Heres some tips to what I’ve done so far.

The windows terminal is one of the better things produced by Microsoft the last couple of years. I have already written a bit about it before, so search for windows terminal, and you will get the other articles. Even though the terminal is nice, there are some minor annoyances, when you are used to work in a bash environment.

  1. No nice “inline” editor
  2. Does not obey ctrl-d to exit the session
  3. Does not have tab completion on entries in the ssh config file

To fix these three annoyances, we need to download vim from www.vim.org, install it and the rest is done creating and configuring a powershell profile, lets dive into it.

Not only do I have to work from a windows machine (my department does primarily FOSS solutions) I also don’t have any elevated permissions on my machine. IT proffesionlas are treated just the same as office workers 🙁

This means I cannot install any software, besides whats picked by the Windows admins. Luckily vim is not picky, and you can install it in your own home folder. So lauch the installer and change the install path accordingly.

When vim is installed, all we need to do is to create a powershell profile file. The file has to be named Microsoft.PowerShell_Profile.ps1 and has to be placed under $home\Documents\PowerShell\
When placed here it will be a user specific profile, you can also do system-wide profiles, take a look at $pshome.

The profile file I have created looks like this:

using namespace System.Management.Automation

# Set aliases

Set-Alias -name vim $home\Vim\vim90\vim.exe
Set-Alias -name vi $home\Vim\vim90\vim.exe

# Obey ctrl-d

Set-PSReadlineKeyHandler -Key ctrl+d -Function ViExit

# Enable ssh tab completion
# Credits to backerman and contributers at github for creating the code

Register-ArgumentCompleter -CommandName ssh,scp,sftp -Native -ScriptBlock {
param($wordToComplete, $commandAst, $cursorPosition)

function Get-SSHHostList($sshConfigPath) {
    Get-Content -Path $sshConfigPath `
    | Select-String -Pattern '^Host ' `
    | ForEach-Object { $_ -replace 'Host ', '' } `
    | ForEach-Object { $_ -split ' ' } `
    | Sort-Object -Unique `
    | Select-String -Pattern '^.*[*!?].*$' -NotMatch
}

function Get-SSHConfigFileList ($sshConfigFilePath) {
    $sshConfigDir = Split-Path -Path $sshConfigFilePath -Resolve -Parent

    $sshConfigFilePaths = @()
    $sshConfigFilePaths += $sshConfigFilePath

    $pathsPatterns = @()
    Get-Content -Path $sshConfigFilePath `
    | Select-String -Pattern '^Include ' `
    | ForEach-Object { $_ -replace 'Include ', '' }  `
    | ForEach-Object { $_ -replace '~', $Env:USERPROFILE } `
    | ForEach-Object { $_ -replace '\$Env:USERPROFILE', $Env:USERPROFILE } `
    | ForEach-Object { $_ -replace '\$Env:HOMEPATH', $Env:USERPROFILE } `
    | ForEach-Object { 
    $sshConfigFilePaths += $(Get-ChildItem -Path $sshConfigDir\$_ -File -ErrorAction SilentlyContinue -Force).FullName `
    | ForEach-Object { Get-SSHConfigFileList $_ } 
    }

    if (($sshConfigFilePaths.Length -eq 1) -and ($sshConfigFilePaths.item(0) -eq $sshConfigFilePath) ) {
        return $sshConfigFilePath
    }

    return $sshConfigFilePaths | Sort-Object -Unique
}

$sshPath = "$Env:USERPROFILE\.ssh"
$hosts = Get-SSHConfigFileList "$sshPath\config" `
| ForEach-Object { Get-SSHHostList $_ } `

# For now just assume it's a hostname.
$textToComplete = $wordToComplete
$generateCompletionText = {
    param($x)
    $x
}
if ($wordToComplete -match "^(?<user>[-\w/\\]+)@(?<host>[-.\w]+)$") {
    $textToComplete = $Matches["host"]
    $generateCompletionText = {
        param($hostname)
        $Matches["user"] + "@" + $hostname
    }
}

$hosts `
| Where-Object { $_ -like "${textToComplete}*" } `
| ForEach-Object { [CompletionResult]::new((&$generateCompletionText($_)), $_, [CompletionResultType]::ParameterValue, $_) }}

Exit your terminal and lauch it again, hopefully you can be a bit more productive with the new “features”

Find and unmount CD drives with PowerCLI

Sometimes someone forgets to unmount the CD drive of a VM. This will interfere with operation tasks like setting a host in maintenance mode or using Update Manager.

I recently had this issue, and the “update manager compliance check” told me that several VM’s where connected to a CD drive, which may interrupt the update process. I quickly found my favorite tool for vcenter management, the powerCLI. The quick and dirty oneliner ended up like this:

get-cluster %clustername% | get-vm | where {(($_ | Get-CDDrive).isopath) -gt ""} | %{$_ | Get-CDDrive | Set-CDDrive -NoMedia -Confirm:$false}

Replace %clustername% with your cluster name, and all your troubles will be over 🙂

I have always loved oneliners. I have spent the part time of my time working in bash terminals, where the history has always been persistent. Luckily Microsoft has also seen the light, and history is now persistent (and searchable) in powershell. Search for a phrase using ctrl+r, search further back by pressing ctrl+r again. I’m sure you will learn to love it, if you don’t already do.

Windows 10 missing ssh-copy-id

Microsoft is finally shipping Windows with SSH. On my Windows 10 machine, it’s OpenSSH:

PS C:\Users\Kasper> ssh -V
OpenSSH_for_Windows_7.7p1, LibreSSL 2.6.5

Somehow they missed to get the ssh-copy-id tool implemented, so we need to find another way of copying our ssh keys. Thankfully it’s not that complicated, we can use powershell (probably even cmd)

cat .\.ssh\id_rsa.pub | ssh -l username ssh_server "cat >> .ssh/authorized_keys"

This will concatenate (cat) your ssh key to the authorized_keys file on your ssh_server.

I’m using cat, to make it easy for Linux/unix admins, type, and get-content will also do, as both cat and type are aliases for get-content. I assume “type” will be available in cmd.exe

Ping not permitted in WSL

Using Windows subsystem for Linux (WSL) is so nice, when you are forced to work from an inferior OS, sometimes also referred to as “a gaming console”
Especially combined with the Windows Terminal, which I wrote about here: https://www.nordal-lund.dk/?p=592 I’m sure that most Linux/Unix administrators will feel right at home.

Despite all the goodness, there are some minor annoyances preventing me from experiencing a big burst of happiness. One of them are the inability to use ping on a std. WSL Debian as a non-root user. That’s right, you need to do “sudo ping nice.little.address” or you will be denied 🙁

The root cause is the ping utility missing the SUID bit, which it has on the real distro. Luckily there’s an easy fix, add the SUID bit to the ping utility:

sudo chmod u+s /bin/ping

Thats it, now you can ping without sudo again 🙂

Happy pinging
/Kasper

Finally a decent terminal for Windows

Tip! Check out my new post about making the terminal great again here

For years and years Windows users have had to work with disabled tools when trying to work in the command line interface. The old cmd had a bad interface, and even powershell until very recent, has also been a pain. One of the most annoying things has been the missing ability to adjust the window size to your needs, furthermore tab completion has either been missing or bad implemented. All in all, flexibility has not been a keyword for any of the old terminals, but this is all in the past, because now we have Windows terminal!

Easy to install from the Windows store or with command line package manager like chocolatey, and has a great deal of the features you know from various Linux terminals.

Windows terminal supports multiple terminals in tabs, split panes horizontal and vertical, custom background and a lot more. Check it out here: https://github.com/microsoft/terminal

If you are a Linux user and sometimes have to work from Windows, Windows terminal also work perfect with WSL (Windows Subsystem for Linux). Install the terminal, install your favorite Linux, and you are good to go. Here are some small tips to make the experience even better:

  1. Make Linux the default shell by editing the json settings file. You find it by clicking the small “down-arrow” and select settings. Add the guid number of the Linux you want to start to the defaultprofile setting.
  2. Make the Linux shell start in the Linux home folder by adding this setting to the bottom of the paragraph of your Linux profile:
    “commandline”: “wsl.exe ~”

If you are interested in command line stuff, and working on Windows, this is a nice resource to follow: https://devblogs.microsoft.com/commandline/

Stop Windows processes remotely

Some customer called saying that they couldn’t log in to a certain Windows box. vMware told me the VM was using 100% CPU, and it was to busy doing something to let users log in.
Powershell saved the day (or at least saved the VM from beeing reset)
To find the process running wild I used the invoke-command cmdlet, like this:

invoke-command -scriptblok(get-process | sort-property CPU -Descending | select -first 10) -computername “Windows Hostname” | ft -autosize

This gave me a nice list of processes with the one we should focus on in the top. Now all i needed to do was:

invoke-command -scriptblok(stop-process -Id “pid”) -computername “Windows Hostname”

The process was stopped, and CPU usage fell to 0-2% allowing application people to login and investigate what happened.

Test network connection with powershell

Sometimes you need to test the network connection for a range of IP addresses. Normally I would use ping from a commandline, but it could be a hugh task to test more than 20-30 addresses.
Utilizing a bit of powershell and the test-connection command will help us overcome the task in an easy way:

[code language=”powershell”]1..100 | %{write-host -nonewline "Testing 10.0.0.$_ : "; Test-Connection 10.0.0.$_ -quiet -Count 1}[/code]

The above one-liner will test the connection to all hosts in a range from 10.0.0.1 to 10.0.0.100 and giva a False or True status.
Remember that % is a short way of using the foreach loop, so you could use “foreach” instead of %.

Using Vim as editor in PowerShell

If you are used to using Vim or Vi as your editor, you might miss it when using powershell. Good news is, theres a way to get it. Download and install Vim for windows, create a profile.ps1 file in this path: (for me at least) c:\users\%username%\documents\WindowsPowerShell\ and type in the following:

$VIMPATH    = “C:\Program Files (x86)\Vim\vim74\vim.exe”

Set-Alias vi   $VIMPATH
Set-Alias vim  $VIMPATH

# for editing your PowerShell profile
Function Edit-Profile
{
vim $profile
}

# for editing your Vim settings
Function Edit-Vimrc
{
vim $home\_vimrc
}

Remember to change the $VIMPATH to your installation.

Now you have a fully functional vim from powershell.

/Kasper

Installer MPEG-2 licens pÄ Raspberry Pi

Raspberry Pi er lavet med henblik pĂ„ at den skal kunne kĂžbes af alle, derfor er der sparet alle steder hvor det er muligt. En af de steder der er sparet er i CPU’ens mulighed for at decode visse codecs, istedet for bare at ligge en licens ind fra starten, der ville forhĂžje prisen for alle, har man valgt en model hvor man selv kĂžber en licens, hvis man vil bruge raspberry pi som mediecenter og har brug forat afspille disse codecs.

For mit vedkommende gÊlder det primÊrt de optagelser jeg laver med min mythtv server, de ligger tit i MPEG-2 format og dem kan jeg sÄ ikke uden videre afspille pÄ min OpenElec installation pÄ raspberry pi.

LĂžsningen er at kĂžbe en licens her: http://www.raspberrypi.com/mpeg-2-license-key/

Omregnet koster den ca. 25 dkr, det er lige til at overkomme, men hvordan fÄr man den sÄ installeret?

Inden man bestiller skal man lige hav fundet serienummeret pÄ sin CPU, det gÞres sÄledes:

SSH til din raspberry pi. PÄ en Openelec er std. kodeord openelec, og brugernavnet er root. Fra windows kan man bruge Putty, pÄ Linux kan man bruge terminalen og skriv:

ssh -l root ip-adresse-pÄ-raspberry-pi

NĂ„r man er logget ind kĂžrer man kommandoen:

cat /proc/cpuinfo

Det ser sÄdan her ud:

root@stuen’s password:
##############################################
# OpenELEC – The living room PC for everyone #
# …… visit http://www.openelec.tv …… #
##############################################

OpenELEC (official) Version: 4.0.6
Stuen:~ # cat /proc/cpuinfo
processor    : 0
model name    : ARMv6-compatible processor rev 7 (v6l)
Features    : swp half thumb fastmult vfp edsp java tls
CPU implementer    : 0x41
CPU architecture: 7
CPU variant    : 0x0
CPU part    : 0xb76
CPU revision    : 7

Hardware    : BCM2708
Revision    : 000f
Serial        : 0000000002529fb3
Stuen:~ #

Min raspberry hedder Stuen, bare for at undgĂ„ misforsatĂ„elser 🙂

NÄr man har fÄet fat i serienummeret kan man bestille sin licens.

Efter et par dage dumper der en mail ind, med en specifik genereret kode der passer til din raspberry pi, nu skal den sÄ installeres, det gÞres som fÞlger:

Log ind pĂ„ din raspberry med ssh igen, i mappen /flash skal der vĂŠre en config.txt fil, mĂ„ske findes den allerede, ellers skal den laves. Men inden vi gĂžr noget skal vi lige sikre os at vi kan skrive i /flash mappen, den er nemlig mounted “read only”, vi remounter den lige med “read write”. GĂžr dette fra root folderen (cd /)

mount /flash -o remount,rw

Nu kan vi skrive i mappen og enten editere den fil der allerede ligger der, eller lave en ny. Filen skal indeholde en linie med “decode_MPG2=den-kode-du-fiki-din-mail”

vi /flash config.txt

tryk pĂ„ “i” for at skrive i filen

tryk :wq for at gemme (kolon efterfulgt af w og q write/quit)

Vi er en editor der kan virke lidt besvÊrlig til at begynde med, men lÊr dig selv de mest basale kommandoer, den findes stort set pÄ alle Unix/Linux systemer

NĂ„r du har gemt filen skriver du reboot i konsollen, systemet genstarter og du kan nu se MPEG2 filer 🙂

ForlĂŠnge windows prĂžve periode.

Ofte kan man have brug for at teste et eller andet i et givent OS, det kune f.eks. vĂŠre Windows 7 embedded standard (det er ihvertfald det jeg skal teste)

Som standard er der en 30 dages prÞvepriode, nÄr den er udlÞbet begynder computeren bl.a. selv at reboote hver anden time for ligesom at gÞre opmÊrksom pÄ at prÞve perioden er udlÞbet.

Den periode kunne vÊre rar at forlÊnge, og det kan man ogsÄ med fÞlgende fremgangsmÄde:

Skiv “cmd” i search boksen i start menuen. Nu kan man hĂžjreklikke pĂ„ programmet cmd.exe Ăžverst i listen og vĂŠlge “kĂžr som administrator”

NĂ„r kommando prompten er fremme skriver man fĂžlgende:

slmgr -rearm

Du vil nu blive bedt om at genstarte computeren, og der skulle nu gerne vĂŠre 30 nye dage til at teste i.

OvenstÄende procedure kan gennemfÞres 3 gange og man kan altsÄ i alt fÄ 120 dage til at teste i