elastic / elastic-agent

Elastic Agent - single, unified way to add monitoring for logs, metrics, and other types of data to a host.
Other
124 stars 134 forks source link

Elastic-Agent: Do not output to STDERR under powershell, unless you want PS to fail execution as an error #118

Open ThorbenJ opened 3 years ago

ThorbenJ commented 3 years ago

Problem:

In certain execution contexts PowerShell will convert any line of text sent to STDERR into an Error object. This will no doubt go unhandled thus the commend is failed by powershell:

 PS C:\Users\Administrator\Documents\EC_Spout> C:\Users\Administrator\Documents\EC_Spout\agent_install+enroll.ps1
Uninstalling existing
Elastic Agent has been uninstalled.
The Elastic Agent is currently in BETA and should not be used in production

elastic-agent.exe : 2020-11-24T07:32:24.902-0800    DEBUG   kibana/client.go:170    Request method: POST, path: 
/api/fleet/agents/enroll
At C:\Users\Administrator\Documents\EC_Spout\agent_install+enroll.ps1:91 char:1
+ & "$download_dir\elastic-agent-$stack_ver-windows-x86_64\elastic-agen ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (2020-11-24T07:3...t/agents/enroll:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError 

Google "PS NativeCommandError" to discover all the happy people that trip over this error.

Solution: On Windows systems (especially under powershell) do not send anything to STDERR unless its really is an error, and the command should be terminated/failed.

Ways to reproduce: In an Interactive PS, this error handling will most likely not be enabled. Under ISE is most often is.

Open PowerShell ISE and write a ps1 script:

 & "$download_dir\elastic-agent-7.10.0-windows-x86_64\elastic-agent.exe" install -f -k "$kn_url" -t "$agent_token" 

Run the script with the 'play' button in the toolbar (after saving it).

Doing it via ISE like this was the easiest way, I think, to have PS in such an error handling mode. I have experienced the same problem with PS scripts start by the task scheduler.

Extra info: I maintain scripts to automate starting a demo env.: https://github.com/ElasticSA/ec_spout (more info for Elastic employees here: https://wiki.elastic.co/display/PRES/EC+Spout )

elasticmachine commented 3 years ago

Pinging @elastic/ingest-management (Team:Ingest Management)

ph commented 3 years ago

@michalpristas or @blakerouse you know more windows than me. Can you take a look?

ThorbenJ commented 3 years ago

Please note if you don't have $ErrorActionPreference = "Stop" (PS equiv of Bash's set -e), then PS will treat the STDERR output as an error and display it, but it wont immediately kill elastic-agent.exe. Tested under PowerShell ISE. Why not under PowerShell interactive? I am no PS expert, but reading up on this it seems, ISE, PS Remote, and I assume task scheduled instances wrap STDERR with System.Management.Automation.ErrorRecord.

elasticmachine commented 2 years ago

Pinging @elastic/elastic-agent-control-plane (Team:Elastic-Agent-Control-Plane)

michalpristas commented 2 years ago

closing, even with the options set i was not able to repro Win 11 64bit

ThorbenJ commented 2 years ago

image

As I document you will not trip this issue in a normal powershell console. This error handling is only on by default in PS Remote, PS ISE and certain ways of scheduling PS scripts. Search for System.Management.Automation.ErrorRecord - If this error handling is enabled any line sent to STDERR becomes an ErrorRecord that needs to be handled. If not you get the NativeCommandError, and with $ErrorActionPreference = "Stop" the exe is stopped/killed.

 [System.Environment]::OSVersion.Version

Major  Minor  Build  Revision
-----  -----  -----  --------
10     0      19042  0       
jlind23 commented 2 years ago

@michalpristas could you please take a look again.