How to get command line application output to a variable in background in PowerShell 5.1?

680 Views Asked by At

SOLVED

Thanks to @mklement0 's advice, I tried to get an exit code from rstcli64.exe:

  • from cmd I get 0
  • from zabbix-agent I get 3 (INVALID_DEVICE, according to manual) So, the culprit is not PowerShell, but rstcli64.exe exiting with an error in conditions: Windows Server 2019 and ran from PS script ran by zabbix-agent. I've updated rstcli from Intel's website and new version has the same syntax and works perfectly in new conditions.

ORIGINAL POST

I have Windows Zabbix Agent, which runs a PowerShell script, which runs a command line application, parses output and gives 1 or 0.

$states = C:\util\rstcli64.exe --information --volume 2> $null | select-string -Pattern "State:"

$notNormalStates = $states | Select-String -Pattern "Normal" -NotMatch
if ($states.Count -gt 0 -and $notNormalStates.Count -eq 0){
    "1"
} Else {
    "0"
}

This script worked on Windows Server 2012 R2, but after migration to Windows Server 2019 (with PowerShell 5.1) it began to output only 0.

This is a wave-particle duality situation: if I run this script from command line (User, Administrator, System - the same), it gives 1, because it receives the output from rstcli64.exe; and if zabbix-agent runs this exact script, it gets nothing from rstcli64.exe, thus gives 0.

So I guess the difference is that I run the script from an interactive shell and zabbix-agent runs the script from background.

And the question is: how do I get the output from a command line application in PowerShell 5.1 (Windows Server 2019), when run in background?

MORE INFO

If I just use this:

$states = C:\util\rstcli64.exe --information --volume
$states
exit

It shows a lot of data if I run the script in command line:

--VOLUME INFORMATION--

Name: HDD_MIRROR Raid Level: 1 Size:
1863 GB StripeSize: 64 KB Num Disks: 2 State:
Normal System: True Initialized: True Cache Policy:
R

--DISKS IN VOLUME: HDD_MIRROR --

ID: 0-0-0-0 Type: Disk Disk Type:
SATA Disk State: Normal

But if ran from zabbix - there's nothing:

6304:20201014:170446.686 EXECUTE_STR() command:'%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -nologo -ExecutionPolicy ByPass -File "C:\util\intel_rst_raid.ps1"' len:0 cmd_result:'' 6304:20201014:170446.686 Sending back []
8208:20201014:170446.687 End of collect_perfstat()

MORE INFO

It just does it with rstcli64.exe. With few other command line tools I get the same output when manually running script in cmd and triggering it from zabbix-agent. Again, only in PowerShell 5.1 in Windows Server 2019, so...

1

There are 1 best solutions below

3
On

This sounds like an issue with redirection and streams. The information stream was introduced in 5.0 and Windows 2012R2 comes with 4.0. Which might explain the different behavior.

About_Redirection

I'd play around with the redirection operators to see if you can get what you need piped to Select-String. It might look something like:

$states = C:\util\rstcli64.exe --information --volume *>&1 | select-string -Pattern "State:" 

This takes all streams and redirects them to the success stream, this way everything goes down the pipeline to Select-string.

I'd also advise you can make your RegEx a little more precise. Maybe "^State:" so you are capturing lines that start with "State:". Though I don't know if there may be preceding white space.