'Powershell script pauses after running Perforce Application with cmd until the termination of Perforce Applicaiton

I am creating a script that will run Perforce and allow the user to login. However, after logging in, the user must manually close Perforce in order for the Powershell script to continue running. I wish to automate that process so that upon logging in, the script will automatically close Perforce itself.

My original code was something like this:

$userName = Read-Host -Prompt 'Input your P4 username'

"p4 -u $userName -p perforceServer:1666" | cmd

"p4 -u$userName -pperforceServer:1666 -cclient files //streamPath @labelName.1.2.3 > fileName.txt" | cmd

$textFile = Get-ChildItem "fileName.txt"

$content = Get-Content $textFile

....

Problems arisen from comments:

  1. How to execute command in Powershell's shell: a) When using p4 -u $userName -p perforceServer:1666 login, nothing happens. Script just exits (yes I do have password and login, but prompt is not coming up for some reason). b) When using p4 -u$userName -pperforceServer:1666 -cclient files //streamPath @labelName.1.2.3 > fileName.txt, the '@' symbol gives me the following error: The splatting operator cannot be used to reference variables in an expression. It can only be used as an argument to the command (which is what I am doing) using the single quote (when doing so the error goes away, but my command does not execute properly as in it does not pull from the stream (fileName.txt is empty).
  2. How to know when user has successfully logged in?

Thanks for the help!



Solution 1:[1]

Piping the p4 command to cmd makes it difficult to interact with the command, since cmd isn't going to spawn an interactive session. You should be able to simply do the interaction within Powershell:

$userName = Read-Host -Prompt 'Input your P4 username'
p4 -u $userName -p perforceServer:1666 login
$content = p4 -u $userName -p perforceServer:1666 files //streamPath/[email protected]

Since the command will write its output to stdout, writing it to a file and then reading it back in from the file is an unnecessary level of indirection; you can just assign it directly to $content.

For the case of a command where you weren't trying to redirect the output, you could simply run the command and then allow the auto-login functionality to handle authentication:

PS C:\perforce\test> $userName = Read-Host -Prompt 'Input your P4 username'
Input your P4 username: bob
PS C:\perforce\test> p4 -u $userName sync -m1
Perforce password (P4PASSWD) invalid or unset.
Attempting login for user 'bob' against server 'rsh:p4d.exe -i -r "c:\Perforce\test\.p4root"'
Enter password:
User bob logged in.
//stream/child_stream/lock/foo#2 - added as c:\Perforce\test\lock\foo

but in the case of your script this isn't suitable because you don't want $content to capture the login prompt.

To check the login status of the user, you can use p4 login -s:

PS C:\perforce\test> p4 -u $userName login -s
User bob ticket expires in 11 hours 54 minutes.
PS C:\perforce\test> p4 -u $userName -Ztag login -s
... User bob
... TicketExpiration 42845

PS C:\perforce\test> p4 -u $userName logout
User bob logged out.
PS C:\perforce\test> p4 -u $userName -Ztag login -s
Perforce password (P4PASSWD) invalid or unset.

Combining -Ztag and -F can give you an easily-parseable string that you specify the format of, eg:

PS C:\perforce\test> p4 -u $userName -Ztag -F "[SUCCESS: %TicketExpiration%|ERROR]" login -s
ERROR
PS C:\perforce\test> p4 -u $userName login
Enter password:
User bob logged in.
PS C:\perforce\test> p4 -u $userName -Ztag -F "[SUCCESS: %TicketExpiration%|ERROR]" login -s
SUCCESS: 43199

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1