Should PowerShell execution policy be Unrestricted on the whole machine?

PowerShell is a legitimate administration and automation tool, but because it is powerful and widely available on Windows systems, it is often included in security hardening decisions. This guide explains what execution policy actually does, why setting Unrestricted for the whole machine is often too broad, and what wider safeguards may matter more in practice.

It is also important to keep the scope realistic. These measures should be understood as prevention and risk reduction steps, not as a complete solution on their own. Execution policy is not a complete hardening measure on its own, and PowerShell related hardening is most useful when it forms part of a broader layered security approach.

This guide does not only list PowerShell commands. It explains what common results mean in plain language, what counts as a broader machine wide setting, and how to tell the difference between a result that needs closer review and one that simply shows a narrower baseline such as RemoteSigned.

What execution policy actually does

PowerShell execution policy controls the conditions under which PowerShell loads configuration files and runs scripts. It helps determine what type of script handling is allowed, but it should not be mistaken for a full application control system or a complete security boundary.

This matters because many people first encounter execution policy only when a script fails to run. That often leads to broad changes for convenience, even when the real need is much narrower and more temporary.

Why Unrestricted on the whole machine is often too broad

Setting execution policy to Unrestricted for the whole machine changes script handling at device level rather than only for one user, one session, or one administrative task. In many environments, that is broader than necessary.

The practical issue is not that PowerShell exists. The issue is that a wide policy change can remain in place long after the original task has been forgotten. This can weaken administrative discipline and make a system easier to misuse than intended.

What safer alternatives may look like

A safer approach usually begins by asking what is actually needed. In some cases, the requirement is only to run one script in one session or under one user context. In others, the better answer may be to use signed scripts, Constrained Language Mode, or stronger application control rather than relaxing execution policy for the whole machine.

The important point is that scope should match need. A temporary exception for one script, one user, or one session is not the same as relaxing script rules across the whole computer. In practice, the safer choice is often the one that changes as little as necessary rather than the one that simply makes PowerShell stop complaining.

In more strongly managed Windows environments, Microsoft’s preferred direction is broader application control through App Control for Business. PowerShell can also detect AppLocker policies, but Microsoft positions App Control for Business as the preferred application control system for Windows.

How script signing fits in

Script signing is one way to introduce more control over which scripts are allowed to run. In principle, it allows organisations to distinguish between trusted scripts and unsigned ones, rather than relying only on a broad execution policy setting.

However, script signing is not simply a quick fix. It introduces certificate trust, signing workflow, and management overhead. For that reason, it should be presented as an organisational control, not as a universal answer for every small environment.

How Constrained Language Mode fits in

Constrained Language Mode is different from execution policy. Execution policy is mainly about the conditions under which scripts are allowed to run. Constrained Language Mode is about limiting what can be done inside a PowerShell session once PowerShell is already running.

That distinction matters because a computer can block many scripts and still allow a very capable interactive PowerShell session. Constrained Language Mode reduces that capability by limiting the language features and object types that can be used.

In more strongly managed Windows environments, Microsoft’s guidance is that Constrained Language Mode is most meaningful when it is enforced through system lockdown with App Control for Business. PowerShell can also detect system wide AppLocker policies, but Microsoft describes App Control for Business as the preferred application control system for Windows. That is the stronger and more durable model because it is based on system level application control rather than a simple local tweak.

That said, smaller organisations and standalone computers do not always have App Control for Business in place.

In those cases, someone managing a standalone or lightly managed computer may still choose to add local friction by influencing PowerShell language mode through methods such as __PSLockdownPolicy. This can still add a layer of resistance against some early stage or less sophisticated misuse, but it should not be described as equivalent to policy enforced lockdown. If malicious code already gains sufficient access, weaker local methods may be changed, bypassed, or removed.

For that reason, a local method such as __PSLockdownPolicy is better described as one additional layer in a broader security approach rather than as a strong standalone hardening control. It may still be worthwhile for some lightly managed or standalone systems, especially because not every attack begins with full administrative control. However, the page should be clear about its limits.

A quick check such as:

$ExecutionContext.SessionState.LanguageMode

can help show whether the current PowerShell session is running in FullLanguage or ConstrainedLanguage mode. This command only shows the language mode of the current session. It does not by itself prove how strongly the wider computer is locked down.

Where these stronger controls are managed

