Added a CustomDistributionManifest policy#14313
Added a CustomDistributionManifest policy#14313craigloewen-msft wants to merge 3 commits intomasterfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Adds an enterprise policy (CustomDistributionManifest) allowing IT admins to override WSL’s distribution manifest (URL or inline JSON), and surfaces a user warning when the list is policy-controlled.
Changes:
- Introduces a new WSL policy value name and helper to read string policy values from
HKLM\Software\Policies\WSL. - Updates distribution manifest loading to honor the policy override and adds a
PolicyOverriddenflag. - Adds user-facing warnings + localization, and wires the new setting into the Intune/Group Policy ADMX/ADML templates.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/windows/inc/wslpolicies.h | Adds CustomDistributionManifest policy name and GetStringPolicyValue helper. |
| src/windows/common/Distribution.h | Tracks whether the distribution list is overridden by policy. |
| src/windows/common/Distribution.cpp | Loads manifest from policy (JSON or URL) and refactors filtering/finalization. |
| src/windows/common/WslInstall.cpp | Emits a user warning when installs use a policy-overridden distribution list. |
| src/windows/common/WslClient.cpp | Emits a user warning when --list --online uses a policy-overridden list. |
| localization/strings/en-US/Resources.resw | Adds localized warning string. |
| intune/en-US/WSL.adml | Adds UI strings/presentation for the new policy. |
| intune/WSL.admx | Defines the new machine policy and registry value mapping. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.
You can also share your feedback on Copilot code review. Take the survey.
| DWORD size = 0; | ||
| LONG result = RegGetValueW(key, nullptr, name, RRF_RT_REG_SZ, nullptr, nullptr, &size); | ||
| if (result == ERROR_PATH_NOT_FOUND || result == ERROR_FILE_NOT_FOUND) | ||
| { | ||
| return std::nullopt; | ||
| } | ||
|
|
||
| THROW_IF_WIN32_ERROR(result); | ||
|
|
||
| std::wstring value(size / sizeof(wchar_t), L'\0'); | ||
| result = RegGetValueW(key, nullptr, name, RRF_RT_REG_SZ, nullptr, value.data(), &size); | ||
| THROW_IF_WIN32_ERROR(result); |
There was a problem hiding this comment.
GetStringPolicyValue currently queries only RRF_RT_REG_SZ and doesn’t guard against a 0-byte size result. Elsewhere in the codebase (registry::ReadOptionalString) string reads accept REG_EXPAND_SZ as well and treat Size==0 as not present. Consider mirroring that behavior here (include RRF_RT_REG_EXPAND_SZ, early-return on size==0, and trim using wcsnlen/resize rather than manual null popping) so policy values like "%SystemRoot%..." work and empty values don’t throw.
| const auto first = value.find_first_not_of(L" \t\r\n"); | ||
| if (first == std::wstring::npos) | ||
| { | ||
| return ReadFromManifest(value); |
There was a problem hiding this comment.
ReadFromJsonOrUrl(): when the policy value is all whitespace, first_not_of() returns npos but the code calls ReadFromManifest(value) with the untrimmed whitespace string. This will likely fail URI parsing in a confusing way. Treat whitespace-only values as empty/invalid explicitly (e.g., return an error that the policy is set but empty, or ignore the policy override) instead of attempting a fetch.
| return ReadFromManifest(value); | |
| // Treat whitespace-only values as no override and fall back to the default manifest URL. | |
| return ReadFromManifest(c_defaultDistroListUrl); |

Summary of the Pull Request
Adds a
CustomDistributionManifestpolicy for IT admins to set a distribution manifest via policy.PR Checklist
Detailed Description of the Pull Request / Additional comments
Adds a
CustomDistributionManifestpolicy to WSL which just acts as an override for the regular value in the registry.Validation Steps Performed
Ran a VM, set the policy in the VM and validated it works for both URL content and JSON content