Saturday, March 19, 2022

Configuring PowerShell 7 With Group Policy

Introduction

Group policy is a feature of Windows Server Active Directory which automagically deploys groups of policies to users and computers. A policy is some computer setting you wish to enforce, such as which screen saver to use, what desktop background to use, or what the default execution policy should be. 

Windows PowerShell has for a while allowed you to set certain group policies to control how PowerShell works. Windows PowerShell 5.1 provides five specific policy settings. PowerShell 7 provides all the Windows PowerShell policies, plus one more. I describe each policy below. 

One neat feature of PowerShell 7 is that you can enable independent policy values for PowerShell 7 and Windows PowerShell. Or you can enable a  PowerShell 7 policy and take any values, such as the Execution Policy from Windows PowerShell policies.

You can set policies for a computer or a user. I base the Group Policy Editor and the PowerShell cmdlets make use of administrative templates stored C:\Windows\PolicyDefinitions folder in your DC (or to a central policy store shared on all DCs). The templates include an XML file that defines a policy or set of policy, which has the extension ADMX. Each template definition a localised set of strings stored in an ADML file. The ADMX file contains pointers to strings defined in the ADML file. Having both files enables the GP Editor to use localised language.

After you apply a policy, the group policy agent on the computer creates entries in the user or computer's registry policy area. You can see the policy if you use registry editor or PowerShell and navigate to HKCU:\Software\Policies\Microsoft\PowerShellCore  for user settings, or you can navigate to HKLM:\Software\Policies\Microsoft\PowerShellCore for computer settings.

The group policy agent runs each time the computer starts, and each time a user logs on. The agent also runs at intervals of 2 hours (less a random time up to 30 minutes). To immediately invoke the agent, you can use the gpupdate.exe console application. 

NOTE: This article started out simple, but as it grew, I've had to split it into two. In this article, I look at the GPO settings you can specify and which registry key(s) and value entries they use. Armed with this information, the next article looks at how you set each policy using PowerShell 7. 

PowerShell Group Policy settings

There are six PowerShell 7 related group policies you can deploy

  • Execution Policy
  • Console Session Configuration (new with PowerShell 7)
  • Module Logging
  • Script block logging
  • Transcription
  • Updatable Help.

Setting Policies

Before setting any policy, note that each policy sets one or more keys and value entries in the user or computer section of the registry. Most policies are a single registry key with one or more value entries. Let's look at the individual policies, and the registry keys and value entries deployed.

Since these policies are registry settings, you can deploy them using group policy, or you can set the registry key manually. You could use a .REG file containing the settings you want to apply to a host, or use PowerShell to set the keys and value entries needed for the policy. 

In the following section, I show how you can create the key and value entries needed for user settings of a policy. In the next article, you can see how to create and deploy the group policy settings using PowerShell cmdlets. 

Execution Policy

The Execution Policy policy defines a particular execution policy or whether to disallow all script execution. I would expect you to know that PowerShell's Execution Policy is not a security barrier. More a speed bump to stop a very in-experienced user to do something silly. I would hope you know it is pretty easy to work around a restricted execution policy. 

For most organisations, an Execution Policy of RemoteSigned is probably sufficient. Your IT Professionals might want to log in and have full access without having to work around a more restricted policy, so setting the policy to Unrestricted for members of the IT department might be useful. Mileage varies. 

The registry key set by the policy is
HKCU:\Software\Policies\Microsoft\PowerShellCore
This is for the user policy setting. If you are setting computer policies, you can use HKLM: instead, which is the case with all the other policy keys used.

There are two value entries for this policy:
  • EnableScripts - This value entry enables this policy. It is of type dword and has a value of 1 if the policy is enabled 
  • ExecutionPolicy - This is the execution policy to be applied. It is a string and can contain any valid PowerShell execution policy 
Here is how to set this policy using PowerShell, in HKCU:
# 1. Set Execution Policy
# Create Key
$Key = 'HKCU:\Software\Policies\Microsoft\PowerShellCore'
if (Test-Path $Key) {
  Write-Verbose "Registry Key exists [$key]"
}
Else {
  Write-Verbose "Creating registry key [$key]"
  New-Item -Path $Key
}
# Set value for execution policy 
Write-Verbose 'Setting Execution Policy On'
$CVHT1   = @{ Path  = $Key
              Name  = 'EnableScripts'
              Type  = 'Dword'
              Value = 1 }
