Skip to content

Instantly share code, notes, and snippets.

@xnohat
Forked from Hashbrown777/ssh.ps1
Created December 7, 2022 06:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xnohat/e20c32d8f153e590285202b173765e73 to your computer and use it in GitHub Desktop.
Save xnohat/e20c32d8f153e590285202b173765e73 to your computer and use it in GitHub Desktop.
A workaround for Windows official openssh client not supporting -f nor -N
#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