Disabling the Command Prompt Does NOT Increase Security

There is a configuration setting in the Windows operating system called “Disable the command prompt.” It “prevents users from running the interactive command prompt, cmd.exe. This policy also determines whether batch files (.cmd and .bat) can run on the computer. If you enable this policy and the user tries to open a command window, the system displays a message explaining that a policy prevents the action” (description copied and pasted from the Microsoft documentation). I’ve seen instances where administrators enable this setting in a Group Policy Object (GPO) under the mistaken impression that this improves security somehow.

This setting is a holdover from Windows 95/98 (which had no security), but it is completely pointless on Windows NT/2000/XP/Server 2003/Vista/Server 2008/7/Server 2008 R2/8/Server 2012/8.1/Server 2012 R2/10/Server 2016 and later. I can’t think of a single good reason to disable the command prompt. Why? Because cmd.exe is a program. It is not a security boundary.

In the Windows operating system, a security boundary prevents a program from doing something, or prevents data from going somewhere, without authorization. If a user opens a command prompt (i.e., starts the cmd.exe program), the cmd.exe program is running as that user, just like any other program the user runs. The cmd.exe program does not somehow give the user the ability to do things they can’t do otherwise. The user’s account is the security boundary, not the command prompt.

I have seen many requests for technical help in various forums, and sometimes the answer to a problem involves typing commands at a command prompt. Occasionally, I will see a reply like: “That won’t work, because we have disabled the command prompt.” My suspicion is that some administrators think that disabling the command prompt somehow increases security, but because this is wrong, the only thing it accomplishes in cases like this is slowing down problem solving processes (thus increasing costs).

PowerShell’s Execution Policy

PowerShell’s execution policy is an administrator safety feature; it’s not a security feature.

Its purpose is to prevent you from accidentally running scripts. It does not stop you from running scripts if you really want to.

All you have to to is start the PowerShell executable with the -ExecutionPolicy parameter set to Bypass (or RemoteSigned, etc.), and your PowerShell process is running with the specified execution policy. Ergo: not a security feature. (If the execution policy was really a security feature, then it wouldn’t be so easy to bypass, would it?)

Even if someone sets the execution policy to Restricted or AllSigned in a Group Policy Object (GPO), this can still be bypassed on the client side by rewriting the registry value (if the user is a member of Administrators) or by running the following function:

function Disable-ExecutionPolicy {
  ($context = $ExecutionContext.GetType().GetField(
   “_context”,”nonpublic,instance”).GetValue($ExecutionContext)).GetType().GetField(
  “_authorizationManager”,”nonpublic,instance”).SetValue(
  $context,(New-Object Management.Automation.AuthorizationManager “Microsoft.PowerShell”))
}

So — if you’re under the impression that a restrictive execution policy will prevent users from running scripts, that’s simply incorrect.

Trying to prevent users from running scripts is a strange thing to want to do anyway. Running scripts doesn’t grant users extra permissions. Another way to say this: PowerShell is a program, not a security boundary. Any program a user starts (including a script, which is run by a program, obviously) runs as that user.

The execution policy can be useful where you want to allow only signed scripts to run automatically by default. But it won’t prevent the user from changing the policy on their own and running scripts.