Windows 11

Deploying Local Group Policy | RMM and MDT | PowerShell



Intro

Deploying local Group Policy to non-domain joined Windows clients is possible with the LGPO tool by Microsoft. More instructions on command-line here. Many years ago I had to create scripts to do this for breathalyzer kiosk images that would be deployed in bars and jails. I figured I would do it again but with PowerShell and for MDT and RMM use.

Configure Local GPOs on Reference Machine

The Local Group Policy Editor (gpedit.msc) allows users to configure system settings on Windows 10 and Windows 11. This guide explains how to open gpedit.msc and configure Group Policy Objects (GPOs).

Opening Local Group Policy Editor (gpedit.msc)

Method 1: Using the Run Dialog

  1. Press Win + R on your keyboard.
  2. Type gpedit.msc and press Enter.
  3. The Local Group Policy Editor window will open.

Method 2: Using Search

  1. Click the Start Menu or press Win + S to open Search.
  2. Type Edit Group Policy and select it from the results.

Method 3: Using Command Prompt or PowerShell

  1. Open Command Prompt (cmd.exe) or PowerShell (Win + X, then select your choice).
  2. Type the following command and press Enter: gpedit.msc

Configuring Group Policy Objects (GPOs)

Navigating GPO Settings

  1. Once gpedit.msc is open, navigate through the folders in:
    • Computer Configuration (Applies settings to the entire computer)
    • User Configuration (Applies settings to the logged-in user)
  2. Use the left pane to browse to the policy setting you want to modify.
  3. Double-click on a policy to open its configuration window.

Understanding Policy Settings

Each Group Policy Object (GPO) setting has three options:

  • Not Configured: The setting remains as Windows defaults.
  • Enabled: Activates the policy’s functionality.
  • Disabled: Deactivates the policy’s functionality.

Each setting also provides:

  • A description of what enabling or disabling the policy does.
  • A “Supported On” field, which lists the minimum OS version that supports the policy.
  • Notes on deprecated policies if a setting is no longer functional in newer versions.

Applying and Enforcing GPOs

  1. After selecting Enabled or Disabled, click Apply and then OK.
  2. Some policies require a restart or a forced update. Run the following command in Command Prompt or PowerShell to apply changes immediately: gpupdate /force

Final Notes

  • Group Policy is only available in Windows Pro, Enterprise, and Education editions. Windows Home users must use the Registry Editor instead.
  • Always check the Supported On field to ensure the policy works on your OS version.
  • If a policy no longer applies to newer versions, its description will mention which Windows versions it was last applicable to.

Export Local Group Policy

Now we need to export the configuration from the reference machines to be applied to our destination machines. Here is a script to do that. I recommend not mixing Windows 10 and Window 11 exports, you should separate those.

PowerShell
# Set global error and warning handling
$ErrorActionPreference = "SilentlyContinue"
$WarningPreference = "SilentlyContinue"

# Function to check errors and exit if needed
function Check-Error {
    param ([string]$Message)
    if (-not $?) {
        Write-Host $Message
        exit
    }
}

# Determine system type
$SystemType = (Get-ComputerInfo).CsPCSystemType
$SystemTypeName = if ($SystemType -eq 'Mobile') { 'Mobile' } else { 'Desktop' }

# Define paths
$SourcePath = "C:\Windows\System32\GroupPolicy"
$ExportPath = "C:\TEMP\Exported-GroupPolicy"
$ZipFile = "C:\TEMP\GroupPolicy-Windows-11-Baseline-$SystemTypeName.zip"

# Create Export Directory
New-Item -Path $ExportPath -ItemType Directory -Force | Out-Null

# Copy content to export directory
Copy-Item -Path "$SourcePath\*" -Destination $ExportPath -Recurse -Force
Check-Error "Failed to copy GroupPolicy contents."

# Compress the contents of the export directory into a ZIP file
Compress-Archive -Path "$ExportPath\*" -DestinationPath $ZipFile -Force
Check-Error "Failed to create ZIP archive."

# Clean up the export directory after compression
Remove-Item -Path $ExportPath -Recurse -Force

Write-Host "GroupPolicy contents exported and saved to: $ZipFile"

Deploy GPO Reference Configuration to Destination Machines

Now with the reference configuration exported we’re going to use PowerShell to deploy/import to our destination machines, adjust your paths to your reference export.

PowerShell
# Suppress Errors & Warnings
$ErrorActionPreference = "SilentlyContinue"
$WarningPreference = "SilentlyContinue"

# Variables
$LogFile = "C:\TEMP\GPO_Deployment.log"
$BasePath = "C:\TEMP"
$DownloadURL = "https://download.microsoft.com/download/8/5/C/85C25433-A1B0-4FFA-9429-7E023E7DA8D8/LGPO.zip"
$DownloadPath = "$BasePath\LGPO.zip"
$LGPOFolder = "$BasePath\LGPO_30"
$WinRegPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion"
$WinBuild = (Get-ItemProperty $WinRegPath).CurrentBuild
$Edition = (Get-ItemProperty $WinRegPath).EditionID
$SystemTypeName = if ((Get-ComputerInfo).CsPCSystemType -eq 'Mobile') { 'Mobile' } else { 'Desktop' }
$SourceFile = "$BasePath\GroupPolicy-Windows-11-Baseline-$SystemTypeName.zip"

# Reset Log
Set-Content -Path $LogFile -Value ""

# Logging Function
function Write-Log {
    "$((Get-Date -Format 'yyyy-MM-dd HH:mm:ss')) - $args" | Out-File -Append -FilePath $LogFile
}

Write-Log "Starting GPO Deployment"

# Windows Version Check
if ($Edition -ne "Professional" -or [int]$WinBuild -lt 22000) {
    Write-Log "Exiting: Windows 11 Pro required. Detected Edition: $Edition, Build: $WinBuild"
    exit
}
Write-Log "Windows 11 Pro detected. Proceeding..."

# Ensure Base Folder Exists
New-Item -Path $BasePath -ItemType Directory -Force | Out-Null

# Download and Extract LGPO Tool
Invoke-WebRequest -Uri $DownloadURL -OutFile $DownloadPath
Expand-Archive -Path $DownloadPath -DestinationPath $BasePath -Force
Write-Log "LGPO tool downloaded and extracted."

# Apply GPOs
Expand-Archive -Path $SourceFile -DestinationPath $BasePath -Force
Start-Process LGPO.exe -WorkingDirectory $LGPOFolder -ArgumentList "/m $BasePath\Machine\Registry.pol" -Wait
Start-Process LGPO.exe -WorkingDirectory $LGPOFolder -ArgumentList "/u $BasePath\User\Registry.pol" -Wait
GPUpdate /Force | Out-Null
Write-Log "GPO applied successfully."

# Cleanup
Remove-Item "$LGPOFolder", "$DownloadPath", "$BasePath\GroupPolicy*", "$BasePath\Machine", "$BasePath\User", "$BasePath\gpt.ini" -Recurse -Force
Write-Log "Cleanup complete. Deployment finished."

Summary of Deployment Script

What the Script Does

  1. Suppresses Errors and Warnings:
    • It sets $ErrorActionPreference and $WarningPreference to "SilentlyContinue" to suppress errors and warnings.
  2. Defines Key Variables:
    • Paths for logging, download, and extraction.
    • Windows edition and build validation.
    • Source file location based on system type (Mobile/Desktop).
  3. Checks Windows Edition & Build:
    • Exits if Windows is not Windows 11 Pro or the build number is below 22000.
  4. Downloads and Extracts the LGPO Tool:
    • Retrieves LGPO.zip from Microsoft and extracts it.
  5. Applies GPO Settings:
    • Extracts GPO configuration files.
    • Uses LGPO.exe to import both machine and user policies.
    • Forces a Group Policy update (GPUpdate /Force).
  6. Performs Cleanup:
    • Removes temporary files and extracted folders.

Potential Enhancements

  • Error Handling:
    The script suppresses errors, making debugging difficult. Logging errors instead of suppressing them would be beneficial.
  • Validation for LGPO.exe:
    Ensure LGPO.exe exists before executing.
  • Dynamic Source File Naming:
    If Windows releases new baselines, an automated method to fetch the correct file would be useful.

Conclusion

I tested on multiple machines with ConnectWise Automate and MDT and all is working. Maybe this can help people trying to move to domain-less environments.

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

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