Run IntelliShell scripts as tasks

Save MongoDB shell scripts as an IntelliShell Script task, run them in order on one or more connections, and write their output to files.

An IntelliShell Script task runs one or more shell scripts, one after the other, and writes what each script prints to a file. Use it for reports (a weekly count of acme_store.orders by status), maintenance scripts, or checks you want to keep the output of.

The task is made of units. A unit has:

  • a source: the connection and database the script starts connected to (its db);
  • a target file: where the script’s console output is written when the task runs;
  • the script itself, kept inside the task.

Create the task

  1. Click Tasks in the global toolbar, then New Task (Ctrl+N), and choose IntelliShell Script.

  2. In IntelliShell Script Source, choose the Connection and, optionally, the Database (empty: the connection’s default). A new IntelliShell Script tab opens with one unit.

  3. Select the unit and click Edit unit. Its script opens in an IntelliShell editor of its own, where you write and test it as usual, for example:

    db.orders.aggregate([
      { $group: { _id: "$status", orders: { $sum: 1 } } },
      { $sort: { orders: -1 } }
    ])
    
  4. Back in the overview, set the IntelliShell Script Target File (the folder button chooses one). To load an existing script instead of typing it, use the button that loads the unit’s script from a file.

  5. Add more units with Add unit (another connection or database); they run in the order shown.

  6. Click Save task and give the task a name.

Run it

  • From the tab: Run runs every unit as it is now, without saving.
  • From the Tasks tab: select the task and click Run (F5).

Before anything starts, the Run Task question lists the units whose scripts can update or delete data or drop databases, collections or indexes. Each unit then starts its own shell, runs its script as IntelliShell does, and writes the output to its target file as it comes. A unit stops at its first error; the report at the end says which units failed.

As in IntelliShell, a find() that is not iterated prints its first 20 documents. Iterate the cursor (for example with .toArray() or forEach) to write every document.

Reference

Toolbar buttonWhat it does
Save taskSaves this IntelliShell Script as a task
Save task as…Saves it as a new task
Load taskLoads a saved IntelliShell Script task into this tab
ScheduleSchedules the saved task (Schedule tasks)
RunRuns every unit, writing each script’s output to its target file
Add unitAdds a unit on another connection or database
Edit unitOpens the selected unit’s script in an IntelliShell editor
Remove unitRemoves the selected units (their editors close)
ItemLimit or behaviour
Units per taskUp to 1,000
Script loaded from a fileUTF-8, up to 16 MB
Target file namePlaceholders ${date} (YYYY-MM-DD), ${time} (HH-MM-SS) and ${datetime} are replaced with the local date and time of the run, also in folder names
Read-only connectionA unit whose script writes is refused before anything runs

Scheduled scripts run isolated

A scheduled run starts on its own, with nobody there to read a question. So a scheduled script can only do what you saw when you scheduled it:

  • Code from outside the task is refused. A script that uses load, require, import, process, fetch or eval cannot be scheduled: what it reads could change after you scheduled it. Paste the code it loads into the unit instead. Snippets are not available either. The same check runs again when a scheduled task is saved and when each scheduled run starts.
  • Indirect tricks are refused too. Function constructors, computed method names and the shell’s internal members (names starting with _) are not allowed in a scheduled script. Write plain shell calls (db.orders.find(…), insertOne, updateMany…) with member names spelled out. Ordinary data access passes: docs[i], doc[key], counts[d.status || "unknown"] through a variable. Destructuring or with cannot reach internals either.
  • The shell process is sandboxed. It cannot start other programs or workers, and it cannot write files outside a private, temporary home folder created for that run and removed afterwards. Your own shell history, configuration and snippets are never touched, and nothing a script leaves behind reaches a later run. The output still goes to the unit’s target file, which the application writes, not the script.

Scheduled scripts need the bundled shell, or mongosh 2.4 or later if you configured your own. When the protection cannot be set up, the run is refused rather than run unprotected.

Running the same task by hand (Run) behaves like IntelliShell: these restrictions apply only to scheduled runs.

Tips

  • Test each unit in its editor first: what you see there is what the task writes.
  • Use ${date} in the target file name (reports/orders-${date}.txt) to keep one file per run instead of overwriting the last one.
  • Use print() or printjson() for exactly the output you want in the file.

Troubleshooting

MessageWhat to do
The connection ‘…’ is read-only: the script of … uses … and was not run.The unit writes on a read-only connection. Use a connection that allows writes, or remove the write.
Schedule Task: the script of unit N of “…” uses load(), which runs code or reads content from outside the task…Paste the loaded code into the unit, then schedule again.
Schedule Task: the script of unit N of “…” reaches the shell’s or Node.js’ internals…Replace computed or internal member access with plain shell methods and named members.
The output file holds only 20 documentsIterate the cursor (.toArray(), forEach) instead of relying on the shell’s display.