Need help with complex WHOSE and IT

Trying to retrieve information from the Windows registry based on a related file system object. Retrieving the info is working fine, but my attempts to restrict it with a WHOSE aren’t working…

This works:
(values "USERNAME" of it, values "USERDOMAIN" of it, (creation times of it, modification times of it, accessed times of it) of files (value "USERPROFILE" of it as string & "\ntuser.dat")) of (keys "Volatile Environment" of keys of key "HKEY_USERS" of native registry)

but adding what I think is the right WHOSE fails:
whose (accessed time of file (value "USERPROFILE" of it as string & "\ntuser.dat") of it > (now - (day * 90)))

As it is, the it in "USERPROFILE" of it as string ends up pointing at the it after it instead of the intended clause. Moving and adding parens just bounces back and forth between The operator "file" is not defined and The operator "concatenate" is not defined.

Any relevance geniuses out there have a helpful pointer (or paren)? :slight_smile:

Put the ‘whose’ clause with the file, wrapping some parentheses around the whole files piece.

(values "USERNAME" of it, values "USERDOMAIN" of it, (creation times of it, modification times of it, accessed times of it) of (files (value "USERPROFILE" of it as string & "\ntuser.dat")) whose (accessed time of it > now - 90 * day)) of (keys "Volatile Environment" of keys of key "HKEY_USERS" of native registry)

1 Like

So, that appears to work… but why? :slight_smile: Why am I not getting USERNAME and USERDOMAIN (but no dates) for computers with files that don’t match the WHOSE?

Not sure I understand the supplementary question.

Your original issue (the operator “concatenate” is not defined) just indicates that at some point you are trying to concatenate an object the the interpreter can’t represent as a string.

I’m at home now, so difficult to test (I only have my laptop with just the debugger, no BESClient) and no aged profiles.

Using plural relevance (as you do with the timestamps) gets robust relevance, but that isn’t always what you want.

You may get some insight with

 (
   values "USERNAME" of it, values "USERDOMAIN" of it, 
   (
     creation time of it as string | "__", modification time of it as string | "__", accessed time of it as string | "__"
   )
   of 
   (
     files 
     (
       value "USERPROFILE" of it as string & "\ntuser.dat"
     )
   )
   whose
   (
     accessed time of it > now - 90 * day
   )
 )
 of 
 (
   keys "Volatile Environment" of keys of key "HKEY_USERS" of native registry
 )
1 Like

Sorry… I wasn’t very clear…

Before, I was basically saying “give me these two registry values and the date of a file represented in a third registry value for entries where the date of that file is within the last 90 days”. This new relevance (as I read it) basically says “give me these two registry values all the time and give me the date of the file represented in a third value only if that date is within the last 90 days”.

I presume that there’s some part of relevance logic and processing that says that “if any part of the data set your asking for doesn’t exist, I’m not giving you any of it”?

Okay… learning more here…

Using commas, it seems to do what I’d said (if one’s not here, you get nothing).

If I use semicolons, however, I end up getting what I expected with registry values and no date for some that have no recent file.

Hrm…

1 Like

It isn’t clear what you are looking for. The whose clause will restrict the files that are returned and as @trn showed you need to have the bar with a value for when the attribute isn’t there or it stops iterating through the list. So make sure you do things like creation time of it as string | "N/A" in those parts

1 Like

Semicolons create a plural object of the same type.
Commas create a tuple of items of possibly different types (and drops instances where one of the items is missing)

Creating a plural folder object with semicolons  (3 folders, one object)
q: (windows folder; system folder; folder "c:\test")
A: C:\WINDOWS
A: C:\WINDOWS\system32
A: c:\test
T: 1.090 ms
I: plural folder

Creating a tuple of a Folder, Boolean, Time (3 items of different object types joined together into one object.)
q: (windows folder, true, now)
A: C:\WINDOWS, True, ( Mon, 12 Apr 2021 14:56:17 -0400 )
T: 0.404 ms
 I: singular ( folder, boolean, time )

Creating the same, only one of the 3 objects is not there, so the entire joined element is dropped
q: (windows folder, true,nothing)
T: 0.623 ms
I: plural ( folder, boolean, undefined )

To loop back around to your ask. You always want to see the Username and UserDomain entries from the registry and you only want to see the 3 date stamps if access time is less than 90 days?

Try:

q: (values "USERNAME" of it, values "USERDOMAIN" of it, (if (accessed time of it > (now - day*90)) then ((creation time of it as string, modification times of it as string, accessed time of it as string)) else ("Your file is older than 90 days...","OldFile","OldFile")) of files (value "USERPROFILE" of it as string & "\ntuser.dat")) of (keys "Volatile Environment" of keys of key "HKEY_USERS" of native registry)
A: brolly33, MyDomain, ( ( Thu, 15 Aug 2019 20:12:29 -0400 ), ( Mon, 12 Apr 2021 14:49:37 -0400 ), ( Mon, 12 Apr 2021 14:49:37 -0400 ) )
T: 0.678 ms
I: plural ( registry key value, registry key value, ( string, string, string ) )
6 Likes

Adding to @brolly33’s example, you could also cast the date to whatever format suits you best (not sure if there is another way to avoid the parenthesized results)

Q: (values "USERNAME" of it as string, values "USERDOMAIN" of it as string, (if (accessed time of it > (now - day*90)) then (( concatenation ", " of ((((month of it as two digits) & "/" & (day_of_month of it as two digits) & "/" & year of it as string) of date ("GMT" as time zone) of it & " " & ((two digit hour of it) & ":" & (two digit minute of it)) of time ("GMT" as time zone) of it) ) of (creation time of it; modification times of it; accessed time of it))) else ("Your file is older than 90 days...")) of files (value "USERPROFILE" of it as string & "\ntuser.dat")) of (keys "Volatile Environment" of keys of key "HKEY_USERS" of native registry)
A: RobG, THELAB, ( 03/22/2021 17:20, 03/23/2021 23:42, 03/23/2021 23:42 )
T: 1.654 ms
I: plural ( string, string, string )
3 Likes

Thanks, @brolly33! Actually, I only want to see any information (the Username, UserDomain, and the dates) if the access time is less than 90 days. If the associated access time is greater than 90 days, I don’t care about the dates, the Username, OR the UserDomain.

Hi @straffin , when I’m writing down relevance sentences - I’m working with the following questions:

  1. What is the main goal of this relevance?
  2. How do I want to structure the result -
  • Do I want it to return some True or False statements? If so , what are definitions for those results in plain english (example: I would like to return True if there was some user that logged into the system …)
  • Do you want it to return string Statements?
    Write down an example

I would be more than happy to help you on your journey with bigfix

Can do!

We can just tweak the if statement to return nothing. and the Nothing will drop the entire tuple element.

q: (values "USERNAME" of it, values "USERDOMAIN" of it, (if (accessed time of it > (now - day*90)) then ((creation time of it as string, modification times of it as string, accessed time of it as string)) else (nothing)) of files (value "USERPROFILE" of it as string & "\ntuser.dat")) of (keys "Volatile Environment" of keys of key "HKEY_USERS" of native registry)
A: brolly33, MyDomain, ( ( Thu, 15 Aug 2019 20:12:29 -0400 ), ( Mon, 26 Apr 2021 11:27:21 -0400 ), ( Mon, 26 Apr 2021 11:28:06 -0400 ) )
2 Likes

Oy. I hadn’t even considered an if instead of whose. It’s so much cleaner (and so obvious, 20/20 hindsight being what it is…)!

I also knew nothing of nothing, so thanks for that! I have just under a bazillion Retrieved Properties that return some form of “N/A” that should probably just return nothing. Time for a clean-up…

Thanks again!!

1 Like

careful with your cleanup - nothing really is nothing, so string value = “N/A” is different than a null string “” and different from <not reported>. The endpoints may “drop out” of things where you don’t expect them to drop out.


image

2 Likes

Understood. Thank you again!