On individual Windows computers, AppLocker rules are commonly reviewed through Local Security Policy under Application Control Policies > AppLocker. In domain managed environments, AppLocker can also be administered through Group Policy.

App Control for Business is typically managed through tools such as Group Policy, Intune, or the App Control Wizard, depending on how the Windows environment is managed. Microsoft positions App Control for Business as the preferred Windows application control system.

How a local Constrained Language Mode setting may be tested or applied

On a standalone or lightly managed computer, some people may choose to test or apply a local Constrained Language Mode setting by using the __PSLockdownPolicy environment variable. That may still add useful friction where no stronger application control is available, but it should not be confused with the stronger enforcement that comes from App Control for Business or other system level controls.

If this local method is used, it should be tested carefully because some PowerShell behaviour, scripts, or administrative workflows may no longer work as expected. It should also be reviewed in context, because local methods are weaker than enforced application control and should not be treated as a complete security boundary.

A short local check can be done as follows:

Open the Windows search box and search for Edit the system environment variables.

Open Environment Variables.

Under System variables, create a new variable named __PSLockdownPolicy.

Set the value to 4.

Open a new PowerShell window and check the result with:

$ExecutionContext.SessionState.LanguageMode

This local method may add useful friction on some systems, but it is not equivalent to system enforced application control.

Why PowerShell 2.0 should usually be removed

Windows PowerShell 2.0 belongs to an older legacy model and should usually not remain enabled in a modern Windows environment. It is mainly retained only for backwards compatibility with older tools and scripts, but that same legacy compatibility can make it attractive in abuse scenarios because it sits outside the expectations of more modern administrative practice.

In practical terms, removing Windows PowerShell 2.0 does not remove PowerShell from the computer. It only disables the older legacy engine. Newer supported versions such as Windows PowerShell 5.1 and PowerShell 7 remain separate.

If the feature is still present, it can usually be reviewed in one of two common ways. In older Windows interfaces, it may appear under “Turn Windows features on or off”.

In current Windows settings, optional features can also be reviewed under Settings > System > Optional features. If Windows PowerShell 2.0 appears, it can be cleared or removed. On newer Windows builds, the feature may not appear at all because Microsoft has removed PowerShell 2.0 from current releases.

This is one of the more straightforward PowerShell hardening decisions because it removes an unnecessary legacy component rather than broadening script execution settings.

PowerShell 7 and policy scope

It is also worth noting that PowerShell 7, also called PowerShell Core, should be reviewed separately where it is present or permitted. A review of Windows PowerShell settings alone may not tell the whole story.

In managed environments, administrators should review PowerShell 7 policy and logging settings in their own right rather than assuming the older Windows PowerShell path is sufficient.

What execution policy does not do

Execution policy does not turn PowerShell into a sealed security boundary. It does not replace wider application control. It does not remove the need for good administrative practice. It also does not prevent every form of script abuse or misuse.

Being explicit about these limits is important because it avoids checklist thinking. PowerShell hardening decisions should be reviewed alongside broader controls such as account security, device management, application control, monitoring, and layered defence.

For example, a system showing LocalMachine = RemoteSigned is different from one showing LocalMachine = Unrestricted, and the page should explain that difference clearly. But neither result, by itself, proves that the wider security model is strong or weak. It only answers one part of the picture. That is why execution policy should be understood as one control among several, not as the final answer to PowerShell related risk.

Execution policy is often misunderstood because it sounds stronger than it is. Microsoft describes it as a safety feature, not as a full security system. It helps control the conditions under which scripts run, but it should not be treated as equivalent to application control or a complete anti malware defence. A determined user or malicious code may still attempt to work around it, especially if broader security controls are weak. That is why a machine showing RemoteSigned instead of Unrestricted is still useful information, but it is not the whole security story.

How to check the current PowerShell state

If someone reviews a Windows computer and runs a few PowerShell checks, the page should help them understand what the results mean. Otherwise, the commands are not very useful on their own.

The purpose of this section is not to provide full PowerShell administration guidance. It is intended to help answer a simpler question first. Is this machine using a broad PowerShell setting across the whole computer, or is it using something narrower and more controlled?

$ExecutionContext.SessionState.LanguageMode
Get-ExecutionPolicy
Get-ExecutionPolicy -List

The first command shows the language mode of the current session only. It does not, by itself, prove whether stronger system wide application control is or is not in place.

These commands help show three different things. The first shows the current language mode for the session. The second shows the effective execution policy currently applying. The third shows where that policy is coming from by scope.

Example result and what it means

Someone checking PowerShell on a Windows computer might see output like this:

PS C:\Users\User> $ExecutionContext.SessionState.LanguageMode
FullLanguage

PS C:\Users\User> Get-ExecutionPolicy
RemoteSigned

PS C:\Users\User> Get-ExecutionPolicy -List

Scope ExecutionPolicy
—– —————
MachinePolicy Undefined
UserPolicy Undefined
Process Undefined
CurrentUser Undefined
LocalMachine RemoteSigned

In an example like this, PowerShell is not configured as Unrestricted across the whole machine.

The result shows that the current session is running in FullLanguage mode, which means PowerShell is operating with its normal broad language capability. It also shows that the effective execution policy is RemoteSigned, not Unrestricted.

The scope list is the most useful part. It shows that only LocalMachine is defined, and that its value is RemoteSigned. It also shows that MachinePolicy and UserPolicy are Undefined, which means Group Policy is not overriding the result in this example. Process is also Undefined, so there is no temporary session level override shown here.

In plain terms, this means the machine is using a narrower local baseline than Unrestricted. That is important because the page is about settings that are broader than necessary. A result like this does not match the main warning case.

In everyday terms, this example is closer to saying, “PowerShell is available, but the machine is not using the broadest possible script setting.” That is different from a computer where the whole device has been left on a much looser configuration.

Why this is different from Unrestricted

RemoteSigned and Unrestricted are not the same thing.

A machine level setting of RemoteSigned is still a PowerShell script policy and should not be treated as a complete security boundary on its own. However, it is narrower than Unrestricted, and that difference matters.

This kind of result is useful because it helps show whether the computer is using Unrestricted or a narrower setting such as RemoteSigned.

What conclusion to take from this example

The practical conclusion from this example is simple.

This computer is not showing a machine wide Unrestricted setting.

Instead, it is showing:

  • FullLanguage for the current session
  • an effective execution policy of RemoteSigned
  • RemoteSigned coming from LocalMachine
  • no Group Policy override in the output shown
  • no temporary Process override in the output shown

This example shows a different case. It shows a machine using a narrower setting than Unrestricted, rather than the broader configuration the guide is warning about.

In simple terms, RemoteSigned is a more limited setting than Unrestricted. It still allows PowerShell use, but it is not the same as telling the whole computer to treat all scripts as broadly acceptable.

What this does and does not tell you

This output provides useful information, but not the full picture.

It does show that the machine in the example is not using Unrestricted across the whole computer.

It does not prove that the system is fully hardened. It does not show whether wider application control is in place. It does not show whether PowerShell is being monitored. It does not show whether older legacy components have been removed. And it does not mean that PowerShell related abuse is impossible.

That is why this page should use examples like this as interpretation tools, not as final proof that a computer is fully secure.

Why this matters in real environments

This topic matters most in shared business systems, managed Windows estates, and environments where administrative tools need to remain available without leaving unnecessarily broad defaults in place. It is particularly relevant when security reviews uncover legacy scripts, old exceptions, or device builds that were relaxed for convenience and never properly reviewed afterwards.

It also matters because PowerShell is often discussed in oversimplified terms. A more useful question is not whether PowerShell is simply good or bad, but whether the way it is configured matches the real administrative need and the wider security model around it.

When this deserves closer review

A PowerShell result does not need to be dramatic before it deserves review. In general, the setting deserves closer attention if the machine shows Unrestricted at LocalMachine level, if Bypass is being used without a clear reason, if older legacy components such as Windows PowerShell 2.0 are still present, or if the setting appears to have been relaxed simply because a script would not run otherwise.

It may also deserve review if the computer relies on a weaker local method to influence language mode but there is no wider explanation of how PowerShell related risk is being managed. A setting that cannot be explained is often a sign that it was added for convenience and never properly revisited.

Further Guidance and Support

This guide forms part of a broader layered security approach. For structured guidance on security and resilience planning, see our Security and Resilience page.

For information about practical implementation and ongoing support, you can review our IT services and local IT support coverage across London, Hertfordshire, and Essex.

Author
Elías Sánchez
IT Support Consultant
Evening Computing
London, United Kingdom

This guide was prepared by Elías Sánchez with research and drafting assistance from AI tools. All technical content has been reviewed and adapted for clarity and accuracy.

Last reviewed
17 April 2026