← Back to insights

Critical infrastructure · 19 August 2026 · 6 min

Script sprawl, service accounts and key-person risk: the automation nobody has visibility into

In almost every IT department in Norwegian critical infrastructure there is a layer of automation that appears in no architecture diagram: PowerShell scripts on individual administrators'…

The hidden infrastructure

In almost every IT department in Norwegian critical infrastructure there is a layer of automation that appears in no architecture diagram: PowerShell scripts on individual administrators' machines, scheduled tasks on an old server, an Azure Automation runbook from 2021, a Python script running from a virtual machine nobody has restarted in two years.

They do real work. They create users, sync groups from line-of-business systems, tidy up licences, generate reports for management. They typically run under a user account with elevated privileges, often with credentials stored in the script or in a file next to it. They were written by someone who still works there, or who doesn't.

This layer has four characteristics that make it one of the most underrated risks in the identity platform:

1. It is not inventoried. Nobody can list every script that makes changes in the directory.

2. It is not version-controlled. Changes to a script leave no history.

3. It is not audited. Actions performed by the script appear in the log as actions performed by the service account, with no justification attached.

4. It is dependent on key people. One person understands why it exists.

Two dates that have already broken things

Microsoft's retirement of the old PowerShell modules is the single change that has surfaced the most hidden automation in Norwegian organisations over the past two years.

The Azure AD, Azure AD Preview and MSOnline modules were declared deprecated on 30 March 2024, with support limited to critical security fixes until 30 March 2025. MSOnline was retired on 30 May 2025. The recommended path forward is the Microsoft Graph PowerShell SDK, or alternatively the newer Microsoft Entra PowerShell module, which according to Microsoft's migration FAQ provides over 90% parity with the old Azure AD commands.

The second date is 1 October 2025. From that date Microsoft began gradually enforcing multi-factor authentication for Azure CLI, Azure PowerShell, the Azure mobile app, IaC tooling and REST endpoints as well, for all create, update and delete operations. Read operations are exempt. Microsoft's explicit recommendation is to migrate user-based service accounts to workload identities.

The consequence for the hidden automation layer is direct: scripts that authenticate as a user account without MFA, and that perform write operations, stop working. In many organisations this has already happened, and the fault was handled by adding an exception rather than migrating. That is technical debt coming due.

Why this is a preparedness matter, not just an operations matter

For organisations in critical infrastructure, the argument is stronger than "this is untidy."

Key-person risk is a preparedness risk. The Power Supply Preparedness Regulations (kraftberedskapsforskriften, FOR-2012-12-07-1157) are built on the premise that entities in the Norwegian power supply contingency organisation (KBO) must be able to maintain function. If the ability to carry out bulk changes in the identity platform — for example, quickly locking out a compromised group of accounts — depends on one script on one person's machine, and that person is on a hiking trip, that is a preparedness weakness regardless of what the contingency plan says.

Unidentified service accounts breach the traceability requirement. the Norwegian National Security Authority's (NSM) Basic Principle 2.6.1 requires access control with traceability to a responsible person. A service account that performs a hundred changes a week without any of them being tied to a decision or a person does not meet this. Basic Principle 2.6.2 requires a formal process for administering accounts and privileges throughout the entire lifecycle — service accounts included.

Scripts with embedded credentials are a direct attack vector. Attackers who gain a foothold on an administrator's workstation look for exactly this. The Norsk Hydro incident in 2019 escalated from a foothold to full control precisely through administrative privileges and domain controllers.

Nonconformity handling presumes you know what happened. The Management Regulations § 22 ("Nonconformity handling") requires root-cause analysis. When an unwanted bulk change has occurred, and it was carried out by a service account running a script nobody has read in three years, the root-cause analysis becomes an archaeology project.

The technical limits that force structure

Even where the automation is well-intentioned and well-written, the platform imposes limits that make the ad hoc approach fragile.

