Powershell SSH Connection manager

I’ve recently a connection manager for SSH connections to the posh-sshell project.

What is Posh-Sshell?

Posh-Sshell is a set of powershell scripts that making working with SSH agents and clients easier. These utilities were originally part of the posh-git project, but have been separated into a separate module in preparation for the Posh-Git 1.0 release.

Posh-Sshell can be downloaded from the powershell gallery by running the following in a powershell prompt:

Install-Module Posh-Sshell -Scope CurrentUser

Once installed, import the module with Import-Module Posh-Shell (you can add this to your powershell profile so you don’t need to run it every time you launch a new terminal).

Connection Manager

Since splitting the SSH functionality out of posh-git, I’ve been working on several new features the first of which is the Connection Manager.

The Connection Manager can be used to display a list of SSH connections as well as add/remove connections from the ~/.ssh/config file. By running Connect-Ssh, you’ll be presented with a list of connections stored in your .ssh/config file:


You can enter the number of the server into the prompt, and an SSH connection will be made to that server. If no username is specified in the configuration file, then you’ll also be prompted for a username.

Adding a New Connection

A new connection can be added by running Add-SshConnection. In its simplest form, it takes an alias and a URI, eg:

Add-SshConnection MyServer3 myserver.mydomain.com

You can also specify additional common properties such as the username, either by using the -User parameter or using the user@host syntax:

# These are both the same
Add-SshConnection MyServer3 myserver.mydomain.com -User jeremy
Add-SshConnection MyServer3 jeremy@myserver.mydomain.com

You can specify a custom key file by using -IdentityFile <path> as well as parameters for configuring an SSH tunnel with -LocalTunnelPort <port number> and -RemoteTunnelPort <port number>.

Additional parameters can also be specified by supplying a hashtable to the -AdditionalOptions parameter.

After running Add-SshConnection MyServer3 myserver.mydomain.com -User jeremy, your .ssh/config file will contain the new entry:

Host MyServer3
  HostName myserver.mydomain.com
  User jeremy

Removing an entry

Entries can be removed from the config file by running Remove-SshConnection <name>

Written on July 30, 2018

Thoughts on using Drupal

After 10 years working with ASP.NET and C#, I’ve spent the last few months working with Drupal 8 and PHP. The last time I worked with PHP was in 2005, and although the language is still full of inconsistencies, it’s nice to see that it’s a fully object-oriented language and supports more modern functionality like anonymous functions and traits.

Working with Drupal 8 has been quite a learning experience. Drupal is an extremely powerful platform, but has a huge learning curve. The documentation is pretty poor compared to the very well-written in-depth tutorials and API docs that ASP.NET provides. However It’s good to see that Drupal 8 has embraced a more MVC-based approach (by using Symfony controllers), dependency injection and plugins. Sadly the horrible hook-based extensibility system hasn’t completely gone away yet.

The hardest thing I’ve found with Drupal is following an application’s flow. Diving into an existing codebase and trying to find where a piece of functionality is implemented is something I found extremely challenging. For example a button on a form could be defined directly in a Form class, through a YAML file, or any number of hooks in any module within the application. I suppose this is the downside of an extremely flexible extensibility model.

I’ve also been enjoying getting much more into Linux and server management using the Bash CLI, something I’ve had very little experience with (my CLI of choice is usually Powershell)

Overall C#/.NET would still be my platform of choice, but learning something new and working on some very interesting projects with a great team is much more important to me than choice of language.

Written on July 28, 2018

Using the same Home Directory in Windows and WSL

I’ve recently been using the Windows Subsystem for Linux (WSL) a lot more recently now that I’m working with Linux servers.

One thing I’ve found frustrating is having to keep my home directories in sync, for example having to duplicate my ssh keys between my Windows home directory in c:\users\Jeremy\.ssh and my WSL installation in \home\jeremy\.ssh, along with various other files like .gitconfig.

It turns out it’s actually pretty straight forward to set WSL to use your Windows home directory.

First, within WSL edit the /etc/passwd file (eg with sudo nano /etc/passwd). Find the line that defines your username (probably at the bottom), which will look something like this:


…and change the home directory path so that it points to your Windows home directory using WSL path notation:


Exit WSL and re-open it, and your home directory will now match your windows directory.

Metadata and File Permissions

A problem with this approach is that your ssh keys need to be secured, but by default Windows files accessed through WSL are readable/writable by everyone and chmod has no affect on Windows files. This can be remedied by re-mounting your Windows partition inside WSL with the metdata option. Edit the /etc/wsl.conf file (create it if it doesn’t exist) and add the following:

options = "metadata"

Log out from WSL and log in again, and now the windows partition will be mounted with metadata and chmod will work against windows files. You can now chmod 600 ~/.ssh/id_rsa and everything will work correctly.

Written on July 27, 2018

FluentValidation 8.0-rc1 is now available

FluentValidation 8.0-rc1 is now available and can be downloaded from nuget This release contains several breaking changes and feature enhancements:

Validating properties by path

You can now validate specific properties using a full path, eg:

validator.Validate(customer, "Address.Line1", "Address.Line2");

Validating a specific ruleset with SetValidator

Previously, if you defined a child validator with SetValidator, then whichever ruleset you invoked on the parent validator will cascade to the child validator. Now you can explicitly define which ruleset will run on the child:

RuleFor(x => x.Address).SetValidator(new AddressValidator(), "myRuleset");

AttrbiutedValidatorFactory has been moved to a separate package

The ValidatorAttribute and the AttributedValidatorFactory were typically used in MVC/WebApi projects to wire models to their validators. This is no longer recommended when usign AspNetCore as the built-in Service Provider is a better alternative. These classes can still be used by explicitly installing the FluentValidation.ValidatorAttribute package. Note this package is installed by default if you are using the legacy MVC5/WebApi integration rather than AspNetCore.

SetCollectionValidator is deprecated

RuleForEach provides a more flexible syntax for the same result.

Additonally lots of methods deprecated in previous versions have now been removed. Please check out the upgrade guide for further details. If you run into any issues, please post them on the GitHub project site

Written on July 24, 2018

FluentValidation 8.0-preview1 is now available

Fluentvalidation 8.0-preview1 is now available. This is a major release with several breaking changes.

The biggest change is that validators should now inherit from ValidatorBase rather than AbstractValidator so you can take advantage of the new rule caching that’s available in FluentValidation 8. This change has been reverted for now and removed from preview2 due to some critical issues which were found.

Please check out the upgrade guide. If you run into any issues, please post them on the GitHub project site

Written on July 10, 2018