> For the complete documentation index, see [llms.txt](https://docs.devolutions.net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.devolutions.net/powershell-universal/config/running-as-a-service-account.md).

# Running as a Service Account

Configure PowerShell Universal to run under a Windows service account, distinguish hosting and Run As permissions, and troubleshoot Windows logon and process-launch failures.

### Application Service Account

PowerShell Universal can run under a dedicated Windows service account instead of LocalSystem. Local application tasks, jobs, and apps use the hosting identity by default. A [PSCredential secret variable](/powershell-universal/platform/variables.md) configured as **Run As** starts a separate process under the selected account.

Distinguish these two identities when assigning permissions:

* **Hosting account**: The account running the PowerShell Universal Windows service, or the IIS application pool identity. It authenticates the Run As account and creates the child process.
* **Run As account**: The account stored in the selected credential secret. Its logon rights and access to files and network resources determine what the child process can do.

For the current non-interactive Windows Run As launch path, check the following rights on the **hosting account**:

| Right                                                           | Applies to                                                                                        |
| --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| Log on as a service (`SeServiceLogonRight`)                     | Running PowerShell Universal as a Windows service.                                                |
| Adjust memory quotas for a process (`SeIncreaseQuotaPrivilege`) | Creating a child process through `CreateProcessAsUser`.                                           |
| Replace a process level token (`SeAssignPrimaryTokenPrivilege`) | Assigning the Run As account's token to the child process when required by `CreateProcessAsUser`. |

{% hint style="warning" %}
Membership in the local **Administrators** group does not remove these requirements. Administrators normally have **Adjust memory quotas for a process**, but do not have **Replace a process level token** by default. Verify the effective rights of the account that actually runs PowerShell Universal.
{% endhint %}

For IIS hosting, check the process-launch privileges on the **application pool identity**, not only on a Windows service account. Configure the hosting identity's logon rights according to the IIS hosting configuration.

The additional process-launch privileges are needed for the non-interactive alternate-account path, not merely because PowerShell Universal runs as a dedicated account. If a job or app should run under the hosting identity, leave **Run As** unset; another logon is not necessary. The Integrated environment does not support alternate Run As credentials. See [Environments](/powershell-universal/config/environments.md).

Health Checks require the following group membership to collect information about the PowerShell Universal system:

* Performance Monitor Users
* Performance Log Users

### Script Run As Requirements

These requirements also apply to Windows app and API processes started by the PowerShell Universal server with alternate credentials.

For a standard username-and-password credential, PowerShell Universal normally attempts an **interactive logon** first using .NET process creation (`CreateProcessWithLogonW`). This path requires **Allow log on locally** (`SeInteractiveLogonRight`) on the Run As account and does not require the hosting account to hold the additional `CreateProcessAsUser` privileges.

If the first attempt fails, PowerShell Universal falls back to **batch logon** (`LogonUser` with logon type 4), followed by `CreateProcessAsUser`. This path requires:

* **Log on as a batch job** (`SeBatchLogonRight`) on the **Run As account**.
* The process-launch privileges described above on the **hosting account**.

PowerShell Universal caches the selected launch path for five minutes, so repeated launches may not repeat both attempts. A successful credential validation does not prove that the hosting account can create a process under those credentials.

{% hint style="info" %}
An interactive logon here is a Windows authentication type. It does not mean that PowerShell Universal opens an interactive desktop or requires an RDP session.
{% endhint %}

{% hint style="warning" %}
**Deny log on locally** overrides **Allow log on locally**, including rights inherited through group membership. It blocks the interactive attempt but does not itself block batch logon. **Deny log on as a batch job** and **Deny log on as a service** independently override the corresponding logon rights. Do not remove an organizational deny policy merely to make the interactive path succeed; configure an approved non-interactive launch instead.
{% endhint %}

#### Group Managed Service Accounts

For a gMSA Run As credential, enter the account as `DOMAIN\account$` and select **Password Not Required** when creating the secret variable. See [Group Managed Service Accounts](/powershell-universal/platform/variables.md#group-managed-service-accounts) for setup.

PowerShell Universal skips the normal interactive attempt for this credential and uses a **service logon** (`LogonUser` with logon type 5). The target gMSA therefore needs **Log on as a service**, with no effective **Deny log on as a service** policy. The hosting account still needs the privileges required to create the child process.

The target gMSA must be configured for use on the PowerShell Universal host, including the appropriate managed-password retrieval permissions. Check `Test-ADServiceAccount` on that host. A successful result checks gMSA configuration; it does not exercise PowerShell Universal's complete logon and process-launch sequence.

Running PowerShell Universal itself as a gMSA is different from launching a child process as a gMSA. Do not assume that a working gMSA service or app pool can launch another gMSA solely because the service starts or `Test-ADServiceAccount` succeeds. Validate the Run As operation under the actual hosting identity. If the child should use the same identity as the host, leave **Run As** unset.

#### User profiles and file access

The Run As account needs access to the executable, configuration repository, working directory, and any other resources used by the job or app. Configure file and network access separately from logon rights.

The non-interactive launcher can also load the Run As account's Windows profile. Windows requires the caller of `LoadUserProfile` to be an administrator or LocalSystem and to hold **Back up files and directories** (`SeBackupPrivilege`) and **Restore files and directories** (`SeRestorePrivilege`). The current launcher skips explicit profile loading when the host is neither an administrator nor LocalSystem. Account for this when the script or app depends on `HKEY_CURRENT_USER` or other profile data. A profile-loading failure is distinct from a `CreateProcessAsUser` privilege failure.

### Assigning user rights

1. Open **Local Security Policy** (`secpol.msc`) on the PowerShell Universal host.
2. Go to **Local Policies > User Rights Assignment**.
3. Assign only the required rights to the appropriate hosting or Run As account, or to a narrowly scoped group. Verify effective group membership and matching deny policies.
4. If domain Group Policy controls the setting, request the change in the governing GPO. Local changes can be overwritten or unavailable.
5. Restart the PowerShell Universal service, or recycle the IIS application pool, after changing the hosting account's rights so it receives a new logon token.

{% hint style="warning" %}
These rights allow sensitive Windows operations. Have the changes reviewed under your organization's security policy. LocalSystem can satisfy the launch requirements, but switching to LocalSystem expands the hosting account's privileges and is not a least-privilege remedy.
{% endhint %}

### Configuring a PowerShell Universal Service to run as the account

After configuring the account and required rights, open **Services** (`services.msc`). Find **PowerShell Universal**, open **Properties**, and use the **Log On** tab to configure the hosting account. Restart the service and verify a job or app using the intended execution identity.

### Troubleshooting Run As startup

Read the PowerShell Universal log and, when logon auditing is enabled, the Windows **Security** log. Identify which stage failed before changing account permissions.

| Failure                                                                                                | What to check                                                                                                                                                                                                                                                |
| ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Security event 4625, logon type 2, status `0xC000015B`; or Windows error 1385 during interactive logon | The Run As account cannot perform the requested interactive logon. Check **Allow log on locally** and **Deny log on locally**. If interactive logon is intentionally denied, inspect the subsequent batch-launch result instead of relaxing that policy.     |
| Windows error 1385 during batch logon (type 4) or service logon (type 5)                               | Check the Run As account's right for that specific logon type and the corresponding deny policy.                                                                                                                                                             |
| `A required privilege is not held by the client` (Windows error 1314) during `CreateProcessAsUser`     | Check **Replace a process level token** and **Adjust memory quotas for a process** on the actual hosting account, even if it is a local administrator.                                                                                                       |
| Windows error 1314 during `LoadUserProfile`                                                            | Check the hosting account's profile-loading privileges and Windows profile-loading requirements, rather than only the process-token privilege.                                                                                                               |
| Windows error 1326 during logon                                                                        | Check the account name, domain, and credential. For a gMSA, also check **Password Not Required**, host configuration, managed-password retrieval permissions, and the hosting identity. Error 1326 alone does not establish that a stored password is wrong. |
| Process starts but the job or app reports access denied to an AppData, temporary, or repository path   | Inspect the path and execution identity. Launch privileges do not correct a working-directory or user-profile path problem. Do not grant broad access to the hosting account's private profile as a substitute for using the intended account's paths.       |

Collect the PowerShell Universal version, hosting mode and identity, whether the credential is a gMSA, the launch stage, native error code, and relevant event 4625 logon type/status when requesting support. Do not include passwords or secret values.

### Windows references

* [CreateProcessWithLogonW](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createprocesswithlogonw): interactive-logon requirements and the LocalSystem restriction.
* [CreateProcessAsUser](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessasuserw): process-token and memory-quota privileges.
* [LogonUser](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-logonuserw) and [account rights](https://learn.microsoft.com/en-us/windows/win32/secauthz/account-rights-constants): batch/service logon and deny-policy precedence.
* [LoadUserProfile](https://learn.microsoft.com/en-us/windows/win32/api/userenv/nf-userenv-loaduserprofilew): profile-loading requirements.
* [Replace a process level token](https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-10/security/threat-protection/security-policy-settings/replace-a-process-level-token): default assignments and security considerations.


---

# 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.devolutions.net/powershell-universal/config/running-as-a-service-account.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.
