| 1 | @echo off |
| 2 | :: |
| 3 | :: This script will: |
| 4 | :: |
| 5 | :: 1. install the windows OpenSSH server (either via dsim or download it) |
| 6 | :: 2. activate the windows OpenSSH service |
| 7 | :: 3. open OpenSSH TCP port at windows firewall |
| 8 | :: 4. create a small batch file to start an MSYS session |
| 9 | :: 5. Set the default OpenSSH startup script to start the MSYS session |
| 10 | :: |
| 11 | :: Problems: |
| 12 | :: On older windows versions, terminal emulation is broken. |
| 13 | :: So, on windows 10 or windows server before 2019, the ssh session |
| 14 | :: will not have proper terminal emulation and will be not be able to |
| 15 | :: be used for editing files. |
| 16 | :: For more info check: |
| 17 | :: https://github.com/PowerShell/Win32-OpenSSH/issues/1260 |
| 18 | :: |
| 19 | |
| 20 | :: Check if OpenSSH Server is already installed |
| 21 | sc query sshd >nul 2>&1 |
| 22 | if %errorlevel% neq 0 ( |
| 23 | echo "OpenSSH Server not found. Attempting to install via dism..." |
| 24 | goto :install_openssh_dism |
| 25 | ) else ( |
| 26 | echo "OpenSSH Server is already installed." |
| 27 | goto :configure_openssh |
| 28 | ) |
| 29 | |
| 30 | :: Install OpenSSH using dism |
| 31 | :install_openssh_dism |
| 32 | dism /online /Enable-Feature /FeatureName:OpenSSH-Client /All >nul 2>&1 |
| 33 | dism /online /Enable-Feature /FeatureName:OpenSSH-Server /All >nul 2>&1 |
| 34 | |
| 35 | :: Check if dism succeeded in installing OpenSSH |
| 36 | sc query sshd >nul 2>&1 |
| 37 | if %errorlevel% neq 0 ( |
| 38 | echo "OpenSSH installation via dism failed or is unavailable." |
| 39 | goto :install_openssh_manual |
| 40 | ) else ( |
| 41 | echo "OpenSSH installed successfully using dism." |
| 42 | goto :configure_openssh |
| 43 | ) |
| 44 | |
| 45 | :: Function to Install OpenSSH manually if dism fails |
| 46 | :install_openssh_manual |
| 47 | echo "Installing OpenSSH manually..." |
| 48 | |
| 49 | :: Download the latest OpenSSH release |
| 50 | set DOWNLOAD_URL=https://github.com/PowerShell/Win32-OpenSSH/releases/download/v9.5.0.0p1-Beta/OpenSSH-Win64.zip |
| 51 | set DOWNLOAD_FILE=%temp%\OpenSSH-Win64.zip |
| 52 | set INSTALL_DIR=C:\Program Files\OpenSSH-Win64 |
| 53 | |
| 54 | :: Create the installation directory if it doesn't exist |
| 55 | if not exist "%INSTALL_DIR%" mkdir "%INSTALL_DIR%" |
| 56 | |
| 57 | :: Attempt to download OpenSSH using Invoke-WebRequest and TLS configuration |
| 58 | powershell -Command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; try { Invoke-WebRequest -Uri '%DOWNLOAD_URL%' -OutFile '%DOWNLOAD_FILE%' -UseBasicParsing; exit 0 } catch { exit 1 }" |
| 59 | if %errorlevel% neq 0 ( |
| 60 | echo "Invoke-WebRequest download failed. Attempting to download using curl..." |
| 61 | curl -L -o "%DOWNLOAD_FILE%" "%DOWNLOAD_URL%" |
| 62 | if %errorlevel% neq 0 ( |
| 63 | echo "Failed to download OpenSSH using curl. Exiting..." |
| 64 | exit /b 1 |
| 65 | ) |
| 66 | ) |
| 67 | |
| 68 | :: Unzip directly to INSTALL_DIR (flatten the folder structure) |
| 69 | powershell -Command "Expand-Archive -Path '%DOWNLOAD_FILE%' -DestinationPath '%INSTALL_DIR%' -Force" |
| 70 | if %errorlevel% neq 0 ( |
| 71 | echo "Failed to unzip OpenSSH package." |
| 72 | exit /b 1 |
| 73 | ) |
| 74 | |
| 75 | :: Move inner contents to INSTALL_DIR if nested OpenSSH-Win64 folder exists |
| 76 | if exist "%INSTALL_DIR%\OpenSSH-Win64" ( |
| 77 | xcopy "%INSTALL_DIR%\OpenSSH-Win64\*" "%INSTALL_DIR%\" /s /e /y |
| 78 | rmdir "%INSTALL_DIR%\OpenSSH-Win64" /s /q |
| 79 | ) |
| 80 | |
| 81 | :: Add the OpenSSH binaries to the system PATH |
| 82 | setx /M PATH "%INSTALL_DIR%;%PATH%" |
| 83 | |
| 84 | :: Register OpenSSH utilities as services using PowerShell |
| 85 | powershell -ExecutionPolicy Bypass -Command "& '%INSTALL_DIR%\install-sshd.ps1'" |
| 86 | |
| 87 | :: Verify if manual installation succeeded |
| 88 | sc query sshd >nul 2>&1 |
| 89 | if %errorlevel% neq 0 ( |
| 90 | echo "Manual OpenSSH installation failed. Exiting..." |
| 91 | exit /b 1 |
| 92 | ) else ( |
| 93 | echo "OpenSSH installed successfully manually." |
| 94 | goto :configure_openssh |
| 95 | ) |
| 96 | |
| 97 | :configure_openssh |
| 98 | :: Ensure OpenSSH Server service is set to start automatically and start the service |
| 99 | sc config sshd start= auto |
| 100 | net start sshd |
| 101 | |
| 102 | :: Create msys2.bat file with specific content |
| 103 | set MSYS2_PATH=C:\msys64 |
| 104 | if not exist "%MSYS2_PATH%" ( |
| 105 | echo "Error: %MSYS2_PATH% does not exist." |
| 106 | exit /b 1 |
| 107 | ) |
| 108 | |
| 109 | echo @%MSYS2_PATH%\msys2_shell.cmd -defterm -here -no-start -msys > %MSYS2_PATH%\msys2.bat |
| 110 | |
| 111 | :: Run PowerShell command to set default shell |
| 112 | powershell -Command "New-ItemProperty -Path 'HKLM:\SOFTWARE\OpenSSH' -Name 'DefaultShell' -Value '%MSYS2_PATH%\msys2.bat' -PropertyType String -Force" |
| 113 | |
| 114 | :: Open the Windows Firewall for sshd (using PowerShell) |
| 115 | powershell -Command "New-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -DisplayName 'OpenSSH Server (sshd) Incoming' -Description 'Allow incoming SSH traffic via OpenSSH server' -Enabled True -Direction Inbound -Protocol TCP -LocalPort 22 -Action Allow" |
| 116 | |
| 117 | echo "OpenSSH has been successfully configured with MSYS2 as the default shell, and the firewall has been opened for sshd." |
| 118 | pause |