ParserError during PowerShell script execution - Bug or design?
Just to make clear, I opened a case on this, I want to hear from Support. However I also wanted to hear whether or not you have come across this.... I mean PowerShell scripting inside DataSources has been around for years so I cannot be the only one encountering this issue...here it is.
A collector incurs ParseException in DataSources using PowerShell script when parsing script parameters such as wmi.pass or wmi.user or any other device property containing single quotes.
so, typical statement in PowerShell such as;
$my_custom_device_property = '##MY.CUSTOM.PROP##'
If the value of that property contains a single quote DataSource will fail with parsing exception;
Unexpected token 'xxxxx'' in expression or statement.
I wonder.... is this fixed in EA Collector 31.100? Reading through release notes there is a reference to fixing parser exceptions but I cannot tell if this is it. I doubt it.
By the way, if you use double quotes in PS script when declaring said parameter then there is no issue. As long as the value does not contain double quote, that is, then you will get parsing exception again. ![]()
mmatec01
OP4 years agoOK, I got the feedback back from the Support. So here it is, right from the horse's mouth, so to speak;
This is actually a known issue that our developers are working on. It looks like it should be solved in collector version 31.200, which is scheduled to be released by the end of the month.
LM User
·4 years agoYes, that is true. What I mean is that to escape a quote in a string in Groovy, you do it the same whether it's single quotes or double quotes encapsulating the string:
Mike Moniz
·4 years agoHmm, I'm not sure if it's about escaping method, afaik groovy has the same single and double quote syntax as PowerShell or many other languages. I think it's more that groovy can import internal/collector functions like hostProps.get() without the collector needing to directly modifying your code with search-replace. Since the collector is java-based I assume that was easy to do but powershell is dotnet based so it can't just import java classes.
LM User
·4 years agoIt's a limitation of the language, not the JVM. The language specifies different ways of escaping based on encapsulation. Groovy is a language that has a unified escaping method, regardless of encapsulating markers.
mmatec01
OP4 years agoWell. Mike. Thank you for couple of suggested workarounds. I don't want to use groovy in this particular DS. By the way if groovy can ingest special characters without scrubbing them, so should PowerShell. That's my point in here, in that PowerShell scripting should be a first-class citizen just like groovy is. Isn't the JVM that's running under the hood and parses both the groovy and PowerShell?
Back to this issue. I ran some tests and now I found a workaround solution.
$my_custom_device_property = (Get-Device_Property /device/devices/${device_id}/properties/${device_prop_name}) -replace "'",''
Note to self - go back to your scripts and change the simple assignments to API get function for the properties you can not control their contents.
Mike Moniz
·4 years agoCan you use groovy since it doesn't do the serach-replace thing? Or perhaps you can try using a here-string like below for powershell.
I'm not sure if there is any real 100% solution when the input is directly injected into code.
mmatec01
OP4 years agoThe thing is.... sometimes the value of device property I am fetching in PowerShell script is instantiated by some automatic action (for example API update) over which I have no control. Meaning, I cannot parse and sanitize (escape single quote) the value before I try to declare it in PowerShell. I can only control what I can control.
LM User
·4 years agoI would imagine in certain cases, if there were two single quotes in the token value, it would sometimes have a parsing issue and sometimes not. The problem is that the way the token values are inserted: by simple search and replace. So, with your statement:
If my.custom.prop is:
Then the resulting script that the collector tries to execute will be:
It's not exactly that anything on the LM side has any issues with that (although i wouldn't rule it out, recursive replacement) but PowerShell obviously has an issue with it. There's no closing quote for the last quote.
It's possible, but I don't know, that the referenced fix might just replace ' (one single quote) with '' (two single quotes) before injecting the value into the powershell script. However, with PowerShell, the encapsulating quotes determine the method of escaping. So, if the encapsulating quotes are single, a single quote is escaped by preceding it another single quote. However, if the encapsulating quotes are double quotes, then single quotes don't need to be escaped (but double quotes do).
Long story short, the lesson is to escape special characters. If you know your script encapsulates the token with single quotes, you'll need to make sure your token's single quotes are escaped with single quotes. Or make sure the script uses double quotes (and escape any double quotes in your token).