Context: you have a shell script running on a linux server and you want this shell script be able to stop or start services on a windows server
Windows: Create a local administrator
Create a local administrator that we call adminservice.
Add this user to the local administrators of your windows server (group Administrators).
Now execute a Remote Desktop connection (RDP) to this windows server with the identifiers of adminservice user so that the user’s directory structure is fully created (C:\Users\adminservice will then be created).
Install OpenSSH on your windows server
To connect to the Windows server from Linux in order to trigger start/stop service commands, we will use OpenSSH.
On Windows Server 2016, it is possible to install OpenSSH through a few manual steps: link to instructions
Starting from Windows Server 2019 and Windows 10 (build 1809 and later), installing OpenSSH is straightforward and described by Microsoft: link to Microsoft’s instructions
In the following commands, you may encounter the error “Start-Service: Service ‘OpenSSH SSH Server (sshd)’ cannot be started due to the following error: Cannot start service sshd on computer ‘.’.”
This error occurs when trying to start the sshd service because, by default, a service is created as “disabled,” preventing it from being started.
The solution is to change the service status from disabled to “automatic” (start automatically at Windows boot). This can be done either through the command line (Set-Service -Name sshd -StartupType ‘Automatic’) or via the Windows Services management screen.
All the commands are available in the provided link and are also here (to be executed in an admin PowerShell session):
Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*' # Install the OpenSSH Client Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0 # Install the OpenSSH Server Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0 # OPTIONAL but recommended: Set-Service -Name sshd -StartupType 'Automatic' # Start the sshd service Start-Service sshd # Confirm the Firewall rule is configured. It should be created automatically by setup. Run the following to verify if (!(Get-NetFirewallRule -Name "OpenSSH-Server-In-TCP" -ErrorAction SilentlyContinue | Select-Object Name, Enabled)) { Write-Output "Firewall Rule 'OpenSSH-Server-In-TCP' does not exist, creating it..." New-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22 } else { Write-Output "Firewall rule 'OpenSSH-Server-In-TCP' has been created and exists." }
NOTE: If copying and pasting the last group of lines doesn’t work correctly, you can simply copy and paste line by line.
Using a private/public key pair
To connect via SSH to the Windows server, we will use a public/private key pair as it is much more secure than a password.
ssh-keygen -f mykey -t rsa -b 4096 chmod 0600 mykey
Deployment of the public key on the Windows server
To make things easier, we will enable password-based SSH login on Windows, just temporarily to execute the commands below. To do this, edit the file C:\ProgramData\ssh\sshd_config and set the following option to yes:
PasswordAuthentication yes
Also comment the following two lines:
Match Group administrators AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
We comment these two lines because as our adminservice user is a local administrator and we don’t want it matches theses two lines. We want the public key to be added in C:\Users\adminservice\.ssh\authorized_keys
The following commands should be executed from the Linux server connecting via SSH to our Windows server. The password for the ‘adminservice’ user will be requested:
# Make sure that the .ssh directory exists in your server's user account home folder ssh refreshauto@<IP_PRIVEE_SERVEUR_WINDOWS> mkdir "C:\Users\refreshauto\.ssh" # (You can also simply do this manually on the windows server) # Use scp to copy the public key file generated previously on your client to the authorized_keys file on your server # Warning it's important to double quote the full path otherwise the back slashes will be interpreted scp mykey.pub adminservice@<IP_WINDOWS_SERVER>:"C:\Users\adminservice\.ssh\authorized_keys"
Windows scripts to start/stop windows services
We’ll start/stop our “horsys” services (horsys is simple the name of a group of services in this example).
We can trigger batch files from the SSH command lines of our Linux server. Therefore, we will create a Windows batch script that will start Windows services. This batch script will utilize a PowerShell script to harness the power of PowerShell. And then, we will do the same for stopping Windows services.
start-horsys.cmd =>
@echo off SET scripts_path=%~dp0 cd %scripts_path% echo Starting horsys services at %Date% %time% >> refreshAuto.log powershell -InputFormat None -F "start-horsys.ps1"
start-horsys.ps1 =>
# This powershell script starts the services with name Horsys and WebDev 19 Start-Service -Name "Horsys" Start-Service -Name "WebDev 19"
stop-horsys.cmd =>
@echo off SET scripts_path=%~dp0 cd %scripts_path% echo Stopping horsys services at %Date% %time% >> refreshAuto.log powershell -InputFormat None -F "stop-horsys.ps1"
stop-horsys.ps1 =>
# This powershell script stops the services with name Horsys and WebDev 19 Stop-Service -Name "Horsys" Stop-Service -Name "WebDev 19"
Place these scripts in the folder C:\User\adminservice\scripts.
Test your ssh connection to your windows server
We will now verify that the SSH key-based connection is operational. From the refreshAuto folder (on the server running refreshAuto), execute the following command
ssh -i ./mykey adminservice@<IP_WINDOWS_SERVER>
If the connection does not establish and you receive a prompt asking for the adminservice user’s password, it means the connection was denied by the Windows server. This is likely due to permissions on the Windows file C:\Users\adminservice\.ssh\authorized_keys.
Ensure that only the following users are allowed in this file (remove others):
- adminservice
- SYSTEM
- Administrators
If the issue persists despite this, enable SSH logs on the Windows server as follows. Edit the file C:\ProgramData\ssh\sshd_config and ensure the values of the following options are as follows:
SyslogFacility LOCAL0 LogLevel DEBUG3
Test that stopping and starting Windows services via SSH is operational
From the refreshAuto directory (on the server running refreshAuto), execute the following commands:
ssh -i mykey adminservice@<ID_WINDOWS_SERVER> "C:\Users\adminservice\scripts\stop-horsys.cmd" ssh -i mykey adminservice@<ID_WINDOWS_SERVER> "C:\Users\adminservice\scripts\start-horsys.cmd"
Remove SSH password-based login permission
To improve security we can modify ssh_config as follow (on our windows server):
PasswordAuthentication no
Don’t forget to restart your openSSH service after modifying the sshd_config file.
Leave a Reply