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~~~~

# Install the OpenSSH Server
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~

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

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
  • 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.