WinGetAdminSettings:用 PowerShell DSC 声明式管理 WinGet 管理员设置
2026/9/20 12:02:38 网站建设 项目流程
  • 包管理器
  • CLI

【免费下载链接】winget-cli

WinGet is the Windows Package Manager. This project includes a CLI (Command Line Interface), PowerShell modules, and a COM (Component Object Model) API (Application Programming Interface).

项目地址:https://gitcode.com/gh_mirrors/wi/winget-cli
点击查看免费下载

导读

WinGet(Windows Package Manager)的部分高级能力(如允许本地清单文件、绕过安装器哈希校验等)属于管理员设置,默认关闭且只能以管理员身份修改。WinGetAdminSettingsMicrosoft.WinGet.DSC模块提供的 DSC(Desired State Configuration)资源,用于以声明式方式**读取、校验(Test)与写入(Set)**这些管理员设置。本文将结合该资源的官方帮助文档、模块源码、示例脚本与 Pester 测试用例,讲解其参数用法、底层实现与最佳实践,帮助你在配置文件或 PowerShell 脚本中安全、可重复地管理 WinGet 管理员开关。

资源定位:WinGet 管理员设置是什么

在 src/PowerShell/Help/Microsoft.WinGet.DSC/WinGetAdminSettings.md 中,该资源的定位被明确描述为:

  • SYNOPSIS:Configures WinGet administrator settings(配置 WinGet 管理员设置)。
  • DESCRIPTION:允许管理员设置被配置或检索;设置管理员设置需要管理员权限。

与针对单个用户的WinGetUserSettings(管理用户级 settings.json)不同,管理员设置作用于 WinGet 的全局安全策略。在 src/AppInstallerCommonCore/AdminSettings.cpp 的底层实现中可以看到,管理员设置被持久化到独立的Stream::AdminSettings存储,通过 YAML 键名读写。从源码结构看,当前支持的管理员设置包括:

设置键名类型用途(依据底层读写逻辑推断)
LocalManifestFiles布尔是否允许从本地清单文件安装
BypassCertificatePinningForMicrosoftStore布尔是否绕过 Microsoft Store 源的证书固定校验
InstallerHashOverride布尔是否允许覆盖安装器哈希校验
LocalArchiveMalwareScanOverride布尔是否覆盖本地压缩包的恶意软件扫描
ProxyCommandLineOptions布尔是否允许通过命令行参数指定代理
ConfigurationProcessorPath布尔是否允许指定配置处理器路径
DefaultProxy字符串默认代理地址

这些键名正是 DSC 资源Settings哈希表中所使用的键。Microsoft.WinGet.Client模块的Get-WinGetSetting命令会输出包含adminSettings属性的结果,可作为查看当前值的入口(见 Get-WinGetSetting.md)。

参数详解

WinGetAdminSettings资源仅有如下两个参数,全部沿袭自官方帮助文档并补充说明:

参数特性数据类型说明允许的值
SIDKeyString目标用户的 SID;传空字符串表示目标为当前用户。目前仅支持空字符串。Windows 安全标识符(Security Identifier,SID)格式
SettingsMandatoryHashtable以哈希表形式给出的管理员设置。通过Get-WinGetSetting输出中的adminSettings属性检查可用键

几点关键约束:

  • SID是资源的 Key 属性:DSC 要求每个资源实例必须有唯一键。正如 Microsoft.WinGet.DSC.psm1 源码注释所写:"We need a key. Do not set."(需要一个键,但请勿设置),实际使用中应保持为空字符串。
  • Settings是必填参数:即使只做查询(Get),也需要传入Settings哈希表(内容可为空),以符合 DSC 资源的参数校验要求。
  • Settings的合法键:即上文表格中的管理员设置键名,每个键对应一个布尔值。可通过Get-WinGetSetting的输出进行核对,例如:
(Get-WinGetSetting).adminSettings # 输出示例(节选): # adminSettings {[ProxyCommandLineOptions, False], [LocalArchiveMalwareScanOverride, False], [InstallerH...

或使用管道展开查看:

Get-WinGetSetting | Select-Object -ExpandProperty adminSettings

在 DSC 配置中声明管理员设置

WinGetAdminSettings是一个标准的 class-based DSC 资源,随Microsoft.WinGet.DSC模块一起分发(模块清单 Microsoft.WinGet.DSC.psd1 中注册了该资源)。在配置脚本中声明它:

Configuration WinGetAdminConfig { Import-DscResource -ModuleName Microsoft.WinGet.DSC WinGetAdminSettings ConfigureAdminSettings { SID = '' Settings = @{ LocalManifestFiles = $true InstallerHashOverride = $false } } }
  • SID = ''表示作用于当前用户(也是当前唯一受支持的目标)。
  • Settings中只列出你关心的设置项即可;未列出的项不会被动过(详见下文"Test 的部分比较语义")。

用 Invoke-DscResource 直接调用 Get / Test / Set

DSC 资源同样支持通过Invoke-DscResource命令直接调用,无需编写完整 Configuration,适合在脚本中快速检查或修正状态。模块自带的示例脚本 WinGetAdminSettingsResourceSample.ps1 完整演示了这一流程,要点如下。

前置条件(示例脚本开头注明):

  • 需要PSDesiredStateConfiguration2.0.6 或更高版本;
  • 需要Microsoft.WinGet.ClientMicrosoft.WinGet.DSC两个模块;
  • 执行Set必须以管理员身份运行

1. 查询当前状态(Get)

