When working with legacy Windows Server 2003 systems running CopSSH (Cygwin + SSHD), executing PowerShell scripts through SSH sessions presents unique technical hurdles. The fundamental issue stems from the environment pathing and shell interpretation differences between Cygwin's Unix-like environment and Windows' native PowerShell.
To bridge these environments, we need a three-part approach:
- Proper PATH configuration in Cygwin
- PowerShell execution wrapper
- Output handling mechanism
First, verify PowerShell is accessible from Cygwin:
# Test basic PowerShell accessibility
$ /cygdrive/c/WINDOWS/system32/WindowsPowerShell/v1.0/powershell.exe -Command "Get-Host"
Create a helper script runps.ps1
:
# PowerShell script to handle input/output properly
param(
[string]$scriptPath,
[string]$arguments
)
$ErrorActionPreference = "Stop"
try {
$scriptContent = Get-Content -Path $scriptPath -Raw
$scriptBlock = [scriptblock]::Create($scriptContent)
& $scriptBlock @arguments
} catch {
Write-Error $_.Exception.Message
exit 1
}
For direct SSH command execution:
ssh username@server '/cygdrive/c/WINDOWS/system32/WindowsPowerShell/v1.0/powershell.exe -File "C:/path/to/runps.ps1" -scriptPath "C:/scripts/myscript.ps1"'
For complex scenarios, create a Cygwin wrapper script ps-wrapper.sh
:
#!/bin/bash
POWERSHELL="/cygdrive/c/WINDOWS/system32/WindowsPowerShell/v1.0/powershell.exe"
SCRIPT_PATH=$(cygpath -w "$1")
shift
"$POWERSHELL" -NonInteractive -NoProfile -ExecutionPolicy Bypass -Command "& { . \"$SCRIPT_PATH\"; $@ }"
- Path Translation: Always use
cygpath
to convert between Unix and Windows paths - Encoding Problems: Set
$OutputEncoding
in PowerShell to UTF-8 - Permission Errors: Verify execute permissions on both Cygwin and Windows sides
For frequent executions, consider these optimizations:
# Persistent PowerShell session using Named Pipes
ssh username@server 'mkfifo /tmp/pspipe; /cygdrive/c/WINDOWS/system32/WindowsPowerShell/v1.0/powershell.exe -Command "& { while($true) { $cmd = Get-Content /tmp/pspipe; if($cmd -eq \'exit\') { break }; Invoke-Expression $cmd | Out-String } }"'
When working with legacy Windows Server 2003 systems using CopSSH (Cygwin + SSHD), running PowerShell scripts remotely presents unique challenges. The core issue involves bridging the Unix-like Cygwin environment with Windows-native PowerShell execution.
First, verify your system configuration:
# Check PowerShell availability
which powershell
# Or for Windows Server 2003 (PS 1.0):
which powershell.exe
The most straightforward approach uses the PowerShell CLI:
ssh user@server 'powershell.exe -ExecutionPolicy Bypass -File C:\\path\\to\\script.ps1'
Key parameters to note:
-ExecutionPolicy Bypass
- Overrides default restrictions- Double backslashes in Windows paths
- Single quotes around the entire command
To properly capture output streams:
ssh user@server 'powershell.exe -NonInteractive -NoProfile -Command "& { C:\\script.ps1 *>&1 }"'
This redirects all streams (output, errors, warnings) through stdout.
Create a Cygwin bash wrapper (runps.sh
):
#!/bin/bash
WINPATH=$(cygpath -w "$1")
powershell.exe -NonInteractive -NoProfile -ExecutionPolicy Bypass -Command "& { $WINPATH }"
Usage example:
ssh user@server '/path/to/runps.sh /cygdrive/c/scripts/test.ps1'
For authentication problems, check:
# Verify SSH service account has execute rights
icacls C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe
Path translation problems? Use Cygwin's path conversion:
ssh user@server 'powershell.exe -Command "& { $(cygpath -w /cygdrive/c/scripts/test.ps1) }"'
For frequent executions, consider:
# Keep a persistent PowerShell session
ssh -t user@server 'powershell.exe -NoExit -Command "& { C:\\script.ps1 }"'
The -t
flag allocates a pseudo-terminal for interactive sessions.