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”

Working with yaml files in vim

when working with yaml files, indentation is crucial. You can setup vim to make it a little easier, like this:

:set ai ts=2 sw=2 expandtab

The above will set tabstop and shiftwidth to 2 spaces, and make the tab key create spaces instead of tabs. So with this config, you will type 2 spaces, whenever you press tab, just like yaml likes it.

This can of course be put in your vimrc file.

zfs filling up the /boot device with snapshots

So, you are trying to update your system and get this:

Requesting to save current system state
ERROR couldn’t save system state: Minimum free space to take a snapshot and preserve ZFS performance is 20%.
Free space on pool “bpool” is xx%

The zfs filesystem is creating a snapshot every time you install a new kernel, this will add up, and suddenly you are not able to update anymore, and you are seeing a lot of error caused by this. If you are unlucky and reboot, it might even brake your system!

Running Ubuntu with zfs will create a pool called bpool as your /boot device. Continuing I will refer to this as bpool.


To get an overview of your zfs pools, use this command: zfspool list

kasper@AsusPro:~$ zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
bpool 1.88G 1.64G 238M – – 32% 87% 1.00x ONLINE –
rpool 114G 26.3G 87.7G – – 7% 23% 1.00x ONLINE

As you see, my bpool pool is 87% filled up, I have a problem.

To get an overview of snapshots in the bpool pool, use this command: zfs list -t snapshot | grep bpool

kasper@AsusPro:~$ zfs list -t snapshot | grep bpool
bpool/BOOT/ubuntu_nijvpt@autozsys_646r7v 8K – 92.8M –
bpool/BOOT/ubuntu_nijvpt@autozsys_5z8j40 8K – 92.8M –
bpool/BOOT/ubuntu_nijvpt@autozsys_rknbhc 0B – 92.8M –
bpool/BOOT/ubuntu_nijvpt@autozsys_cd3k48 0B – 92.8M –
bpool/BOOT/ubuntu_nijvpt@autozsys_e3s23t 0B – 185M –
bpool/BOOT/ubuntu_nijvpt@autozsys_teumkd 0B – 185M –
bpool/BOOT/ubuntu_nijvpt@autozsys_iaxh6k 88K – 279M –
bpool/BOOT/ubuntu_nijvpt@autozsys_8uh3k1 88K – 372M –
bpool/BOOT/ubuntu_nijvpt@autozsys_kpxpbq 88K – 187M –
bpool/BOOT/ubuntu_nijvpt@autozsys_3lafml 0B – 280M –
bpool/BOOT/ubuntu_nijvpt@autozsys_0gvki1 0B – 280M –
bpool/BOOT/ubuntu_nijvpt@autozsys_8j52ch 82.3M – 187M –
bpool/BOOT/ubuntu_nijvpt@autozsys_2sibtv 72K – 284M –
bpool/BOOT/ubuntu_nijvpt@autozsys_3t44c8 56K – 284M –
bpool/BOOT/ubuntu_nijvpt@autozsys_u58usc 0B – 284M –
bpool/BOOT/ubuntu_nijvpt@autozsys_3okd08 0B – 284M –
bpool/BOOT/ubuntu_nijvpt@autozsys_v18vua 0B – 284M –
bpool/BOOT/ubuntu_nijvpt@autozsys_f5185b 0B – 284M –
bpool/BOOT/ubuntu_nijvpt@autozsys_12i3wc 0B – 288M –
bpool/BOOT/ubuntu_nijvpt@autozsys_o6sgfl 0B – 288M –

Seems like zfs is not doing any housecleaning by itself, we need to help!
To remove a snapshot, we need to destroy it. This is done with the destroy option, like this:

sudo zfs destroy /path/to/snapshot

To remove all snashots in the bpool, you can use the following:

for i in $(zfs list -t snapshot | grep bpool | cut -d ” ” -f 1);do sudo zfs destroy $i; done

This will destroy all snapshots and free up your bpool pool.

If you don’t want to remove all snapshots, pipe your snapshots listing into tail or head. You can add a creation column to the list like this:

zfs list -t snapshot -o name,creation -s creation

This will list your snapshots in order of creation date. Use wc -l to count them and use head to get x amount fewer.

zfs list -t snapshot -o name,creation -s creation | wc -l
20

for i in $(zfs list -t snapshot | grep bpool | cut -d ” ” -f 1 | head -15);do sudo zfs destroy $i; done

I did try to format the commands, but as usual Word Press make things so complicated to use, that i had to revert all the special formatting, instead of spending the entire day figuring out why html tags are not respected in “enlighter inline code”

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.

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/

Upgrading from vSphere VCSA 6.5 pre version U1d to post version U1d not possible

Yesterday I had to upgrade a VCSA 6.5 U1b to U2e, but I got stuck in the process because the VCSA manager said this:

Latest updates already installed on vCSA, Nothing to stage/install

Hmm, thats not right… google, google, google
Seems that vmware changed the build numbering scheme, and they have an article about my issue:
https://kb.vmware.com/s/article/59659
Unfortunately the link to the attachement was dead 🙁 I had to create a case with vmware support to get the shell script.
So, to prevent this from happening again, heres the four lines thats in the script:

sed -i “s/if metadata[‘buildnumber’] <= _getBaseBuildNumber():/if int(metadata[‘buildnumber’]) <= int(_getBaseBuildNumber()):/g” /usr/lib/applmgmt/base/py/vmware/vherd/base/software_update.py
service-control –stop applmgmt
service-control –start applmgmt

Create a file on your VCSA in /root/ called buildversion.sh, paste the four lines above into it. Make it executable, run it, upgrade your VCSA.

Lidt mere om SSH tunneler

Jeg har tidligere skrevet lidt om hvoran man kan bruge SSH tunnel til at lave portforwarding, det kan vĂŠre en lĂžsning hvis man f.eks. ikke vil Ă„bne sin webserver op mod internettet.

Netop denne situation stod jeg i da min bror havde brug for et regnskabsprogram og jeg tilbĂžd ham at installere en webserver med det danske gratis regnskabsprogram Saldi.

Jeg kender ikke til sikkerheden i webapplikationen, og jeg er ikke sikker pĂ„ hvor tit jeg lige fĂ„r opdateret denne server (det skulle helst vĂŠre en “install and forget”) Derfor ville jeg ikke Ă„bne op for det store internet.

Jeg valgte istedet at installere tunnelier fra bitvise pÄ min brors PC, og herefter konfigurere den til at oprette en tunnel og starte en browser op, der peger pÄ den side han skal ind pÄ.

Det er der jo i forhold til min tidligere post ikke noget nyt i, det nye kommer her:

For at sikre mig at min bror ikke laver rav i den fra den bash shell han som default fÄr nÄr jeg opretter ham pÄ mit system, Êndrede jeg hans shell fra /bin/bash til /bin/false i /etc/passwd filen. Nu har han ikke mulighed for at logge ind med en shell, men han kan stadig forwarde porte.

Husk derfor ogsÄ, at /bin/false skal bruges med omtanke, da den altsÄ giver visse muligheder udover bare at blokere for login. Brug istedet /bin/nologin hvis du vil spÊrre helt af for en brugers mulighed for at logge ind/bruge portforwarding.

LĂŠs evt. mere om det her: http://www.semicomplete.com/articles/ssh-security/

Mvh.