Relevance for multiple properties via SOAP

(imported topic written by daveb91)

Howdy,

I’m new to BigFix and can barely spell “relevance”, but I’m comfortable with SOAP and have managed to query a few properties of our managed computers via SOAP. My perspective on this may be skewed due to my unfamiliarity with relevance and long-time use of SQL, so I may be thinking about this in the wrong way. Any pointers would be appreciated. I have two questions, one on Relevance and one on the SOAP API:

Relevance

: I wish to retrieve multiple properties for a list of computers that match a criteria. Specifically, I’d like to retrieve “Computer Name, CPU, Uptime - Windows” for every computer in the “10.5.5.0” subnet. Could someone provide a complete example of relevance that would do this? I’m really stumped on the criteria syntax, and I think that if I could get this completely working it would really help me “click” with relevance.

SOAP AP

I: In playing with the SOAP API, it appears that the only way to retrieve multiple properties for multiple computers is to concatenate the property values together into a string, and get an array of these strings (one for each computer).

Array (

[0] => “COMPUTERNAME1, 1000 Mhz Pentinum 4, 3 days”

[1] => “COMPUTERNAME5, 2000 Mhz Pentinum 4, 1 days”

[2] => “COMPUTERNAME9, 1500 Mhz Pentinum 4, 5 days”

)

I believe this works, and I can live with it, but when using SOAP (as opposed to XML-RPC) I’m used to thinking of arrays of objects (literally, arrays of SOAP type “XSD:STRUCT”) which greatly appeals to my personal preference to use associative arrays for everything, even when it doesn’t add value. :slight_smile:

I’m wondering if there is a syntax available that would return an array of structs (array of associative arrays) that would be closer to the following. Can either of these be done?

Array (

[0] => Array (

Computer Name

=> “COMPUTERNAME1”,

CPU

=> “1000 Mhz Pentinum 4”,

Uptime - Windows

=> “3 days”

)

[1] => Array (

Computer Name

=> “COMPUTERNAME2”,

CPU

=> “2000 Mhz Pentinum 4”,

Uptime - Windows

=> “1 days”

)

[2] => Array (

Computer Name

=> “COMPUTERNAME3”,

CPU

=> “1500 Mhz Pentinum 4”,

Uptime - Windows

=> “5 days”

)

)

As you might imagine, an array of SOAP “structs” per the above is very easy to dereference in the resulting code (in most of the languages I use, it is deserialized directly into an associative array). Yeah, not a show-stopper, but thought I’d ask.

I’d really appreciate a working example of the relevance above. If anyone knows a trick for the SOAP that would be icing on the cake.

Thanks,

David

(imported comment written by BenKus)

Hi David,

Here is the session relevance you are looking for:

(names of it, cpus of it, values of results (bes property “Uptime”, it)) of bes computers

(Note that the way I have written it, if a computer is missing one of these values, it will not show up in the list… and I am assuming you have a property defined called “Uptime”).

I think your advice on adding the concept of arrays to the SOAP API is a good idea. The SOAP API was introduced in 7.0 and only now are we starting to see some significant widespread use and we will be looking to make improvements based on feedback like this.

The nice thing about the SOAP API is that it is built on session relevance, which makes it very flexible in terms of what data you can grab and how you can retrieve it… but it also means that you need to be able to build session relevance to get SOAP queries to work and the data returned is always a string element.

I will create an enhacement request based on the info that you suggested.

Ben

(imported comment written by daveb91)

Ben Kus

Here is the session relevance you are looking for:
(names of it, cpus of it, values of results (bes property “Uptime”, it)) of bes computers

(Note that the way I have written it, if a computer is missing one of these values, it will not show up in the list… and I am assuming you have a property defined called “Uptime”).

Thanks! The above works and from your comment I think I understand the “values of results” part to mean “only show computers that have a value for this property”. If I’m getting that right, then I am making progress. I had seen that construct in another example, but I never understood it before. Double thanks! I do have an analysis property called “Uptime - Windows” that provides the uptime value I’m looking for. The following returns a list of all computers that have that value:

(names of it, cpus of it, values of results (bes property “Uptime - Windows”, it)) of bes computers

I’m still struggling with the overall selection/filter criteria. I would like to extend the above to only return these records for computers in a particular subnet. To make things harder, I have some computers that return multiple values for subnet (laptops on the move) and need to catch those also. I’m looking to add a clause to the above that only returns computers if the given subnet (e.g. ‘10.5.5.0’) is in the list of Subnet Addresses returned for the computer. Here’s the expanded relevance that correctly provides the necessary attributes for the

unfiltered

result set:

( names of it, cpus of it,
values of results (bes property “Uptime - Windows”, it),
values of results (bes property “Subnet Address”, it) ) of bes computers

What I need now, in a SQL sense, is a “WHERE” clause. I’m trying to attach something like

(“Subnet Address” as string contains “10.5.5.0”)

to the above but can’t quite grok the syntax necessary to apply it. The following seems to parse OK, but returns no results:

(names of it, cpus of it,
values of results (bes property “Uptime - Windows”, it),
values of results (bes property “Subnet Address”, it)
) of bes computers
whose (“Subnet Address” as string contains “10.5.5.0”)

I have hundreds of computers in the subnet I am searching for (as demonstrated by my unfiltered results) but get no results from the filtered query. So, I clearly don’t know how to apply the filter. :frowning: I’d appreciate any further guidance you might have.

