如何在Azure Packer构建Windows镜像时指定特定用户名?
配置Packer使用特定用户名安装软件
针对你的需求,需要分两步操作:先创建所需的特定用户,再以该用户身份执行软件安装。以下是修改后的Packer配置及说明:
1. 创建特定本地用户
在Chocolatey安装完成后、软件安装前,添加PowerShell provisioner创建目标用户(示例为StoreID_1234):
provisioner "powershell" { inline = [ # 创建本地用户并设置密码,密码需符合Windows复杂度要求 "New-LocalUser -Name 'StoreID_1234' -Password (ConvertTo-SecureString 'YourStrongPassword123!' -AsPlainText -Force) -FullName 'StoreID_1234' -Description 'User for software installation'", # 将用户添加到管理员组(若安装需要管理员权限) "Add-LocalGroupMember -Group 'Administrators' -Member 'StoreID_1234'" ] }
2. 以特定用户身份执行软件安装
修改原有的Chocolatey安装provisioner,使用Start-Process以目标用户身份运行安装命令:
provisioner "powershell" { inline = [ "$username = 'StoreID_1234'", "$password = ConvertTo-SecureString 'YourStrongPassword123!' -AsPlainText -Force", "$credential = New-Object System.Management.Automation.PSCredential ($username, $password)", # 以指定用户身份执行Chocolatey安装 "Start-Process -FilePath 'choco' -ArgumentList 'install --confirm D:/packages.config' -Credential $credential -Wait -NoNewWindow", ] valid_exit_codes = [0, 3010] }
完整修改后的Packer配置
packer { required_plugins { azure = { source = "github.com/hashicorp/azure" version = "~> 2" } } } source "azure-arm" "avd" { # WinRM Communicator communicator = "winrm" winrm_use_ssl = true winrm_insecure = true winrm_timeout = "5m" winrm_username = "packer" # Service Principal Authentication use_azure_cli_auth = true # Source Image os_type = "Windows" image_publisher = var.source_image_publisher image_offer = var.source_image_offer image_sku = var.source_image_sku image_version = var.source_image_version # Destination Image managed_image_resource_group_name = var.artifacts_resource_group managed_image_name = "${var.source_image_sku}-${var.source_image_version}" # Packer Computing Resources build_resource_group_name = var.build_resource_group vm_size = "Standard_DS3_v2" } build { source "azure-arm.avd" {} # Install Chocolatey provisioner "powershell" { inline = ["Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))"] } # 创建特定安装用户 provisioner "powershell" { inline = [ "New-LocalUser -Name 'StoreID_1234' -Password (ConvertTo-SecureString 'YourStrongPassword123!' -AsPlainText -Force) -FullName 'StoreID_1234' -Description 'User for software installation'", "Add-LocalGroupMember -Group 'Administrators' -Member 'StoreID_1234'" ] } # 上传packages.config provisioner "file" { source = "./packages.config" destination = "D:/packages.config" } # 以特定用户身份安装Chocolatey包 provisioner "powershell" { inline = [ "$username = 'StoreID_1234'", "$password = ConvertTo-SecureString 'YourStrongPassword123!' -AsPlainText -Force", "$credential = New-Object System.Management.Automation.PSCredential ($username, $password)", "Start-Process -FilePath 'choco' -ArgumentList 'install --confirm D:/packages.config' -Credential $credential -Wait -NoNewWindow", ] valid_exit_codes = [0, 3010] } provisioner "windows-restart" {} # Azure PowerShell Modules provisioner "powershell" { script = "./install-azure-powershell.ps1" } # Generalize image using Sysprep provisioner "powershell" { inline = [ "while ((Get-Service RdAgent).Status -ne 'Running') { Start-Sleep -s 5 }", "while ((Get-Service WindowsAzureGuestAgent).Status -ne 'Running') { Start-Sleep -s 5 }", "& $env:SystemRoot\System32\Sysprep\Sysprep.exe /oobe /generalize /quiet /quit /mode:vm", "while ($true) { $imageState = Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\State | Select ImageState; if($imageState.ImageState -ne 'IMAGE_STATE_GENERALIZE_RESEAL_TO_OOBE') { Write-Output $imageState.ImageState; Start-Sleep -s 10 } else { break } }" ] } }
注意事项
- 替换
YourStrongPassword123!为符合Windows密码复杂度要求的安全密码,建议通过Packer变量管理密码,避免硬编码。 - 如果软件不需要管理员权限,可以跳过将用户添加到管理员组的步骤。
- Sysprep会重置本地用户,所以该特定用户不会保留在最终生成的镜像中,符合通用镜像的要求。
内容的提问来源于stack exchange,提问作者Christian Sauer
相关产品推荐
相关产品推荐