#Requires -Modules Microsoft.WinGet.Client, Microsoft.WinGet.DSC using module Microsoft.WinGet.DSC $resource = @{ Name = 'WinGetAdminSettings' ModuleName = 'Microsoft.WinGet.DSC' Property = @{ Settings = @{} } } $getResult = Invoke-DscResource @resource -Method Get $getResult.Settings # 当前管理员设置哈希表

Get会调用模块内部的Get-WinGetSetting,并返回其adminSettings属性(见 Microsoft.WinGet.DSC.psm1)。

2. 校验是否符合期望(Test)

$resource.Property = @{ Settings = @{ LocalManifestFiles = $true } } $testResult = Invoke-DscResource @resource -Method Test if (-not $testResult.InDesiredState) { Write-Host "LocalManifestFiles 当前未启用,需要执行 Set" }

3. 应用期望状态(Set)

Invoke-DscResource @resource -Method Set | Out-Null # 再次 Test 验证结果 $testResult2 = Invoke-DscResource @resource -Method Test if ($testResult2.InDesiredState) { Write-Host "LocalManifestFiles 已启用" }

示例脚本随后演示了将LocalManifestFiles置回$true的完整"检查 → 修正 → 复验"闭环,并提醒:脚本执行后会留下LocalManifestFiles处于启用状态,属于有意的副作用。

源码视角:Get / Test / Set 的实现原理

在 Microsoft.WinGet.DSC.psm1 中,WinGetAdminSettings类的三个方法清晰呈现了资源的工作机制:

  • Get():调用Get-WinGetSetting,取其adminSettings属性作为当前状态返回;SID恒返回空字符串。
  • Test()只做部分比较——遍历当前实际生效的管理员设置,仅当该键同时出现在你传入的Settings中时才比较值;不一致则返回$false,全部一致则返回$true。源码注释说明了这一设计意图:"This doesn't do a full comparison to allow users to don't have to update their resource every time a new admin setting is added on winget."(不做全量比较,这样每次 WinGet 新增管理员设置时,用户无需更新自己的资源配置)。
  • Set():首先调用Assert-IsAdministrator校验管理员权限(非管理员直接抛出 "This resource must run as an Administrator."),然后对Settings中的每一项逐一遍历:值为$true时调用Enable-WinGetSetting,为$false时调用Disable-WinGetSetting

底层落盘逻辑位于 src/AppInstallerCommonCore/AdminSettings.cpp:SetAdminSetting通过SetAdminSettingAndSave完成"修改 → 保存 → 失败重载"的原子化流程,SaveAdminSettings将全部设置以 YAML 键值对形式写入管理员设置流,字符串型设置(如DefaultProxy)则单独处理。

测试验证:Pester 用例如何覆盖该资源

Microsoft.WinGet.DSC模块的 Pester 测试 Microsoft.WinGet.DSC.Tests.ps1 对WinGetAdminSettings做了端到端覆盖(测试需在管理员 PowerShell 窗口中运行,且需要本地 Web 服务器提供测试数据):

  • 资源清单校验Get-DscResource -Module Microsoft.WinGet.DSC应恰好返回 5 个资源,WinGetAdminSettings是其中之一(其余为WinGetPackageWinGetPackageManagerWinGetSourceWinGetUserSettings)。
  • Get 测试:构造包含BypassCertificatePinningForMicrosoftStoreInstallerHashOverrideLocalManifestFilesLocalArchiveMalwareScanOverride四项的反转哈希表,断言Get返回值与(Get-WinGetSetting).adminSettings一致。
  • Test 测试:对反转后的设置调用Test,断言InDesiredState$false(因为当前状态与期望相反)。
  • Set 测试:调用Set应用反转设置,再Get校验四个值确实被翻转,最后Test断言进入期望状态。

该测试同时印证了Settings哈希表支持上述四个布尔设置键,可作为编写自定义配置时的权威参考。

注意事项与最佳实践

  1. 必须管理员权限Set方法会强制校验当前进程是否为管理员(Assert-IsAdministrator)。请以"以管理员身份运行"的方式启动 PowerShell 或执行配置编译。
  2. SID目前只支持空字符串:资源尚不支持为其他用户配置管理员设置;传非空 SID 可能得到不符合预期的行为,请勿依赖。
  3. 只声明你关心的项:得益于Test()的部分比较语义,你无需列出全部管理员设置,WinGet 后续新增设置也不会破坏现有配置的幂等性。
  4. 布尔语义Settings中键值为$true表示启用该管理员设置,$false表示禁用;底层布尔设置的默认值均为$false(见 AdminSettings.cpp 中AdminSettingValues的初始化)。
  5. 验证闭环:生产脚本建议遵循"Get查看现状 →Test判断偏差 →Set应用 → 再次Test/Get复验"的流程,与示例脚本和 Pester 用例保持一致。
  6. 与用户设置的边界:管理员设置是全局安全策略,区别于WinGetUserSettings管理的用户级 settings.json;两者用途不同,请勿混用。
  • 包管理器
  • CLI

【免费下载链接】winget-cli

WinGet is the Windows Package Manager. This project includes a CLI (Command Line Interface), PowerShell modules, and a COM (Component Object Model) API (Application Programming Interface).

项目地址:https://gitcode.com/gh_mirrors/wi/winget-cli
点击查看免费下载
上一篇:SwiftShader:在CPU上解锁Vulkan图形渲染的终极方案
下一篇:从GitHub Actions到HACS:lovelace-horizon-card稳定版与Beta发布完整流程指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询