Skip to content

feat: add TrustedHosts policy config option to allow whitelisting of UNC paths#26688

Open
Antvirf wants to merge 5 commits intoPowerShell:masterfrom
Antvirf:fix-allowed-hosts
Open

feat: add TrustedHosts policy config option to allow whitelisting of UNC paths#26688
Antvirf wants to merge 5 commits intoPowerShell:masterfrom
Antvirf:fix-allowed-hosts

Conversation

@Antvirf
Copy link

@Antvirf Antvirf commented Jan 14, 2026

PR Summary

Add a configuration option in both registry and config JSON to whitelist server names to be marked as "local intranet zones" as far as script execution is concerned. Otherwise, PS7 cannot execute scripts from remote locations with a . in the name, breaking e.g. the loading of powershell profiles when the user's Documents directory is redirected to a server referred to via an FQDN.

Resolves #12336

PR Context

The default behaviour of assuming any hostname with a . in it being insecure is not usable in environments where one wishes to refer to a path via FQDN, for example when using DFS to refer to file servers. The configuration option added here allows a group-policy as well as a config-file based approach to whitelisting hosts.

PR Checklist

TBC

  • Testing requirements? Happy to extend here as needed
  • Documentation changes?

Tests

# without any configs set
& "D:\PowerShell\src\powershell-win-core\bin\release\net10.0\win7-x64\pwsh.exe" -NoExit -File "\\company.domain\files\profile.ps1"
PowerShell 7.6.0-preview.5-159-g5858bfd7960c703d53a70e834dd685661077164f
Cannot load PSReadline module.  Console is running without PSReadline.
.: File \\company.domain\files\profile.ps1 cannot be loaded because running scripts is disabled on this system. For more information, see about_Execution_Policies at https://go.microsoft.com/fwlink/?LinkID=135170.


# set an execution policy (ALREADY SUPPORTED BY POWERSHELL)
$basePath = "HKLM:\Software\Policies\Microsoft\PowerShellCore"
$trustedHostsPath = "$basePath\TrustedHosts"
$patternsPath = "$trustedHostsPath\Patterns"
New-Item -Path $basePath -Force | Out-Null
New-ItemProperty -Path $basePath -Name "EnableScripts" -Value 1 -PropertyType DWord -Force | Out-Null
New-ItemProperty -Path $basePath -Name "ExecutionPolicy" -Value "RemoteSigned" -PropertyType String -Force | Out-Null


# try again, still does not work as execution policy itself is not enough, hence why this PR is needed
& "D:\PowerShell\src\powershell-win-core\bin\release\net10.0\win7-x64\pwsh.exe" -NoExit -File "\\company.domain\files\profile.ps1"
PowerShell 7.6.0-preview.5-159-g5858bfd7960c703d53a70e834dd685661077164f
.: File \\company.domain\files\profile.ps1 cannot be loaded. The file \\company.domain\files\profile.ps1 is not digitally signed. You cannot run this script on the current system. For more information about running scripts and setting execution policy, see about_Execution_Policies at https://go.microsoft.com/fwlink/?LinkID=135170.


# set the new options whitelisting the company domain
New-Item -Path $patternsPath -Force | Out-Null
New-ItemProperty -Path $patternsPath -Name "company.domain" -Value "company.domain" -PropertyType String -Force | Out-Null
New-ItemProperty -Path $patternsPath -Name "*.company.domain" -Value "*.company.domain" -PropertyType String -Force | Out-Null


# works fine now
& "D:\PowerShell\src\powershell-win-core\bin\release\net10.0\win7-x64\pwsh.exe" -NoExit -File "\\company.domain\files\profile.ps1"
PowerShell 7.6.0-preview.5-159-g5858bfd7960c703d53a70e834dd685661077164f
Profile loaded successfully!

…f UNC paths

The default behaviour of assuming any hostname with a `.` in it is not usable in environments where one wishes to refer to a path via FQDN, for example when using DFS to refer to file servers. The configuration option added here allows a group-policy as well as a config-file based approach to whitelisting hosts.
@Antvirf Antvirf marked this pull request as ready for review January 16, 2026 10:41
@Antvirf Antvirf requested a review from a team as a code owner January 16, 2026 10:41
Copilot AI review requested due to automatic review settings January 16, 2026 10:41
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a configuration option to whitelist UNC server hostnames/paths that should be treated as "Intranet" security zone instead of "Internet" zone during script execution policy checks. This addresses an issue where PowerShell Core treats any UNC path with a period (.) in the hostname as originating from the Internet security zone, which prevents script execution from FQDN UNC paths even with RemoteSigned execution policy.

Changes:

  • Added TrustedHosts policy configuration class with wildcard pattern support for trusted hostnames/paths
  • Implemented trusted host checking in security zone evaluation logic with Group Policy and config file support
  • Added Group Policy template definitions (ADMX/ADML) for TrustedHosts configuration

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/System.Management.Automation/utils/ClrFacade.cs Adds IsTrustedHost method to check UNC paths against trusted host patterns and integrates it into security zone mapping logic
src/System.Management.Automation/engine/Utils.cs Registers TrustedHosts policy type in policy retrieval infrastructure and adds registry key mapping
src/System.Management.Automation/engine/PSConfiguration.cs Defines TrustedHosts policy class with Patterns property for storing trusted host patterns
assets/GroupPolicy/PowerShellCoreExecutionPolicy.admx Adds Group Policy definition for TrustedHosts with list-based pattern configuration
assets/GroupPolicy/PowerShellCoreExecutionPolicy.adml Adds UI strings and help text for TrustedHosts Group Policy setting

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +150 to +157
#if !UNIX
/// <summary>
/// Check if a UNC path matches any trusted host pattern.
/// </summary>
/// <param name="uncPath">The full UNC path to check.</param>
/// <param name="hostname">The hostname from the UNC path.</param>
/// <returns>True if the path matches a trusted host pattern, false otherwise.</returns>
private static bool IsTrustedHost(string uncPath, string hostname)
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method is wrapped in #if !UNIX directive at line 150, but it's already inside a #if !UNIX block that starts at line 137 (#region Security). This creates a redundant nested preprocessor directive. Remove the inner #if !UNIX directive at line 150 and its corresponding #endif at line 196.

Copilot uses AI. Check for mistakes.
Comment on lines +187 to +191
catch (Exception)
{
// Invalid pattern - skip it silently
continue;
}
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exception handler catches all exceptions without any logging or diagnostic information. This could make it difficult to troubleshoot configuration issues where a pattern is invalid. Consider catching only specific exceptions like WildcardPatternException or ArgumentException, or at minimum add diagnostic logging to help administrators identify invalid patterns.

Suggested change
catch (Exception)
{
// Invalid pattern - skip it silently
continue;
}
catch (WildcardPatternException)
{
// Invalid pattern - skip it silently
continue;
}
catch (ArgumentException)
{
// Invalid pattern - skip it silently
continue;
}

Copilot uses AI. Check for mistakes.
- *.corp.internal (matches any hostname in corp.internal domain)
- \\server.domain.com\Users\*\Documents\* (matches specific UNC path pattern)

Wildcard syntax supports: * (zero or more chars), ? (one char), [abc] (character set), ` (escape char)
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation states that the backtick () is the escape character, but in the context of wildcard patterns in PowerShell, the backtick is specifically used to escape wildcards in the pattern string itself. This might be confusing since the backtick is also PowerShell's general escape character. Consider clarifying this by adding an example or rephrasing to: 'Wildcard syntax supports: * (zero or more chars), ? (one char), [abc] (character set), (escape char to treat wildcards as literals)'.

Suggested change
Wildcard syntax supports: * (zero or more chars), ? (one char), [abc] (character set), ` (escape char)
Wildcard syntax supports: * (zero or more chars), ? (one char), [abc] (character set), ` (escape char to treat wildcards as literals).

Copilot uses AI. Check for mistakes.
@microsoft-github-policy-service microsoft-github-policy-service bot added the Review - Needed The PR is being reviewed label Jan 31, 2026
@Antvirf
Copy link
Author

Antvirf commented Feb 5, 2026

@microsoft-github-policy-service agree company="Marshall Wace"

@microsoft-github-policy-service
Copy link
Contributor

@Antvirf the command you issued was incorrect. Please try again.

Examples are:

@microsoft-github-policy-service agree

and

@microsoft-github-policy-service agree company="your company"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Review - Needed The PR is being reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add ability to configure internet zone server names for execution policy in PS v7

1 participant