SSH Service - Built In PS

Install the latest version of PowerShell

  • Get the newest version from the Github page (msi version for windows):

  • https://github.com/PowerShell/PowerShell/releases

  • Move the MSI to the server. This can be done by going to the C$ of the server after the firewall is off.

  • Run and install the MSI:

    • msiexec.exe /package PowerShell-7.0.2-win-x64.msi /quiet ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL=1 ENABLE_PSREMOTING=1 REGISTER_MANIFEST=1

    • # Go ahead and install the windows update module while at it.

    • Install-Module PSWindowsUpdate

Install SSH

  • This needs to be done from an elevated command. In order to do this (if you're already not elevated). Run the command:

    • start-process powershell -verb runAs

  • Next Run the Command:

    • Get-WindowsCapability -Online | ? Name -like 'OpenSSH*'

  • This should display the Client and Server versions available.

  • Assuming you see the Server and client versions available, install them with the commands:

    • Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0

    • Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0

  • Both should return True for Online and False for Restart Needed

  • Then Start the service:

    • Start-Service sshd

  • Set it to start automatically:

    • Set-Service -Name sshd -StartupType 'Automatic'

  • Confirm the Firewall rule is configured. It should be created automatically by setup.

    • Get-NetFirewallRule -Name *ssh*

  • There should be a firewall rule named "OpenSSH-Server-In-TCP", which should be enabled

  • If the firewall does not exist, create one

    • New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22

  • At this point you should be able to SSH into the server (although it doesn't default to PowerShell)

Configure SSH

  • Next lets configure SSH to go directly to PowerShell. Set the default Shell for SSH in the registry:

    • New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -PropertyType String -Force

  • Or to set it to the newest version of PowerShell that was just installed:

    • New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "c:/progra~1/powershell/7/pwsh.exe" -PropertyType String -Force

  • Make sure the 8.3 short name for Program Files folder in Windows works:

    • Get-CimInstance Win32_Directory -Filter 'Name="C:\\Program Files"' | Select-Object EightDotThreeFileName

  • The rest of the configuration is done through the %programdata%\ssh\sshd_config file by default. Add some options to this file (this can be done with vim if you do a full install of it):

  • These are to insure PW auth and setup PS7 for the PS subsystem

    • PasswordAuthentication yes

    • Subsystem powershell c:/progra~1/powershell/7/pwsh.exe -sshs -NoLogo -NoProfile

  • Commands such as these are to deny and allow users

    • # blocks contoso\admin from 192.168.2.23

    • DenyUsers contoso\admin@192.168.2.23

    • # blocks all users from contoso domain

    • DenyUsers contoso\*

    • # only allow users from contoso\sshusers group

    • AllowGroups contoso\sshusers

    • AllowGroups "sbschools\Domain Admins"

    • # Examples for local users and groups

    • AllowUsers localuser@192.168.2.23

    • AllowGroups sshusers

    • After the config file is finished being edited, restart the service

      • Restart-Service sshd

Configure Prompt

  • Configure the default prompt for all users by editing the file $PSHOME\Profile.ps1

  • Here's the contents of the current prompt version

    • function prompt {

    • $pidentity = [Security.Principal.WindowsIdentity]::GetCurrent()

    • $pprincipal = [Security.Principal.WindowsPrincipal] $pidentity

    • $padminRole = [Security.Principal.WindowsBuiltInRole]::Administrator

    • # set username color based on permissions

    • if (Test-Path variable:/PSDebugContext) { $pcolor = "yellow" }

    • elseif($pprincipal.IsInRole($padminRole)) { $pcolor = "red" }

    • else { $pcolor = "green" }

    • $PromptTime = $(get-date).ToString("hh:mm MM/dd/yy")

    • # Display titlebar

    • $host.ui.rawui.WindowTitle = "::" + $env:computername + ":: - " + $PromptTime + " - PS Version: " + $Host.Version + " Line: " + $host.UI.RawUI.CursorPosition.Y

    • $ppath = ((get-location).path).replace($Home,'~')

      • if ( $ppath.length -gt 20 ) {

      • $ppath = ".." + $ppath.substring($ppath.length - 20)

      • }

    • # Write Prompt

    • Write-Host "[" -NoNewline

    • Write-Host "$env:UserName" -f $pcolor -NoNewline

    • Write-Host "@" -NoNewline

    • Write-Host "$env:computername" -f DarkCyan -NoNewline

    • Write-Host " $ppath]:" -NoNewline

    • return " "

    • }

https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell-core-on-windows

https://docs.microsoft.com/en-us/powershell/scripting/learn/remoting/ssh-remoting-in-powershell-core

https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_server_configuration