> For the complete documentation index, see [llms.txt](https://docs.openiam.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.openiam.com/administration-guide/identities/bulk-operations.md).

# Change many users at once

Run a bulk operation over a searched population of users, knowing exactly which accounts are protected, what select-all really selects, and why there is no undo.

## What this is, and when you need it

A bulk operation applies one lifecycle or entitlement change to every user a search returns. It is the right tool for a mass activation after an acquisition, a mass revocation after a project closes, or a notification to a defined population.

It has **no dry-run, no confirmation beyond the screen, and no undo**. Exactly two accounts in the whole system are protected from it. Read the two hazards below before you run anything.

## At a glance

|                          |                                                                                                                  |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------- |
| **You will end up with** | The chosen operation applied, one user at a time, to every user in the staged population                         |
| **Where**                | **User Admin → User Bulk Operations**, `/webconsole/bulkOperations`                                              |
| **You need first**       | The `BULK_OPS` menu grant, and a search that returns exactly the population you mean — verified by count         |
| **Takes**                | Minutes to stage; the run itself is asynchronous and proportional to the population                              |
| **Reversible**           | **No.** Undoing means running the inverse operation, and `DELETE_USER` and `RESET_USER_PASSWORD` have no inverse |

## Run the bulk operation

{% stepper %}
{% step %}

### Establish the population on the user search screen first, and read the count

Run the search you intend to use at `/webconsole/users` and note how many users it returns. **That count minus at most two is what you are about to change.** This is the only pre-flight check the product offers, and it is a check you perform, not one it performs for you.

{% hint style="danger" %}
**Exactly two user IDs are protected from every bulk operation: `0001` and `3001`.** Those are the shipped seed accounts. Nothing else is excluded — not your own account, not other administrators, not service accounts.

If you select all and run **Delete**, every user in the result except those two is removed, including you. There is no confirmation beyond the screen, no dry-run, and no undo.
{% endhint %}
{% endstep %}

{% step %}

### Choose the population on the bulk screen

`/webconsole/bulkOperations` is the first of three screens: choose the users, choose the operations, start.

{% hint style="warning" %}
**Select-all does not mean "the rows I am looking at".** With select-all set, OpenIAM discards your tick list and re-runs the search at the moment you save, with no size limit. The population is therefore *whatever the search returns now*, not what was on screen when you ticked. If the index changed in between, the population changed with it.

Untick select-all and tick the individual users when the population must be exactly the rows you reviewed.
{% endhint %}

| What you set                   | What OpenIAM stages                                                                 |
| ------------------------------ | ----------------------------------------------------------------------------------- |
| Select-all off, users ticked   | Exactly the users you ticked                                                        |
| Select-all on, users ticked    | **The tick list is ignored** and the search is re-run with no size limit            |
| Select-all on, nothing ticked  | The re-run search, and an invalid search bean yields nothing rather than everything |
| Select-all off, nothing ticked | Rejected with `USERS_NOT_SELECTED`                                                  |

The staged population lives in your HTTP session, so it does not survive a session timeout. Do not leave the flow idle between screens.
{% endstep %}

{% step %}

### Choose the object type, then the operation

The object type decides which operations are offered, and the list is short:

| Object type                                         | Operations offered                                                                     |
| --------------------------------------------------- | -------------------------------------------------------------------------------------- |
| **User**                                            | Activate, DeActivate, Delete, Enable, Disable, Reset Password, Send Email Notification |
| **Group**, **Role**, **Resource**, **Organization** | Add, Delete — the entitlement grant and revoke                                         |

{% hint style="info" %}
Only nine operations are reachable from these screens. The bulk operations enumeration has 25 values, and the other sixteen — every `CHANGE_*` operation, plus the two entitlement-attribute operations — belong to the bulk flow on the entitlement objects, not to the user bulk screens. Do not expect to find them in the user drop-down. The full list is in [Enumerated values](/administration-guide/reference/enums.md#bulk-operations).
{% endhint %}

The labels on screen do not always resemble the constants you will see in the audit log. The two worth remembering are **DeActivate**, which deprovisions, and **Delete**, which sets status `REMOVE` and deletes accounts in the targets. Both carry the same consequences here as they do on a single user — see [Run a user lifecycle action](/administration-guide/identities/user-lifecycle-actions.md).

One operation deserves separate thought: **Change assign to all** toggles "assign to all users" on an entitlement, which is a population-wide grant in its own right. Treat it as the widest change on this screen.
{% endstep %}

{% step %}

### Test on two users before you run it on two thousand

Narrow the search to two test users, run the operation, and confirm the outcome in the managed systems. Only then widen the search. There is no other way to learn what the operation does to your data.
{% endstep %}

{% step %}

### Start the run

Starting returns immediately with the success message `USER_BULK_OPERATION_STARTED`. That means the run was accepted, not that anything has happened yet. Two rejections are possible: `USERS_NOT_SELECTED` when the population is empty and `OPERATIONS_NOT_SELECTED` when no operation was chosen.
{% endstep %}
{% endstepper %}

## Verification

Two audit actions, and you need both. `START_BULK_OPERATION` proves somebody pressed the button; `BULK_OPERATION` proves work happened. Search for the first to find the launch, then for the second to count what it actually did.

Bulk password resets audit under their own actions depending on the path taken: `BULK_PASSWORD_RESET_ON_BEHALF`, `BULK_PASSWORD_RESET`, `BULK_ADMIN_USER_RESET_PASSWORD` and `BULK_PASSWORD_RESET_CSV_FILE_ATTACHED`.

Then verify the outcome where it matters: the per-user state in the managed systems. A bulk run that started successfully and produced no connector operations has done nothing.

## When it goes wrong

| Symptom                                                                          | Cause                                                                                                | Fix                                                                        |
| -------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| The operation affected more users than expected                                  | Select-all re-ran the search instead of using your tick list                                         | Untick select-all, or verify the search count at `/webconsole/users` first |
| The operation affected an administrator, or you                                  | Only `0001` and `3001` are excluded                                                                  | Narrow the search. There is no other protection                            |
| The bulk screen forgot the population between steps                              | The staged population lives in the HTTP session and the session expired                              | Restart the flow; do not leave it idle                                     |
| An operation you expected is missing from the drop-down                          | Only nine of the 25 values are offered by the user bulk screens                                      | Use the entitlement bulk flow for the `CHANGE_*` operations                |
| The run was rejected immediately                                                 | `USERS_NOT_SELECTED` or `OPERATIONS_NOT_SELECTED`                                                    | Select at least one user and one operation                                 |
| `START_BULK_OPERATION` is in the audit log but no `BULK_OPERATION` events follow | The run was accepted but produced no work — usually an empty staged population                       | Re-check the count, then re-stage                                          |
| Some users in the population were unaffected and no error was reported           | Each user goes through the normal provisioning path, so a per-user failure is a per-user audit event | Read the `BULK_OPERATION` events for the users that did not change         |

## Roll it back

**Not reversible as a batch.** Each operation is applied per user through the normal provisioning path, so undoing one means running the inverse on the same population — and reconstructing that population exactly, which select-all makes harder than it sounds.

Two operations have no inverse at all: **Delete** deletes accounts in the targets and **Reset Password** destroys the previous credentials. For those, the rollback is a restore from the managed system's own backup and a credential re-issue, not anything OpenIAM can do.

Establish the population and test the operation on two users before you run it on two thousand.

## Related

* [Run a user lifecycle action](/administration-guide/identities/user-lifecycle-actions.md) — the single-user form of every lifecycle operation offered here
* [Enumerated values](/administration-guide/reference/enums.md#bulk-operations) — all 25 bulk operation values with their labels
* [Change configuration safely](/administration-guide/start/change-safely.md) — the wide-blast-radius list this belongs on

*Applies to OpenIAM 2026.8.1. Last reviewed 7 August 2026.*


---

# 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.openiam.com/administration-guide/identities/bulk-operations.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.
