Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"$pid" command failing on initialize #56

Open
mreedmdev opened this issue Jan 7, 2019 · 21 comments
Open

"$pid" command failing on initialize #56

mreedmdev opened this issue Jan 7, 2019 · 21 comments
Assignees

Comments

@mreedmdev
Copy link

mreedmdev commented Jan 7, 2019

As a user of earlier versions of jpowershell, I've upgraded to 3.0.1, but cannot seem to get off the ground.
When attempting to openSession(), at line 168 the PowerShell.inialize method fails whenh parsing the result of the $pid command. In my case it is always an empty string and throws NumberFormatException.

//Get and store the PID of the process
this.pid = Long.valueOf(executeCommand("$pid").getCommandOutput());

I've tried configuring my own powershell (powershell-core) and the default installation of PowerShell in my environment. I've adjusted timeouts to give powershell more time to start since it appears the resultant "" is because PowerShell never gets started and cannot execute executeCommand("$pid") on line 168. This results in a NumberFormatException.

Used jpowershell.properties to set maxWait so that openSession is effected.
maxWait:30000 and greater values.

Have tried nearly every variant of simply calling openSession and it fails regardless as described.

  try(PowerShell powerShell = PowerShell.openSession()) {
    PowerShellResponse response = powerShell.
        executeScript(pathToScript);
    log.info("{}", response);
  }catch(Exception e) {
    log.error("{}", e.getMessage());
  }

It seems the cause is that:

  • PowerShell is not getting launched,

  • A timeout occurs waiting on the response to the subsequent "$pid" command, which results in ""

  • this.pid = Long.valueOf(executeCommand("$pid").getCommandOutput()); throws NumberFormatException on the resultant empty string.

I've ensured that powershell is available either as the default 'powershell.exe' or a custom powershell installation. No matter which configuration I try it seems Powershell is not started. Any Ideas on my problme?

As a secondary item, in working my problem I think the line in bullet 3 should be changed to handle this situation better?

Any help would be appreciated.
Thanks

@jflefebvre06
Copy link

Hello,

Same problem.

To reproduce, add a file "%USERPROFILE%\documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1"

with the content :

#$HOME\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1

Write-Host "Loaded."

@profesorfalken profesorfalken self-assigned this Feb 4, 2019
@profesorfalken
Copy link
Owner

Hello,
Weird. Thanks for reporting it.
I will check this.

Best regards

@profesorfalken
Copy link
Owner

profesorfalken commented Feb 5, 2019

Hello,

It should be OK if you try the 3.0.2 version.

Nevertheless I would like to understand why this happens, because I am not able to reproduce it.

  • @mreedmdev you say that the command returns "" in your case. That happens also when you type the command $PID in your PowerShell console? What is your SO and your Powershell version?
  • @wortner you get some strange symbols when recovering the PID... what is your system locale?
  • @jflefebvre06 this is normal since your are prefixing all the command outputs with "Loaded.". Anyway, my fix in 3.0.2 is able to bypass it.

@mreedmdev
Copy link
Author

profesorfalken,
It does NOT occur when I issue the $PID command from a console. I get a normal response of the process id. This only occurs when using jpowershell as described in my original post(if it is clear, i hope).

Windows Powershell v5.0.10586.117 and
Powershell CORE v6.1.0

Thanks for your attention to this! I am happy to provide any more useful information. I have already update to your latest fix, but have not tested it yet. I will let you know.

Thanks!

@mreedmdev
Copy link
Author

After getting the latest code I am now getting something other than "" empty string.
Exception Message -> For input string: "Running MicrosoftPowerShell_profile.ps1...
30468"

In fact openSession() is throwing the exception and now seems to be trying to parse what you see in the exception message above "Running MicrosoftPowerShell_profile.ps1..." is prefixing the returned PID and infact instead of just a blank string. After several runs I see multiple powershell processes(started as a result of the test run) in task manager hung up after multiple subsequent runs.

I'll let you know some more information tomorrow. I incrementally rolled back to v2.0 and seemingly get the same message on all these versions. Although I had to change my code a bit since in v2.0 AutoCloseable is not implemented, as expected. So this let me know I was running against the correct version(s).

