-
-
Save xnohat/e20c32d8f153e590285202b173765e73 to your computer and use it in GitHub Desktop.
A workaround for Windows official openssh client not supporting -f nor -N
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#accepts all arguments for ssh except command, -N and -f | |
#command can be piped in | |
Filter ssh-f { | |
$N = $False | |
if (!$_) { | |
#the same as -N | |
$_ = 'read' | |
$N = $True | |
} | |
$_ = 'echo SUCCESS;' + $_ | |
$args += "`"${_}`"" | |
$_ = [Diagnostics.ProcessStartInfo]::new() | |
$_.CreateNoWindow = $False | |
$_.UseShellExecute = $False | |
$_.RedirectStandardInput = $True | |
$_.RedirectStandardOutput = $True | |
$_.RedirectStandardError = $True | |
$_.FileName = 'ssh' | |
#ArgumentList apparently isn't in my version of .NET/PowerShell | |
$_.Arguments = $args | |
$ssh = [Diagnostics.Process]::new() | |
$ssh.StartInfo = $_ | |
$started=[Collections.ArrayList]@() | |
$watch = { | |
if (![String]::IsNullOrEmpty($EventArgs.Data)) { | |
$Event.MessageData.Add($EventArgs.Data) | |
} | |
} | |
$out = Register-ObjectEvent ` | |
-InputObject $ssh ` | |
-Action $watch ` | |
-EventName 'OutputDataReceived' ` | |
-MessageData $started | |
$err = Register-ObjectEvent ` | |
-InputObject $ssh ` | |
-Action $watch ` | |
-EventName 'ErrorDataReceived' ` | |
-MessageData $started | |
$ssh.Start() | Out-Null | |
$ssh.BeginOutputReadLine() | |
$ssh.BeginErrorReadLine() | |
if (!$N) { | |
$ssh.StandardInput.Close() | |
} | |
try { | |
while (!$ssh.HasExited) { | |
while ($started.Count) { | |
if ($started[0] -eq 'SUCCESS') { | |
$started.RemoveAt(0) | |
Unregister-Event -SourceIdentifier $out.Name | |
Unregister-Event -SourceIdentifier $err.Name | |
$started | Out-Host | |
$started.Clear() | |
#if I attempt to `break` or `return` instead of `throw` we hang!! WHAT | |
#it has to do with `CreateNoWindow = $False` but if it's true ssh can no longer accept PIN code input (which is NOT stdin) | |
if ($N) { | |
'Call .StandardInput.Close() to close your session' | Out-Host | |
} | |
else { | |
'You can monitor when your session closes at .HasExited' | Out-Host | |
} | |
throw $ssh | |
} | |
$started[0] | Out-Host | |
$started.RemoveAt(0) | |
} | |
} | |
} | |
catch { | |
$_.TargetObject | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment