From 91700318608df432c8908f5699620e97b5a7f498 Mon Sep 17 00:00:00 2001 From: Joey Dreijer Date: Tue, 23 Jun 2026 21:58:13 +0200 Subject: [PATCH 1/9] Remove all unused fields (for now) --- src/openhound_jamf/models/sso.py | 41 -------------------------------- 1 file changed, 41 deletions(-) diff --git a/src/openhound_jamf/models/sso.py b/src/openhound_jamf/models/sso.py index be7c387..7278807 100644 --- a/src/openhound_jamf/models/sso.py +++ b/src/openhound_jamf/models/sso.py @@ -21,33 +21,8 @@ class SSOProperties(JAMFNodeProperties): class SAMLSettings(BaseModel): - token_expiration_disabled: bool | None = Field( - default=None, alias="tokenExpirationDisabled" - ) - user_attribute_enabled: bool | None = Field( - default=None, alias="userAttributeEnabled" - ) - user_attribute_name: str | None = Field(default=None, alias="userAttributeName") - user_mapping: str | None = Field(default=None, alias="userMapping") group_attribute_name: str = Field(alias="groupAttributeName") group_rdn_key: str = Field(alias="groupRdnKey") - idp_url: str | None = Field(default=None, alias="idpUrl") - idp_provider_type: str | None = Field(default=None, alias="idpProviderType") - entity_id: str | None = Field(default=None, alias="entityId") - - -class OIDCSettings(BaseModel): - user_mapping: str | None = Field(default=None, alias="userMapping") - username_attribute_claim_mapping: str | None = Field( - default=None, alias="usernameAttributeClaimMapping" - ) - jamf_id_authentication_enabled: bool | None = Field( - default=None, alias="jamfIdAuthenticationEnabled" - ) - - -class EnrollmentConfig(BaseModel): - hosts: list[str] = Field(default_factory=list) @app.asset( @@ -88,23 +63,7 @@ class SSO(JAMFAsset): configuration_type: str = Field(alias="configurationType") sso_for_enrollment_enabled: bool = Field(alias="ssoForEnrollmentEnabled") saml_settings: SAMLSettings | None = Field(alias="samlSettings", default=None) - oidc_settings: OIDCSettings | None = Field(alias="oidcSettings", default=None) sso_enabled: bool = Field(alias="ssoEnabled") - sso_for_mac_os_self_service_enabled: bool | None = Field( - default=None, alias="ssoForMacOsSelfServiceEnabled" - ) - enrollment_sso_for_account_driven_enrollment_enabled: bool | None = Field( - default=None, alias="enrollmentSsoForAccountDrivenEnrollmentEnabled" - ) - enrollment_sso_config: EnrollmentConfig | None = Field( - default=None, alias="enrollmentSsoConfig" - ) - group_enrollment_access_enabled: bool | None = Field( - default=None, alias="groupEnrollmentAccessEnabled" - ) - group_enrollment_access_name: str | None = Field( - default=None, alias="groupEnrollmentAccessName" - ) @property def id(self): From bccdce8746e2221bcd7c64d3ab39358747179781 Mon Sep 17 00:00:00 2001 From: Joey Dreijer Date: Tue, 23 Jun 2026 21:58:44 +0200 Subject: [PATCH 2/9] Remove all unused fields (for now) --- src/openhound_jamf/models/script.py | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/openhound_jamf/models/script.py b/src/openhound_jamf/models/script.py index fc141bd..babbe3b 100644 --- a/src/openhound_jamf/models/script.py +++ b/src/openhound_jamf/models/script.py @@ -1,21 +1,11 @@ -from enum import Enum -from typing import Any - from openhound.core.asset import BaseAsset -from pydantic import BaseModel, Field +from pydantic import BaseModel from openhound_jamf.main import app -class Priority(Enum): - Before = "Before" - After = "After" - During = "During" - - class BaseScript(BaseModel): id: int - name: str | None = None @app.asset( @@ -37,10 +27,6 @@ class Script(BaseAsset): filename: str | None = None info: str | None = None notes: str | None = None - priority: Priority | None = None - parameters: dict[str, Any] = Field(default_factory=dict) - os_requirements: str | None = None - script_contents_encoded: str | None = None @property def as_node(self): From 9860d4613959deae33e5dd7dd71cb66963e3ba46 Mon Sep 17 00:00:00 2001 From: Joey Dreijer Date: Tue, 23 Jun 2026 21:59:06 +0200 Subject: [PATCH 3/9] Remove all unused fields (for now) --- src/openhound_jamf/models/group.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/openhound_jamf/models/group.py b/src/openhound_jamf/models/group.py index a8adc39..41cb0ab 100644 --- a/src/openhound_jamf/models/group.py +++ b/src/openhound_jamf/models/group.py @@ -12,12 +12,10 @@ class User(BaseModel): id: int - name: str | None = None class Site(BaseModel): id: int - name: str | None = None @dataclass @@ -36,7 +34,6 @@ class GroupProperties(JAMFNodeProperties): class BaseGroup(BaseModel): - name: str | None = None id: int From 8c0aab97fcc21e8eea80a6b99f6a54de37ee1066 Mon Sep 17 00:00:00 2001 From: Joey Dreijer Date: Tue, 23 Jun 2026 21:59:14 +0200 Subject: [PATCH 4/9] Remove all unused fields (for now) --- src/openhound_jamf/models/computerextensionatt.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/openhound_jamf/models/computerextensionatt.py b/src/openhound_jamf/models/computerextensionatt.py index c7f45f0..d14bc5c 100644 --- a/src/openhound_jamf/models/computerextensionatt.py +++ b/src/openhound_jamf/models/computerextensionatt.py @@ -3,5 +3,3 @@ class ComputerextensionAttribute(BaseModel): id: int - name: str | None = None - enabled: bool | None = None From 415c6a1201125a0ada6db6a3886bf7383c25615f Mon Sep 17 00:00:00 2001 From: Joey Dreijer Date: Tue, 23 Jun 2026 21:59:37 +0200 Subject: [PATCH 5/9] Remove all unused fields (for now) --- src/openhound_jamf/models/computer.py | 67 --------------------------- 1 file changed, 67 deletions(-) diff --git a/src/openhound_jamf/models/computer.py b/src/openhound_jamf/models/computer.py index 8a96d13..acf6523 100644 --- a/src/openhound_jamf/models/computer.py +++ b/src/openhound_jamf/models/computer.py @@ -1,5 +1,4 @@ from dataclasses import dataclass -from datetime import datetime from openhound.core.asset import EdgeDef, NodeDef from openhound.core.models.entries_dataclass import Edge, EdgePath, EdgeProperties @@ -56,20 +55,6 @@ class ComputerProperties(JAMFNodeProperties): class RemoteManagement(BaseModel): managed: bool | None = None - management_username: str | None = Field(default=None, alias="managementUsername") - - -class UserManagementInfo(BaseModel): - capable_user: str | None = Field(default=None, alias="capableUser") - management_id: str | None = Field(default=None, alias="managementId") - - -class MdmCapable(BaseModel): - capable: bool | None = None - # capable_users: list[str] = Field(alias="capableUsers") deprecated - user_management_info: list[UserManagementInfo] = Field( - default_factory=list, alias="userManagementInfo" - ) class Site(BaseModel): @@ -77,12 +62,6 @@ class Site(BaseModel): name: str -class EnrollmentMethod(BaseModel): - id: str | None = None - object_name: str | None = Field(alias="objectName", default=None) - object_type: str | None = Field(default=None, alias="objectType") - - class UserAndLocation(BaseModel): username: str | None = None realname: str | None = None @@ -92,10 +71,6 @@ class UserAndLocation(BaseModel): class Hardware(BaseModel): - model: str | None = None - make: str | None = None - model_identifier: str | None = Field(default=None, alias="modelIdentifier") - mac_address: str | None = Field(default=None, alias="macAddress") serial_number: str | None = Field(default=None, alias="serialNumber") processor_type: str | None = Field(default=None, alias="processorType") apple_silicon: bool | None = Field(default=None, alias="appleSilicon") @@ -127,7 +102,6 @@ class DiskEncryption(BaseModel): class GroupMembership(BaseModel): - group_id: str | None = Field(default=None, alias="groupId") group_name: str = Field(alias="groupName") @@ -171,60 +145,19 @@ class Computer(JAMFAsset): id: str udid: str - extension_attributes: list = Field( - default_factory=list, alias="extensionAttributes" - ) name: str last_ip_address: str | None = Field(default=None, alias="lastIpAddress") last_reported_ip_v4: str | None = Field(default=None, alias="lastReportedIpV4") last_reported_ip_v6: str | None = Field(default=None, alias="lastReportedIpV6") jamf_binary_version: str | None = Field(default=None, alias="jamfBinaryVersion") - platform: str | None = None - barcode1: str | None = None - barcode2: str | None = None - asset_tag: str | None = Field(default=None, alias="assetTag") remote_management: RemoteManagement | None = Field( default=None, alias="remoteManagement" ) supervised: bool | None = None - mdm_capable: MdmCapable | None = Field(default=None, alias="mdmCapable") - report_date: str | None = Field(default=None, alias="reportDate") - last_contact_time: str | None = Field(default=None, alias="lastContactTime") - last_cloud_backup_date: str | None = Field( - default=None, alias="lastCloudBackupDate" - ) - last_enrolled_date: str | None = Field(default=None, alias="lastEnrolledDate") - mdm_profile_expiration: datetime | None = Field( - default=None, alias="mdmProfileExpiration" - ) - initial_entry_date: str | None = Field(default=None, alias="initialEntryDate") - distribution_point: str | None = Field(default=None, alias="distributionPoint") - itunes_store_account_active: bool | None = Field( - default=None, alias="itunesStoreAccountActive" - ) enrolled_via_automated_device_enrollment: bool | None = Field( default=None, alias="enrolledViaAutomatedDeviceEnrollment" ) user_approved_mdm: bool | None = Field(default=None, alias="userApprovedMdm") - enrollment_method: EnrollmentMethod | None = Field( - default=None, alias="enrollmentMethod" - ) - declarative_device_management_enabled: bool | None = Field( - default=None, alias="declarativeDeviceManagementEnabled" - ) - management_id: str | None = Field(default=None, alias="managementId") - last_logged_in_username_self_service: str | None = Field( - default=None, alias="lastLoggedInUsernameSelfService" - ) - last_logged_in_username_self_service_timestamp: str | None = Field( - default=None, alias="lastLoggedInUsernameSelfServiceTimestamp" - ) - last_logged_in_username_binary: str | None = Field( - default=None, alias="lastLoggedInUsernameBinary" - ) - last_logged_in_username_binary_timestamp: str | None = Field( - default=None, alias="lastLoggedInUsernameBinaryTimestamp" - ) site: Site user_and_location: UserAndLocation | None = Field( default=None, alias="userAndLocation" From b357c42e1cb2f6bc98ee70bd7b4b4c5d2b4f58d3 Mon Sep 17 00:00:00 2001 From: Joey Dreijer Date: Tue, 23 Jun 2026 21:59:48 +0200 Subject: [PATCH 6/9] Remove all unused fields (for now) --- src/openhound_jamf/models/api_integrations.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/openhound_jamf/models/api_integrations.py b/src/openhound_jamf/models/api_integrations.py index 79832bd..edfe204 100644 --- a/src/openhound_jamf/models/api_integrations.py +++ b/src/openhound_jamf/models/api_integrations.py @@ -172,9 +172,6 @@ class ApiIntegration(JAMFAsset): id: int display_name: str = Field(alias="displayName") authorization_scopes: list[str] = Field(alias="authorizationScopes") - access_token_lifetime_seconds: int | None = Field( - default=None, alias="accessTokenLifetimeSeconds" - ) enabled: bool app_type: str = Field(alias="appType") client_id: str = Field(alias="clientId") From 822f41348bd5dfdbcfd0a0fd695000d95758f90b Mon Sep 17 00:00:00 2001 From: Joey Dreijer Date: Tue, 23 Jun 2026 21:59:53 +0200 Subject: [PATCH 7/9] Remove all unused fields (for now) --- src/openhound_jamf/models/account.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/openhound_jamf/models/account.py b/src/openhound_jamf/models/account.py index 838fa93..d738ac4 100644 --- a/src/openhound_jamf/models/account.py +++ b/src/openhound_jamf/models/account.py @@ -49,13 +49,11 @@ class AccountProperties(JAMFNodeProperties): class BaseAccount(BaseModel): - name: str | None = None id: int class Site(BaseModel): id: int - name: str | None = None class Privilege(BaseModel): @@ -230,7 +228,6 @@ class Account(JAMFAsset): email: str email_address: str | None = None enabled: str - force_password_change: bool | None = None access_level: str privilege_set: str site: Optional[Site] | None = None From 47d8d3b3ed1dc085217fe8f9c677da7d5e964fdf Mon Sep 17 00:00:00 2001 From: Joey Dreijer Date: Tue, 23 Jun 2026 22:01:48 +0200 Subject: [PATCH 8/9] Remove all unused fields (for now) --- src/openhound_jamf/models/user.py | 50 ------------------------------- 1 file changed, 50 deletions(-) diff --git a/src/openhound_jamf/models/user.py b/src/openhound_jamf/models/user.py index 4f7a13c..efc615d 100644 --- a/src/openhound_jamf/models/user.py +++ b/src/openhound_jamf/models/user.py @@ -1,5 +1,4 @@ from dataclasses import dataclass, field -from typing import Any from openhound.core.asset import EdgeDef, NodeDef from openhound.core.models.entries_dataclass import Edge, EdgePath, EdgeProperties @@ -13,54 +12,14 @@ class BaseUser(BaseModel): id: int - name: str | None = None class Computer(BaseModel): id: int - name: str | None = None - - -class Peripherals(BaseModel): - id: int | None = None - name: str | None = None - - -class VPP(BaseModel): - id: int | None = None - name: str | None = None - - -class Mobile(BaseModel): - id: int | None = None - name: str | None = None - - -class ExtensionAtt(BaseModel): - id: int | None = None - name: str | None = None - - -class Site(BaseModel): - id: int | None = None - name: str | None = None - - -class UserGroup(BaseModel): - size: int | None = None - - -class LDAPServer(BaseModel): - id: int | None = None - name: str | None = None class Links(BaseModel): computers: list[Computer] = Field(default_factory=list) - peripherals: Any = None - mobile_devices: Any = None - vpp_assignments: Any = None - total_vpp_code_count: int | None = None @dataclass @@ -112,16 +71,7 @@ class User(JAMFAsset): name: str full_name: str email: str | None = None - email_address: str | None = None phone_number: str - position: str | None = None - managed_apple_id: str | None = None - enable_custom_photo_url: bool | None = None - custom_photo_url: str | None = None - ldap_server: LDAPServer | None = None - extension_attributes: list[ExtensionAtt] = Field(default_factory=list) - sites: list[Site] = Field(default_factory=list) - user_groups: UserGroup | None = None links: Links | None = None @property From 18be5e8c22de683a5843eea8d223c0933358e963 Mon Sep 17 00:00:00 2001 From: Joey Dreijer Date: Tue, 23 Jun 2026 22:04:41 +0200 Subject: [PATCH 9/9] Remove all unused fields (for now) --- src/openhound_jamf/models/policy.py | 257 ++-------------------------- src/openhound_jamf/transforms.py | 5 +- 2 files changed, 13 insertions(+), 249 deletions(-) diff --git a/src/openhound_jamf/models/policy.py b/src/openhound_jamf/models/policy.py index ec1ffb0..749eef1 100644 --- a/src/openhound_jamf/models/policy.py +++ b/src/openhound_jamf/models/policy.py @@ -1,123 +1,23 @@ -from dataclasses import dataclass - from openhound.core.asset import BaseAsset from pydantic import BaseModel, Field -from openhound_jamf.graph import JAMFNodeProperties from openhound_jamf.main import app class BasePolicy(BaseModel): id: int - name: str | None = None - - -class IdName(BaseModel): - id: int | None = None - name: str | None = None - - -class DateTimeLimitations(BaseModel): - activation_date: str | None = None - activation_date_epoch: int | None = None - activation_date_utc: str | None = None - expiration_date: str | None = None - expiration_date_epoch: int | None = None - expiration_date_utc: str | None = None - no_execute_start: str | None = None - no_execute_end: str | None = None - - -class NetworkLimitations(BaseModel): - minimum_network_connection: str | None = None - any_ip_address: bool | None = None - network_segments: list[dict[str, IdName]] = Field(default_factory=list) -class OverrideDefaultSettings(BaseModel): - target_drive: str | None = None - distribution_point: str | None = None - force_afp_smb: bool | None = None - sus: str | None = None - - -class Computer(BaseModel): +class ScopedComputer(BaseModel): id: int - name: str | None = None - udid: str - -class LimitToUsers(BaseModel): - user_groups: list[dict[str, str]] | list[str] = Field(default_factory=list) - -class Limitations(BaseModel): - users: list[dict[str, IdName]] = Field(default_factory=list) - user_groups: list[dict[str, IdName]] = Field(default_factory=list) - network_segments: list[dict[str, IdName]] = Field(default_factory=list) - ibeacons: list[dict[str, IdName]] = Field(default_factory=list) +class ExcludedComputer(BaseModel): + udid: str class Exclusions(BaseModel): - computers: list[Computer] - computer_groups: list[dict[str, IdName]] = Field(default_factory=list) - buildings: list[dict[str, IdName]] = Field(default_factory=list) - departments: list[dict[str, IdName]] = Field(default_factory=list) - users: list[dict[str, IdName]] = Field(default_factory=list) - user_groups: list[dict[str, IdName]] = Field(default_factory=list) - network_segments: list[dict[str, IdName]] = Field(default_factory=list) - ibeacons: list[dict[str, IdName]] = Field(default_factory=list) - - -class Scope(BaseModel): - all_computers: bool - computers: list[Computer] - computer_groups: list[dict[str, IdName]] = Field(default_factory=list) - buildings: list[dict[str, IdName]] = Field(default_factory=list) - departments: list[dict[str, IdName]] = Field(default_factory=list) - limit_to_users: LimitToUsers | None = None - limitations: Limitations | None = None - exclusions: Exclusions - - -class Category(BaseModel): - id: int | None = None - name: str | None = None - display_in: bool | None = None - feature_in: bool | None = None - - -class SelfServiceIcon(BaseModel): - id: int | None = None - filename: str | None = None - uri: str | None = None - - -class SelfService(BaseModel): - use_for_self_service: bool | None = None - self_service_display_name: str | None = None - install_button_text: str | None = None - reinstall_button_text: str | None = None - self_service_description: str | None = None - force_users_to_view_description: bool | None = None - self_service_icon: SelfServiceIcon = Field(default_factory=dict) - feature_on_main_page: bool | None = None - self_service_categories: list[Category] = Field(default_factory=list) - - -class Package(BaseModel): - id: int | None = None - name: str | None = None - - -class Packages(BaseModel): - size: int | None = None - package: Package | None = None - - -class PackageConfiguration(BaseModel): - packages: list[Packages] = Field(default_factory=list) - distribution_point: str | None = None + computers: list[ExcludedComputer] class Script(BaseModel): @@ -134,158 +34,23 @@ class Script(BaseModel): parameter11: str | None = None -class ManagementAccount(BaseModel): - action: str | None = None - - -class OpenFirmwareEfiPassword(BaseModel): - of_mode: str | None = None - of_password_sha256: str | None = None - - -class DBinding(BaseModel): - id: int | None = None - name: str | None = None - - -class DBindings(BaseModel): - size: int | None = None - binding: DBinding | None = None - - -class MaintenanceAccount(BaseModel): - action: str | None = None - username: str | None = None - admin: bool | None = None - home: str | None = None - - -class MaintenanceAccounts(BaseModel): - size: int | None = None - account: MaintenanceAccount | None = None - - -class AccountMaintenance(BaseModel): - accounts: list[MaintenanceAccounts] = Field(default_factory=list) - directory_bindings: list[DBindings] = Field(default_factory=list) - management_account: ManagementAccount | None = None - open_firmware_efi_password: OpenFirmwareEfiPassword | None = None - - -class Reboot(BaseModel): - message: str | None = None - startup_disk: str | None = None - specify_startup: str | None = None - no_user_logged_in: str | None = None - user_logged_in: str | None = None - minutes_until_reboot: int | None = None - start_reboot_timer_immediately: bool | None = None - file_vault_2_reboot: bool | None = None - - -class Maintenance(BaseModel): - recon: bool | None = None - reset_name: bool | None = None - install_all_cached_packages: bool | None = None - heal: bool | None = None - prebindings: bool | None = None - permissions: bool | None = None - byhost: bool | None = None - system_cache: bool | None = None - user_cache: bool | None = None - verify: bool | None = None - - -class FilesProcesses(BaseModel): - search_by_path: str | None = None - delete_file: bool | None = None - locate_file: str | None = None - update_locate_database: bool | None = None - spotlight_search: str | None = None - search_for_process: str | None = None - kill_process: bool | None = None - run_command: str | None = None - - -class UserInteraction(BaseModel): - message_start: str | None = None - allow_users_to_defer: bool | None = None - allow_deferral_until_utc: str | None = None - allow_deferral_minutes: int | None = None - message_finish: str | None = None - - -class DiskEncryption(BaseModel): - action: str | None = None - - -class DockItem(BaseModel): - id: int | None = None - name: str | None = None - action: str | None = None - - -class DockItems(BaseModel): - size: int | None = None - dock_item: DockItem | None = None - - -@dataclass -class PolicyProperties(JAMFNodeProperties): - """JAMF Policy node properties""" - - pass +class Scope(BaseModel): + all_computers: bool + computers: list[ScopedComputer] + exclusions: Exclusions @app.asset( - description="Jamf Policy asset. Returns a node representing a Jamf Policy and edges to its tenant." + description="Jamf Policy asset. Returns no graph output directly; policy data feeds recurring-script transforms." ) class Policy(BaseAsset): - """JAMF policy resource parsed into a Pydantic model. - - Parses the raw JAMF policy payload and exposes OpenGraph Node and Edges via - the `as_node` and `edges` properties. - - Args: - BaseAsset (BaseAsset): Base class providing OpenGraph node/edge exports. - """ + """JAMF policy fields needed by recurring-script edge transforms.""" id: int - name: str enabled: bool - trigger: str | None = None - trigger_checkin: bool | None = None - trigger_enrollment_complete: bool | None = None - trigger_login: bool | None = None - trigger_network_state_changed: bool | None = None - trigger_startup: bool | None = None - trigger_other: str | None = None frequency: str - retry_event: str | None = None - retry_attempts: int | None = None - notify_on_each_failed_retry: bool | None = None - location_user_only: bool | None = None - target_drive: str | None = None - offline: bool | None = None - category: IdName | None = None - date_time_limitations: DateTimeLimitations | None = None - network_limitations: NetworkLimitations | None = None - override_default_settings: OverrideDefaultSettings | None = None - network_requirements: str | None = None - site: IdName | None = None - scope: Scope - self_service: SelfService | None = None - package_configuration: PackageConfiguration | None = None - scripts: list[Script] - printers: list | None = Field(default_factory=list) - dock_items: list[DockItems] = Field(default_factory=list) - account_maintenance: AccountMaintenance | None = None - reboot: Reboot | None = None - maintenance: Maintenance | None = None - files_processes: FilesProcesses | None = None - user_interaction: UserInteraction | None = None - disk_encryption: DiskEncryption | None = None + scripts: list[Script] = Field(default_factory=list) @property def as_node(self): diff --git a/src/openhound_jamf/transforms.py b/src/openhound_jamf/transforms.py index ddb8282..e55fa4a 100644 --- a/src/openhound_jamf/transforms.py +++ b/src/openhound_jamf/transforms.py @@ -70,10 +70,9 @@ def recurring_script_policies(con, schema: str = "jamf") -> None: CREATE OR REPLACE TABLE {schema}.recurring_script_policies AS SELECT p.id AS policy_id, - p.name AS policy_name, from_json(p.scope, '{{"all_computers": "BOOLEAN"}}').all_computers AS all_computers, - from_json(p.scope, '{{"computers": [{{"id":"INTEGER","name":"VARCHAR","udid":"VARCHAR"}}]}}').computers AS scope_computers, - from_json(p.scope, '{{"exclusions": {{"computers": [{{"id":"INTEGER","name":"VARCHAR","udid":"VARCHAR"}}]}}}}').exclusions.computers AS exclusion_computers, + from_json(p.scope, '{{"computers": [{{"id":"INTEGER"}}]}}').computers AS scope_computers, + from_json(p.scope, '{{"exclusions": {{"computers": [{{"udid":"VARCHAR"}}]}}}}').exclusions.computers AS exclusion_computers, p.scripts AS scripts FROM {schema}.policy_details p WHERE p.enabled = true