Ben Kus

I think your advice on adding the concept of arrays to the SOAP API is a good idea. The SOAP API was introduced in 7.0 and only now are we starting to see some significant widespread use and we will be looking to make improvements based on feedback like this.

The nice thing about the SOAP API is that it is built on session relevance, which makes it very flexible in terms of what data you can grab and how you can retrieve it… but it also means that you need to be able to build session relevance to get SOAP queries to work and the data returned is always a string element.

I will create an enhancement request based on the info that you suggested.

Ben

Thanks for that too. And based on your earlier guidance, I think I have found further justification. When I run the “unfiltered” query above, it works and I get results. For computers that report multiple subnets, however, I expected to retrieve a single record like “[1] => COMPUTER_3, 2800 MHz Pentium 4, 0 days, (10.5.5.0, 10.20.20.0, 10.40.40.0)” or something similar. Instead, I get multiple records for a single computer, one for each subnet it reported:

[0] => COMPUTER_3, 2800 MHz Pentium 4, 0 days, 10.5.5.0

[1] => COMPUTER_3, 2800 MHz Pentium 4, 0 days, 10.20.20.0

[2] => COMPUTER_3, 2800 MHz Pentium 4, 0 days, 10.40.40.0

This is problematic. What I’m looking for is “computers with this property” but what it is returning is “unique combinations of computer/property key/value pairs”. Hmmmm… I’d guess there’s a relevance trick I don’t know (lots of them, I’m sure) but returning an array value for properties that have multiple values would help. At least, it would help me.

Thanks again,

David

(imported comment written by sonnyryan91)

Hi Ben,

I am trying to use SOAP API to fetch multiple Retrieved Properties in a single Session Relevance query like the example below:

(names of it, values of results (bes property “Computer serial number or service tag”,it), values of results (bes property “Uptime - Windows”,it), values of results (bes property “Computer Manufacturer - Windows”,it), values of results (bes property “Computer Model - Windows”,it)) of bes computers

However like you mentioned below, if a computer is missing one of these values it would not show up in the list. So instead of getting 100 computers, I only get 88 since 12 computers do not have valid serial number (yes, those machines have no serial number). I would like the SOAP API to still return the missing 12 computers with Serial number value as blank or N/A. Is that possible? I dont want to create separate query for each property.

Please advise.

Thanks much!

Ben Kus

Hi David,

Here is the session relevance you are looking for:
(names of it, cpus of it, values of results (bes property “Uptime”, it)) of bes computers

(Note that the way I have written it, if a computer is missing one of these values, it will not show up in the list… and I am assuming you have a property defined called “Uptime”).

I think your advice on adding the concept of arrays to the SOAP API is a good idea. The SOAP API was introduced in 7.0 and only now are we starting to see some significant widespread use and we will be looking to make improvements based on feedback like this.

The nice thing about the SOAP API is that it is built on session relevance, which makes it very flexible in terms of what data you can grab and how you can retrieve it… but it also means that you need to be able to build session relevance to get SOAP queries to work and the data returned is always a string element.

I will create an enhacement request based on the info that you suggested.

Ben

(imported comment written by BenKus)

Hi sonnyryan / daveb,

I can answer both of your questions with the same answer. The following relevance will print out multiple results on one line AND it will not ignore computers that don’t have a result (it will just show a blank there):

(concatenation “,” of names of it, concatenation “,” of cpus of it, concatenation “,” of values of results (bes property “subnet address”, it)) of bes computers

If you want to add “n/a” instead of blank, you just need to add “if” statements for each value to check for results doing something like this:

… if (exists value of results (bes property “subnet address”, it)) then values of results (bes property “subnet address”, it) else “n/a”…

Ben

(imported comment written by sonnyryan91)

Awesome! It worked as expected. Thanks Ben!

-Sonny

(imported comment written by khanand91)

hi,

can anyone tell me which characters need to be escaped in the session query when sending in a SOAP message, I keep getting the expressions can not be evaluated … but i know that the example i’m using works as i tried it in the excel connector …

(it, multiplicity of it - 1) of unique values of (it as lowercase) of (if (it contains “:”) then preceding text of first “:” of it else it) of (relay hostnames of bes computers whose (relay server flag of it OR root server flag of it); relay servers of bes computers)

thanks

(imported comment written by Lee Wei)

khanand,

In looking at your relevance statement, the only characters that might be the quotes.

What language are you calling from?

What happens if we try a simple relevance statement such as:

“any string”

When I issue relevance statements from JavaScript, I have to do:

var relevance = ““any string””;

Lee Wei

(imported comment written by khanand91)

hi lee,

I’m using the XP soapclient which is called from a vbScript. A simple statement like ‘names of bes computers’ works fine.

I already tried doubling up the quotes which is how I would expect it to work. Let me try some more variations … if no other chars should be causing a problem then I should be able to figure it out on that basis …

thanks

(imported comment written by SY57_Jim_Montgomery)

With VB you don’t escape quotes with backslashes, but with more quotes! So something closer to

relevance = “”"“any string”""" may work better.

I don’t remember if you need 3 or 4 quotes (I think 4).

I know 5 is too many and 6 is right out!

–Jim

(imported comment written by Lee Wei)

A quick search online seems to indicate that for VBScript, the string literals will need 3 quotes:

s = “”“Test”""