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

654 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 answers

3
Steven 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.