简体   繁体   中英

How can I suppress part of an external program's prompt when called from powershell?

I have a powershell script that, among other things, sometimes needs to call a third-party application (TPA) to trigger a login prompt. My issue is that TPA's password prompt includes additional warning lines that I don't need cluttering up my UX. I can (and am) passing the username to the application just fine via $TpaParams , but I'd prefer to leave the handling the user's password to the TPA itself.

The password warning comes through through via STDOUT (not STDERR) and this is the same place that the necessary prompt text comes through. If I redirect the whole thing (Out-Null or the like), then the login fails because it couldn't ask for the password.

I am hoping to be able to show the prompt (only) and strip out the warning. Failing that, I'd be just as happy to recolor the warning text (using Write-Host ) to dark-gray-on-blue to make it less eye-catching (I already have a number of colors set up in my script for just this purpose).

Additional (potentially helpful?) data:

  • TpaCmd is a CMD file that contains lots of error checking plus one line of actual code: "%JAVACMD%" -jar "%JARFILE%" %*
  • I've been unable to find any help with either Java or TPA's author (IBM), either
  • I do not have the ability to change the JAR file; it has to remain intact.

Can anyone think of a way to do this on the powershell end?

Things I've tried without success:

No redirection

$TpaCmd login $TpaParams

Password not passed [...]  
Password :  

Redirect Out/Err Separately
$TpaCmd login $TpaParams 1> $TmpOut 2> $TmpErr

(null output)  

$TmpOut contains

Password not passed [...]  

$TmpErr contains

tpapp.cmd : java.lang.NullPointerException  
At D:\path\to\powershell\DoStuff.ps1:288 char:3  
+         &  ${TpaCmd} login --verbose ${TpaParams} 1> $TmpOut  
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
    + CategoryInfo          : NotSpecified: (java.lang.NullPointerException:String) [], RemoteException  
    + FullyQualifiedErrorId : NativeCommandError  
  
    at com.tpappname.ds.client.DeployCLI.main(DeployCLI.java:246)  
java.lang.NullPointerException  

Redirect Out, leave Err
$TpaCmd login $TpaParams 1> $TmpOut
$TmpOut contains

Password not passed as command line property password or set in environment, DS_PASSWORD  

NullPointerException error (above) is displayed to the screen

Redirect Err, leave Out
$TpaCmd login $TpaParams 2> $TmpErr

Password not passed [...]  
Password :  

$TmpErr is empty

Redirect Everything
$TpaCmd login $TpaParams *> $TmpAll

(null output)  

$TmpAll contains both the password warning and the NPE

Password not passed [...]
Retry with --verbose flag for more info.
tpapp.cmd : java.lang.NullPointerException  
    At D:\path\to\powershell\DoStuff.ps1:288 char:3  
    +         &  ${TpaCmd} login --verbose ${TpaParams} 1> $TmpOut  
    +         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
        + CategoryInfo          : NotSpecified: (java.lang.NullPointerException:String) [], RemoteException  
        + FullyQualifiedErrorId : NativeCommandError  
      
        at com.tpappname.ds.client.DeployCLI.main(DeployCLI.java:246)  
    java.lang.NullPointerException  

After doing a bit more research AND using the answers above as inspiration, I've decided to go with this:

$UserEncryptedPassword = Read-Host "Enter login password" -AsSecureString
& $TpaCmd login $TpaParams -password ([Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR(${UserEncryptedPassword})))

Thank you all for your inspiration and assistance!

You'll need to use a trick to get this to work, which relies on you knowing both the content of the line to ignore and the prompt string that the batch file uses to prompt for the password:

& $TpaCmd login $TpaParams |
  ForEach-Object { 
    if ($_ -match '\bPassword not passed\b') { # Line to ignore
      # Simulate the prompt that the batch file will show next, but
      # initially invisibly.
      Write-Host -NoNewLine 'Password : '
    } elseif ($_ -match '^Password : (.*)') { # The line with the prompt
      # Print the part of the line *after* the prompt string, which is
      # the *next* statement's output.
      $Matches.1 
    } else { # All other lines: pass through
      $_
    }
}

Depending on what you mean by I'd prefer to leave the handling the user's password to the TPA itself there might be more solutions.

Temporary password variable: the following might be a simple way to pass the password

$Password = Read-Host "Enter Password"
$TpaParms += " -password $Password"
$TpaCmd login $TpaParams

If you don't want the password in a variable, you might try this with no password variable:

$TpaCmd login "$TpaParms -password $(Read-Host "Enter Password")"

As i don't have your program and your $TpaParms to test my script i tried to find a documentation by the error messages and error codes, and found the syntax on that page https://www.ibm.com/docs/en/urbancode-deploy/7.0.3?topic=reference-command-format that i used for password. The -username [username] has to be in the $TpaParms to make this work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM