---
title: Privileged Account Extend Searchable Properties
slug: privileged-account-extend-searchable-properties
docTags: 
createdAt: 2026-02-19T20:53:07.693Z
---

This update extends how **Privileged Accounts** can be queried in scripts by allowing additional searchable properties to be defined via SQL joins, similar to how joins/common properties can be exposed for **Services** and **Assets**. The main use case is being able to search privileged accounts by **Owner** (and other fields), even when those fields are not directly available in the v\_PrivilegedAccount view.

# Overview

Previously, when you loaded a PrivilegedAccountCollection and called LoadQuery(...), filters could only target columns exposed by the v\_PrivilegedAccount view. This limited searching to whatever that view surfaced.

With this feature, you can define one or more **joins** and expose additional **properties** (for filtering and selection) by adding an XML join definition to the Privileged Accounts root object.

This change does not alter existing queries. It only adds the ability to expose additional queryable properties when join definitions are configured.

# What changes for developers

You can now:

- Keep using PrivilegedAccountCollection.LoadQuery(...)&#x20;
- Filter using additional properties (for example, Owner)&#x20;
- Extend later with more joins/properties without changing script logic&#x20;

Example (existing pattern remains the same):

:::BlockQuote
using System;
using System.Data;
using Innovation.Activate;

class Script : ScriptBase
\{
&#x20;   public void main()
&#x20;   \{
&#x20;       PrivilegedAccountCollection accounts = new PrivilegedAccountCollection(null);

&#x20;       PrivilegedAccount root = Evaluator.GetObject("=/Resources/Privileged Accounts/Administrator Account") as PrivilegedAccount;

&#x20;       accounts.LoadQuery(root, "&#x7B;Owner} = 'owner\@example.com'");

&#x20;       foreach (PrivilegedAccount account in accounts)
&#x20;           Trace.WriteLine(account.Path);
&#x20;   }
}
:::

# Configuration

To expose additional fields, add an XML definition to the Privileged Accounts root object to define the required joins and mapped properties.

## Join definition example

:::BlockQuote
\<root>
&#x20; \<join to="left outer join Approver a on a.Guid = s.Guid and EndTime is NULL">
&#x20; \</join>
&#x20; \<join to="left outer join ADCache ad on ad.GUID = a.ApproverGuid">
&#x20;   \<property name="Owner">ad.mail\</property>
&#x20; \</join>
\</root>
:::

## How it works

- Each \<join> element appends a join to the query.&#x20;
- A \<property> maps a friendly property name (used in filters) to a SQL expression/column.&#x20;
- In the example above:&#x20;
  - The query joins from the privileged account record to Approver, then to ADCache&#x20;
  - The exposed property Owner is mapped to ad.mail&#x20;

Property values must align with what your scripts supply in filters. For example, if Owner is mapped to ad.mail, your filter should compare against an email address. If you want to filter by GUID instead, map Owner to the appropriate GUID column.

# Querying with exposed properties

Once configured, you can filter using the new property name in LoadQuery(...).

Example patterns:

:::BlockQuote
accounts.LoadQuery(root, "&#x7B;Owner} = 'user\@example.com'");
:::

:::BlockQuote
accounts.LoadQuery(root, "&#x7B;Owner} like '%@example.com'");
:::

Use the same filter syntax you already use elsewhere in Activate collection queries. The key difference is that the property must be defined in the join XML to be queryable.

# Common use cases

## Search privileged accounts by owner

- Add joins that resolve the owner to a stable identifier (GUID, email, username)&#x20;
- Expose it as &#x7B;Owner}&#x20;
- Filter in scripts using &#x7B;Owner} = ...&#x20;

## Extend for additional fields later

You can add more \<property> mappings (and supporting joins) over time, for example:

- Owner display name&#x20;
- Owner GUID&#x20;
- Request/approval state metadata&#x20;
- Source directory attributes&#x20;

# Troubleshooting

## “Invalid column/property” or property not recognised

- Confirm the \<property name="...">...\</property> is present in the join XML&#x20;
- Confirm the property name in your query matches exactly (case and spacing)&#x20;
- Confirm the SQL column/expression referenced by the property exists in the join scope&#x20;

## Filters return no results

- Validate what the property is mapped to (for example, ad.mail vs ad.GUID)&#x20;
- Ensure your filter value matches the mapped data type and format&#x20;
- Check join conditions (for example, the EndTime is NULL clause may exclude expected rows)&#x20;

## Performance concerns

- Prefer targeted joins and indexed columns (GUIDs often perform better than free-text mail fields)&#x20;
- Avoid adding unnecessary joins if you only need one or two properties&#x20;

# Notes for implementation

- Keep property names stable (Owner, OwnerGuid, etc.) so scripts don’t need frequent updates.&#x20;
- If you need to support multiple identifier types (email + GUID), expose multiple properties rather than overloading one.
