I have a PowerShell script which starts a background job (it does port-forwarding using kubectl):
$forwardjob = Start-Job -ScriptBlock{kubectl port-forward service/db 7125:7125} -Name "Database Port-Forwarder"
This works fine, however every so often kubectl asks for credentials. I am wondering how I could capture and insert some user input in that case?
My idea with the following additional two lines was to wait some time until we have a response for sure, then check the result and if there is a prompt for a password, simply enter it. However, at that point, the job always results in an error (due to the missing input) and the job is completed.
$forwardjob = Start-Job -ScriptBlock{kubectl port-forward service/db 7125:7125} -Name "Database Port-Forwarder"
Start-Sleep -Milliseconds 1000
$result = Receive-Job -Job $forwardjob
So, the question is how can one capture a input prompt and enter it correctly?
The only way to respond to interactive prompts presented by an external program in the context of Start-Job
(a PowerShell background job) is to send all responses ahead of time, via the pipeline.
This is the same technique you'd use to automate responses to the interactive prompts of external programs in direct invocation. However, note that - unlike in direct invocation - you fundamentally cannot respond to interactive prompts interactively when using background jobs.
That is:
You don't get to control the timing of when the responses are sent: they are sent to the external program's stdin (standard input) stream right after launching the external program.
You need to anticipate all interactive prompts the program may show (if more than one), in the sequence you anticipate, as reflected in the order of the inputs you send.
Additionally, this technique can fundamentally only work:
Note that external programs may (sensibly) print their prompt messages directly to the terminal (e.g., Enter your password:
), which means that they will not show up in what the background job captures and outputs via Receive-Job
.
Here are self-contained, platform-specific examples that show the technique: they use the platform-native shell to simulate some processing, then prompt for a "password" and echo the response, which is provided up front via PowerShell's pipeline: Perhaps needless to say, providing plain-text passwords this way is a security risk.
'somepassword' |
Start-Job { cmd /v /c 'echo doing things... & powershell -NoProfile sleep 2 & set /p pass=Enter^ password: & echo You entered: !pass!' } |
Receive-Job -AutoRemoveJob -Wait
'somepassword' |
Start-Job { bash -c 'echo doing things...; sleep 2; read -p ''Enter password: '' pass; echo You entered: $pass' } |
Receive-Job -AutoRemoveJob -Wait