Managing Windows services across multiple servers can be tedious when you constantly need to RDP into each machine. In my case, I needed to automate the restart of a CherryPy service running as a Windows service after deployment updates.
The initial approach using psexec \\server "net restart cherrypyservice"
doesn't work because:
- 'net restart' isn't a valid command - the correct syntax is 'net stop' followed by 'net start'
- PsExec requires proper authentication parameters
- The service name might need to match the exact display name
Here are three proven approaches:
Method 1: Using SC Command
psexec \\targetserver -u domain\username -p password "sc stop \"CherryPy Service\" && sc start \"CherryPy Service\""
Method 2: PowerShell Remoting
Invoke-Command -ComputerName targetserver -ScriptBlock {
Restart-Service -Name "cherrypyservice" -Force
}
Method 3: Python WinRM Solution
import winrm
session = winrm.Session('targetserver', auth=('username', 'password'))
result = session.run_ps('Restart-Service -Name "cherrypyservice" -Force')
print(result.status_code)
When implementing remote service control:
- Always use the exact service name (check with
sc query
) - Include proper error handling for connection issues
- Consider service dependencies that might prevent restart
- For production systems, implement proper logging
import subprocess
import time
def restart_remote_service(server, service_name, username, password):
stop_cmd = f'sc stop "{service_name}"'
start_cmd = f'sc start "{service_name}"'
try:
# Stop service
subprocess.run([
'psexec', f'\\\\{server}',
'-u', username,
'-p', password,
stop_cmd
], check=True)
# Wait for service to stop
time.sleep(5)
# Start service
subprocess.run([
'psexec', f'\\\\{server}',
'-u', username,
'-p', password,
start_cmd
], check=True)
return True
except subprocess.CalledProcessError as e:
print(f"Failed to restart service: {e}")
return False
# Usage
restart_remote_service(
server='prod-web-01',
service_name='CherryPy Web Service',
username='admin',
password='securepassword123'
)
When automating service restarts:
- Never hardcode credentials - use environment variables or vault solutions
- Restrict service control permissions using Service Control Manager
- Consider using certificate-based authentication for PowerShell remoting
- Implement proper network segmentation for management traffic
When managing production servers, constantly RDPing into machines to restart services becomes tedious. For services like CherryPy running as Windows services, we need reliable scripting methods that work across networks.
The most robust approach uses PowerShell remoting (WinRM):
# First enable PSRemoting on target server (run as admin):
Enable-PSRemoting -Force
# Then from your local machine:
$cred = Get-Credential
Invoke-Command -ComputerName SERVER01 -Credential $cred -ScriptBlock {
Restart-Service -Name "cherrypyservice" -Force
}
For environments without PSRemoting, the SC command works well:
sc \\SERVER01 stop cherrypyservice
timeout /t 5
sc \\SERVER01 start cherrypyservice
For Python-based deployment scripts, use WMI:
import wmi
c = wmi.WMI(computer="SERVER01", user="admin", password="pass")
service = c.Win32_Service(Name="cherrypyservice")[0]
service.StopService()
service.StartService()
If you encounter "Access Denied" errors:
- Ensure the account has admin rights on the target
- Check firewall rules (TCP 135, 445)
- For PSRemoting, verify WinRM is enabled (winrm quickconfig)
Always:
- Use service accounts instead of personal credentials
- Encrypt credentials in scripts
- Limit which machines can execute remote commands