Add -t to allocate a pty ... Ok, so now the user input can be seen, but I get Ctrl+H (^H) when backspace is pressed
Make your script run [ -t 0 ] && stty erase ^H
and the Backspace key should be accepted.
An even better solution is to use a port of OpenSSH – for example, that from Cygwin or MinGW – it will give you full terminal emulation as PuTTY does, but keep it in the console window. (The plink tool is designed for raw 8-bit data transfers.)
Edit: A downside of Cygwin might be its lack of IPv6 support (if I remember correctly).
Get password prompt, cannot provide password like with plink
[...] but this is a closed, private network, and its easier not to bother with keys!
And yet you have a problem which setting up keys would solve :)
(I'll feel bad for saying this, but PuTTY also accepts -pw
.)
/*
This script is run in the server computer from the remote computer
to disconnect the session without locking the server computer
and do not require UAC after the first use
*/
; self elevate
TaskName := RunAsTask()
; get the conexion number
Conn := ActiveSession()
; close the connection
Run, %COMSPEC% /c TSCON %Conn% /dest:console
; functions
RunAsTask() { ; By SKAN, http://ahkscript.org/boards/viewtopic.php?t=4334
Local CmdLine, TaskName, TaskExists, XML, TaskSchd, TaskRoot, RunAsTask
Local TASK_CREATE := 0x2, TASK_LOGON_INTERACTIVE_TOKEN := 3
Try TaskSchd := ComObjCreate( "Schedule.Service" ), TaskSchd.Connect()
, TaskRoot := TaskSchd.GetFolder( "\" )
Catch
Return "", ErrorLevel := 1
CmdLine := ( A_IsCompiled ? "" : """" A_AhkPath """" ) A_Space ( """" A_ScriptFullpath """" )
TaskName := "[RunAsTask] " A_ScriptName " @" SubStr( "000000000" DllCall( "NTDLL\RtlComputeCrc32"
, "Int",0, "WStr",CmdLine, "UInt",StrLen( CmdLine ) * 2, "UInt" ), -9 )
Try RunAsTask := TaskRoot.GetTask( TaskName )
TaskExists := ! A_LastError
If ( not A_IsAdmin and TaskExists ) {
RunAsTask.Run( "" )
ExitApp
}
If ( not A_IsAdmin and not TaskExists ) {
Run *RunAs %CmdLine%, %A_ScriptDir%, UseErrorLevel
ExitApp
}
If ( A_IsAdmin and not TaskExists ) {
XML := "
( LTrim Join
<?xml version=""1.0"" ?><Task xmlns=""http://schemas.microsoft.com/windows/2004/02/mit/task""><Regi
strationInfo /><Triggers /><Principals><Principal id=""Author""><LogonType>InteractiveToken</LogonT
ype><RunLevel>HighestAvailable</RunLevel></Principal></Principals><Settings><MultipleInstancesPolic
y>Parallel</MultipleInstancesPolicy><DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries><
StopIfGoingOnBatteries>false</StopIfGoingOnBatteries><AllowHardTerminate>false</AllowHardTerminate>
<StartWhenAvailable>false</StartWhenAvailable><RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAva
ilable><IdleSettings><StopOnIdleEnd>true</StopOnIdleEnd><RestartOnIdle>false</RestartOnIdle></IdleS
ettings><AllowStartOnDemand>true</AllowStartOnDemand><Enabled>true</Enabled><Hidden>false</Hidden><
RunOnlyIfIdle>false</RunOnlyIfIdle><DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteApp
Session><UseUnifiedSchedulingEngine>false</UseUnifiedSchedulingEngine><WakeToRun>false</WakeToRun><
ExecutionTimeLimit>PT0S</ExecutionTimeLimit></Settings><Actions Context=""Author""><Exec>
<Command>" ( A_IsCompiled ? A_ScriptFullpath : A_AhkPath ) "</Command>
<Arguments>" ( !A_IsCompiled ? """" A_ScriptFullpath """" : "" ) "</Arguments>
<WorkingDirectory>" A_ScriptDir "</WorkingDirectory></Exec></Actions></Task>
)"
TaskRoot.RegisterTask( TaskName, XML, TASK_CREATE, "", "", TASK_LOGON_INTERACTIVE_TOKEN )
}
Return TaskName, ErrorLevel := 0
}
ActiveSession() {
if ((wtsapi32 := DllCall("LoadLibrary", "Str", "wtsapi32.dll", "Ptr")))
{
if (DllCall("wtsapi32\WTSEnumerateSessionsEx", "Ptr", WTS_CURRENT_SERVER_HANDLE := 0, "UInt*", 1, "UInt", 0, "Ptr*", pSessionInfo, "UInt*", wtsSessionCount))
{
WTS_CONNECTSTATE_CLASS := {0: "WTSActive", 1: "WTSConnected", 2: "WTSConnectQuery", 3: "WTSShadow", 4: "WTSDisconnected", 5: "WTSIdle", 6: "WTSListen", 7: "WTSReset", 8: "WTSDown", 9: "WTSInit"}
cbWTS_SESSION_INFO_1 := A_PtrSize == 8 ? 56 : 32
Loop % wtsSessionCount {
currSessOffset := cbWTS_SESSION_INFO_1 * (A_Index - 1)
ExecEnvId := NumGet(pSessionInfo+0, currSessOffset, "UInt")
currSessOffset += 4
State := NumGet(pSessionInfo+0, currSessOffset, "UInt")
currSessOffset += 4
SessionId := NumGet(pSessionInfo+0, currSessOffset, "UInt")
currSessOffset += A_PtrSize
SessionName := StrGet(NumGet(pSessionInfo+0, currSessOffset, "Ptr"),, A_IsUnicode ? "UTF-16" : "CP0")
currSessOffset += A_PtrSize
HostName := StrGet(NumGet(pSessionInfo+0, currSessOffset, "Ptr"),, A_IsUnicode ? "UTF-16" : "CP0")
currSessOffset += A_PtrSize
UserName := StrGet(NumGet(pSessionInfo+0, currSessOffset, "Ptr"),, A_IsUnicode ? "UTF-16" : "CP0")
currSessOffset += A_PtrSize
DomainName := StrGet(NumGet(pSessionInfo+0, currSessOffset, "Ptr"),, A_IsUnicode ? "UTF-16" : "CP0")
currSessOffset += A_PtrSize
FarmName := StrGet(NumGet(pSessionInfo+0, currSessOffset, "Ptr"),, A_IsUnicode ? "UTF-16" : "CP0")
; MsgBox % "Username: " . UserName . "`r`n" . "State: " . WTS_CONNECTSTATE_CLASS[State] . " (raw state: " . State . ")"
If (UserName = A_UserName && State = 0)
Activa := SessionId
}
DllCall("wtsapi32\WTSFreeMemoryEx", "UInt", WTSTypeSessionInfoLevel1 := 2, "Ptr", pSessionInfo, "UInt", wtsSessionCount)
}
DllCall("FreeLibrary", "Ptr", wtsapi32)
}
Return Activa
}
Best Answer
If you are running plink, then you are not using PS remoting to do this, as you are just running a plink command one of the PS hosts (console / ISE / VSCode). This is not a PS issue, but a how to run and exe in PS. I do plink to Linux boxes daily without issue, but as you've noted in your second command and start command issue.
If you are in one of the PS consoles, you have to provide a execution command, and for external .exe, you should get into the habit of fully qualifying the exe.
For example, here it the way I do this successfully to all my Linux boxes. That & (ampersand) means - Execute string as command. Basically that same thing you are doing by calling cmd.exe start, but without the additional terminal window.
If you want stuff to run in the background that is what PS jobs are for.
See also the PS help file info regarding parallel processes and Runspaces.
I've not however tried this with Plink.
But there are lots of articles regarding PS and Plink use cases, even for Cisco switches.
And point of note, PS has an SSH module, so, you don't have to use Plink specifically to interop with Linux clients.