> For the complete documentation index, see [llms.txt](https://docs.realmjoin.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.realmjoin.com/automation/runbooks/runbook-references/org/devices/notify-users-about-stale-devices_scheduled.md).

# Notify Users About Stale Devices Scheduled

{% hint style="info" %}
This is a scheduled runbook. It is designed to run on a recurring schedule rather than being triggered for a single object. See [Scheduling](/automation/runbooks/scheduling.md) for details on how to configure runbook schedules.
{% endhint %}

### Description

Identifies devices that haven't been active for a specified number of days and sends personalized email notifications to the primary users of those devices. The email contains device information and action steps for the user. Optionally filter users by including or excluding specific groups. Three optional routing targets are available: a global override recipient that redirects ALL notifications (for testing and piloting), a dedicated recipient for users whose UPN matches a name pattern (e.g. Device Enrollment Manager accounts), and a dedicated recipient that receives one combined email for stale devices without a primary user.

### Setup regarding email sending

Sending an email report is optional and only happens when a recipient (`EmailTo`) is provided. The sender address is taken from the `RJReport.EmailSender` tenant setting.

This runbook sends emails using the Microsoft Graph API. To send emails via Graph API, you need to configure an existing email address in the runbook customization.

See the [RealmJoin Report Settings documentation](https://docs.realmjoin.com/automation/runbooks/runbook-report-settings) for details.

#### Email branding

The report email honors the optional `RJReport.Branding.*` tenant settings: a custom header image, a custom footer image (public HTTPS URLs, PNG/JPEG/GIF, max. 200 KB each), a custom footer link, and custom accent and text colors (6-digit hex values, e.g. `#0052cc`). When these settings are not configured, the default RealmJoin graphics and colors are used. A branding image that cannot be downloaded or validated, or a color value that is not a valid hex color, never prevents the report email - the corresponding default is used instead.

See the [RealmJoin Report Settings documentation](https://docs.realmjoin.com/automation/runbooks/runbook-report-settings) for setup details.

### Mail Template Language Selection

This runbook supports three email template options:

1. **EN (English - Default)**: Uses the built-in English template
2. **DE (German)**: Uses the built-in German template
3. **Custom**: Uses a custom template from Runbook Customizations

#### Using Custom Mail Templates

To use a custom mail template (e.g., in Dutch, Spanish, or any other language), you need to configure the template text in the Runbook Customizations. If any custom template parameter is missing, the runbook will automatically fall back to the English template.

**Example: Custom Template**

```json
{
    "Runbooks": {
        "rjgit-org_devices_notify-users-about-stale-devices_scheduled": {
            "Parameters": {
                "CustomMailTemplateSubject": {
                    "Default": "This is a custom subject - Action Required: Inactive Devices"
                },
                "CustomMailTemplateBeforeDeviceDetails": {
                    "Default": "**This is above the Device Details.** \n\nDear user ..."
                },
                "CustomMailTemplateAfterDeviceDetails": {
                    "Default": "**This is below the Device Details.** \n\n## What you should do..."
                }
            }
        }
    }
}
```

**Important Notes:**

* Use `\n` for line breaks in the JSON configuration
* Markdown formatting (##, ###, \*\*, -) is supported in the template text
* All three custom template parameters (Subject, BeforeDeviceDetails, AfterDeviceDetails) should be configured
* If any parameter is missing, the runbook automatically falls back to the English (EN) template
* When using the custom template, select "Custom - Use Template from Runbook Customizations" in the Mail Template dropdown

### Email Routing

The runbook knows three independent routing targets, checked in this order of precedence:

1. **Global override (testing):** A filled `OverrideEmailRecipient` redirects **ALL** emails - user notifications, pattern-routed notifications and the combined email for devices without a primary user - to that address. No end user receives an email. Use this for testing, piloting, or routing everything to a shared mailbox or ticket system. A warning is logged on every run while the override is active.
2. **Pattern-matched users:** When `OverrideUserNamePattern` is set, notifications of users whose UPN matches the pattern are sent to `UserNamePatternEmailRecipient` instead of the user. All other users receive their notification directly. Typical use: Device Enrollment Manager or kiosk accounts (`DEM-*`, `KIOSK-*`) whose mailboxes nobody reads.
3. **Devices without a primary user:** When `SendNoPrimaryUserDevicesToOverride` is enabled, stale devices without a primary user are collected into **one** combined email to `NoPrimaryUserEmailRecipient`. Otherwise these devices are skipped. This setting never changes how user notifications are routed.

Incomplete configurations stop the runbook with an error instead of silently mailing end users:

* `SendNoPrimaryUserDevicesToOverride` enabled without `NoPrimaryUserEmailRecipient` (and without a global override) - error.
* `OverrideUserNamePattern` set without `UserNamePatternEmailRecipient` (and without a global override) - error.
* A recipient set without its feature (`NoPrimaryUserEmailRecipient` without the toggle, `UserNamePatternEmailRecipient` without a pattern) - warning, the recipient is ignored.

While the global override is active, the dedicated recipients do not need to be set - everything goes to the override recipient anyway.

#### User Name Pattern

`OverrideUserNamePattern` accepts one or more wildcard patterns (comma-separated) matched against the primary user's UPN, e.g. `DEM-*` for Device Enrollment Manager accounts or `DEM-*,KIOSK-*` for multiple patterns. Matching is case-insensitive and uses PowerShell wildcard syntax (`*`, `?`). When the pattern routing is active, the runbook logs a warning stating which pattern is redirected to which recipient.

**Important Notes:**

* All recipient parameters accept multiple comma-separated addresses
* Devices without a primary user bypass the user scope filtering (they have no user to match against groups)
* Pattern-matched users are still subject to user scope filtering first; users excluded by scope produce no notification at all
* The combined email for devices without a primary user uses an administrative wording (no end-user action steps), independent of custom templates
* Redirected notifications state the affected user in the email subject and body

### Location

Organization → Devices → Notify Users About Stale Devices (Scheduled)

**Full Runbook name**

rjgit-org\_devices\_notify-users-about-stale-devices\_scheduled

### Details

| Property         | Value                                                                                   |
| ---------------- | --------------------------------------------------------------------------------------- |
| Version          | 1.7.0                                                                                   |
| Required modules | <p>RealmJoin.RunbookHelper (>= 0.8.9)<br>Microsoft.Graph.Authentication (>= 2.39.0)</p> |
| Schedulable      | yes                                                                                     |

### Notes

This runbook automatically sends personalized email notifications to users who have devices that haven't synced for a specified number of days. The email is sent directly to the primary user's email address and includes detailed information about each inactive device.

Prerequisites:

* EmailFrom parameter must be configured in runbook customization (RJReport.EmailSender setting)
* Optional: Service Desk contact information can be configured (ServiceDesk\_DisplayName, ServiceDesk\_EMail, ServiceDesk\_Phone, ServiceDesk\_PortalUrl)

Common Use Cases:

* Automated user reminders about inactive devices to encourage regular device check-ins
* Proactive device lifecycle management by alerting users before devices are retired
* Security and compliance by ensuring users are aware of all devices registered to them
* Using MaxDays parameter for staged notifications (e.g., first reminder at 30 days, final notice at 60 days)
* User scope filtering to target specific departments or exclude service accounts
* Centrally handling devices without a primary user or owned by Device Enrollment Manager (e.g. DEM-\*) accounts via dedicated recipients

Pilot and Testing Options:

* Use OverrideEmailRecipient parameter to send all notifications to a test mailbox instead of end users
* Perfect for validating email content and testing filters before rolling out to production
* Send notifications to ticket systems or shared mailboxes for centralized handling

### Permissions

#### Application permissions

* **Type**: Microsoft Graph
  * DeviceManagementManagedDevices.Read.All
    * *Reads Intune managed devices filtered by lastSyncDateTime to find stale devices and their primary users*
  * Directory.Read.All
    * *Reads the tenant name for the mail footer and resolves user ids for the group scope filtering*
  * Group.Read.All
    * *Lists the include/exclude group members to filter which primary users get notified*
  * Mail.Send
    * *Sends the stale-device notification mails to each primary user or the override recipient*

### Parameters

#### Days

Number of days without activity to be considered stale (minimum threshold).

| Property            | Value                         |
| ------------------- | ----------------------------- |
| Required            | false                         |
| Default Value       | 30                            |
| Type                | Int32                         |
| Portal display name | Minimum Days Without Activity |

#### MaxDays

Optional maximum number of days without activity. If set, only devices inactive between Days and MaxDays will be included.

| Property            | Value                                    |
| ------------------- | ---------------------------------------- |
| Required            | false                                    |
| Default Value       |                                          |
| Type                | Int32                                    |
| Portal display name | (Optional) Maximum Days Without Activity |

#### Windows

Include Windows devices in the results.

| Property            | Value                   |
| ------------------- | ----------------------- |
| Required            | false                   |
| Default Value       | True                    |
| Type                | Boolean                 |
| Portal display name | Include Windows Devices |

#### MacOS

Include macOS devices in the results.

| Property            | Value                 |
| ------------------- | --------------------- |
| Required            | false                 |
| Default Value       | True                  |
| Type                | Boolean               |
| Portal display name | Include macOS Devices |

#### iOS

Include iOS devices in the results.

| Property            | Value               |
| ------------------- | ------------------- |
| Required            | false               |
| Default Value       | True                |
| Type                | Boolean             |
| Portal display name | Include iOS Devices |

#### Android

Include Android devices in the results.

| Property            | Value                   |
| ------------------- | ----------------------- |
| Required            | false                   |
| Default Value       | True                    |
| Type                | Boolean                 |
| Portal display name | Include Android Devices |

#### EmailFrom

The sender email address. This needs to be configured in the runbook customization.

| Property         | Value                                  |
| ---------------- | -------------------------------------- |
| Required         | false                                  |
| Default Value    |                                        |
| Type             | String                                 |
| Hidden in portal | yes (preset via runbook customization) |

#### BrandingHeaderImageUrl

Optional public HTTPS URL of a custom header image (PNG/JPEG/GIF, max. 200 KB) for the report email. Sourced from the RJReport.Branding.HeaderImageUrl tenant setting. When empty, the default RealmJoin header graphic is used.

| Property         | Value                                  |
| ---------------- | -------------------------------------- |
| Required         | false                                  |
| Default Value    |                                        |
| Type             | String                                 |
| Hidden in portal | yes (preset via runbook customization) |

#### BrandingFooterImageUrl

Optional public HTTPS URL of a custom footer image (PNG/JPEG/GIF, max. 200 KB) for the report email. Sourced from the RJReport.Branding.FooterImageUrl tenant setting. When empty, the default RealmJoin footer graphic is used.

| Property         | Value                                  |
| ---------------- | -------------------------------------- |
| Required         | false                                  |
| Default Value    |                                        |
| Type             | String                                 |
| Hidden in portal | yes (preset via runbook customization) |

#### BrandingFooterLink

Optional URL the footer image links to. Sourced from the RJReport.Branding.FooterLink tenant setting. When empty, the default link (<https://www.realmjoin.com>) is used.

| Property         | Value                                  |
| ---------------- | -------------------------------------- |
| Required         | false                                  |
| Default Value    |                                        |
| Type             | String                                 |
| Hidden in portal | yes (preset via runbook customization) |

#### BrandingAccentColor

Optional accent color override (6-digit hex, e.g. '#0052cc') for the report email template. Sourced from the RJReport.Branding.AccentColor tenant setting. When empty or invalid, the default RealmJoin accent color is used.

| Property         | Value                                  |
| ---------------- | -------------------------------------- |
| Required         | false                                  |
| Default Value    |                                        |
| Type             | String                                 |
| Hidden in portal | yes (preset via runbook customization) |

#### BrandingTextColor

Optional text color override (6-digit hex) for the report email template. Sourced from the RJReport.Branding.TextColor tenant setting. When empty or invalid, the default RealmJoin text color is used.

| Property         | Value                                  |
| ---------------- | -------------------------------------- |
| Required         | false                                  |
| Default Value    |                                        |
| Type             | String                                 |
| Hidden in portal | yes (preset via runbook customization) |

#### ServiceDeskDisplayName

Service Desk display name for user contact information (optional).

| Property         | Value                                  |
| ---------------- | -------------------------------------- |
| Required         | false                                  |
| Default Value    |                                        |
| Type             | String                                 |
| Hidden in portal | yes (preset via runbook customization) |

#### ServiceDeskEmail

Service Desk email address for user contact information (optional).

| Property         | Value                                  |
| ---------------- | -------------------------------------- |
| Required         | false                                  |
| Default Value    |                                        |
| Type             | String                                 |
| Hidden in portal | yes (preset via runbook customization) |

#### ServiceDeskPhone

Service Desk phone number for user contact information (optional).

| Property         | Value                                  |
| ---------------- | -------------------------------------- |
| Required         | false                                  |
| Default Value    |                                        |
| Type             | String                                 |
| Hidden in portal | yes (preset via runbook customization) |

#### ServiceDeskPortalUrl

Service Desk portal URL for user contact information, rendered as a clickable link (optional).

| Property         | Value                                  |
| ---------------- | -------------------------------------- |
| Required         | false                                  |
| Default Value    |                                        |
| Type             | String                                 |
| Hidden in portal | yes (preset via runbook customization) |

#### ServiceDeskTicketUrl

Direct link to a Service Desk ticket, rendered as a clickable link (optional). Empty by default, so no ticket link is added.

| Property         | Value                                  |
| ---------------- | -------------------------------------- |
| Required         | false                                  |
| Default Value    |                                        |
| Type             | String                                 |
| Hidden in portal | yes (preset via runbook customization) |

#### UseUserScope

Enable user scope filtering to include or exclude users based on group membership.

| Property            | Value                                  |
| ------------------- | -------------------------------------- |
| Required            | false                                  |
| Default Value       | False                                  |
| Type                | Boolean                                |
| Portal display name | Use User Scope Filtering               |
| Hidden in portal    | yes (preset via runbook customization) |

#### IncludeUserGroup

Only send emails to users who are members of this group. Requires UseUserScope to be enabled.

| Property            | Value                                  |
| ------------------- | -------------------------------------- |
| Required            | false                                  |
| Default Value       |                                        |
| Type                | String                                 |
| Portal display name | Users to include (Group)               |
| Hidden in portal    | yes (preset via runbook customization) |

#### ExcludeUserGroup

Do not send emails to users who are members of this group. Requires UseUserScope to be enabled.

| Property            | Value                                  |
| ------------------- | -------------------------------------- |
| Required            | false                                  |
| Default Value       |                                        |
| Type                | String                                 |
| Portal display name | Users to exclude (Group)               |
| Hidden in portal    | yes (preset via runbook customization) |

#### OverrideEmailRecipient

Optional: Global override - when set, ALL notifications (user notifications, pattern-routed notifications and the combined email for devices without a primary user) are sent to this address instead of their normal recipients. Can be comma-separated for multiple recipients. Perfect for testing and piloting, or for routing everything to a ticket system. If left empty, the normal routing applies.

| Property            | Value                                              |
| ------------------- | -------------------------------------------------- |
| Required            | false                                              |
| Default Value       |                                                    |
| Type                | String                                             |
| Portal display name | Redirect \* ALL \* Emails to Override Recipient(s) |

#### OverrideUserNamePattern

Optional wildcard pattern(s) matched against the primary user UPN (comma-separated, e.g. 'DEM-*,KIOSK-*', case-insensitive). Notifications of matching users are redirected to UserNamePatternEmailRecipient; all other users are mailed directly. Not evaluated separately while the global override (OverrideEmailRecipient) is active, since all notifications are redirected anyway.

| Property            | Value                                                                          |
| ------------------- | ------------------------------------------------------------------------------ |
| Required            | false                                                                          |
| Default Value       |                                                                                |
| Type                | String                                                                         |
| Portal display name | (Optional) Primary User Name Pattern - redirect matching users (e.g. 'DEM-\*') |

#### UserNamePatternEmailRecipient

Email address(es) that receive the notifications of users matching OverrideUserNamePattern. Can be comma-separated. Required when OverrideUserNamePattern is set, unless OverrideEmailRecipient is set.

| Property            | Value                                  |
| ------------------- | -------------------------------------- |
| Required            | false                                  |
| Default Value       |                                        |
| Type                | String                                 |
| Portal display name | Recipient(s) for Pattern-Matched Users |

#### SendNoPrimaryUserDevicesToOverride

If enabled, stale devices without a primary user are collected into one combined email to NoPrimaryUserEmailRecipient (or to OverrideEmailRecipient while the global override is active). Does not change how user notifications are routed. Devices without a primary user bypass user scope filtering.

| Property            | Value                                               |
| ------------------- | --------------------------------------------------- |
| Required            | false                                               |
| Default Value       | False                                               |
| Type                | Boolean                                             |
| Portal display name | Send Devices without Primary User as Combined Email |
| Hidden in portal    | yes (preset via runbook customization)              |

#### NoPrimaryUserEmailRecipient

Email address(es) that receive the combined email for stale devices without a primary user. Can be comma-separated. Required when SendNoPrimaryUserDevicesToOverride is enabled, unless OverrideEmailRecipient is set.

| Property            | Value                                         |
| ------------------- | --------------------------------------------- |
| Required            | false                                         |
| Default Value       |                                               |
| Type                | String                                        |
| Portal display name | Recipient(s) for Devices without Primary User |
| Hidden in portal    | yes (preset via runbook customization)        |

#### MailTemplateLanguage

Select which email template to use: EN (English, default), DE (German), or Custom (from Runbook Customizations).

| Property            | Value                                  |
| ------------------- | -------------------------------------- |
| Required            | false                                  |
| Default Value       | EN                                     |
| Type                | String                                 |
| Portal display name | Mail Template                          |
| Hidden in portal    | yes (preset via runbook customization) |

#### CustomMailTemplateSubject

Custom email subject line (only used when MailTemplateLanguage is set to 'Custom').

| Property            | Value                                  |
| ------------------- | -------------------------------------- |
| Required            | false                                  |
| Default Value       |                                        |
| Type                | String                                 |
| Portal display name | Custom: Email Subject                  |
| Hidden in portal    | yes (preset via runbook customization) |

#### CustomMailTemplateBeforeDeviceDetails

Custom text to display before the device list (only used when MailTemplateLanguage is set to 'Custom'). Supports Markdown formatting.

| Property            | Value                                  |
| ------------------- | -------------------------------------- |
| Required            | false                                  |
| Default Value       |                                        |
| Type                | String                                 |
| Portal display name | Custom: Text Before Device List        |
| Hidden in portal    | yes (preset via runbook customization) |

#### CustomMailTemplateAfterDeviceDetails

Custom text to display after the device list (only used when MailTemplateLanguage is set to 'Custom'). Supports Markdown formatting.

| Property            | Value                                  |
| ------------------- | -------------------------------------- |
| Required            | false                                  |
| Default Value       |                                        |
| Type                | String                                 |
| Portal display name | Custom: Text After Device List         |
| Hidden in portal    | yes (preset via runbook customization) |

[Back to Runbook Reference overview](/automation/runbooks/runbook-references.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.realmjoin.com/automation/runbooks/runbook-references/org/devices/notify-users-about-stale-devices_scheduled.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