Microsoft Graph has service-specific throttling rules. For identity and directory objects, these include a limit per application and tenant of 3,500 ResourceUnits per 10 seconds for small tenants, 5,000 for medium tenants (50–500 users) and 8,000 for large tenants (over 500 users). In addition, there is a write quota per tenant of 18,000 requests per five minutes, and per application and tenant 3,000 write requests per 2 minutes and 30 seconds. The cost varies per call — GET /groups/{id}/transitiveMembers costs 5 ResourceUnits, using $select gives a one-unit discount, $expand costs one extra.

In practice this means a naively written script set to change a few thousand objects during a reorganisation will get throttled midway through. What happens then — whether the script resumes, which objects were processed, which were not — depends on whether the person who wrote it thought about it. Often they didn't, and the result is a partially completed bulk change with no complete overview of what was actually carried out.

This is one of the most underrated sources of error in the identity platform: not malicious actions, but half-finished ones.

What centralised execution changes

Entra Logic is built on exactly the same building blocks as the scripts are — PowerShell and Microsoft Graph. That is a point in itself: this is the standard way to automate Entra ID, not a proprietary language administrators have to learn. The difference lies in where the execution happens and what comes with it.

Centralised, version-controlled execution. The automation runs in one place, not on individual machines. What was run, in which version, against which objects, is known.

Every action has an order behind it. A bulk change across a thousand objects is carried out as a single operation, but each individual change gets its own attributable record with justification and approver. This is both an audit property and an operational property: a partially completed operation is visible as partially completed, per object.

No credentials in circulation. An administrator does not need a stored credential to do the job, because the job is done by the engine after approval.

The key-person dependency disappears. When no single person holds all the keys and all the scripts, the organisation is no longer vulnerable to that particular person being sick, on holiday or gone.

Two honest caveats. First, the extent to which this actually replaces existing local scripts at a given customer — as opposed to governing new operations — is something that has to be worked out concretely in a technical review; it depends on what the scripts do. Second, centralising execution within the Entra domain does not solve the scripts that do something else entirely, such as integrations with line-of-business systems or OT-adjacent tools.

Three tasks with immediate value

1. Inventory the service accounts. List every user account in the tenant that has authenticated in the last 30 days without an interactive sign-in, and find out what each one does. The count tends to surprise.

2. Find the scripts before they find you. Ask everyone on the operations team which scripts they have that make changes in Entra or M365. Not as an audit — as mapping. The answers only come if the question doesn't feel threatening.

3. Test whether anything is running on deprecated modules. MSOnline is retired. Anything still calling it no longer works, whether or not anyone has noticed.

Sources

  • Microsoft, Azure AD PowerShell to Microsoft Graph and Microsoft Entra PowerShell migration FAQ (MSOnline retired 30.05.2025) — https://learn.microsoft.com/en-us/powershell/azure/active-directory/migration-faq?view=azureadps-2.0
  • Microsoft, Plan for mandatory Microsoft Entra multifactor authentication (phase 2 from 01.10.2025) — https://learn.microsoft.com/en-us/entra/identity/authentication/concept-mandatory-multifactor-authentication
  • Microsoft Graph, Service-specific throttling limits — https://learn.microsoft.com/en-us/graph/throttling-limits
  • NSM, Basic Principles for ICT Security v2.1, measures 2.6.1–2.6.3 — https://nsm.no/getfile.php/1313975-1717589722/NSM/Filer/Dokumenter/Veiledere/NSMs%20Grunnprinsipper%20for%20IKT-sikkerhet%20v2.1.pdf
  • Havtil, the Management Regulations § 22 — https://www.havtil.no/globalassets/regelverk/gjeldende-regelverk-2022/styringsforskriften_n.pdf
  • Microsoft/Norsk Hydro on the 2019 attack (escalation via administrative privileges) — https://news.microsoft.com/source/features/digital-transformation/hackers-hit-norsk-hydro-ransomware-company-responded-transparency/

RELEVANT SOLUTION

See how this is handled in practice:

Norwegian version: Les artikkelen på norsk