Skip to content

Bulk actions and CSV import

Bulk actions run the same single actions on many accounts at once, and the CSV import creates many accounts from an onboarding template. Nothing is decided in bulk: every account is decided on its own, on fresh facts read by GUID (delegation scope, tier gate, VIP, privileged accounts never manageable, never your own account). An account the console refuses is reported as refused with the reason and left untouched.

Select accounts

On Users, tick accounts in the card or table view, or use Select this page. When the search has more results than the loaded pages, Select all N matching users selects the whole search: the browser sends the search's signed cursor (the server resolves it again with the same checks; another operator's or an expired cursor is refused), and unticked rows are sent as exclusions. At most 500 accounts per run.

Actions

Action What each account gets Needs (on each account)
Add to group / Remove from group The membership change of the Groups page (adding accepts an optional until date) groups.members.write on the group and users.read on the account (VIP: a delegation with vip.manage too)
Set attribute One delegated attribute (e.g. department, title, company, manager, telephone, extension attributes); empty clears it. Names, mail and the expiry are never set this way users.attributes.write on that attribute
Set account expiry A last day of validity, never, or now users.attributes.write on accountExpires
Disable / Enable The account state, through the password service users.disable / users.enable + helpdesk
Reset password A strong random password, must change at next sign-in. A ticket is always required users.password.reset + helpdesk
Unlock Clears the lockout users.unlock + helpdesk
Run leaver template The leaver template's steps that the console allows on that account; the random password is never handed over the action of each step

Preview, then run

  1. Preview shows, per account, allowed or refused with the reason. Nothing is written.
  2. Run asks the ticket (instance rule; always for a password reset), a confirmation, typing the number of accounts when there are more than 20, and a step-up.
  3. The run is a background job: the dialog shows the progress and the result of each account (done, no change, refused, failed, unknown, partial for a leaver with some steps failed). Closing the dialog does not stop it; the Users page links to a running job.
  4. Cancel stops before the next account (never in the middle of one); the remaining accounts are marked cancelled and left untouched. A job also stops when the console session that started it ends (sign-out, revocation).
  5. Download results gives the per-account results as CSV (formula-safe).

Limits: one running job per operator (four at once on the instance), 10 runs per hour and 20 previews per minute per operator. Jobs are kept 2 hours in the console's memory (not across a restart).

If your delegation holds the action only with approval, the console offers to send the bulk action as an approval request instead; it then runs as the approver's job.

Generated passwords

Bulk password resets and CSV imports generate passwords that are never shown, stored, logged or audited. Once the job is finished, the operator who ran it can download them once as CSV (login, display name, password). They are wiped from memory as they are handed over: a second download answers gone, and they are also wiped when the job is forgotten. Hand the file over through your secure channel and delete it. Passwords never start with a symbol, so a spreadsheet never reads them as formulas.

CSV onboarding import

Users > Import CSV creates accounts from an onboarding template, one per row. It needs users.create on the template's OU (and the other rights of a single creation) and the helpdesk.

File format

  • UTF-8 (a BOM is accepted), separator , or ; (detected), a header row, at most 500 rows, 32 columns and 256 KB.
  • Columns:

    • firstName and lastName, required, case-insensitive (also accepted: first, givenName, prenom, prĂ©nom / last, surname, sn, nom);
    • any attribute key of the template (an empty cell keeps the template's value);
    • optional expiry (or expiration), yyyy-MM-dd.

    Any other column refuses the file.

Example, for a template that sets department:

firstName;lastName;department;expiry
Jane;Doe;Finance;2027-03-31
Luc;Martin;Sales;2027-06-30

CSV injection. A cell starting with =, @, -, a tab, or + (except a phone number such as +41 22 ...) refuses its row (formula-like): such values would land in AD and later in someone's spreadsheet. Control characters and malformed quoting refuse the row too.

Preview. Per row: the login, UPN, display name and OU the creation would use now, the decision (the same all-or-nothing decision as a single creation), and warnings: name already taken (a numeric suffix is added: check the person does not already have an account) and duplicate in file. A preview is valid for 30 minutes and can be run once.

Run. Ticket, password mode (random or passphrase), confirmation (typed count above 20) and step-up, then a background job: each row is a full single creation, decided again (a refused row creates nothing), audited users.create. Each row also counts against the per-operator creation limit (Onboarding:MaxCreationsPerOperator, 20 per hour by default): rows beyond it create nothing and are reported rate_limited (raise the limit before a large import). The run also counts against the 10 runs per hour. Passwords: downloadable once, as above.

Audit

One correlation id per run (shown in the progress view), with the ticket on every row:

  • bulk.start (action, number of accounts);
  • for each account, the decision (authz.decision) and one row under the action's usual name (groups.members.add / .remove, users.attributes.write, users.disable / .enable, users.password.reset with mode:random and bulk, users.unlock, users.leaver, users.create), refusals included;
  • bulk.cancel when cancelled, and bulk.finish with the counts per result.

Previews are audited as bulk.preview / bulk.import.preview, downloads as bulk.results.export / bulk.passwords.download (never a value).