Set-ItemProperty @CVHT1
Write-Verbose 'Setting Execution Policy to Unrestricted'
$CVHT2   = @{ Path  = $Key
              Name  = 'ExecutionPolicy'
              Type  = 'String'
              Value = 'Unrestricted'}
Set-ItemProperty @CVHT2


Console Session Configuration 

The Console Session Configuration specifies a remoting configuration endpoint to use. Remote sessions then run against that endpoint. You can specify any endpoint, include a JEA endpoint.

The  registry key set by this policy is:

HKCU:Software\Policies\Microsoft\PowerShellCore\ConsoleSessionConfiguration

There are two value entries for this key:
  • EnableConsoleSessionConfiguration - this entry enables the policy. It is of type dword and has a value of 1 to indicate that the policy is applied.
  • ConsoleSessionConfigurationName - this entry is the remoting endpoint that is used. It is a string, such as "PowerShell.7". 

Module Logging

Module Logging requires PowerShell to log module usage and for which modules. If you set this policy, PowerShell logs pipeline execution events for the specified modules to the PowerShell Core event log. 

Be careful with this setting as you could generate a lot of log entries. If you are going to log module events, have a strategy for reviewing the events generate

This policy requires the use of two registry keys. The first is:
HKCU:\Software\Policies\Microsoft\PowerShellCore\ModuleLogging 

There is one value entry for this key:
  • EnableModuleLogging - This entry enables the policy. It is of type dword and has a value of 1 to indicate that the policy is applied.

The second key used by this policy is:

HKCU:\Software\Policies\Microsoft\PowerShellCore\ModuleLogging\ModuleNames

There are multiple value entries you can specify for this key, each one a module for logging. Each value entry has a name and a value of the module name. So if you wanted to log events for the FOO42 module, you would have a registry value name FOO42 with an associated value of FOO42. You can specify as many modules as you like.

    Script block logging

    You use the Script block logging policy to turn on PowerShell's logging of any important script blocks.  PowerShell does not log all script blocks only those that change something. Nevertheless, this policy can generate a lot of logging. In Windows PowerShell, setting this policy could result in performance degradation although has been much improved in PowerShell 7.

    The  registry key used by this policy is:

    HKCU:Software\Policies\Microsoft\PowerShellCore\ScriptBlockLogging

    There is one value entry under this policy.
    • EnableScriptBlockLogging - This entry enables the policy. It is of type dword and has a value of 1 to indicate that the policy is applied.

      Transcription

      The Transcription policy allows you to automatically create a transcript of every PowerShell session. 

      The  registry key set by this policy is:
      HKCU:\Software\Policies\Microsoft\PowerShellCore\Transcription

      There are two value entries used by this policy:
      • EnableTranscripting - This entry enables the policy. It is of type dword and has a value of 1 to indicate that the policy is applied.
      • OutputDirectory - this is a string and specifies the folder in which PowerShell writes session transcripts. 

      Updatable Help

      The Updatable Help policy allows you to configure a default value fore Update-Help's parameter SourcePath. If you enable the policy, Update-Help uses the setting as a default location for new help information. You can always override this by specifying a different value for the source path when you run Update-Help.

      The  registry key set by this policy is:

      HKCU:\Software\Policies\Microsoft\PowerShellCore\UpdatableHelp

      There are two value entries under this policy.
      • EnableUpdateHelpDefaultSourcePath - This entry enables the policy. It is of type dword and has a value of 1 to indicate that the policy is applied.
      • DefaultSourcePath -This parameter defines the location to be used as the default source path and is of type String. You would probably use a network share. Irrespective,  you should note that in this string you must escape any back slash character with aqn additional backslash. If the default source path is \\dc1\help, you see it as "\\\\dc1\\help".

      Using Windows PowerShell Settings

      As I mentioned above, you can set a policy for PowerShell 7 use but use whatever values you set for Windows PowerShell policy. In most or at least many cases, if you have Windows PowerShell policies set, you probably want the same policies set for PowerShell usage as well.

      To set any of the 6 polices to apply to PowerShell 7, but using the Windows PowerShell session you set two value entries in the six polices review above. The first is the Enable value entry, which enables that policy. Then you add another value entry:
      • UseWindowsPowerShellPolicySetting - This value entry indicates that the policy details should come from Windows PowerShell policies. It is of type dword and has a value of 1.

      Summary

      We looked at the six policies you can set and which registry key and value entries used by each policy. In the next article, I show you how to use the Group Policy cmdlets and PowerShell 7 to create and deploy these policies.