So.. I am going to pull latest again tomorrow and ensure I have made no mistakes in pulling, building and running the latest code for 3.0.2, but this is what I discovered today.

Thanks

@jflefebvre06
Copy link

@profesorfalken works fine with 3.0.2 thank you.

@profesorfalken
Copy link
Owner

@mreedmdev
Thank you for your answer. Now I see the problem. It is very interesting.
I think I know how to fix it. I will try to do it today so you will be able to use the 3.x version which includes the proper autocloseable.

Best regards

@profesorfalken
Copy link
Owner

A new 3.0.3 version is available. Can you check @mreedmdev ?

Thanks

@mreedmdev
Copy link
Author

@profesorfalken - Yes, I will check immediately and let you know the result ASAP.

Thank You !

@mreedmdev
Copy link
Author

@profesorfalken, 3.0.3 seems to exhibit similar results.
1)It seems that the result of starting the session is loading the profile which results in the message
"Running MicrosoftPowerShell_profile.ps1... and this is getting picked up in the outputstream being parsed when the $pid command is issued.
2)When I manually run the exact command getting ran by openSession() in a console, this is the first message output to the console before a prompt is presented.
3)Then I run the $pid command manually and get expected pid.

As I think you have already figured out the buffer is not getting cleared prior to the $pid command getting issued and NumberFormatException is thrown trying to parse the profile load message concatenated with the pid from the $pid command ""Running MicrosoftPowerShell_profile.ps1...23432"

This is the powershell prompt input/output from manually taking the same steps the code takes.

`C:>powershell.exe
Windows PowerShell
Copyright (C) 2015 Microsoft Corporation. All rights reserved.

Running MicrosoftPowerShell_profile.ps1...
C:\mreed

$pid
17276
C:\mreed
`

I think you are on the right track clearing the buffer prior to the $pid being issued, but my test of 3.0.3 show that the entire "Running MicrosoftPowerShell_profile.ps1...23432" is still being parsed and throwing.

Mark

@mreedmdev
Copy link
Author

mreedmdev commented Feb 6, 2019

@profesorfalken

1)I have found that the profile that is loading has a line in the script
Write-Host "Running MicrosoftPowerShell_profile.ps1..."
So this is where that is coming from.
@jflefebvre06 pointed this out in his earlier post.

2)If I remove the line from the profile the $PID command is executed and parsed correctly!

A couple of thoughts:

  1. I am using the jpowershell.properties file to create longer waits since some configurations take longer to load powershell than others.
    2)If the loading of the session does timeout there is still an NumberFormatException that is thrown because the result of the $PID command is "" empty string on a timeout and this still seems to occur on 3.0.3
    3)Not sure if any users may have any Write-Host commands in any profile scripts, but this can cause the problem of the output being picked up in the buffer of the $PID command output and reproduces the NumberFormatException.

So at this point if I exclude the Write-Host and avoid an openSession() timeout, I am past the reported issue with 3.0.3.
Mark

@wortner
Copy link

wortner commented Feb 7, 2019

3.0.3 is working. I checked the power shell folder, but it is empty so I don't need to take care about Write-Host. So far couple of times I have got closeAndWait WARNING: Powershell process cannot be closed. Session seems to be blocked. It seems to be connected with some timeout setting and now I'm looking for way to set it.

@jflefebvre06
Copy link

jflefebvre06 commented Feb 7, 2019

@profesorfalken No way to execute command excluding powershell profile ? perhaps -NoProfile option ?

Fix proposal :

PowerShellCommandProcessor.java :

pb = new ProcessBuilder("cmd.exe", "/c", "chcp", codePage, ">", "NUL", "&", powerShellExecutablePath,
                    "-ExecutionPolicy", "Bypass", "-NoExit", "-Command", "-");
pb = new ProcessBuilder("cmd.exe", "/c", "chcp", codePage, ">", "NUL", "&", powerShellExecutablePath,
                    "-ExecutionPolicy", "Bypass", "-NoExit", "-NoProfile", "-Command", "-");

PowerShell.java :
Remove commandOutput.replaceAll("\\D", ""); from getPID() method.

