Windows Links‎ > ‎

SSH Service - Built In PS

Install the latest version of PowerShell

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

  • 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~~~~
    Add-WindowsCapability -Online -Name OpenSSH.Server~~~~

  • 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
    DenyUsers contoso\admin@

    # 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@
    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 " "