如何在Chocolatey安装前/安装时预配置软件源?
问题描述
我正在使用Chocolatey结合Azure ARM模板构建虚拟机(VM)并安装所需软件。我知道在Chocolatey安装完成后可以配置其拉取安装文件的sources位置,但想请教是否有办法在Chocolatey安装前(或安装过程中)预配置该软件源位置?
我希望实现全程无人值守安装,因此在Chocolatey安装完成后、软件安装前修改配置文件的方式,会违背无人值守的初衷。
我查看了Chocolatey的PS1安装脚本,但未找到可修改Choco包源位置的相关设置。
以下是Azure ARM模板中用于安装VM的自定义脚本扩展(Custom Script Extension)代码:
{ "name": "[concat(parameters('virtualMachineName'),'/chocolatey')]", "type": "Microsoft.Compute/virtualMachines/extensions", "location": "[resourceGroup().location]", "apiVersion": "2015-06-15", "dependsOn": [ "[concat('Microsoft.DevTestLab/schedules/', 'shutdown-computevm-', parameters('virtualMachineName'))]" ], "properties": { "publisher": "Microsoft.Compute", "type": "CustomScriptExtension", "typeHandlerVersion": "1.9", "autoUpgradeMinorVersion": true, "settings": { "fileUris": [ "[concat(parameters('setupChocolatelyScriptLocation'),parameters('setupChocolateyScriptFileName'))]" ], "commandToExecute": "[concat('powershell -ExecutionPolicy bypass -File ', parameters('setupChocolateyScriptFileName'), ' -chocoPackages ',parameters('chocoPackages'))]" } } },
解决方案
好消息是,有几种靠谱的办法能在Chocolatey安装过程中就完成源的预配置,完全满足你无人值守的需求:
方法1:利用环境变量预先指定默认源
Chocolatey的官方安装脚本支持通过环境变量设置默认源,你根本不需要修改官方的install.ps1,只要在执行安装脚本前设置好CHOCOLATEY_SOURCE环境变量就行。
在你的自定义PowerShell安装脚本(也就是setupChocolateyScriptFileName对应的脚本)里,可以这么写:
# 先设置环境变量,指定你的自定义源地址 $env:CHOCOLATEY_SOURCE = "https://your-custom-repo-url/api/v2/" # 下载并执行Chocolatey安装脚本 Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) # 可选:验证源是否配置成功,方便调试 choco source list
安装完成后,Chocolatey会自动把你指定的源设为默认,完全不需要后续手动修改配置。
方法2:预创建Chocolatey配置文件
如果需要更复杂的源配置(比如添加多个源、设置优先级、禁用官方源或者配置代理),你可以在安装Chocolatey之前,就把自定义的chocolatey.config文件放到它的默认配置路径($env:ProgramData\chocolatey\config\chocolatey.config)。
示例脚本如下:
# 先创建Chocolatey配置目录(如果不存在的话) $chocoConfigDir = "$env:ProgramData\chocolatey\config" if (-not (Test-Path $chocoConfigDir)) { New-Item -ItemType Directory -Path $chocoConfigDir | Out-Null } # 写入自定义的配置内容 $chocoConfigContent = @" <?xml version="1.0" encoding="utf-8"?> <chocolatey xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <sources> <source id="custom-primary" value="https://your-primary-repo/api/v2/" disabled="false" priority="1" /> <source id="custom-secondary" value="https://your-secondary-repo/api/v2/" disabled="false" priority="2" /> <!-- 如果不需要官方源,直接删除下面这行 --> <source id="chocolatey" value="https://community.chocolatey.org/api/v2/" disabled="false" priority="3" /> </sources> <!-- 还可以添加其他配置项,比如代理、日志级别等 --> </chocolatey> "@ $chocoConfigContent | Out-File "$chocoConfigDir\chocolatey.config" -Encoding utf8 # 执行Chocolatey安装脚本 Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
这种方式的优势是可以完全自定义所有配置项,安装过程中Chocolatey会直接加载你预先设置好的配置,一步到位。
方法3:安装后立即配置(整合到无人值守流程)
如果你的需求比较简单,也可以在Chocolatey安装完成后立刻执行choco source命令来配置源,虽然是安装后操作,但可以把所有步骤整合到同一个脚本里,依然是无人值守的。
你可以先修改ARM模板里的commandToExecute,传递自定义源参数:
"commandToExecute": "[concat('powershell -ExecutionPolicy bypass -File ', parameters('setupChocolateyScriptFileName'), ' -chocoPackages ', parameters('chocoPackages'), ' -customSource https://your-custom-repo-url/api/v2/')]"
然后在你的PowerShell脚本里接收参数并执行配置:
param( [string]$chocoPackages, [string]$customSource ) # 安装Chocolatey Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) # 添加自定义源并设置优先级,可选禁用官方源 choco source add -n="custom-source" -s="$customSource" --priority=1 # choco source disable -n="chocolatey" # 如需禁用官方源,取消注释这行 # 安装指定的软件包 choco install $chocoPackages -y
总结
如果追求“安装过程中预配置”的纯无人值守体验,推荐使用方法1或方法2,它们能完美整合到你的Azure ARM模板自定义脚本扩展中,完全符合你的需求。
内容的提问来源于stack exchange,提问作者Beefcake