@profesorfalken
Copy link
Owner

profesorfalken commented Feb 7, 2019

@mreedmdev

Hi Mark,
This is exactly how I tested the fix for 3.0.3:

-First, I created a profile file at USER\Documents\WindowsPowerShell called Microsoft.PowerShell_profile.ps1
-I have written inside:
Write-Host "Running MicrosoftPowerShell_profile.ps1..."
-After that, I have launch one test and I have seen that executeCommand("$pid").getCommandOutput() returned:
Running MicrosoftPowerShell_profile.ps1... 10562
-So I have added the clearOutput() method that clears the initial buffer before launching the first command.
-And after that, I had the good result:
10562

So the problem of write-host on profile should be totally fixed in 3.0.3.

I still have the profile file set in my system and all the tests pass without a single problem.
I cannot understand how that continued to generate a NumberFormatException in your case with the 3.0.3 version.

2)If the loading of the session does timeout there is still an NumberFormatException that is thrown because the result of the $PID command is "" empty string on a timeout and this still seems to occur on 3.0.3

I cannot understand how il can return an emty string. Event in 3.0.2 that should be fixed. Are you sure you are using the 3.0.3 version?

Best regards

@profesorfalken
Copy link
Owner

@wortner

Thanks to confirm that it works.

The closeAndWait WARNING: Powershell process cannot be closed. Session seems to be blocked. happens sometimes when the PowerShell console hangs (for example, if it has not finished to execute the command).
This is why I have to take the PID at the initialization. In this cases I use this PID to kill the process and avoid 'zombie' processes in the background.
Maybe it happens that your command is a little bit long, so in that case you can simply give a little more of time. By default it waits 10 secs.

If you want to give more time:

//Init
Map<String, String> myConfig = new HashMap<>();
myConfig.put("maxWait", "30000");
response = powerShell.configuration(myConfig).executeCommand("Get-WmiObject Win32_BIOS");
//Close

Best regards

@profesorfalken
Copy link
Owner

profesorfalken commented Feb 7, 2019

@jflefebvre06

Thats a great idea!. Do you want to make me a Pull Request yourself or do you prefer me to change it?

Best regards

@jflefebvre06
Copy link

@profesorfalken
Im out of office, could you please make the change

@profesorfalken
Copy link
Owner

v3.0.4 is published

@DipteshSavla
Copy link

Getting same issue on v3.1.0 for
Powershell version
Major Minor Build Revision


5 1 14393 1884

Best Regards

@dsagomonov
Copy link

Getting same issue on v3.1.0
java.lang.NumberFormatException: For input string: "3784"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Long.parseLong(Unknown Source)
at java.lang.Long.valueOf(Unknown Source)
at com.profesorfalken.jpowershell.PowerShell.initalize(PowerShell.java:168)
at com.profesorfalken.jpowershell.PowerShell.openSession(PowerShell.java:129)
at com.profesorfalken.jpowershell.PowerShell.openSession(PowerShell.java:108)
at com.profesorfalken.wmi4java.WMIPowerShell.executeCommand(WMIPowerShell.java:42)
at com.profesorfalken.wmi4java.WMIPowerShell.queryObject(WMIPowerShell.java:122)
at com.profesorfalken.wmi4java.WMI4Java.getWMIObjectList(WMI4Java.java:332)

@jenskreidler
Copy link

@wortner

Thanks to confirm that it works.

The closeAndWait WARNING: Powershell process cannot be closed. Session seems to be blocked. happens sometimes when the PowerShell console hangs (for example, if it has not finished to execute the command). This is why I have to take the PID at the initialization. In this cases I use this PID to kill the process and avoid 'zombie' processes in the background. Maybe it happens that your command is a little bit long, so in that case you can simply give a little more of time. By default it waits 10 secs.

If you want to give more time:

//Init
Map<String, String> myConfig = new HashMap<>();
myConfig.put("maxWait", "30000");
response = powerShell.configuration(myConfig).executeCommand("Get-WmiObject Win32_BIOS");
//Close

Best regards

Since Java 9+ we could get the PID directly from the java.lang.Process#pid(). We could get rid of the extra-Powershell call.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants