11/18/2020 Jim Hill

How to Block the Use of PowerShell in Windows 10 by Implementing an Applocker Policy through Microsoft Endpoint Manager

In a Cloud Only Microsoft 365 Environment

Microsoft’s PowerShell is a powerful scripting application which is built natively into Windows 10 devices. While this application allows great power for administrators to configure and control their devices it also opens up huge opportunities for hackers to launch malware attacks including the recent spike of ransomware attacks in which the universal element in common was the use of PowerShell. This article describes how a Microsoft 365 Endpoint administrator can selective disable PowerShell either on a device by device basis or for a group of devices registered through the Microsoft 365 Azure Active Directory.  These instructions were created for Windows 10 devices registered through the BYOD registration method but should also work for the other enrollment methods albeit with slight differences.  These would also work within a hybrid environment with small adjustments. For the latter, just follow these instructions but when you roll out the configuration profile in Microsoft Endpoint Manager but make adjustments by following the config profile creation for Intune per this article: https://www.petervanderwoude.nl/post/managing-applocker-on-windows-10-via-oma-dm/ 

Note: I am thankful for the very helpful instructions provided by Peter van der Woude in the article referenced above. I also wish to thank Alex Fields from ITProMentor who sent me Peter’s article as well as for his very helpful articles on Microsoft 365. I highly recommend reading them at his site at:  https://www.itpromentor.com/

Summary of Steps to Disable PowerShell in a Microsoft 365 Cloud Only Environment through the Microsoft Endpoint Manager:

Note: Thanks to a comment from James B we have revised this procedure to utilize the file hash method instead of the file path method.  That is now reflected below as of September 22, 2021. This policy will now block the execution of the four files, however if the files are updated the policy will need to reflect the new hash values. 

  1. Create New Security Group. In Endpoint Manager, create a security group which you will use to assign users and devices for which you want to disable PowerShell.  I recommend that you add just one test device to this new security group at first for testing purposes before you roll it out to your entire enterprise.  You could name your security group something like “Disable Powershell for Users and Devices.”
  2. Create XML Device Policy. Using a Windows 10 computer, use the Group Policy Editor to create a Applocker device policy which blocks the use of the EXE files associated with PowerShell.  Use the file hash method and for these two four files found in these locations:
    C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
    C:\Windows\System32\WindowsPowerShell\v1.0\powershell_ise.exe
    C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe
    C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell_ise.exe
    Important: You will need to edit the XML created in the Group Policy Manager and delete just the elements you need. 
  3. Apply the Device Profile. Finally, roll out the device configuration profile in the Microsoft Endpoint Manager using the following OMI-URI:
    ./Vendor/MSFT/AppLocker/ApplicationLaunchRestrictions/9000/EXE/Policy  where the string value of “9000” is some value that you decide upon that makes sense to you. The other values must be entered exactly and this string is case sensitive.  I use policy strings with 9’s in them when they contain restrictions, use what makes sense to you.

Detailed Steps of how to Disable PowerShell in a Microsoft 365 Cloud Only Environment through the Microsoft Endpoint Manager:

Step 1 – Create new Security Group in Endpoint Manager

Build the Security Group you will use to restrict devices and users from using PowerShell.  If users never require the use of PowerShell, and they already have local administrative access, then why allow them to have access to this powerful program in the first place?  Open the Endpoint Manager  and browse to Groups from the home menu tree.  Create a new security group and name it with something that makes sense like “Disable PowerShell for Users and Devices.”  Add one test device to the new security group.  Later, when you want to quickly enforce the policy on this device, you will open that Windows 10 computer, select the Company Portal app (you do have this installed for every device per the BYOD device enrollment process, right?) and under the settings gear select “Sync.” This will sync the policies in the Endpoint Manager to the local Windows 10 device.

Step 2 – Create the Device Policy in the Group Policy Editor

Open the local group policy editor on a Windows 10 computer by typing “edit group policy” at the start menu.  When the policy editor opens browse to this tree. It is helpful to follow the more detailed instructions provided by Kenneth Van Surksun in this very helpful article.  Note that even though you will need to create the default policies in that tree you will later edit the XML file and remove everything that is not relevant to the new policy restricting the use of PowerShell.  Microsoft has also provided an excellent technical article detailing the Applocker CSP which provides the information necessary to specify the correct OMI-URI settings for the restriction of the EXE part of the tree.  Note: This is a fairly hard element to figure out without help from others. It took me a long while to determine the correct values so hopefully this article was of help to you!

group policy editor

Figure One: Tree Diagram from the Group Policy Editor

Figure One: Tree Diagram from the Group Policy Editor

Notice that I have already defined both the default policies as well as the restrictions for the EXE files associated with PowerShell.  You will need to include policy restrictions for these EXE files:

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
C:\Windows\System32\WindowsPowerShell\v1.0\powershell_ise.exe

And, for 64-bit Machines:
C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe
C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell_ise.exe

The following is one of these deny policies:

deny policy in group policy editor

Figure 2: Example Policy for Restriction of the PowerShell EXE

 

file hash group policy editor screen shot for applocker policy

Figure 3: File Hash Method for Applocker Policy

 

screen shot of file hash method

Figure 4: The Four Hash Values for the Four Files being Blocked

Create each of the four policies, then right click on the AppLocker tree and select Export. This will export an XML file for the new policy.  Then, edit the XML file by removing everything except the single policy you have defined for the new restriction. 

Your final XML file should look something like mine:

<RuleCollection Type=”Exe” EnforcementMode=”Enabled”>
<FilePathRule Id=”921cc481-6e17-4653-8f75-050b80acca20″ Name=”(Default Rule) All files located in the Program Files folder” Description=”Allows members of the Everyone group to run applications that are located in the Program Files folder.” UserOrGroupSid=”S-1-1-0″ Action=”Allow”>
<Conditions>
<FilePathCondition Path=”%PROGRAMFILES%\*” />
</Conditions>
</FilePathRule>
<FilePathRule Id=”a61c8b2c-a319-4cd0-9690-d2177cad7b51″ Name=”(Default Rule) All files located in the Windows folder” Description=”Allows members of the Everyone group to run applications that are located in the Windows folder.” UserOrGroupSid=”S-1-1-0″ Action=”Allow”>
<Conditions>
<FilePathCondition Path=”%WINDIR%\*” />
</Conditions>
</FilePathRule>
<FilePathRule Id=”fd686d83-a829-4351-8ff4-27c7de5755d2″ Name=”(Default Rule) All files” Description=”Allows members of the local Administrators group to run all applications.” UserOrGroupSid=”S-1-5-32-544″ Action=”Allow”>
<Conditions>
<FilePathCondition Path=”*” />
</Conditions>
</FilePathRule>
<FileHashRule Id=”df42b48b-0bd5-444a-893a-98eb3bac349b” Name=”Via Hash powershell.exe powershell_ise.exe” Description=”Block via hash Via Hash powershell.exe powershell_ise.exe” UserOrGroupSid=”S-1-1-0″ Action=”Deny”>
<Conditions>
<FileHashCondition>
<FileHash Type=”SHA256″ Data=”0xB6F3EF35A570861DEDD3ED9BFAD1910B537AE38C701B4AB19C5966A05E61689E” SourceFileName=”powershell.exe” SourceFileLength=”433152″ />
<FileHash Type=”SHA256″ Data=”0x45C77CCBCE87AD3A7B87755E83E8947C7FF08701C239076BCC0336198EB790C8″ SourceFileName=”powershell_ise.exe” SourceFileLength=”213504″ />
<FileHash Type=”SHA256″ Data=”0xBAC613D793971F156BA846F8B1C1ABF6A635309EA32BD9258CD2AA1E1CD8C51E” SourceFileName=”powershell.exe” SourceFileLength=”452608″ />
<FileHash Type=”SHA256″ Data=”0x30E126A34BB6E9D83642D47C4B21D9154A9CE063C5BD2E8EBD1747B42D3731CE” SourceFileName=”powershell_ise.exe” SourceFileLength=”212992″ />
</FileHashCondition>
</Conditions>
</FileHashRule>
</RuleCollection>

Download my XML File

Step 3 – Apply the Device Profile in Microsoft Endpoint Manager

Create a new device configuration profile for Windows 10 devices and apply it only to the new security group you created above.  For the profile type select “Custom” and then use the OMA-URI value of:

./Vendor/MSFT/AppLocker/ApplicationLaunchRestrictions/9000/EXE/Policy

where the string value of “9000” is some value that you decide upon that makes sense to you. The other values must be entered exactly and this string is case sensitive.  I use policy strings with 9’s in them when they contain restrictions, use what makes sense to you. Peter did a better job of describing the process in his excellent article.

You will then want to visit the test computer that you assigned to the security group and select “Synch” in the Company Portal App.  Test out the policy by typing “PowerShell” at the start menu. If all is working correctly you will see the following message:

screen shot of policy warning for powershell blocked

Figure Five:  Error Message for Blocked Application per the new Applocker Policy Restriction

 

Conclusion:

You have now successfully configurated an Applocker restriction policy for Windows 10 devices  and applied it using the Microsoft Endpoint Manager. This will make things harder for hackers to mess with your Windows 10 devices.

Frequently Asked Questions:

Why is it important to disable PowerShell when it is a built-in program in Windows 10?

Quite simply, PowerShell is how malware moves through a local area network from computer to computer, and is also a way that malware runs programs to wreck computers.

Your instructions were for a pure cloud, Microsoft 365 environment. How could I do this for my hybrid Windows Active Directly which is federated to Microsoft 365?

This is outside the scope of this article, but the steps are very similar. You may wish to reach out to a Microsoft partner who could adapt our instructions for that instance.

Are there instances where disabling PowerShell will break certain management functions on my computer?

Yes, that is indeed the case for certain companies using perhaps things like ManageEngine (a most excellent tool by the way!) or programs that perhaps run PowerShell scripts during installation or upgrade. My advice for this would be to go ahead and disable PowerShell for all users except for perhaps power users such as developers and IT staff. Then if an issue arises regarding programs not working correctly they can raise an internal support ticket and you can handle it that way. Our company has disabled PowerShell for a full year as of this writing (June 2021) with no issue at all from regular users. We have established a security group for those users needing it and we then just excluded them from the configuration profile in Azure AD.

What about disabling other programs that many standard office workers would never need on their computer, such as the Windows Command Prompt Shell.

That is an excellent idea, and this could perhaps even lock down computers for an even higher level of security. I would suggest doing much testing with a group of users first though. I have found that when I remote into a user’s computer it is very handy to have access to the Windows Command Shell however, so I would then have to log out that user and log in as myself as administrator in order to debug the user’s issue. This could create some support issues for helping your desktop users.

Would disabling PowerShell in some way satisfy my Cyber insurance policy requirement for having an air-gapped backup or system image?

No. Disabling PowerShell would not satisfy that requirement. However, if the malware cannot run the .ps scripts encoded inside of it to encrypt your computer, or enumerate local computers and spread to other computers because it requires PowerShell to do it, then it does go a long way towards protecting corporate interests when backup system images are stored on a local drive hot-connected to each user’s computer. The idea of an air-gapped storage is to have an air gap switch on the USB device, or have the backup device turned off. But this requires a level of user interaction when running system images. It is better to script and run the system images (via something like Macrium or Acronis) and have these saved in an air-gapped storage device under the control of the system administrator. Then these images could either be run at the exact time when the storage was going to be hot (live connected).

My company uses Azure Cloud Backup which creates a recovery vault for all of our Windows 10 computers in the office. What are the implications for disabling PowerShell?

Unfortunately, if you want to use this neat backup utility you must keep PowerShell enabled. You can easily see this by just disabling PowerShell on one computer (you can just edit the group policy for that single machine) and then attempt to install the Azure Cloud Backup sensor program. Installation will fail at the first instant you launch it because one of the prerequisites is to have PowerShell in place.


Code Blocks:

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
C:\Windows\System32\WindowsPowerShell\v1.0\powershell_ise.exe
C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe
C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell_ise.exe
 <RuleCollection Type="Exe" EnforcementMode="Enabled">
<FilePathRule Id="921cc481-6e17-4653-8f75-050b80acca20" Name="(Default Rule) All files located in the Program Files folder" Description="Allows members of the Everyone group to run applications that are located in the Program Files folder." UserOrGroupSid="S-1-1-0" Action="Allow">
<Conditions>
<FilePathCondition Path="%PROGRAMFILES%\*" />
</Conditions>
</FilePathRule>
<FilePathRule Id="a61c8b2c-a319-4cd0-9690-d2177cad7b51" Name="(Default Rule) All files located in the Windows folder" Description="Allows members of the Everyone group to run applications that are located in the Windows folder." UserOrGroupSid="S-1-1-0" Action="Allow">
<Conditions>
<FilePathCondition Path="%WINDIR%\*" />
</Conditions>
</FilePathRule>
<FilePathRule Id="fd686d83-a829-4351-8ff4-27c7de5755d2" Name="(Default Rule) All files" Description="Allows members of the local Administrators group to run all applications." UserOrGroupSid="S-1-5-32-544" Action="Allow">
<Conditions>
<FilePathCondition Path="*" />
</Conditions>
</FilePathRule>
<FileHashRule Id="df42b48b-0bd5-444a-893a-98eb3bac349b" Name="Via Hash powershell.exe powershell_ise.exe" Description="Block via hash Via Hash powershell.exe powershell_ise.exe" UserOrGroupSid="S-1-1-0" Action="Deny">
<Conditions>
<FileHashCondition>
<FileHash Type="SHA256" Data="0xB6F3EF35A570861DEDD3ED9BFAD1910B537AE38C701B4AB19C5966A05E61689E" SourceFileName="powershell.exe" SourceFileLength="433152" />
<FileHash Type="SHA256" Data="0x45C77CCBCE87AD3A7B87755E83E8947C7FF08701C239076BCC0336198EB790C8" SourceFileName="powershell_ise.exe" SourceFileLength="213504" />
<FileHash Type="SHA256" Data="0xBAC613D793971F156BA846F8B1C1ABF6A635309EA32BD9258CD2AA1E1CD8C51E" SourceFileName="powershell.exe" SourceFileLength="452608" />
<FileHash Type="SHA256" Data="0x30E126A34BB6E9D83642D47C4B21D9154A9CE063C5BD2E8EBD1747B42D3731CE" SourceFileName="powershell_ise.exe" SourceFileLength="212992" />
</FileHashCondition>
</Conditions>
</FileHashRule>
</RuleCollection>

Did you Benefit from this Article?  Please Leave A Comment Below

, , , ,

Jim Hill

In my role at User Friendly Consulting I handle security operations, desktop and server administration, and digital marketing. We leverage the Microsoft 365 enterprise suite in order to provide maximum efficiency and security for our employees. My primary work is developing and implement digital marketing programs as well as control the IT infrastructure for the company.  I love the area of digital security and the adoption of secure practices, email delivery, and Office 365 security and configuration.  My background is mechanical engineering and information technology. I began my career as an engineer at Ford Motor Company in Dearborn and then transitioned into the IT field in 1998. My first work with computers was with finite element analysis on a Macintosh computer where I wrote a program to analyze stress on a flat plate for my senior design project. I began working at User Friendly Consulting in 1998 in various capacities but have landed in a role

Comments (4)

  1. As I am reading this it looks like you have nothing preventing a user from copying the powershell.exe file out of the folder and running it from another location. Please correct me if I am wrong.

    • Jim Hill

      Yes, that does appear to be the case, I’ll see if there is a way to block the whole command by not using hard coded paths and instead by using a REGEX. At least the first time the machine is infected the .PS programs won’t fire until they are savvy enough to dig around in the computer for the Powershell exe file and copy it to another path.

    • Jim Hill

      Hi James, I updated the post to reflect the use of the file hash blocking method. This will work but if the files are ever updated you will need to update the policy to reflect the new hash values. You could implement a policy which blocked by both file hash and file path for a way to have some level of blocking in place even if the files were updated.

      Thanks so much for pointing this out.

  2. Jim Hill

    The only way that I can see to protect this outside of using a hard coded file path (even with an Applocker path variable, see https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-defender-application-control/applocker/understanding-the-path-rule-condition-in-applocker), is to use a hash rule instead of a path rule. This would then block any file with the file hash(s) listed in the rule. The obvious issue with this method is that whenever the two Powershell files were updated the file hash would change and the rule would have to be fixed. As far as I know I cannot use a REGEX in the file path rule in order to locate the Powershell executable if it were moved outside of the normal location.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.