> 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

Email users about devices they have not used for a while

{% 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

Finds Intune devices that have not been active for a given number of days. Each primary user gets an email listing their stale devices and what to do about them. Users can be included or excluded by group. Emails can be redirected: all of them to an override address for tests, or those of accounts matching a name pattern to a dedicated recipient. Stale devices without a primary user can be collected into one combined email.

### 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
* Staged notifications via the `MaxDays` parameter, for example a first reminder at 30 days and a final notice at 60 days
* User scope filtering to target specific departments or to exclude service accounts
* Central handling of devices without a primary user or owned by Device Enrollment Manager accounts (for example `DEM-*`) via dedicated recipients

### 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 on all available settings.

#### Email branding

The report email honors the optional `RJReport.Branding.*` tenant settings:

* **Header and footer image** – public HTTPS URLs, PNG/JPEG/GIF, max. 200 KB each
* **Footer link** – target of the footer image
* **Accent and text color** – 6-digit hex values, e.g. `#0052cc`

When these settings are not configured, the default RealmJoin graphics and colors are used. An image that cannot be downloaded or validated, or an invalid color value, never prevents the report email – the corresponding default is used instead.

Setup instructions and image requirements: [Email branding](https://docs.realmjoin.com/automation/runbooks/runbook-report-settings#email-branding-optional).

#### Service Desk contact information

The optional `RJReport.ServiceDesk_DisplayName`, `RJReport.ServiceDesk_EMail`, `RJReport.ServiceDesk_Phone` and `RJReport.ServiceDesk_PortalUrl` tenant settings add a contact block to the end of every notification email. `ServiceDeskTicketUrl` can additionally link to a ticket.

### 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.10)<br>Microsoft.Graph.Authentication (>= 2.41.2)</p> |
| Schedulable      | yes                                                                                      |

### 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

Devices inactive for at least this many days count as stale.

| Property            | Value                 |
| ------------------- | --------------------- |
| Required            | false                 |
| Default Value       | 30                    |
| Type                | Int32                 |
| Portal display name | Days without activity |

#### MaxDays

Only devices inactive for at most this many days are included. Leave empty for no upper limit.

| Property            | Value                         |
| ------------------- | ----------------------------- |
| Required            | false                         |
| Default Value       |                               |
| Type                | Int32                         |
| Portal display name | Maximum days without activity |

#### Windows

Includes Windows devices.

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

#### MacOS

Includes macOS devices.

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

#### iOS

Includes iOS and iPadOS devices.

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

#### Android

Includes Android devices.

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

#### EmailFrom

Sender address of the notification email. Taken from the tenant setting RJReport.EmailSender.

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

#### BrandingHeaderImageUrl

Header image of the report email (HTTPS URL, PNG/JPEG/GIF, max 200 KB). Taken from the tenant setting RJReport.Branding.HeaderImageUrl; the default RealmJoin header is used when empty.

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

#### BrandingFooterImageUrl

Footer image of the report email (HTTPS URL, PNG/JPEG/GIF, max 200 KB). Taken from the tenant setting RJReport.Branding.FooterImageUrl; the default RealmJoin footer is used when empty.

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

#### BrandingFooterLink

Link behind the footer image of the report email. Taken from the tenant setting RJReport.Branding.FooterLink; realmjoin.com is used when empty.

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

#### BrandingAccentColor

Accent color of the report email as a 6-digit hex value. Taken from the tenant setting RJReport.Branding.AccentColor; the RealmJoin default is used when empty or invalid.

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

#### BrandingTextColor

Text color of the report email as a 6-digit hex value. Taken from the tenant setting RJReport.Branding.TextColor; the RealmJoin default is used when empty or invalid.

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

#### ServiceDeskDisplayName

Service desk name shown in the email. Taken from the tenant setting RJReport.ServiceDesk\_DisplayName.

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

#### ServiceDeskEmail

Service desk email address shown in the email. Taken from the tenant setting RJReport.ServiceDesk\_EMail.

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

#### ServiceDeskPhone

Service desk phone number shown in the email. Taken from the tenant setting RJReport.ServiceDesk\_Phone.

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

#### ServiceDeskPortalUrl

Link to the service desk portal shown in the email. Taken from the tenant setting RJReport.ServiceDesk\_PortalUrl.

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

#### ServiceDeskTicketUrl

Link to the service desk ticket shown in the email. Leave empty for no link.

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

#### UseUserScope

Whether users are filtered by group membership. Set by the "Filter users by group?" choice.

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

#### IncludeUserGroup

Only users in this group are notified.

| Property            | Value                                  |
| ------------------- | -------------------------------------- |
| Required            | false                                  |
| Default Value       |                                        |
| Type                | String                                 |
| Portal display name | Include users from group               |
| Hidden in portal    | yes (preset via runbook customization) |

#### ExcludeUserGroup

Users in this group are not notified.

| Property            | Value                                  |
| ------------------- | -------------------------------------- |
| Required            | false                                  |
| Default Value       |                                        |
| Type                | String                                 |
| Portal display name | Exclude users from group               |
| Hidden in portal    | yes (preset via runbook customization) |

#### OverrideEmailRecipient

Sends every email, including pattern-routed ones and the combined email, to these addresses instead of the normal recipients. For tests, pilots or a ticket system.

| Property            | Value                  |
| ------------------- | ---------------------- |
| Required            | false                  |
| Default Value       |                        |
| Type                | String                 |
| Portal display name | Redirect all emails to |

#### OverrideUserNamePattern

Wildcard patterns for user names, separated by commas, for example DEM-*,KIOSK-*. Emails of matching users go to the "Recipient for pattern-matched users" instead.

| Property            | Value                     |
| ------------------- | ------------------------- |
| Required            | false                     |
| Default Value       |                           |
| Type                | String                    |
| Portal display name | Primary user name pattern |

#### UserNamePatternEmailRecipient

Addresses that receive the emails of users matching the pattern, separated by commas. Required when a pattern is set and no override is active.

| Property            | Value                               |
| ------------------- | ----------------------------------- |
| Required            | false                               |
| Default Value       |                                     |
| Type                | String                              |
| Portal display name | Recipient for pattern-matched users |

#### SendNoPrimaryUserDevicesToOverride

Collects stale devices that have no primary user into one combined email to the "Recipient for devices without primary user". Those devices ignore the user filter.

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

#### NoPrimaryUserEmailRecipient

Addresses for the combined email, separated by commas. Required when the combined email is enabled and no override is set.

| Property            | Value                                      |
| ------------------- | ------------------------------------------ |
| Required            | false                                      |
| Default Value       |                                            |
| Type                | String                                     |
| Portal display name | Recipient for devices without primary user |
| Hidden in portal    | yes (preset via runbook customization)     |

#### MailTemplateLanguage

English, German, or the custom template from the runbook customization; English is used where the custom template is empty.

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

#### CustomMailTemplateSubject

Subject of the email when the custom template is used.

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

#### CustomMailTemplateBeforeDeviceDetails

Text above the device list when the custom template is used. Markdown is allowed.

| 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

Text below the device list when the custom template is used. Markdown is allowed.

| 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

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

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
