From 107a8ccbb2f2f18cf972610c12a216f59de2ec79 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Mon, 16 Mar 2026 13:01:46 +0100 Subject: [PATCH 01/55] Add win11-arm template and toolset --- .../templates/build.windows-11-arm64.pkr.hcl | 279 ++++++++++++++++ .../windows/templates/locals.windows.pkr.hcl | 4 + .../toolsets/toolset-win-11-arm64.json | 315 ++++++++++++++++++ 3 files changed, 598 insertions(+) create mode 100644 images/windows/templates/build.windows-11-arm64.pkr.hcl create mode 100644 images/windows/toolsets/toolset-win-11-arm64.json diff --git a/images/windows/templates/build.windows-11-arm64.pkr.hcl b/images/windows/templates/build.windows-11-arm64.pkr.hcl new file mode 100644 index 0000000000..b37c591b4b --- /dev/null +++ b/images/windows/templates/build.windows-11-arm64.pkr.hcl @@ -0,0 +1,279 @@ +build { + sources = ["source.azure-arm.image"] + name = "windows-11-arm64" + + provisioner "powershell" { + inline = [ + "New-Item -Path ${var.image_folder} -ItemType Directory -Force", + "New-Item -Path ${var.temp_dir} -ItemType Directory -Force" + ] + } + + provisioner "file" { + destination = "${var.image_folder}\\" + sources = [ + "${path.root}/../assets", + "${path.root}/../scripts", + "${path.root}/../toolsets" + ] + } + + provisioner "file" { + destination = "${var.image_folder}\\scripts\\docs-gen\\" + source = "${path.root}/../../../helpers/software-report-base" + } + + provisioner "powershell" { + inline = [ + "Move-Item '${var.image_folder}\\assets\\post-gen' 'C:\\post-generation'", + "Remove-Item -Recurse '${var.image_folder}\\assets'", + "Move-Item '${var.image_folder}\\scripts\\docs-gen' '${var.image_folder}\\SoftwareReport'", + "Move-Item '${var.image_folder}\\scripts\\helpers' '${var.helper_script_folder}\\ImageHelpers'", + "New-Item -Type Directory -Path '${var.helper_script_folder}\\TestsHelpers\\'", + "Move-Item '${var.image_folder}\\scripts\\tests\\Helpers.psm1' '${var.helper_script_folder}\\TestsHelpers\\TestsHelpers.psm1'", + "Move-Item '${var.image_folder}\\scripts\\tests' '${var.image_folder}\\tests'", + "Remove-Item -Recurse '${var.image_folder}\\scripts'", + "Move-Item '${var.image_folder}\\toolsets\\toolset-win-11-arm64.json' '${var.image_folder}\\toolset.json'", + "Remove-Item -Recurse '${var.image_folder}\\toolsets'" + ] + } + + provisioner "windows-shell" { + inline = [ + "net user ${var.install_user} ${var.install_password} /add /passwordchg:no /passwordreq:yes /active:yes /Y", + "net localgroup Administrators ${var.install_user} /add", + "winrm set winrm/config/service/auth @{Basic=\"true\"}", + "winrm get winrm/config/service/auth" + ] + } + + provisioner "powershell" { + inline = ["if (-not ((net localgroup Administrators) -contains '${var.install_user}')) { exit 1 }"] + } + + provisioner "powershell" { + elevated_password = "${var.install_password}" + elevated_user = "${var.install_user}" + inline = ["bcdedit.exe /set TESTSIGNING ON"] + } + + provisioner "powershell" { + environment_vars = ["IMAGE_VERSION=${var.image_version}", "IMAGE_OS=${var.image_os}", "AGENT_TOOLSDIRECTORY=${var.agent_tools_directory}", "IMAGEDATA_FILE=${var.imagedata_file}", "IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] + execution_policy = "unrestricted" + scripts = [ + "${path.root}/../scripts/build/Configure-WindowsDefender.ps1", + "${path.root}/../scripts/build/Configure-PowerShell.ps1", + "${path.root}/../scripts/build/Install-PowerShellModules.ps1", + # "${path.root}/../scripts/build/Install-WSL2.ps1", + "${path.root}/../scripts/build/Install-WindowsFeatures.ps1", + "${path.root}/../scripts/build/Install-Chocolatey.ps1", + "${path.root}/../scripts/build/Configure-BaseImage.ps1", + "${path.root}/../scripts/build/Configure-ImageDataFile.ps1", + "${path.root}/../scripts/build/Configure-SystemEnvironment.ps1", + "${path.root}/../scripts/build/Configure-DotnetSecureChannel.ps1" + ] + } + + provisioner "windows-restart" { + check_registry = true + restart_check_command = "powershell -command \"& {while ( (Get-WindowsOptionalFeature -Online -FeatureName Containers -ErrorAction SilentlyContinue).State -ne 'Enabled' ) { Start-Sleep 30; Write-Output 'InProgress' }}\"" + restart_timeout = "10m" + } + + provisioner "powershell" { + inline = ["Set-Service -Name wlansvc -StartupType Manual", "if ($(Get-Service -Name wlansvc).Status -eq 'Running') { Stop-Service -Name wlansvc}"] + } + + provisioner "powershell" { + environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] + scripts = [ + # "${path.root}/../scripts/build/Install-Docker.ps1", + # "${path.root}/../scripts/build/Install-DockerWinCred.ps1", + # "${path.root}/../scripts/build/Install-DockerCompose.ps1", + "${path.root}/../scripts/build/Install-PowershellCore.ps1", + "${path.root}/../scripts/build/Install-WebPlatformInstaller.ps1" + ] + } + + provisioner "windows-restart" { + restart_timeout = "30m" + } + + provisioner "powershell" { + elevated_password = "${var.install_password}" + elevated_user = "${var.install_user}" + environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] + scripts = [ + "${path.root}/../scripts/build/Install-VisualStudio.ps1", + "${path.root}/../scripts/build/Install-KubernetesTools.ps1" + ] + valid_exit_codes = [0, 3010] + } + + provisioner "windows-restart" { + check_registry = true + restart_timeout = "10m" + } + + # TODO: + # 1. Add ${path.root}/../scripts/build/Install-CMake.ps1 + # 2. Add ${path.root}/../scripts/build/Install-Ninja.ps1 + # 3. Check if need to move ${path.root}/../scripts/build/Install-LLVM.ps1 into this block + provisioner "powershell" { + pause_before = "2m0s" + environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] + scripts = [ + # "${path.root}/../scripts/build/Install-Wix.ps1", + "${path.root}/../scripts/build/Install-WDK.ps1", + "${path.root}/../scripts/build/Install-VSExtensions.ps1", + "${path.root}/../scripts/build/Install-AzureCli.ps1", + "${path.root}/../scripts/build/Install-AzureDevOpsCli.ps1", + "${path.root}/../scripts/build/Install-ChocolateyPackages.ps1", + "${path.root}/../scripts/build/Install-JavaTools.ps1", + "${path.root}/../scripts/build/Install-Kotlin.ps1", + "${path.root}/../scripts/build/Install-OpenSSL.ps1" + ] + } + + provisioner "powershell" { + execution_policy = "remotesigned" + environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] + scripts = ["${path.root}/../scripts/build/Install-ServiceFabricSDK.ps1"] + } + + provisioner "windows-restart" { + restart_timeout = "10m" + } + + # TODO: + # 1. Add ${path.root}/../scripts/build/Install-Mercurial.ps1 + # 2. Add ${path.root}/../scripts/build/Install-NSIS.ps1 + # 3. Add ${path.root}/../scripts/build/Install-AliyunCli.ps1 + provisioner "powershell" { + environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] + scripts = [ + "${path.root}/../scripts/build/Install-ActionsCache.ps1", + "${path.root}/../scripts/build/Install-Ruby.ps1", + # "${path.root}/../scripts/build/Install-PyPy.ps1", + "${path.root}/../scripts/build/Install-Toolset.ps1", + "${path.root}/../scripts/build/Configure-Toolset.ps1", + "${path.root}/../scripts/build/Install-NodeJS.ps1", + # "${path.root}/../scripts/build/Install-AndroidSDK.ps1", + "${path.root}/../scripts/build/Install-PowershellAzModules.ps1", + "${path.root}/../scripts/build/Install-Pipx.ps1", + "${path.root}/../scripts/build/Install-Git.ps1", + "${path.root}/../scripts/build/Install-GitHub-CLI.ps1", + "${path.root}/../scripts/build/Install-PHP.ps1", + "${path.root}/../scripts/build/Install-Rust.ps1", + "${path.root}/../scripts/build/Install-Sbt.ps1", + "${path.root}/../scripts/build/Install-Chrome.ps1", + "${path.root}/../scripts/build/Install-EdgeDriver.ps1", + "${path.root}/../scripts/build/Install-Firefox.ps1", + "${path.root}/../scripts/build/Install-Selenium.ps1", + "${path.root}/../scripts/build/Install-IEWebDriver.ps1", + "${path.root}/../scripts/build/Install-Apache.ps1", + "${path.root}/../scripts/build/Install-Nginx.ps1", + # "${path.root}/../scripts/build/Install-Msys2.ps1", + "${path.root}/../scripts/build/Install-WinAppDriver.ps1", + "${path.root}/../scripts/build/Install-R.ps1", + "${path.root}/../scripts/build/Install-AWSTools.ps1", + "${path.root}/../scripts/build/Install-DACFx.ps1", + "${path.root}/../scripts/build/Install-MysqlCli.ps1", + "${path.root}/../scripts/build/Install-SQLPowerShellTools.ps1", + "${path.root}/../scripts/build/Install-SQLOLEDBDriver.ps1", + "${path.root}/../scripts/build/Install-DotnetSDK.ps1", + "${path.root}/../scripts/build/Install-Mingw64.ps1", + # "${path.root}/../scripts/build/Install-Haskell.ps1", + "${path.root}/../scripts/build/Install-Stack.ps1", + # "${path.root}/../scripts/build/Install-Miniconda.ps1", + "${path.root}/../scripts/build/Install-AzureCosmosDbEmulator.ps1", + # "${path.root}/../scripts/build/Install-Zstd.ps1", + "${path.root}/../scripts/build/Install-Vcpkg.ps1", + "${path.root}/../scripts/build/Install-Bazel.ps1", + "${path.root}/../scripts/build/Install-RootCA.ps1", + # "${path.root}/../scripts/build/Install-MongoDB.ps1", + "${path.root}/../scripts/build/Install-CodeQLBundle.ps1", + "${path.root}/../scripts/build/Configure-Diagnostics.ps1" + ] + } + + provisioner "powershell" { + elevated_password = "${var.install_password}" + elevated_user = "${var.install_user}" + environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] + scripts = [ + # "${path.root}/../scripts/build/Install-PostgreSQL.ps1", + "${path.root}/../scripts/build/Install-WindowsUpdates.ps1", + "${path.root}/../scripts/build/Configure-DynamicPort.ps1", + "${path.root}/../scripts/build/Configure-GDIProcessHandleQuota.ps1", + "${path.root}/../scripts/build/Configure-Shell.ps1", + "${path.root}/../scripts/build/Configure-DeveloperMode.ps1", + "${path.root}/../scripts/build/Install-LLVM.ps1" + ] + } + + provisioner "windows-restart" { + check_registry = true + restart_check_command = "powershell -command \"& {if ((-not (Get-Process TiWorker.exe -ErrorAction SilentlyContinue)) -and (-not [System.Environment]::HasShutdownStarted) ) { Write-Output 'Restart complete' }}\"" + restart_timeout = "30m" + } + + provisioner "powershell" { + pause_before = "2m0s" + environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] + scripts = [ + "${path.root}/../scripts/build/Install-WindowsUpdatesAfterReboot.ps1", + "${path.root}/../scripts/build/Invoke-Cleanup.ps1", + "${path.root}/../scripts/tests/RunAll-Tests.ps1" + ] + } + + provisioner "powershell" { + inline = ["if (-not (Test-Path ${var.image_folder}\\tests\\testResults.xml)) { throw '${var.image_folder}\\tests\\testResults.xml not found' }"] + } + + provisioner "powershell" { + environment_vars = ["IMAGE_VERSION=${var.image_version}", "IMAGE_FOLDER=${var.image_folder}"] + inline = ["pwsh -File '${var.image_folder}\\SoftwareReport\\Generate-SoftwareReport.ps1'"] + } + + provisioner "powershell" { + inline = ["if (-not (Test-Path C:\\software-report.md)) { throw 'C:\\software-report.md not found' }", "if (-not (Test-Path C:\\software-report.json)) { throw 'C:\\software-report.json not found' }"] + } + + provisioner "file" { + destination = "${path.root}/../Windows11-arm-Readme.md" + direction = "download" + source = "C:\\software-report.md" + } + + provisioner "file" { + destination = "${path.root}/../software-report.json" + direction = "download" + source = "C:\\software-report.json" + } + + provisioner "powershell" { + environment_vars = ["INSTALL_USER=${var.install_user}"] + scripts = [ + "${path.root}/../scripts/build/Install-NativeImages.ps1", + "${path.root}/../scripts/build/Configure-System.ps1", + "${path.root}/../scripts/build/Configure-User.ps1", + "${path.root}/../scripts/build/Post-Build-Validation.ps1" + ] + skip_clean = true + } + + provisioner "windows-restart" { + restart_timeout = "10m" + } + + provisioner "powershell" { + inline = [ + "if( Test-Path $env:SystemRoot\\System32\\Sysprep\\unattend.xml ){ rm $env:SystemRoot\\System32\\Sysprep\\unattend.xml -Force}", + "& $env:SystemRoot\\System32\\Sysprep\\Sysprep.exe /oobe /generalize /mode:vm /quiet /quit", + "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 } }" + ] + } + +} diff --git a/images/windows/templates/locals.windows.pkr.hcl b/images/windows/templates/locals.windows.pkr.hcl index 6cca76993e..9fb08913d9 100644 --- a/images/windows/templates/locals.windows.pkr.hcl +++ b/images/windows/templates/locals.windows.pkr.hcl @@ -12,6 +12,10 @@ locals { source_image_marketplace_sku = "MicrosoftWindowsServer:WindowsServer:2025-Datacenter-g2" os_disk_size_gb = 150 } + "win11-arm64" = { + source_image_marketplace_sku = "windows11preview-arm64:microsoftwindowsdesktop:win11-25h2-ent:latest" + os_disk_size_gb = 256 + } } source_image_marketplace_sku = local.image_properties_map[var.image_os].source_image_marketplace_sku diff --git a/images/windows/toolsets/toolset-win-11-arm64.json b/images/windows/toolsets/toolset-win-11-arm64.json new file mode 100644 index 0000000000..0aa1f7e7d5 --- /dev/null +++ b/images/windows/toolsets/toolset-win-11-arm64.json @@ -0,0 +1,315 @@ +{ + "toolcache": [ + { + "name": "Ruby", + "arch": "aarch64", + "platform" : "win32", + "versions": [ + "3.4" + ], + "default": "3.4" + }, + { + "name": "Python", + "url" : "https://raw.githubusercontent.com/actions/python-versions/main/versions-manifest.json", + "arch": "x64", + "platform" : "win32", + "versions": [ + "3.13.*" + ] + }, + { + "name": "Python", + "url" : "https://raw.githubusercontent.com/actions/python-versions/main/versions-manifest.json", + "arch": "arm64", + "platform" : "win32", + "versions": [ + "3.12.*", + "3.13.*", + "3.14.*" + ], + "default": "3.13.*" + }, + { + "name": "node", + "url" : "https://raw.githubusercontent.com/actions/node-versions/main/versions-manifest.json", + "arch": "arm64", + "platform" : "win32", + "versions": [ + "20.*", + "22.*", + "24.*" + ] + }, + { + "name": "go", + "url" : "https://raw.githubusercontent.com/actions/go-versions/main/versions-manifest.json", + "arch": "arm64", + "platform" : "win32", + "versions": [ + "1.22.*", + "1.23.*", + "1.24.*", + "1.25.*" + ], + "default": "1.24.*" + } + ], + "powershellModules": [ + { "name": "DockerMsftProvider" }, + { "name": "MarkdownPS" }, + { "name": "Pester" }, + { "name": "PowerShellGet" }, + { "name": "PSScriptAnalyzer" }, + { "name": "PSWindowsUpdate" }, + { "name": "SqlServer" }, + { "name": "VSSetup" }, + { "name": "Microsoft.Graph" }, + { "name": "AWSPowershell" } + ], + "azureModules": [ + { + "name": "az", + "versions": [ + "12.5.0" + ], + "zip_versions": [ + + ] + } + ], + "java": { + "default": "21", + "versions": [ "21", "23" ] + }, + "android": { + "commandline_tools_url": "https://dl.google.com/android/repository/commandlinetools-win-9123335_latest.zip", + "hash": "8A90E6A3DEB2FA13229B2E335EFD07687DCC8A55A3C544DA9F40B41404993E7D", + "platform_min_version": "31", + "build_tools_min_version": "31.0.0", + "extras": [ + "android;m2repository", + "google;m2repository", + "google;google_play_services" + ], + "addons": [], + "additional_tools": [ + "cmake;3.18.1", + "cmake;3.22.1" + ], + "ndk": { + "default": "27", + "versions": [ + "26", "27", "28" + ] + } + }, + "mingw": { + "version": "14.*", + "runtime": "ucrt" + }, + "MsysPackages": { + "msys2": [], + "mingw": [] + }, + "windowsFeatures": [ + { "name": "Containers", "optionalFeature": true }, + { "name": "Microsoft-Windows-Subsystem-Linux", "optionalFeature": true }, + { "name": "VirtualMachinePlatform", "optionalFeature": true }, + { "name": "NetFx4-AdvSrvs", "optionalFeature": true }, + { "name": "Client-ProjFS", "optionalFeature": true }, + { "name": "Microsoft-Hyper-V-All", "optionalFeature": true }, + { "name": "Microsoft-Hyper-V", "optionalFeature": true }, + { "name": "Microsoft-Hyper-V-Tools-All", "optionalFeature": true }, + { "name": "Microsoft-Hyper-V-Hypervisor", "optionalFeature": true }, + { "name": "Microsoft-Hyper-V-Management-PowerShell", "optionalFeature": true } + ], + "visualStudio": { + "version" : "2022", + "subversion" : "17", + "edition" : "Enterprise", + "channel": "release", + "installChannel": "", + "workloads": [ + "Component.Dotfuscator", + "Component.Linux.CMake", + "Component.Unreal.Android", + "Component.Xamarin", + "Microsoft.Component.VC.Runtime.UCRTSDK", + "Microsoft.Net.Component.4.7.2.SDK", + "Microsoft.Net.Component.4.7.TargetingPack", + "Microsoft.Net.Component.4.7.2.TargetingPack", + "Microsoft.Net.Component.4.8.1.SDK", + "Microsoft.Net.Component.4.8.1.TargetingPack", + "Microsoft.VisualStudio.Component.AspNet45", + "Microsoft.VisualStudio.Component.Debugger.JustInTime", + "Microsoft.VisualStudio.Component.EntityFramework", + "Microsoft.VisualStudio.Component.DslTools", + "Microsoft.VisualStudio.Component.SQL.SSDT", + "Microsoft.VisualStudio.Component.PortableLibrary", + "Microsoft.VisualStudio.Component.TestTools.CodedUITest", + "Microsoft.VisualStudio.Component.TestTools.WebLoadTest", + "Microsoft.VisualStudio.Component.UWP.VC.ARM64", + "Microsoft.VisualStudio.Component.UWP.VC.ARM64EC", + "Microsoft.VisualStudio.Component.VC.CLI.Support", + "Microsoft.VisualStudio.Component.VC.CMake.Project", + "Microsoft.VisualStudio.Component.VC.DiagnosticTools", + "Microsoft.VisualStudio.Component.VC.Llvm.Clang", + "Microsoft.VisualStudio.Component.VC.Llvm.ClangToolset", + "Microsoft.VisualStudio.Component.VC.TestAdapterForBoostTest", + "Microsoft.VisualStudio.Component.VC.TestAdapterForGoogleTest", + "Microsoft.VisualStudio.Component.VC.Tools.ARM", + "Microsoft.VisualStudio.Component.VC.Tools.ARM64", + "Microsoft.VisualStudio.Component.VC.Tools.ARM64EC", + "Microsoft.VisualStudio.Component.VC.Redist.MSM", + "Microsoft.VisualStudio.Component.VC.Runtimes.ARM.Spectre", + "Microsoft.VisualStudio.Component.VC.Runtimes.ARM64.Spectre", + "Microsoft.VisualStudio.Component.VC.Runtimes.ARM64EC.Spectre", + "Microsoft.VisualStudio.Component.VC.MFC.ARM64", + "Microsoft.VisualStudio.Component.VC.MFC.ARM64.Spectre", + "Microsoft.VisualStudio.Component.VC.ATLMFC", + "Microsoft.VisualStudio.Component.VC.ATLMFC.Spectre", + "Microsoft.VisualStudio.Component.VC.ATL", + "Microsoft.VisualStudio.Component.VC.ATL.Spectre", + "Microsoft.VisualStudio.Component.VC.ATL.ARM", + "Microsoft.VisualStudio.Component.VC.ATL.ARM.Spectre", + "Microsoft.VisualStudio.Component.VC.ATL.ARM64", + "Microsoft.VisualStudio.Component.VC.ATL.ARM64.Spectre", + "Microsoft.VisualStudio.Component.VC.ASAN", + "Microsoft.VisualStudio.Component.Windows10SDK.19041", + "Microsoft.VisualStudio.Component.Windows11SDK.22621", + "Microsoft.VisualStudio.Component.Windows11SDK.26100", + "Microsoft.VisualStudio.ComponentGroup.NativeDesktop.Llvm.Clang", + "Microsoft.VisualStudio.ComponentGroup.UWP.VC.v142", + "Microsoft.VisualStudio.ComponentGroup.Web.CloudTools", + "Microsoft.VisualStudio.Workload.ManagedDesktop", + "Microsoft.VisualStudio.Workload.ManagedGame", + "Microsoft.VisualStudio.Workload.NativeCrossPlat", + "Microsoft.VisualStudio.Workload.NativeDesktop", + "Microsoft.VisualStudio.Workload.NativeGame", + "Microsoft.VisualStudio.Workload.NetCrossPlat", + "Microsoft.VisualStudio.Workload.NetWeb", + "Microsoft.VisualStudio.Workload.Node", + "Microsoft.VisualStudio.Workload.Universal", + "Microsoft.VisualStudio.Workload.VisualStudioExtension", + "Component.MDD.Linux", + "Component.Microsoft.Windows.DriverKit", + "wasm.tools", + "Microsoft.Component.MSBuild" + ], + "vsix": [ + "SSIS.MicrosoftDataToolsIntegrationServices", + "VisualStudioClient.MicrosoftVisualStudio2022InstallerProjectsArm64" + ] + }, + "docker": { + "images": [ + "mcr.microsoft.com/windows/servercore:ltsc2022", + "mcr.microsoft.com/windows/nanoserver:ltsc2022", + "mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2022", + "mcr.microsoft.com/dotnet/framework/runtime:4.8-windowsservercore-ltsc2022", + "mcr.microsoft.com/dotnet/framework/sdk:4.8-windowsservercore-ltsc2022" + ], + "components": { + "docker": "26.1.3", + "compose": "2.27.1" + } + }, + "pipx": [ + { + "package": "yamllint", + "cmd": "yamllint --version" + } + ], + "selenium": { + "version": "4" + }, + "npm": { + "global_packages": [ + { "name": "yarn", "test": "yarn --version" }, + { "name": "newman", "test": "newman --version" }, + { "name": "lerna", "test": "lerna --version" }, + { "name": "gulp-cli", "test": "gulp --version" }, + { "name": "grunt-cli", "test": "grunt --version" } + ] + }, + "serviceFabric": { + "runtime": { + "version": "10.1.2493.9590", + "checksum": "09C63A971BACDE338282C73B3C9174BED9AAD53E1D3A1B73D44515852C9C00CF" + }, + "sdk": { + "version": "7.1.2493", + "checksum": "0CB1084156C75CF5075EA91ABA330CF10B58648B8E036C9C2F286805263C497F" + } + }, + "dotnet": { + "versions": [ + "6.0", + "8.0", + "9.0", + "10.0" + ], + "tools": [ + { "name": "nbgv", "test": "nbgv --version", "getversion": "nbgv --version" } + ], + "warmup": false + }, + "choco": { + "common_packages": [ + { "name": "7zip.install" }, + { "name": "aria2" }, + { "name": "azcopy10" }, + { "name": "Bicep" }, + { "name": "innosetup" }, + { "name": "jq" }, + { "name": "NuGet.CommandLine" }, + { "name": "packer" }, + { + "name": "strawberryperl" , + "args": [ "--version", "5.32.1.1" ] + }, + { "name": "pulumi" }, + { "name": "swig" }, + { "name": "vswhere" }, + { + "name": "julia", + "args": [ "--ia", "/DIR=C:\\Julia" ] + }, + { "name": "imagemagick" } + ] + }, + "node": { + "default": "24.*" + }, + "maven": { + "version": "3.9" + }, + "mysql": { + "version": "8.0" + }, + "mongodb": { + "version": "5.0" + }, + "nsis": { + "version": "3.10" + }, + "llvm": { + "version": "20.1.6" + }, + "php": { + "version": "8.4" + }, + "postgresql": { + "version": "14" + }, + "kotlin": { + "version": "latest" + }, + "openssl": { + "version": "3.*" + }, + "pwsh": { + "version": "7.4" + } +} From 4b60db63fd68d4f61d2d1936b35c41859619fdb3 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Mon, 16 Mar 2026 13:46:06 +0100 Subject: [PATCH 02/55] Update Install Helpers --- images/windows/scripts/helpers/ImageHelpers.psm1 | 1 + .../windows/scripts/helpers/InstallHelpers.ps1 | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/images/windows/scripts/helpers/ImageHelpers.psm1 b/images/windows/scripts/helpers/ImageHelpers.psm1 index 4ebbd8fc88..8915ef9367 100644 --- a/images/windows/scripts/helpers/ImageHelpers.psm1 +++ b/images/windows/scripts/helpers/ImageHelpers.psm1 @@ -25,6 +25,7 @@ Export-ModuleMember -Function @( 'Get-TCToolVersionPath' 'Test-IsWin25' 'Test-IsWin22' + 'Test-IsWin11' 'Expand-7ZipArchive' 'Get-WindowsUpdateStates' 'Invoke-ScriptBlockWithRetry' diff --git a/images/windows/scripts/helpers/InstallHelpers.ps1 b/images/windows/scripts/helpers/InstallHelpers.ps1 index 032e8b58be..06b57609c0 100644 --- a/images/windows/scripts/helpers/InstallHelpers.ps1 +++ b/images/windows/scripts/helpers/InstallHelpers.ps1 @@ -356,6 +356,22 @@ function Test-IsWin22 { (Get-CimInstance -ClassName Win32_OperatingSystem).Caption -match "2022" } +function Test-IsWin11 { + <# + .SYNOPSIS + Checks if the current Windows operating system is Windows 11. + .DESCRIPTION + This function uses the Get-CimInstance cmdlet to retrieve information + about the current Windows operating system. It then checks if the Caption + property of the Win32_OperatingSystem class contains the string "Windows 11", + indicating that the operating system is Windows 11. + .OUTPUTS + Returns $true if the current Windows operating system is Windows 11. + Otherwise, returns $false. + #> + (Get-CimInstance -ClassName Win32_OperatingSystem).Caption -match "Windows 11" +} + function Expand-7ZipArchive { <# .SYNOPSIS From 81627deb4d7e8b5da90205d3f8a14a027bd37f30 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Wed, 18 Mar 2026 18:43:13 +0100 Subject: [PATCH 03/55] Modify codebase to support Arm --- .../scripts/build/Configure-BaseImage.ps1 | 5 +- .../scripts/build/Configure-ImageDataFile.ps1 | 6 +- .../windows/scripts/build/Configure-Shell.ps1 | 4 +- .../scripts/build/Configure-Toolset.ps1 | 8 ++- .../windows/scripts/build/Configure-User.ps1 | 4 +- .../windows/scripts/build/Install-CMake.ps1 | 35 +++++++++ .../windows/scripts/build/Install-Chrome.ps1 | 8 ++- .../scripts/build/Install-DotnetSDK.ps1 | 25 +++---- .../scripts/build/Install-EdgeDriver.ps1 | 8 ++- .../windows/scripts/build/Install-Firefox.ps1 | 12 +++- images/windows/scripts/build/Install-Git.ps1 | 9 ++- .../scripts/build/Install-GitHub-CLI.ps1 | 9 ++- .../scripts/build/Install-JavaTools.ps1 | 16 +++-- images/windows/scripts/build/Install-LLVM.ps1 | 32 ++++++++- .../scripts/build/Install-NativeImages.ps1 | 20 +++--- .../windows/scripts/build/Install-Ninja.ps1 | 28 ++++++++ .../windows/scripts/build/Install-NodeJS.ps1 | 8 ++- .../windows/scripts/build/Install-OpenSSL.ps1 | 8 ++- .../scripts/build/Install-PowershellCore.ps1 | 8 ++- images/windows/scripts/build/Install-R.ps1 | 9 ++- images/windows/scripts/build/Install-Ruby.ps1 | 14 +++- images/windows/scripts/build/Install-Rust.ps1 | 24 +++++-- .../scripts/build/Install-VisualStudio.ps1 | 9 ++- images/windows/scripts/build/Install-WDK.ps1 | 3 + .../docs-gen/Generate-SoftwareReport.ps1 | 71 ++++++++++++------- .../docs-gen/SoftwareReport.CachedTools.psm1 | 2 +- .../scripts/docs-gen/SoftwareReport.Java.psm1 | 6 +- .../windows/scripts/helpers/ImageHelpers.psm1 | 1 + .../scripts/helpers/InstallHelpers.ps1 | 16 +++++ .../scripts/helpers/VisualStudioHelpers.ps1 | 5 +- .../windows/scripts/tests/Android.Tests.ps1 | 2 +- .../scripts/tests/ChocoPackages.Tests.ps1 | 6 +- .../windows/scripts/tests/Databases.Tests.ps1 | 4 +- images/windows/scripts/tests/Docker.Tests.ps1 | 8 +-- .../windows/scripts/tests/Haskell.Tests.ps1 | 2 +- images/windows/scripts/tests/Java.Tests.ps1 | 12 +++- images/windows/scripts/tests/MSYS2.Tests.ps1 | 4 +- .../windows/scripts/tests/Miniconda.Tests.ps1 | 4 +- images/windows/scripts/tests/Shell.Tests.ps1 | 2 +- images/windows/scripts/tests/Tools.Tests.ps1 | 38 +++++++++- .../windows/scripts/tests/Toolset.Tests.ps1 | 4 ++ .../scripts/tests/VisualStudio.Tests.ps1 | 2 +- images/windows/scripts/tests/Wix.Tests.ps1 | 2 +- .../templates/build.windows-11-arm64.pkr.hcl | 19 +++-- .../toolsets/toolset-win-11-arm64.json | 2 +- 45 files changed, 409 insertions(+), 115 deletions(-) create mode 100644 images/windows/scripts/build/Install-CMake.ps1 create mode 100644 images/windows/scripts/build/Install-Ninja.ps1 diff --git a/images/windows/scripts/build/Configure-BaseImage.ps1 b/images/windows/scripts/build/Configure-BaseImage.ps1 index b1b963eb5a..8caf55460c 100644 --- a/images/windows/scripts/build/Configure-BaseImage.ps1 +++ b/images/windows/scripts/build/Configure-BaseImage.ps1 @@ -44,7 +44,10 @@ function Disable-WindowsUpdate { Add-Content -Path $profile.AllUsersAllHosts -Value '$ErrorActionPreference="Stop"' Write-Host "Disable Server Manager on Logon" -Get-ScheduledTask -TaskName ServerManager | Disable-ScheduledTask +$srvManagerTask = Get-ScheduledTask -TaskName ServerManager +if ($srvManagerTask) { + Disable-ScheduledTask -TaskName ServerManager +} Write-Host "Disable 'Allow your PC to be discoverable by other PCs' popup" New-Item -Path HKLM:\System\CurrentControlSet\Control\Network -Name NewNetworkWindowOff -Force diff --git a/images/windows/scripts/build/Configure-ImageDataFile.ps1 b/images/windows/scripts/build/Configure-ImageDataFile.ps1 index d0b73effa6..5abbc42430 100644 --- a/images/windows/scripts/build/Configure-ImageDataFile.ps1 +++ b/images/windows/scripts/build/Configure-ImageDataFile.ps1 @@ -27,8 +27,12 @@ if ((Test-IsWin25) -and $env:INSTALL_VS_2026) { $imageLabel = "windows-2022" $softwareUrl = "${githubUrl}/win22/$imageMajorVersion.$imageMinorVersion/images/windows/Windows2022-Readme.md" $releaseUrl = "https://github.com/actions/runner-images/releases/tag/win22%2F$imageMajorVersion.$imageMinorVersion" +} elseif ((Test-IsWin11) -and (Test-IsArm64)) { + $imageLabel = "windows-11-arm64" + $softwareUrl = "${githubUrl}/win11-arm64/$imageMajorVersion.$imageMinorVersion/images/windows/Windows11-Arm64-Readme.md" + $releaseUrl = "https://github.com/actions/runner-images/releases/tag/win11-arm64%2F$imageMajorVersion.$imageMinorVersion" } else { - throw "Invalid platform version is found. Either Windows Server 2022 or 2025 are required" + throw "Invalid platform version is found. Either Windows Server 2022, 2025 or Windows 11 are required" } $json = @" diff --git a/images/windows/scripts/build/Configure-Shell.ps1 b/images/windows/scripts/build/Configure-Shell.ps1 index f9ac961557..334d724a1f 100644 --- a/images/windows/scripts/build/Configure-Shell.ps1 +++ b/images/windows/scripts/build/Configure-Shell.ps1 @@ -2,7 +2,8 @@ $shellPath = "C:\shells" New-Item -Path $shellPath -ItemType Directory | Out-Null -# add a wrapper for C:\msys64\usr\bin\bash.exe +if (-not (Test-IsWin11)) { + # add a wrapper for C:\msys64\usr\bin\bash.exe @' @echo off setlocal @@ -11,6 +12,7 @@ IF NOT DEFINED MSYSTEM set MSYSTEM=mingw64 set CHERE_INVOKING=1 C:\msys64\usr\bin\bash.exe -leo pipefail %* '@ | Out-File -FilePath "$shellPath\msys2bash.cmd" -Encoding ascii +} # gitbash <--> C:\Program Files\Git\bin\bash.exe New-Item -ItemType SymbolicLink -Path "$shellPath\gitbash.exe" -Target "$env:ProgramFiles\Git\bin\bash.exe" | Out-Null diff --git a/images/windows/scripts/build/Configure-Toolset.ps1 b/images/windows/scripts/build/Configure-Toolset.ps1 index de8da36f0a..880f177e27 100644 --- a/images/windows/scripts/build/Configure-Toolset.ps1 +++ b/images/windows/scripts/build/Configure-Toolset.ps1 @@ -4,6 +4,12 @@ ## Desc: Configure Toolset ################################################################################ +if ( Test-IsArm64 ) { + $envVarTemplate = "GOROOT_{0}_{1}_AARCH64" +} else { + $envVarTemplate = "GOROOT_{0}_{1}_X64" +} + $toolEnvConfigs = @{ Python = @{ pathTemplates = @( @@ -15,7 +21,7 @@ $toolEnvConfigs = @{ pathTemplates = @( "{0}\bin" ) - envVarTemplate = "GOROOT_{0}_{1}_X64" + envVarTemplate = $envVarTemplate } } diff --git a/images/windows/scripts/build/Configure-User.ps1 b/images/windows/scripts/build/Configure-User.ps1 index 6ede0d8cc6..63c596c56a 100644 --- a/images/windows/scripts/build/Configure-User.ps1 +++ b/images/windows/scripts/build/Configure-User.ps1 @@ -27,8 +27,8 @@ if ($LASTEXITCODE -ne 0) { throw "Failed to copy HKCU\Software\Microsoft\VisualStudio to HKLM\DEFAULT\Software\Microsoft\VisualStudio" } -# TortoiseSVN not installed on Windows 2025 image due to Sysprep issues -if (-not (Test-IsWin25)) { +# TortoiseSVN not installed on Windows 2025 and Windows 11 due to Sysprep issues +if (-not (Test-IsWin25) -and -not (Test-IsWin11)) { # disable TSVNCache.exe $registryKeyPath = 'HKCU:\Software\TortoiseSVN' if (-not(Test-Path -Path $registryKeyPath)) { diff --git a/images/windows/scripts/build/Install-CMake.ps1 b/images/windows/scripts/build/Install-CMake.ps1 new file mode 100644 index 0000000000..13acab72ff --- /dev/null +++ b/images/windows/scripts/build/Install-CMake.ps1 @@ -0,0 +1,35 @@ +################################################################################ +## File: Install-CMake.ps1 +## Desc: Install CMake (ARM64 only; x64 is installed via Choco) +## Supply chain security: CMake - checksum validation +################################################################################ + +if (-not (Test-IsArm64)) { + exit 0 +} + +# Install CMake +$downloadUrl = Resolve-GithubReleaseAssetUrl ` + -Repo "Kitware/CMake" ` + -Version "latest" ` + -UrlMatchPattern "cmake-*-windows-arm64.msi" + +#region Supply chain security - CMake +$packageName = Split-Path $downloadUrl -Leaf +$checksumsUrl = Resolve-GithubReleaseAssetUrl ` + -Repo "Kitware/CMake" ` + -Version "latest" ` + -UrlMatchPattern "cmake-*-SHA-256.txt" +$externalHash = Get-ChecksumFromUrl -Type "SHA256" ` + -Url $checksumsUrl ` + -FileName $packageName +#endregion + +Install-Binary ` + -Url $downloadUrl ` + -ExtraInstallArgs @("ADD_CMAKE_TO_PATH=System") ` + -ExpectedSHA256Sum $externalHash + +Update-Environment + +Invoke-PesterTests -TestFile "Tools" -TestName "CMake" diff --git a/images/windows/scripts/build/Install-Chrome.ps1 b/images/windows/scripts/build/Install-Chrome.ps1 index f8c98c3fa1..54f5cdb265 100644 --- a/images/windows/scripts/build/Install-Chrome.ps1 +++ b/images/windows/scripts/build/Install-Chrome.ps1 @@ -3,9 +3,15 @@ ## Desc: Install Google Chrome browser and Chrome WebDriver ################################################################################ +if (Test-IsArm64) { + $browserDownloadUrl = "https://dl.google.com/tag/s/dl/chrome/install/googlechromestandaloneenterprise_arm64.msi" +} else { + $browserDownloadUrl = "https://dl.google.com/tag/s/dl/chrome/install/googlechromestandaloneenterprise64.msi" +} + # Download and install latest Chrome browser Install-Binary ` - -Url 'https://dl.google.com/tag/s/dl/chrome/install/googlechromestandaloneenterprise64.msi' ` + -Url $browserDownloadUrl ` -ExpectedSubject 'CN=Google LLC, O=Google LLC, L=Mountain View, S=California, C=US, SERIALNUMBER=3582691, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, OID.1.3.6.1.4.1.311.60.2.1.3=US' # Prepare firewall rules diff --git a/images/windows/scripts/build/Install-DotnetSDK.ps1 b/images/windows/scripts/build/Install-DotnetSDK.ps1 index 793c6a01c5..a1c3b3489c 100644 --- a/images/windows/scripts/build/Install-DotnetSDK.ps1 +++ b/images/windows/scripts/build/Install-DotnetSDK.ps1 @@ -82,9 +82,14 @@ function Install-DotnetSDK { # If installation failed, tests will fail anyway #region Supply chain security + if (Test-IsArm64) { + $expectedArch = "arm64" + } else { + $expectedArch = "x64" + } $releasesJsonUri = "https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/${DotnetVersion}/releases.json" $releasesData = (Invoke-DownloadWithRetry $releasesJsonUri) | Get-Item | Get-Content | ConvertFrom-Json - $distributorFileHash = $releasesData.releases.sdks.Where({ $_.version -eq $SDKVersion }).files.Where({ $_.name -eq 'dotnet-sdk-win-x64.zip' }).hash + $distributorFileHash = $releasesData.releases.sdks.Where({ $_.version -eq $SDKVersion }).files.Where({ $_.name -eq "dotnet-sdk-win-$expectedArch.zip" }).hash Test-FileChecksum $zipPath -ExpectedSHA512Sum $distributorFileHash #endregion } @@ -97,11 +102,9 @@ $installScriptPath = Invoke-DownloadWithRetry -Url "https://dot.net/v1/dotnet-in # Visual Studio 2022 pre-creates sdk-manifests/8.0.100 folder, causing dotnet-install to skip manifests creation # https://github.com/actions/runner-images/issues/11402 -if ((Test-IsWin22) -or (Test-IsWin25)) { - $sdkManifestPath = "C:\Program Files\dotnet\sdk-manifests\8.0.100" - if (Test-Path $sdkManifestPath) { - Move-Item -Path $sdkManifestPath -Destination $env:TEMP_DIR -ErrorAction Stop - } +$sdkManifestPath = "C:\Program Files\dotnet\sdk-manifests\8.0.100" +if (Test-Path $sdkManifestPath) { + Move-Item -Path $sdkManifestPath -Destination $env:TEMP_DIR -ErrorAction Stop } # Install and warm up dotnet @@ -122,12 +125,10 @@ foreach ($dotnetVersion in $dotnetToolset.versions) { # Replace manifests inside sdk-manifests/8.0.100 folder with ones from Visual Studio # https://github.com/actions/runner-images/issues/11402 -if ((Test-IsWin22) -or (Test-IsWin25)) { - if (Test-Path "${env:TEMP_DIR}\8.0.100") { - Get-ChildItem -Path "${env:TEMP_DIR}\8.0.100" | ForEach-Object { - Remove-Item -Path "$sdkManifestPath\$($_.BaseName)" -Recurse -Force | Out-Null - Move-Item -Path $_.FullName -Destination $sdkManifestPath -Force -ErrorAction Stop - } +if (Test-Path "${env:TEMP_DIR}\8.0.100") { + Get-ChildItem -Path "${env:TEMP_DIR}\8.0.100" | ForEach-Object { + Remove-Item -Path "$sdkManifestPath\$($_.BaseName)" -Recurse -Force | Out-Null + Move-Item -Path $_.FullName -Destination $sdkManifestPath -Force -ErrorAction Stop } } diff --git a/images/windows/scripts/build/Install-EdgeDriver.ps1 b/images/windows/scripts/build/Install-EdgeDriver.ps1 index f410ea688a..895f3fd3d7 100644 --- a/images/windows/scripts/build/Install-EdgeDriver.ps1 +++ b/images/windows/scripts/build/Install-EdgeDriver.ps1 @@ -3,6 +3,12 @@ ## Desc: Install Edge WebDriver and configure Microsoft Edge ################################################################################ +if (Test-IsArm64) { + $expectedArch = "arm64" +} else { + $expectedArch = "win64" +} + # Disable Edge auto-updates Rename-Item -Path "C:\Program Files (x86)\Microsoft\EdgeUpdate\MicrosoftEdgeUpdate.exe" -NewName "Disabled_MicrosoftEdgeUpdate.exe" -ErrorAction Stop @@ -20,7 +26,7 @@ $versionInfoFile = Invoke-DownloadWithRetry -Url $versionInfoUrl -Path "$edgeDri $latestVersion = Get-Content -Path $versionInfoFile Write-Host "Download Microsoft Edge WebDriver..." -$downloadUrl = "https://msedgedriver.microsoft.com/$latestVersion/edgedriver_win64.zip" +$downloadUrl = "https://msedgedriver.microsoft.com/$latestVersion/edgedriver_$expectedArch.zip" $archivePath = Invoke-DownloadWithRetry $downloadUrl Write-Host "Expand Microsoft Edge WebDriver archive..." diff --git a/images/windows/scripts/build/Install-Firefox.ps1 b/images/windows/scripts/build/Install-Firefox.ps1 index 984588a3b9..ff9e952d61 100644 --- a/images/windows/scripts/build/Install-Firefox.ps1 +++ b/images/windows/scripts/build/Install-Firefox.ps1 @@ -4,17 +4,23 @@ ## Supply chain security: Firefox browser - checksum validation ################################################################################ +if (Test-IsArm64) { + $expectedArch = "win64-aarch64" +} else { + $expectedArch = "win64" +} + # Install and configure Firefox browser Write-Host "Get the latest Firefox version..." $versionsManifest = Invoke-RestMethod "https://product-details.mozilla.org/1.0/firefox_versions.json" Write-Host "Install Firefox browser..." -$installerUrl = "https://download.mozilla.org/?product=firefox-$($versionsManifest.LATEST_FIREFOX_VERSION)&os=win64&lang=en-US" +$installerUrl = "https://download.mozilla.org/?product=firefox-$($versionsManifest.LATEST_FIREFOX_VERSION)&os=$expectedArch&lang=en-US" $hashUrl = "https://archive.mozilla.org/pub/firefox/releases/$($versionsManifest.LATEST_FIREFOX_VERSION)/SHA256SUMS" $externalHash = Get-ChecksumFromUrl -Type "SHA256" ` -Url $hashUrl ` - -FileName "win64/en-US/Firefox Setup*exe" + -FileName "$expectedArch/en-US/Firefox Setup*exe" Install-Binary -Type EXE ` -Url $installerUrl ` @@ -46,7 +52,7 @@ Write-Host "Download Gecko WebDriver WebDriver..." $geckoDriverDownloadUrl = Resolve-GithubReleaseAssetUrl ` -Repo "mozilla/geckodriver" ` -Version $geckoDriverVersion ` - -UrlMatchPattern "geckodriver-*-win64.zip" + -UrlMatchPattern "geckodriver-*-$expectedArch.zip" $geckoDriverArchPath = Invoke-DownloadWithRetry $geckoDriverDownloadUrl Write-Host "Expand Gecko WebDriver archive..." diff --git a/images/windows/scripts/build/Install-Git.ps1 b/images/windows/scripts/build/Install-Git.ps1 index 0e6843d79b..4be12ddc37 100644 --- a/images/windows/scripts/build/Install-Git.ps1 +++ b/images/windows/scripts/build/Install-Git.ps1 @@ -4,12 +4,17 @@ ## Supply chain security: Git - checksum validation, Hub CLI - managed by package manager ################################################################################ -# Install the latest version of Git for Windows +if (Test-IsArm64) { + $expectedArch = "arm64" +} else { + $expectedArch = "64-bit" +} +# Install the latest version of Git for Windows $downloadUrl = Resolve-GithubReleaseAssetUrl ` -Repo "git-for-windows/git" ` -Version "latest" ` - -UrlMatchPattern "Git-*-64-bit.exe" + -UrlMatchPattern "Git-*-$expectedArch.exe" $externalHash = Get-ChecksumFromGithubRelease ` -Repo "git-for-windows/git" ` diff --git a/images/windows/scripts/build/Install-GitHub-CLI.ps1 b/images/windows/scripts/build/Install-GitHub-CLI.ps1 index 0d1d80fd58..2df04861b8 100644 --- a/images/windows/scripts/build/Install-GitHub-CLI.ps1 +++ b/images/windows/scripts/build/Install-GitHub-CLI.ps1 @@ -4,12 +4,17 @@ ## Supply chain security: GitHub CLI - checksum validation ################################################################################ -Write-Host "Get the latest gh version..." +if (Test-IsArm64) { + $expectedArch = "arm64" +} else { + $expectedArch = "amd64" +} +Write-Host "Get the latest gh version..." $downloadUrl = Resolve-GithubReleaseAssetUrl ` -Repo "cli/cli" ` -Version "latest" ` - -UrlMatchPattern "gh_*_windows_amd64.msi" + -UrlMatchPattern "gh_*_windows_$expectedArch.msi" $checksumsUrl = Resolve-GithubReleaseAssetUrl ` -Repo "cli/cli" ` diff --git a/images/windows/scripts/build/Install-JavaTools.ps1 b/images/windows/scripts/build/Install-JavaTools.ps1 index 5a29a9a15f..7c272f6f81 100644 --- a/images/windows/scripts/build/Install-JavaTools.ps1 +++ b/images/windows/scripts/build/Install-JavaTools.ps1 @@ -19,8 +19,8 @@ function Set-JavaPath { exit 1 } - Write-Host "Set 'JAVA_HOME_${Version}_X64' environmental variable as $javaPath" - [Environment]::SetEnvironmentVariable("JAVA_HOME_${Version}_X64", $javaPath, "Machine") + Write-Host "Set 'JAVA_HOME_${Version}_$($Architecture.ToUpper())' environmental variable as $javaPath" + [Environment]::SetEnvironmentVariable("JAVA_HOME_${Version}_$($Architecture.ToUpper())", $javaPath, "Machine") if ($Default) { # Clean up any other Java folders from PATH to make sure that they won't conflict with each other @@ -91,6 +91,12 @@ function Install-JavaJDK { New-Item -ItemType File -Path $javaVersionPath -Name "$Architecture.complete" | Out-Null } +if (Test-IsArm64) { + $expectedArch = "aarch64" +} else { + $expectedArch = "x64" +} + $toolsetJava = (Get-ToolsetContent).java $defaultVersion = $toolsetJava.default $jdkVersionsToInstall = $toolsetJava.versions @@ -98,12 +104,12 @@ $jdkVersionsToInstall = $toolsetJava.versions foreach ($jdkVersionToInstall in $jdkVersionsToInstall) { $isDefaultVersion = $jdkVersionToInstall -eq $defaultVersion - Install-JavaJDK -JDKVersion $jdkVersionToInstall + Install-JavaJDK -JDKVersion $jdkVersionToInstall -Architecture $expectedArch if ($isDefaultVersion) { - Set-JavaPath -Version $jdkVersionToInstall -Default + Set-JavaPath -Version $jdkVersionToInstall -Architecture $expectedArch -Default } else { - Set-JavaPath -Version $jdkVersionToInstall + Set-JavaPath -Version $jdkVersionToInstall -Architecture $expectedArch } } diff --git a/images/windows/scripts/build/Install-LLVM.ps1 b/images/windows/scripts/build/Install-LLVM.ps1 index 41b8aef951..08883dc7c2 100644 --- a/images/windows/scripts/build/Install-LLVM.ps1 +++ b/images/windows/scripts/build/Install-LLVM.ps1 @@ -1,10 +1,36 @@ ################################################################################ ## File: Install-LLVM.ps1 -## Desc: Install the latest stable version of llvm and clang compilers +## Desc: Install the stable version of llvm and clang compilers ################################################################################ $llvmVersion = (Get-ToolsetContent).llvm.version -$latestChocoVersion = Resolve-ChocoPackageVersion -PackageName "llvm" -TargetVersion $llvmVersion -Install-ChocoPackage llvm -ArgumentList '--version', $latestChocoVersion + +if (Test-IsArm64) { + $installDir = "C:\Program Files\LLVM" + + Write-Host "Resolve LLVM $llvmVersion ARM64 download URL" + $downloadUrl = Resolve-GithubReleaseAssetUrl ` + -Repository "llvm/llvm-project" ` + -Version $llvmVersion ` + -UrlMatchPattern "clang*llvm-*-aarch64-pc-windows-msvc.tar.xz" + + Write-Host "Download LLVM $llvmVersion ARM64 archive" + $archivePath = Invoke-DownloadWithRetry $downloadUrl + + Write-Host "Extract LLVM archive" + $tarPath = $archivePath -replace '\.xz$' + Expand-7ZipArchive -Path $archivePath -DestinationPath (Split-Path $archivePath) + Expand-7ZipArchive -Path $tarPath -DestinationPath $env:TEMP_DIR + + Write-Host "Install LLVM to $installDir" + $extractedDir = Get-ChildItem -Path $env:TEMP_DIR -Directory -Filter "clang+llvm-*" | Select-Object -First 1 + Move-Item -Path $extractedDir.FullName -Destination $installDir -Force + + Add-MachinePathItem (Join-Path $installDir "bin") + Update-Environment +} else { + $latestChocoVersion = Resolve-ChocoPackageVersion -PackageName "llvm" -TargetVersion $llvmVersion + Install-ChocoPackage llvm -ArgumentList '--version', $latestChocoVersion +} Invoke-PesterTests -TestFile "LLVM" diff --git a/images/windows/scripts/build/Install-NativeImages.ps1 b/images/windows/scripts/build/Install-NativeImages.ps1 index 214a9577a6..71d159e151 100644 --- a/images/windows/scripts/build/Install-NativeImages.ps1 +++ b/images/windows/scripts/build/Install-NativeImages.ps1 @@ -9,14 +9,16 @@ if ($LASTEXITCODE -ne 0) { throw "Installation of Microsoft.PowerShell.Utility.Activities failed with exit code $LASTEXITCODE" } -Write-Host "NGen: update x64 native images..." -& $env:SystemRoot\Microsoft.NET\Framework64\v4.0.30319\ngen.exe update | Out-Null -if ($LASTEXITCODE -ne 0) { - throw "Update of x64 native images failed with exit code $LASTEXITCODE" -} +if (-not (Test-IsWin11)) { + Write-Host "NGen: update x64 native images..." + & $env:SystemRoot\Microsoft.NET\Framework64\v4.0.30319\ngen.exe update | Out-Null + if ($LASTEXITCODE -ne 0) { + throw "Update of x64 native images failed with exit code $LASTEXITCODE" + } -Write-Host "NGen: update x86 native images..." -& $env:SystemRoot\Microsoft.NET\Framework\v4.0.30319\ngen.exe update | Out-Null -if ($LASTEXITCODE -ne 0) { - throw "Update of x86 native images failed with exit code $LASTEXITCODE" + Write-Host "NGen: update x86 native images..." + & $env:SystemRoot\Microsoft.NET\Framework\v4.0.30319\ngen.exe update | Out-Null + if ($LASTEXITCODE -ne 0) { + throw "Update of x86 native images failed with exit code $LASTEXITCODE" + } } diff --git a/images/windows/scripts/build/Install-Ninja.ps1 b/images/windows/scripts/build/Install-Ninja.ps1 new file mode 100644 index 0000000000..21c509caae --- /dev/null +++ b/images/windows/scripts/build/Install-Ninja.ps1 @@ -0,0 +1,28 @@ +################################################################################ +## File: Install-Ninja.ps1 +## Desc: Install Ninja build system (ARM64 only; x64 is installed via Choco) +################################################################################ + +if (-not (Test-IsArm64)) { + exit 0 +} + +$installDir = "C:\Tools\Ninja" + +Write-Host "Resolve Ninja latest ARM64 download URL" +$downloadUrl = Resolve-GithubReleaseAssetUrl ` + -Repository "ninja-build/ninja" ` + -Version "latest" ` + -UrlMatchPattern "ninja-winarm64.zip" + +Write-Host "Download Ninja ARM64 archive" +$zipPath = Invoke-DownloadWithRetry $downloadUrl + +Write-Host "Install Ninja to $installDir" +New-Item -ItemType Directory -Path $installDir -Force | Out-Null +Expand-7ZipArchive -Path $zipPath -DestinationPath $installDir + +Add-MachinePathItem $installDir +Update-Environment + +Invoke-PesterTests -TestFile "Tools" -TestName "Ninja" diff --git a/images/windows/scripts/build/Install-NodeJS.ps1 b/images/windows/scripts/build/Install-NodeJS.ps1 index 1063ba8e9d..d65977a451 100644 --- a/images/windows/scripts/build/Install-NodeJS.ps1 +++ b/images/windows/scripts/build/Install-NodeJS.ps1 @@ -7,12 +7,18 @@ $prefixPath = 'C:\npm\prefix' $cachePath = 'C:\npm\cache' +if (Test-IsArm64) { + $expectedArch = "arm64" +} else { + $expectedArch = "x64" +} + New-Item -Path $prefixPath -Force -ItemType Directory New-Item -Path $cachePath -Force -ItemType Directory $defaultVersion = (Get-ToolsetContent).node.default $nodeVersion = (Get-GithubReleasesByVersion -Repo "nodejs/node" -Version "${defaultVersion}").version | Select-Object -First 1 -$downloadUrl = "https://nodejs.org/dist/v${nodeVersion}/node-v${nodeVersion}-x64.msi" +$downloadUrl = "https://nodejs.org/dist/v${nodeVersion}/node-v${nodeVersion}-${expectedArch}.msi" $packageName = Split-Path $downloadUrl -Leaf $externalHash = Get-ChecksumFromUrl -Type "SHA256" ` diff --git a/images/windows/scripts/build/Install-OpenSSL.ps1 b/images/windows/scripts/build/Install-OpenSSL.ps1 index 3717ddc545..f47103749b 100644 --- a/images/windows/scripts/build/Install-OpenSSL.ps1 +++ b/images/windows/scripts/build/Install-OpenSSL.ps1 @@ -4,7 +4,13 @@ ## Supply chain security: checksum validation ################################################################################ -$arch = 'INTEL' +if (Test-IsArm64) { + $expectedArch = "ARM" +} else { + $expectedArch = "INTEL" +} + +$arch = $expectedArch $bits = '64' $light = $false $installerType = "exe" diff --git a/images/windows/scripts/build/Install-PowershellCore.ps1 b/images/windows/scripts/build/Install-PowershellCore.ps1 index 68a3bc80ab..a479526d1b 100644 --- a/images/windows/scripts/build/Install-PowershellCore.ps1 +++ b/images/windows/scripts/build/Install-PowershellCore.ps1 @@ -6,6 +6,12 @@ $ErrorActionPreference = "Stop" +if (Test-IsArm64) { + $expectedArch = "arm64" +} else { + $expectedArch = "x64" +} + $tempDir = Join-Path ([System.IO.Path]::GetTempPath()) ([System.IO.Path]::GetRandomFileName()) New-Item -ItemType Directory -Path $tempDir -Force -ErrorAction SilentlyContinue | Out-Null try { @@ -18,7 +24,7 @@ try { $releases = $metadata.LTSReleaseTag -replace '^v' foreach ($release in $releases) { if ($release -like "${pwshMajorMinor}*") { - $downloadUrl = "https://github.com/PowerShell/PowerShell/releases/download/v${release}/PowerShell-${release}-win-x64.msi" + $downloadUrl = "https://github.com/PowerShell/PowerShell/releases/download/v${release}/PowerShell-${release}-win-${expectedArch}.msi" break } } diff --git a/images/windows/scripts/build/Install-R.ps1 b/images/windows/scripts/build/Install-R.ps1 index 96743d7256..0abd6e96c6 100644 --- a/images/windows/scripts/build/Install-R.ps1 +++ b/images/windows/scripts/build/Install-R.ps1 @@ -6,6 +6,13 @@ Install-ChocoPackage R.Project Install-ChocoPackage rtools -$rscriptPath = Resolve-Path "C:\Program Files\R\*\bin\x64" +if (Test-IsArm64) { + $rscriptPathPattern = "C:\Program Files (x86)\R\*\bin\x64" +} else { + $rscriptPathPattern = "C:\Program Files\R\*\bin\x64" +} + +$rscriptPath = Resolve-Path $rscriptPathPattern Add-MachinePathItem $rscriptPath + Invoke-PesterTests -TestFile "Tools" -TestName "R" diff --git a/images/windows/scripts/build/Install-Ruby.ps1 b/images/windows/scripts/build/Install-Ruby.ps1 index 01bd525bb1..ad83e884bc 100644 --- a/images/windows/scripts/build/Install-Ruby.ps1 +++ b/images/windows/scripts/build/Install-Ruby.ps1 @@ -63,6 +63,12 @@ function Set-DefaultRubyVersion { Add-MachinePathItem -PathItem $rubyDir | Out-Null } +if (Test-IsArm64) { + $expectedArch = "arm" +} else { + $expectedArch = "x64" +} + # Install Ruby $rubyTools = (Get-ToolsetContent).toolcache | Where-Object { $_.name -eq "Ruby" } $rubyToolVersions = $rubyTools.versions @@ -73,8 +79,14 @@ foreach ($rubyVersion in $rubyToolVersions) { $downloadUrl = Resolve-GithubReleaseAssetUrl ` -Repo "oneclick/rubyinstaller2" ` -Version "$rubyVersion*" ` - -UrlMatchPattern "*-x64.7z" + -UrlMatchPattern "*-${expectedArch}.7z" $packagePath = Invoke-DownloadWithRetry $downloadUrl + + if (Test-IsArm64) { + Install-Ruby -PackagePath $packagePath -Architecture "aarch64" + } else { + Install-Ruby -PackagePath $packagePath -Architecture "x64" + } Install-Ruby -PackagePath $packagePath } diff --git a/images/windows/scripts/build/Install-Rust.ps1 b/images/windows/scripts/build/Install-Rust.ps1 index cf35a74102..adcce9008b 100644 --- a/images/windows/scripts/build/Install-Rust.ps1 +++ b/images/windows/scripts/build/Install-Rust.ps1 @@ -4,16 +4,22 @@ ## Supply chain security: checksum validation for bootstrap, managed by rustup for workloads ################################################################################ +if (Test-IsArm64) { + $expectedArch = "aarch64" +} else { + $expectedArch = "x86_64" +} + # Rust Env $env:RUSTUP_HOME = "C:\Users\Default\.rustup" $env:CARGO_HOME = "C:\Users\Default\.cargo" -# Download the latest rustup-init.exe for Windows x64 +# Download the latest rustup-init.exe for Windows # See https://rustup.rs/# -$rustupPath = Invoke-DownloadWithRetry "https://static.rust-lang.org/rustup/dist/x86_64-pc-windows-msvc/rustup-init.exe" +$rustupPath = Invoke-DownloadWithRetry "https://static.rust-lang.org/rustup/dist/${expectedArch}-pc-windows-msvc/rustup-init.exe" #region Supply chain security -$distributorFileHash = (Invoke-RestMethod -Uri 'https://static.rust-lang.org/rustup/dist/x86_64-pc-windows-msvc/rustup-init.exe.sha256').Trim() +$distributorFileHash = (Invoke-RestMethod -Uri "https://static.rust-lang.org/rustup/dist/${expectedArch}-pc-windows-msvc/rustup-init.exe.sha256").Trim() Test-FileChecksum $rustupPath -ExpectedSHA256Sum $distributorFileHash #endregion @@ -28,11 +34,15 @@ Add-DefaultPathItem "%USERPROFILE%\.cargo\bin" # Add Rust binaries to the path $env:Path += ";$env:CARGO_HOME\bin" -# Add i686 target for building 32-bit binaries -rustup target add i686-pc-windows-msvc +if (Test-IsArm64) { + rustup target add aarch64-pc-windows-msvc +} else { + # Add i686 target for building 32-bit binaries + rustup target add i686-pc-windows-msvc -# Add target for building mingw-w64 binaries -rustup target add x86_64-pc-windows-gnu + # Add target for building mingw-w64 binaries + rustup target add x86_64-pc-windows-gnu +} # Install common tools rustup component add rustfmt clippy diff --git a/images/windows/scripts/build/Install-VisualStudio.ps1 b/images/windows/scripts/build/Install-VisualStudio.ps1 index e866ffeb65..492c000956 100644 --- a/images/windows/scripts/build/Install-VisualStudio.ps1 +++ b/images/windows/scripts/build/Install-VisualStudio.ps1 @@ -4,6 +4,12 @@ ################################################################################ $vsToolset = (Get-ToolsetContent).visualStudio +if (Test-IsArm64) { + $expectedArch = "arm64" +} else { + $expectedArch = "x64" +} + # Install Visual Studio for Windows 22 and 25 with InstallChannel Install-VisualStudio ` -Version $vsToolset.subversion ` @@ -11,7 +17,8 @@ Install-VisualStudio ` -Channel $vsToolset.channel ` -InstallChannelUri $vsToolset.installChannelUri ` -RequiredComponents $vsToolset.workloads ` - -ExtraArgs "--allWorkloads --includeRecommended --remove Component.CPython3.x64" + -ExtraArgs "--allWorkloads --includeRecommended --remove Component.CPython3.x64" ` + -Architecture $expectedArch # Find the version of VS installed for this instance # Only supports a single instance diff --git a/images/windows/scripts/build/Install-WDK.ps1 b/images/windows/scripts/build/Install-WDK.ps1 index 1cac470cf7..14a978e0ef 100644 --- a/images/windows/scripts/build/Install-WDK.ps1 +++ b/images/windows/scripts/build/Install-WDK.ps1 @@ -7,6 +7,9 @@ if (Test-IsWin22) { # SDK is available through Visual Studio $wdkUrl = "https://go.microsoft.com/fwlink/?linkid=2324617" +} elseif (Test-IsWin11) { + # SDK is available through Visual Studio + $wdkUrl = "https://go.microsoft.com/fwlink/?linkid=2335869" } else { throw "Invalid version of Visual Studio is found. Windows Server 2022 is required" } diff --git a/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 b/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 index 40fe4b1ca0..2073e24de1 100644 --- a/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 +++ b/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 @@ -44,7 +44,9 @@ $packageManagement = $installedSoftware.AddHeader("Package Management") $packageManagement.AddToolVersion("Chocolatey", $(Get-ChocoVersion)) $packageManagement.AddToolVersion("Composer", $(Get-ComposerVersion)) $packageManagement.AddToolVersion("Helm", $(Get-HelmVersion)) -$packageManagement.AddToolVersion("Miniconda", $(Get-CondaVersion)) +if (-not (Test-IsWin11)) { + $packageManagement.AddToolVersion("Miniconda", $(Get-CondaVersion)) +} $packageManagement.AddToolVersion("NPM", $(Get-NPMVersion)) $packageManagement.AddToolVersion("NuGet", $(Get-NugetVersion)) $packageManagement.AddToolVersion("pip", $(Get-PipVersion)) @@ -70,13 +72,17 @@ $tools.AddToolVersion("azcopy", $(Get-AzCopyVersion)) $tools.AddToolVersion("Bazel", $(Get-BazelVersion)) $tools.AddToolVersion("Bazelisk", $(Get-BazeliskVersion)) $tools.AddToolVersion("Bicep", $(Get-BicepVersion)) -$tools.AddToolVersion("Cabal", $(Get-CabalVersion)) +if (-not (Test-IsWin11)) { + $tools.AddToolVersion("Cabal", $(Get-CabalVersion)) +} $tools.AddToolVersion("CMake", $(Get-CMakeVersion)) $tools.AddToolVersion("CodeQL Action Bundle", $(Get-CodeQLBundleVersion)) -$tools.AddToolVersion("Docker", $(Get-DockerVersion)) -$tools.AddToolVersion("Docker Compose v2", $(Get-DockerComposeVersionV2)) -$tools.AddToolVersion("Docker-wincred", $(Get-DockerWincredVersion)) -$tools.AddToolVersion("ghc", $(Get-GHCVersion)) +if (-not (Test-IsWin11)) { + $tools.AddToolVersion("Docker", $(Get-DockerVersion)) + $tools.AddToolVersion("Docker Compose v2", $(Get-DockerComposeVersionV2)) + $tools.AddToolVersion("Docker-wincred", $(Get-DockerWincredVersion)) + $tools.AddToolVersion("ghc", $(Get-GHCVersion)) +} $tools.AddToolVersion("Git", $(Get-GitVersion)) $tools.AddToolVersion("Git LFS", $(Get-GitLFSVersion)) $tools.AddToolVersion("ImageMagick", $(Get-ImageMagickVersion)) @@ -98,17 +104,23 @@ $tools.AddToolVersion("OpenSSL", $(Get-OpenSSLVersion)) $tools.AddToolVersion("Packer", $(Get-PackerVersion)) $tools.AddToolVersion("Pulumi", $(Get-PulumiVersion)) $tools.AddToolVersion("R", $(Get-RVersion)) -$tools.AddToolVersion("Service Fabric SDK", $(Get-ServiceFabricSDKVersion)) +if (-not (Test-IsWin11)) { + $tools.AddToolVersion("Service Fabric SDK", $(Get-ServiceFabricSDKVersion)) +} $tools.AddToolVersion("Stack", $(Get-StackVersion)) -if (-not (Test-IsWin25)) { +if (-not (Test-IsWin25) -and -not (Test-IsWin11)) { $tools.AddToolVersion("Subversion (SVN)", $(Get-SVNVersion)) } $tools.AddToolVersion("Swig", $(Get-SwigVersion)) $tools.AddToolVersion("VSWhere", $(Get-VSWhereVersion)) $tools.AddToolVersion("WinAppDriver", $(Get-WinAppDriver)) -$tools.AddToolVersion("WiX Toolset", $(Get-WixVersion)) +if (-not (Test-IsWin11)) { + $tools.AddToolVersion("WiX Toolset", $(Get-WixVersion)) +} $tools.AddToolVersion("yamllint", $(Get-YAMLLintVersion)) -$tools.AddToolVersion("zstd", $(Get-ZstdVersion)) +if (-not (Test-IsWin11)) { + $tools.AddToolVersion("zstd", $(Get-ZstdVersion)) +} $tools.AddToolVersion("Ninja", $(Get-NinjaVersion)) # CLI Tools @@ -150,26 +162,32 @@ $browsersAndWebdrivers.AddHeader("Environment variables").AddTable($(Build-Brows $installedSoftware.AddHeader("Java").AddTable($(Get-JavaVersions)) # Shells -$installedSoftware.AddHeader("Shells").AddTable($(Get-ShellTarget)) +if (-not (Test-IsWin11)) { + $installedSoftware.AddHeader("Shells").AddTable($(Get-ShellTarget)) +} # MSYS2 -$msys2 = $installedSoftware.AddHeader("MSYS2") -$msys2.AddToolVersion("Pacman", $(Get-PacmanVersion)) +if (-not (Test-IsWin11)) { + $msys2 = $installedSoftware.AddHeader("MSYS2") + $msys2.AddToolVersion("Pacman", $(Get-PacmanVersion)) -$notes = @' + $notes = @' Location: C:\msys64 Note: MSYS2 is pre-installed on image but not added to PATH. '@ -$msys2.AddHeader("Notes").AddNote($notes) + $msys2.AddHeader("Notes").AddNote($notes) +} # Cached Tools $installedSoftware.AddHeader("Cached Tools").AddNodes($(Build-CachedToolsSection)) # Databases -$databases = $installedSoftware.AddHeader("Databases") -$databases.AddHeader("PostgreSQL").AddTable($(Get-PostgreSQLTable)) -$databases.AddHeader("MongoDB").AddTable($(Get-MongoDBTable)) +if (-not (Test-IsWin11)) { + $databases = $installedSoftware.AddHeader("Databases") + $databases.AddHeader("PostgreSQL").AddTable($(Get-PostgreSQLTable)) + $databases.AddHeader("MongoDB").AddTable($(Get-MongoDBTable)) +} # Database tools $databaseTools = $installedSoftware.AddHeader("Database tools") @@ -178,9 +196,10 @@ $databaseTools.AddToolVersion("DacFx", $(Get-DacFxVersion)) $databaseTools.AddToolVersion("MySQL", $(Get-MySQLVersion)) $databaseTools.AddToolVersion("SQL OLEDB Driver 18", $(Get-SQLOLEDBDriver18Version)) $databaseTools.AddToolVersion("SQL OLEDB Driver 19", $(Get-SQLOLEDBDriver19Version)) -$databaseTools.AddToolVersion("SQLPS", $(Get-SQLPSVersion)) -$databaseTools.AddToolVersion("MongoDB Shell (mongosh)", $(Get-MongoshVersion)) - +if (-not (Test-IsWin11)) { + $databaseTools.AddToolVersion("SQLPS", $(Get-SQLPSVersion)) + $databaseTools.AddToolVersion("MongoDB Shell (mongosh)", $(Get-MongoshVersion)) +} # Web Servers $installedSoftware.AddHeader("Web Servers").AddTable($(Build-WebServersSection)) @@ -216,13 +235,15 @@ $psModules.AddNodes($(Get-PowerShellModules)) # Android -$android = $installedSoftware.AddHeader("Android") -$android.AddTable($(Build-AndroidTable)) +if (-not (Test-IsWin11)) { + $android = $installedSoftware.AddHeader("Android") + $android.AddTable($(Build-AndroidTable)) -$android.AddHeader("Environment variables").AddTable($(Build-AndroidEnvironmentTable)) + $android.AddHeader("Environment variables").AddTable($(Build-AndroidEnvironmentTable)) +} # Cached Docker images -if (-not (Test-IsWin25)) { +if (-not (Test-IsWin25) -and -not (Test-IsWin11)) { $installedSoftware.AddHeader("Cached Docker images").AddTable($(Get-CachedDockerImagesTableData)) } diff --git a/images/windows/scripts/docs-gen/SoftwareReport.CachedTools.psm1 b/images/windows/scripts/docs-gen/SoftwareReport.CachedTools.psm1 index a62ed45257..7ecf866822 100644 --- a/images/windows/scripts/docs-gen/SoftwareReport.CachedTools.psm1 +++ b/images/windows/scripts/docs-gen/SoftwareReport.CachedTools.psm1 @@ -34,7 +34,7 @@ function Build-CachedToolsSection [ToolVersionsListNode]::new("Go", $(Get-ToolcacheGoVersions), '^\d+\.\d+', 'List'), [ToolVersionsListNode]::new("Node.js", $(Get-ToolcacheNodeVersions), '^\d+', 'List'), [ToolVersionsListNode]::new("Python", $(Get-ToolcachePythonVersions), '^\d+\.\d+', 'List'), - [ToolVersionsListNode]::new("PyPy", $(Get-ToolcachePyPyVersions), '^\d+\.\d+', 'List'), + $(if (-not (Test-IsWin11)) { [ToolVersionsListNode]::new("PyPy", $(Get-ToolcachePyPyVersions), '^\d+\.\d+', 'List') }), [ToolVersionsListNode]::new("Ruby", $(Get-ToolcacheRubyVersions), '^\d+\.\d+', 'List') ) } diff --git a/images/windows/scripts/docs-gen/SoftwareReport.Java.psm1 b/images/windows/scripts/docs-gen/SoftwareReport.Java.psm1 index cd6c077d3e..2249451744 100644 --- a/images/windows/scripts/docs-gen/SoftwareReport.Java.psm1 +++ b/images/windows/scripts/docs-gen/SoftwareReport.Java.psm1 @@ -1,6 +1,10 @@ function Get-JavaVersions { $defaultJavaPath = $env:JAVA_HOME - $javaVersions = Get-Item env:JAVA_HOME_*_X64 + if (Test-IsArm64) { + $javaVersions = Get-Item env:JAVA_HOME_*_AARCH64 + } else { + $javaVersions = Get-Item env:JAVA_HOME_*_X64 + } $sortRules = @{ Expression = { [Int32] $_.Name.Split("_")[2] } Descending = $false diff --git a/images/windows/scripts/helpers/ImageHelpers.psm1 b/images/windows/scripts/helpers/ImageHelpers.psm1 index 8915ef9367..07e4b022d4 100644 --- a/images/windows/scripts/helpers/ImageHelpers.psm1 +++ b/images/windows/scripts/helpers/ImageHelpers.psm1 @@ -26,6 +26,7 @@ Export-ModuleMember -Function @( 'Test-IsWin25' 'Test-IsWin22' 'Test-IsWin11' + 'Test-IsArm64' 'Expand-7ZipArchive' 'Get-WindowsUpdateStates' 'Invoke-ScriptBlockWithRetry' diff --git a/images/windows/scripts/helpers/InstallHelpers.ps1 b/images/windows/scripts/helpers/InstallHelpers.ps1 index 06b57609c0..83abfbd0b0 100644 --- a/images/windows/scripts/helpers/InstallHelpers.ps1 +++ b/images/windows/scripts/helpers/InstallHelpers.ps1 @@ -322,6 +322,22 @@ function Get-TCToolVersionPath { return Join-Path $foundVersion $Arch } +function Test-IsArm64 { + <# + .SYNOPSIS + Checks if the current Windows operating system is running on an ARM64 architecture. + .DESCRIPTION + This function uses the Get-CimInstance cmdlet to retrieve information + about the current Windows operating system. It then checks if the OSArchitecture + property of the Win32_OperatingSystem class contains the string "ARM 64-bit", + indicating that the operating system is running on an ARM64 processor. + .OUTPUTS + Returns $true if the current Windows operating system is running on ARM64. + Otherwise, returns $false. + #> + (Get-CimInstance -ClassName Win32_OperatingSystem).OSArchitecture -match "ARM 64-bit" +} + function Test-IsWin25 { <# .SYNOPSIS diff --git a/images/windows/scripts/helpers/VisualStudioHelpers.ps1 b/images/windows/scripts/helpers/VisualStudioHelpers.ps1 index db02591a71..fd9eff81bd 100644 --- a/images/windows/scripts/helpers/VisualStudioHelpers.ps1 +++ b/images/windows/scripts/helpers/VisualStudioHelpers.ps1 @@ -32,7 +32,8 @@ Function Install-VisualStudio { [Parameter(Mandatory)] [String] $Channel, [String] $InstallChannelUri = "", [Parameter(Mandatory)] [String[]] $RequiredComponents, - [String] $ExtraArgs = "" + [String] $ExtraArgs = "", + [String] $Architecture = "x64" ) if ($env:INSTALL_VS_2026) { @@ -61,7 +62,7 @@ Function Install-VisualStudio { "channelUri" = $channelUri "channelId" = $channelId "productId" = $productId - "arch" = "x64" + "arch" = $Architecture "add" = $RequiredComponents | ForEach-Object { "$_;includeRecommended" } } diff --git a/images/windows/scripts/tests/Android.Tests.ps1 b/images/windows/scripts/tests/Android.Tests.ps1 index c53f99b3e3..1a092ac2a0 100644 --- a/images/windows/scripts/tests/Android.Tests.ps1 +++ b/images/windows/scripts/tests/Android.Tests.ps1 @@ -1,4 +1,4 @@ -Describe "Android SDK" { +Describe "Android SDK" -Skip:(Test-IsWin11) { $androidToolset = (Get-ToolsetContent).android $androidInstalledPackages = Get-AndroidInstalledPackages diff --git a/images/windows/scripts/tests/ChocoPackages.Tests.ps1 b/images/windows/scripts/tests/ChocoPackages.Tests.ps1 index 1f283ca804..b088a0a822 100644 --- a/images/windows/scripts/tests/ChocoPackages.Tests.ps1 +++ b/images/windows/scripts/tests/ChocoPackages.Tests.ps1 @@ -58,7 +58,7 @@ Describe "Pulumi" { } } -Describe "Svn" -Skip:(Test-IsWin25) { +Describe "Svn" -Skip:((Test-IsWin25) -or (Test-IsWin11)) { It "svn" { "svn --version --quiet" | Should -ReturnZeroExitCode } @@ -86,7 +86,7 @@ Describe "Julia" { } } -Describe "CMake" { +Describe "CMake" -Skip:(Test-IsArm64) { It "cmake" { "cmake --version" | Should -ReturnZeroExitCode } @@ -98,7 +98,7 @@ Describe "ImageMagick" { } } -Describe "Ninja" { +Describe "Ninja" -Skip:(Test-IsArm64) { BeforeAll { $ninjaProjectPath = $(Join-Path $env:TEMP_DIR "ninjaproject") New-item -Path $ninjaProjectPath -ItemType Directory -Force diff --git a/images/windows/scripts/tests/Databases.Tests.ps1 b/images/windows/scripts/tests/Databases.Tests.ps1 index 03d8921084..aa58e7c5e3 100644 --- a/images/windows/scripts/tests/Databases.Tests.ps1 +++ b/images/windows/scripts/tests/Databases.Tests.ps1 @@ -1,4 +1,4 @@ -Describe "MongoDB" { +Describe "MongoDB" -Skip:(Test-IsWin11) { Context "Version" { It "" -TestCases @( @{ ToolName = "mongos" } @@ -33,7 +33,7 @@ Describe "MongoDB" { } } -Describe "PostgreSQL" { +Describe "PostgreSQL" -Skip:(Test-IsWin11) { $psqlTests = @( @{envVar = "PGROOT"; pgPath = Get-EnvironmentVariable "PGROOT" } @{envVar = "PGBIN"; pgPath = Get-EnvironmentVariable "PGBIN" } diff --git a/images/windows/scripts/tests/Docker.Tests.ps1 b/images/windows/scripts/tests/Docker.Tests.ps1 index b994430e3f..cf2a6acaa4 100644 --- a/images/windows/scripts/tests/Docker.Tests.ps1 +++ b/images/windows/scripts/tests/Docker.Tests.ps1 @@ -1,4 +1,4 @@ -Describe "Docker" { +Describe "Docker" -Skip:(Test-IsWin11) { It "docker is installed" { "docker --version" | Should -ReturnZeroExitCode } @@ -12,20 +12,20 @@ Describe "Docker" { } } -Describe "DockerCompose" { +Describe "DockerCompose" -Skip:(Test-IsWin11) { It "docker compose v2" { "docker compose version" | Should -ReturnZeroExitCode } } -Describe "DockerWinCred" { +Describe "DockerWinCred" -Skip:(Test-IsWin11) { It "docker-wincred" { "docker-credential-wincred version" | Should -ReturnZeroExitCode } } -Describe "DockerImages" -Skip:(Test-IsWin25) { +Describe "DockerImages" -Skip:((Test-IsWin25) -or (Test-IsWin11)) { Context "docker images" { $testCases = (Get-ToolsetContent).docker.images | ForEach-Object { @{ ImageName = $_ } } diff --git a/images/windows/scripts/tests/Haskell.Tests.ps1 b/images/windows/scripts/tests/Haskell.Tests.ps1 index 866ef5dca6..b89e4654c4 100644 --- a/images/windows/scripts/tests/Haskell.Tests.ps1 +++ b/images/windows/scripts/tests/Haskell.Tests.ps1 @@ -1,4 +1,4 @@ -Describe "Haskell" { +Describe "Haskell" -Skip:(Test-IsWin11) { $ghcPackagesPath = "c:\ghcup\ghc" [array] $ghcVersionList = Get-ChildItem -Path $ghcPackagesPath -Filter "*" | ForEach-Object { $_.Name.Trim() } $ghcCount = $ghcVersionList.Count diff --git a/images/windows/scripts/tests/Java.Tests.ps1 b/images/windows/scripts/tests/Java.Tests.ps1 index bf40a8d430..b8194967fa 100644 --- a/images/windows/scripts/tests/Java.Tests.ps1 +++ b/images/windows/scripts/tests/Java.Tests.ps1 @@ -5,9 +5,17 @@ Describe "Java" { [array] $testCases = $jdkVersions | ForEach-Object { @{Version = $_ } } + BeforeAll { + if (Test-IsArm64) { + $expectedArch = "AARCH64" + } else { + $expectedArch = "X64" + } + } + It "Java is default" -TestCases @(@{ DefaultJavaVersion = $defaultVersion }) { $actualJavaPath = Get-EnvironmentVariable "JAVA_HOME" - $expectedJavaPath = Get-EnvironmentVariable "JAVA_HOME_${DefaultJavaVersion}_X64" + $expectedJavaPath = Get-EnvironmentVariable "JAVA_HOME_${DefaultJavaVersion}_${expectedArch}" $actualJavaPath | Should -Not -BeNullOrEmpty $expectedJavaPath | Should -Not -BeNullOrEmpty @@ -24,7 +32,7 @@ Describe "Java" { } It "Java " -TestCases $testCases { - $javaVariableValue = Get-EnvironmentVariable "JAVA_HOME_${Version}_X64" + $javaVariableValue = Get-EnvironmentVariable "JAVA_HOME_${Version}_${expectedArch}" $javaVariableValue | Should -Not -BeNullOrEmpty $javaPath = Join-Path $javaVariableValue "bin\java" diff --git a/images/windows/scripts/tests/MSYS2.Tests.ps1 b/images/windows/scripts/tests/MSYS2.Tests.ps1 index c92e7a8da5..760b5c8674 100644 --- a/images/windows/scripts/tests/MSYS2.Tests.ps1 +++ b/images/windows/scripts/tests/MSYS2.Tests.ps1 @@ -3,7 +3,7 @@ BeforeAll { $originalPath = $env:PATH } -Describe "MSYS2 packages" { +Describe "MSYS2 packages" -Skip:(Test-IsWin11) { BeforeEach { $env:PATH = "$msys2Dir;$env:PATH" } @@ -31,7 +31,7 @@ Describe "MSYS2 packages" { $mingwTypes = (Get-ToolsetContent).MsysPackages.mingw foreach ($mingwType in $mingwTypes) { - Describe "$($mingwType.arch) packages" { + Describe "$($mingwType.arch) packages" -Skip:(Test-IsWin11) { $tools = $mingwType.runtime_packages $execDir = Join-Path "C:\msys64" $mingwType.exec_dir | Join-Path -ChildPath "bin" diff --git a/images/windows/scripts/tests/Miniconda.Tests.ps1 b/images/windows/scripts/tests/Miniconda.Tests.ps1 index 763a158e23..3284204d31 100644 --- a/images/windows/scripts/tests/Miniconda.Tests.ps1 +++ b/images/windows/scripts/tests/Miniconda.Tests.ps1 @@ -1,4 +1,4 @@ -Describe "Miniconda" { +Describe "Miniconda" -Skip:(Test-IsWin11) { It "Miniconda Environment variables is set. " { ${env:CONDA} | Should -Not -BeNullOrEmpty } @@ -11,4 +11,4 @@ Describe "Miniconda" { $condaPath | Should -Exist "$condaPath --version" | Should -ReturnZeroExitCode } -} \ No newline at end of file +} diff --git a/images/windows/scripts/tests/Shell.Tests.ps1 b/images/windows/scripts/tests/Shell.Tests.ps1 index caddaf7fb7..10d40aa559 100644 --- a/images/windows/scripts/tests/Shell.Tests.ps1 +++ b/images/windows/scripts/tests/Shell.Tests.ps1 @@ -1,7 +1,7 @@ Describe "Shell" { $shellTestCases = @( @{Name = "C:\shells\gitbash.exe"; Target = "$env:ProgramFiles\Git\bin\bash.exe"}, - @{Name = "C:\shells\msys2bash.cmd"; Target = $null} + $(if (-not (Test-IsWin11)) { @{Name = "C:\shells\msys2bash.cmd"; Target = $null} }), @{Name = "C:\shells\wslbash.exe"; Target = "$env:SystemRoot\System32\bash.exe"} ) diff --git a/images/windows/scripts/tests/Tools.Tests.ps1 b/images/windows/scripts/tests/Tools.Tests.ps1 index 3c6301613a..d5dd358fde 100644 --- a/images/windows/scripts/tests/Tools.Tests.ps1 +++ b/images/windows/scripts/tests/Tools.Tests.ps1 @@ -118,7 +118,7 @@ Describe "Sbt" { } } -Describe "ServiceFabricSDK" { +Describe "ServiceFabricSDK" -Skip:(Test-IsWin11) { It "PowerShell Module" { # Ignore PowerShell version check if running in PowerShell Core # https://github.com/microsoft/service-fabric/issues/1343 @@ -160,7 +160,7 @@ Describe "WebPlatformInstaller" { } } -Describe "Zstd" { +Describe "Zstd" -Skip:(Test-IsWin11) { It "zstd" { "zstd -V" | Should -ReturnZeroExitCode } @@ -213,3 +213,37 @@ Describe "OpenSSL" { Get-ChildItem -Path "$env:SystemRoot\System32" -Filter "libssl-*.dll" -File -ErrorAction SilentlyContinue | Should -BeNullOrEmpty } } + +Describe "CMake" { + It "cmake" { + "cmake --version" | Should -ReturnZeroExitCode + } +} + +Describe "Ninja" { + BeforeAll { + $ninjaProjectPath = $(Join-Path $env:TEMP_DIR "ninjaproject") + New-item -Path $ninjaProjectPath -ItemType Directory -Force +@' +cmake_minimum_required(VERSION 3.10) +project(NinjaTest NONE) +'@ | Out-File -FilePath "$ninjaProjectPath/CMakeLists.txt" -Encoding utf8 + + $ninjaProjectBuildPath = $(Join-Path $ninjaProjectPath "build") + New-item -Path $ninjaProjectBuildPath -ItemType Directory -Force + Set-Location $ninjaProjectBuildPath + } + + It "Make a simple ninja project" { + "cmake -GNinja $ninjaProjectPath" | Should -ReturnZeroExitCode + } + + It "build.ninja file should exist" { + $buildFilePath = $(Join-Path $ninjaProjectBuildPath "build.ninja") + $buildFilePath | Should -Exist + } + + It "Ninja" { + "ninja --version" | Should -ReturnZeroExitCode + } +} diff --git a/images/windows/scripts/tests/Toolset.Tests.ps1 b/images/windows/scripts/tests/Toolset.Tests.ps1 index 83d4b9a40f..7dd0b7020e 100644 --- a/images/windows/scripts/tests/Toolset.Tests.ps1 +++ b/images/windows/scripts/tests/Toolset.Tests.ps1 @@ -19,6 +19,10 @@ $toolsExecutables = @{ ) } +if (Test-IsWin11) { + $toolsExecutables.Remove("PyPy") +} + function Get-ToolExecutables { Param ([String] $Name) if ($toolsExecutables.ContainsKey($Name)) { $toolsExecutables[$Name] } else { @() } diff --git a/images/windows/scripts/tests/VisualStudio.Tests.ps1 b/images/windows/scripts/tests/VisualStudio.Tests.ps1 index bc26c77236..c2bf867ae8 100644 --- a/images/windows/scripts/tests/VisualStudio.Tests.ps1 +++ b/images/windows/scripts/tests/VisualStudio.Tests.ps1 @@ -25,7 +25,7 @@ Describe "Visual Studio" { } } -Describe "Windows 10 SDK" -Skip:(Test-IsWin25) { +Describe "Windows 10 SDK" -Skip:((Test-IsWin25) -or (Test-IsWin11)) { It "Verifies 17763 SDK is installed" { "${env:ProgramFiles(x86)}\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\10.0.17763.0\UAP.props" | Should -Exist } diff --git a/images/windows/scripts/tests/Wix.Tests.ps1 b/images/windows/scripts/tests/Wix.Tests.ps1 index cf6fc2fdf1..5f1ff0314e 100644 --- a/images/windows/scripts/tests/Wix.Tests.ps1 +++ b/images/windows/scripts/tests/Wix.Tests.ps1 @@ -1,4 +1,4 @@ -Describe "Wix" { +Describe "Wix" -Skip:(Test-IsWin11) { BeforeAll { $regKey = "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" $installedApplications = Get-ItemProperty -Path $regKey diff --git a/images/windows/templates/build.windows-11-arm64.pkr.hcl b/images/windows/templates/build.windows-11-arm64.pkr.hcl index b37c591b4b..fb9c5b7df8 100644 --- a/images/windows/templates/build.windows-11-arm64.pkr.hcl +++ b/images/windows/templates/build.windows-11-arm64.pkr.hcl @@ -84,6 +84,8 @@ build { inline = ["Set-Service -Name wlansvc -StartupType Manual", "if ($(Get-Service -Name wlansvc).Status -eq 'Running') { Stop-Service -Name wlansvc}"] } + # TODO: + # 1. Double check if Install-Runner.ps1 is needed, should be taken care of during specialization. Left out for now provisioner "powershell" { environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] scripts = [ @@ -116,8 +118,8 @@ build { } # TODO: - # 1. Add ${path.root}/../scripts/build/Install-CMake.ps1 - # 2. Add ${path.root}/../scripts/build/Install-Ninja.ps1 + # 1. Add ${path.root}/../scripts/build/Install-CMake.ps1 - Done, instead of Choco package, updated to latest + # 2. Add ${path.root}/../scripts/build/Install-Ninja.ps1 - Done, instead of Choco package, updated to latest # 3. Check if need to move ${path.root}/../scripts/build/Install-LLVM.ps1 into this block provisioner "powershell" { pause_before = "2m0s" @@ -129,6 +131,8 @@ build { "${path.root}/../scripts/build/Install-AzureCli.ps1", "${path.root}/../scripts/build/Install-AzureDevOpsCli.ps1", "${path.root}/../scripts/build/Install-ChocolateyPackages.ps1", + "${path.root}/../scripts/build/Install-CMake.ps1", + "${path.root}/../scripts/build/Install-Ninja.ps1", "${path.root}/../scripts/build/Install-JavaTools.ps1", "${path.root}/../scripts/build/Install-Kotlin.ps1", "${path.root}/../scripts/build/Install-OpenSSL.ps1" @@ -146,9 +150,9 @@ build { } # TODO: - # 1. Add ${path.root}/../scripts/build/Install-Mercurial.ps1 - # 2. Add ${path.root}/../scripts/build/Install-NSIS.ps1 - # 3. Add ${path.root}/../scripts/build/Install-AliyunCli.ps1 + # 1. Add ${path.root}/../scripts/build/Install-Mercurial.ps1 - Done + # 2. Add ${path.root}/../scripts/build/Install-NSIS.ps1 - Done + # 3. Add ${path.root}/../scripts/build/Install-AliyunCli.ps1 - Done provisioner "powershell" { environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] scripts = [ @@ -187,9 +191,12 @@ build { "${path.root}/../scripts/build/Install-Stack.ps1", # "${path.root}/../scripts/build/Install-Miniconda.ps1", "${path.root}/../scripts/build/Install-AzureCosmosDbEmulator.ps1", + "${path.root}/../scripts/build/Install-Mercurial.ps1", + "${path.root}/../scripts/build/Install-NSIS.ps1", # "${path.root}/../scripts/build/Install-Zstd.ps1", "${path.root}/../scripts/build/Install-Vcpkg.ps1", "${path.root}/../scripts/build/Install-Bazel.ps1", + "${path.root}/../scripts/build/Install-AliyunCli.ps1", "${path.root}/../scripts/build/Install-RootCA.ps1", # "${path.root}/../scripts/build/Install-MongoDB.ps1", "${path.root}/../scripts/build/Install-CodeQLBundle.ps1", @@ -242,7 +249,7 @@ build { } provisioner "file" { - destination = "${path.root}/../Windows11-arm-Readme.md" + destination = "${path.root}/../Windows11-Arm64-Readme.md" direction = "download" source = "C:\\software-report.md" } diff --git a/images/windows/toolsets/toolset-win-11-arm64.json b/images/windows/toolsets/toolset-win-11-arm64.json index 0aa1f7e7d5..0a8421cb47 100644 --- a/images/windows/toolsets/toolset-win-11-arm64.json +++ b/images/windows/toolsets/toolset-win-11-arm64.json @@ -129,7 +129,7 @@ "subversion" : "17", "edition" : "Enterprise", "channel": "release", - "installChannel": "", + "installChannelUri": "", "workloads": [ "Component.Dotfuscator", "Component.Linux.CMake", From 20afed4b79c3b0ab0ca07867688e7940779178cc Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Wed, 18 Mar 2026 19:57:28 +0100 Subject: [PATCH 04/55] Fix source_image_marketplace_sku --- images/windows/templates/locals.windows.pkr.hcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images/windows/templates/locals.windows.pkr.hcl b/images/windows/templates/locals.windows.pkr.hcl index 9fb08913d9..9a671dc5dd 100644 --- a/images/windows/templates/locals.windows.pkr.hcl +++ b/images/windows/templates/locals.windows.pkr.hcl @@ -13,7 +13,7 @@ locals { os_disk_size_gb = 150 } "win11-arm64" = { - source_image_marketplace_sku = "windows11preview-arm64:microsoftwindowsdesktop:win11-25h2-ent:latest" + source_image_marketplace_sku = "microsoftwindowsdesktop:windows11preview-arm64:win11-25h2-ent" os_disk_size_gb = 256 } } From d9157b491d6e682c38d27224427ff995fe273341 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Thu, 19 Mar 2026 13:00:51 +0100 Subject: [PATCH 05/55] DEBUG: elevated packer, add SeBatchLogonRight --- .../templates/build.windows-11-arm64.pkr.hcl | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/images/windows/templates/build.windows-11-arm64.pkr.hcl b/images/windows/templates/build.windows-11-arm64.pkr.hcl index fb9c5b7df8..7d10cead26 100644 --- a/images/windows/templates/build.windows-11-arm64.pkr.hcl +++ b/images/windows/templates/build.windows-11-arm64.pkr.hcl @@ -51,6 +51,24 @@ build { inline = ["if (-not ((net localgroup Administrators) -contains '${var.install_user}')) { exit 1 }"] } + provisioner "powershell" { + inline = [<<-EOF + $sidStr = (New-Object Security.Principal.NTAccount("${var.install_user}")).Translate([Security.Principal.SecurityIdentifier]).Value + $tmpFile = [IO.Path]::GetTempFileName() + secedit /export /cfg $tmpFile /areas USER_RIGHTS /quiet + $policy = Get-Content $tmpFile -Raw + if ($policy -match 'SeBatchLogonRight\s*=\s*(.*)') { + $policy = $policy -replace 'SeBatchLogonRight\s*=\s*(.*)', "SeBatchLogonRight = `$1,*$sidStr" + } else { + $policy += "`r`nSeBatchLogonRight = *$sidStr" + } + Set-Content $tmpFile $policy + secedit /configure /db "$env:TEMP\secedit.sdb" /cfg $tmpFile /areas USER_RIGHTS /quiet + Remove-Item $tmpFile + EOF + ] + } + provisioner "powershell" { elevated_password = "${var.install_password}" elevated_user = "${var.install_user}" From c0d2ad3f81942dcc24880c65d90a4665f0af966d Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Thu, 19 Mar 2026 16:38:11 +0100 Subject: [PATCH 06/55] DEBUG:V2 elevated packer, add SeBatchLogonRight --- .../templates/build.windows-11-arm64.pkr.hcl | 60 +++++++++++++++---- 1 file changed, 49 insertions(+), 11 deletions(-) diff --git a/images/windows/templates/build.windows-11-arm64.pkr.hcl b/images/windows/templates/build.windows-11-arm64.pkr.hcl index 7d10cead26..eabf8735cd 100644 --- a/images/windows/templates/build.windows-11-arm64.pkr.hcl +++ b/images/windows/templates/build.windows-11-arm64.pkr.hcl @@ -51,20 +51,58 @@ build { inline = ["if (-not ((net localgroup Administrators) -contains '${var.install_user}')) { exit 1 }"] } + # v1 + # provisioner "powershell" { + # inline = [<<-EOF + # $sidStr = (New-Object Security.Principal.NTAccount("${var.install_user}")).Translate([Security.Principal.SecurityIdentifier]).Value + # $tmpFile = [IO.Path]::GetTempFileName() + # secedit /export /cfg $tmpFile /areas USER_RIGHTS /quiet + # $policy = Get-Content $tmpFile -Raw + # if ($policy -match 'SeBatchLogonRight\s*=\s*(.*)') { + # $policy = $policy -replace 'SeBatchLogonRight\s*=\s*(.*)', "SeBatchLogonRight = `$1,*$sidStr" + # } else { + # $policy += "`r`nSeBatchLogonRight = *$sidStr" + # } + # Set-Content $tmpFile $policy + # secedit /configure /db "$env:TEMP\secedit.sdb" /cfg $tmpFile /areas USER_RIGHTS /quiet + # Remove-Item $tmpFile + # EOF + # ] + # } + + # v2 provisioner "powershell" { inline = [<<-EOF - $sidStr = (New-Object Security.Principal.NTAccount("${var.install_user}")).Translate([Security.Principal.SecurityIdentifier]).Value - $tmpFile = [IO.Path]::GetTempFileName() - secedit /export /cfg $tmpFile /areas USER_RIGHTS /quiet - $policy = Get-Content $tmpFile -Raw - if ($policy -match 'SeBatchLogonRight\s*=\s*(.*)') { - $policy = $policy -replace 'SeBatchLogonRight\s*=\s*(.*)', "SeBatchLogonRight = `$1,*$sidStr" - } else { - $policy += "`r`nSeBatchLogonRight = *$sidStr" + $code = @' + using System; + using System.Runtime.InteropServices; + public class LsaUtil { + [DllImport("advapi32.dll", SetLastError=true)] + static extern uint LsaOpenPolicy(IntPtr SystemName, ref LSA_OBJECT_ATTRIBUTES ObjectAttributes, uint AccessMask, out IntPtr PolicyHandle); + [DllImport("advapi32.dll", SetLastError=true)] + static extern uint LsaAddAccountRights(IntPtr PolicyHandle, IntPtr AccountSid, LSA_UNICODE_STRING[] UserRights, long CountOfRights); + [DllImport("advapi32.dll")] + static extern uint LsaClose(IntPtr ObjectHandle); + [StructLayout(LayoutKind.Sequential)] public struct LSA_OBJECT_ATTRIBUTES { public int Length; public IntPtr RootDirectory; public IntPtr ObjectName; public uint Attributes; public IntPtr SecurityDescriptor; public IntPtr SecurityQualityOfService; } + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct LSA_UNICODE_STRING { public ushort Length; public ushort MaximumLength; [MarshalAs(UnmanagedType.LPWStr)] public string Buffer; } + public static void AddRight(string accountName, string rightName) { + var attrs = new LSA_OBJECT_ATTRIBUTES(); + IntPtr policy; + LsaOpenPolicy(IntPtr.Zero, ref attrs, 0x00020000 | 0x00000800, out policy); + var sid = new System.Security.Principal.NTAccount(accountName).Translate(typeof(System.Security.Principal.SecurityIdentifier)); + var sidBytes = new byte[((System.Security.Principal.SecurityIdentifier)sid).BinaryLength]; + ((System.Security.Principal.SecurityIdentifier)sid).GetBinaryForm(sidBytes, 0); + var sidPtr = Marshal.AllocHGlobal(sidBytes.Length); + Marshal.Copy(sidBytes, 0, sidPtr, sidBytes.Length); + var rights = new[] { new LSA_UNICODE_STRING { Buffer = rightName, Length = (ushort)(rightName.Length * 2), MaximumLength = (ushort)(rightName.Length * 2 + 2) } }; + LsaAddAccountRights(policy, sidPtr, rights, 1); + Marshal.FreeHGlobal(sidPtr); + LsaClose(policy); + } } - Set-Content $tmpFile $policy - secedit /configure /db "$env:TEMP\secedit.sdb" /cfg $tmpFile /areas USER_RIGHTS /quiet - Remove-Item $tmpFile + '@ + Add-Type $code + [LsaUtil]::AddRight("${var.install_user}", "SeBatchLogonRight") EOF ] } From 12bdc44d56f50b26a46fb9d39bc3ce8bf946167f Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Fri, 20 Mar 2026 09:34:19 +0100 Subject: [PATCH 07/55] DEBUG:V3 elevated packer, test auto logon --- .../templates/build.windows-11-arm64.pkr.hcl | 82 +++++++++++-------- 1 file changed, 50 insertions(+), 32 deletions(-) diff --git a/images/windows/templates/build.windows-11-arm64.pkr.hcl b/images/windows/templates/build.windows-11-arm64.pkr.hcl index eabf8735cd..47e3c716e5 100644 --- a/images/windows/templates/build.windows-11-arm64.pkr.hcl +++ b/images/windows/templates/build.windows-11-arm64.pkr.hcl @@ -71,39 +71,48 @@ build { # } # v2 + # provisioner "powershell" { + # inline = [<<-EOF + # $code = @' + # using System; + # using System.Runtime.InteropServices; + # public class LsaUtil { + # [DllImport("advapi32.dll", SetLastError=true)] + # static extern uint LsaOpenPolicy(IntPtr SystemName, ref LSA_OBJECT_ATTRIBUTES ObjectAttributes, uint AccessMask, out IntPtr PolicyHandle); + # [DllImport("advapi32.dll", SetLastError=true)] + # static extern uint LsaAddAccountRights(IntPtr PolicyHandle, IntPtr AccountSid, LSA_UNICODE_STRING[] UserRights, long CountOfRights); + # [DllImport("advapi32.dll")] + # static extern uint LsaClose(IntPtr ObjectHandle); + # [StructLayout(LayoutKind.Sequential)] public struct LSA_OBJECT_ATTRIBUTES { public int Length; public IntPtr RootDirectory; public IntPtr ObjectName; public uint Attributes; public IntPtr SecurityDescriptor; public IntPtr SecurityQualityOfService; } + # [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct LSA_UNICODE_STRING { public ushort Length; public ushort MaximumLength; [MarshalAs(UnmanagedType.LPWStr)] public string Buffer; } + # public static void AddRight(string accountName, string rightName) { + # var attrs = new LSA_OBJECT_ATTRIBUTES(); + # IntPtr policy; + # LsaOpenPolicy(IntPtr.Zero, ref attrs, 0x00020000 | 0x00000800, out policy); + # var sid = new System.Security.Principal.NTAccount(accountName).Translate(typeof(System.Security.Principal.SecurityIdentifier)); + # var sidBytes = new byte[((System.Security.Principal.SecurityIdentifier)sid).BinaryLength]; + # ((System.Security.Principal.SecurityIdentifier)sid).GetBinaryForm(sidBytes, 0); + # var sidPtr = Marshal.AllocHGlobal(sidBytes.Length); + # Marshal.Copy(sidBytes, 0, sidPtr, sidBytes.Length); + # var rights = new[] { new LSA_UNICODE_STRING { Buffer = rightName, Length = (ushort)(rightName.Length * 2), MaximumLength = (ushort)(rightName.Length * 2 + 2) } }; + # LsaAddAccountRights(policy, sidPtr, rights, 1); + # Marshal.FreeHGlobal(sidPtr); + # LsaClose(policy); + # } + # } + # '@ + # Add-Type $code + # [LsaUtil]::AddRight("${var.install_user}", "SeBatchLogonRight") + # EOF + # ] + # } + + # v3 - set and remove after all elevated tasks are done, might need additional reboot provisioner "powershell" { - inline = [<<-EOF - $code = @' - using System; - using System.Runtime.InteropServices; - public class LsaUtil { - [DllImport("advapi32.dll", SetLastError=true)] - static extern uint LsaOpenPolicy(IntPtr SystemName, ref LSA_OBJECT_ATTRIBUTES ObjectAttributes, uint AccessMask, out IntPtr PolicyHandle); - [DllImport("advapi32.dll", SetLastError=true)] - static extern uint LsaAddAccountRights(IntPtr PolicyHandle, IntPtr AccountSid, LSA_UNICODE_STRING[] UserRights, long CountOfRights); - [DllImport("advapi32.dll")] - static extern uint LsaClose(IntPtr ObjectHandle); - [StructLayout(LayoutKind.Sequential)] public struct LSA_OBJECT_ATTRIBUTES { public int Length; public IntPtr RootDirectory; public IntPtr ObjectName; public uint Attributes; public IntPtr SecurityDescriptor; public IntPtr SecurityQualityOfService; } - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct LSA_UNICODE_STRING { public ushort Length; public ushort MaximumLength; [MarshalAs(UnmanagedType.LPWStr)] public string Buffer; } - public static void AddRight(string accountName, string rightName) { - var attrs = new LSA_OBJECT_ATTRIBUTES(); - IntPtr policy; - LsaOpenPolicy(IntPtr.Zero, ref attrs, 0x00020000 | 0x00000800, out policy); - var sid = new System.Security.Principal.NTAccount(accountName).Translate(typeof(System.Security.Principal.SecurityIdentifier)); - var sidBytes = new byte[((System.Security.Principal.SecurityIdentifier)sid).BinaryLength]; - ((System.Security.Principal.SecurityIdentifier)sid).GetBinaryForm(sidBytes, 0); - var sidPtr = Marshal.AllocHGlobal(sidBytes.Length); - Marshal.Copy(sidBytes, 0, sidPtr, sidBytes.Length); - var rights = new[] { new LSA_UNICODE_STRING { Buffer = rightName, Length = (ushort)(rightName.Length * 2), MaximumLength = (ushort)(rightName.Length * 2 + 2) } }; - LsaAddAccountRights(policy, sidPtr, rights, 1); - Marshal.FreeHGlobal(sidPtr); - LsaClose(policy); - } - } - '@ - Add-Type $code - [LsaUtil]::AddRight("${var.install_user}", "SeBatchLogonRight") - EOF + inline = [ + "Set-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name AutoAdminLogon -Value 1 -type String", + "Set-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name DefaultUsername -Value \"${var.install_user}\" -type String", + "Set-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name DefaultPassword -Value \"${var.install_password}\" -type String", ] } @@ -275,6 +284,15 @@ build { ] } + # v3 + provisioner "powershell" { + inline = [ + "Remove-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name AutoAdminLogon", + "Remove-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name DefaultUsername", + "Remove-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name DefaultPassword", + ] + } + provisioner "windows-restart" { check_registry = true restart_check_command = "powershell -command \"& {if ((-not (Get-Process TiWorker.exe -ErrorAction SilentlyContinue)) -and (-not [System.Environment]::HasShutdownStarted) ) { Write-Output 'Restart complete' }}\"" From 614b8c5522bce432612d1f7ddfce277119abd0fc Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Fri, 20 Mar 2026 09:48:50 +0100 Subject: [PATCH 08/55] DEBUG:V3 elevated packer, test auto logon with reboot --- .../windows/templates/build.windows-11-arm64.pkr.hcl | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/images/windows/templates/build.windows-11-arm64.pkr.hcl b/images/windows/templates/build.windows-11-arm64.pkr.hcl index 47e3c716e5..d17c439ee0 100644 --- a/images/windows/templates/build.windows-11-arm64.pkr.hcl +++ b/images/windows/templates/build.windows-11-arm64.pkr.hcl @@ -51,7 +51,7 @@ build { inline = ["if (-not ((net localgroup Administrators) -contains '${var.install_user}')) { exit 1 }"] } - # v1 + # v1 - elevated user issue # provisioner "powershell" { # inline = [<<-EOF # $sidStr = (New-Object Security.Principal.NTAccount("${var.install_user}")).Translate([Security.Principal.SecurityIdentifier]).Value @@ -70,7 +70,7 @@ build { # ] # } - # v2 + # v2 - elevated user issue # provisioner "powershell" { # inline = [<<-EOF # $code = @' @@ -116,6 +116,12 @@ build { ] } + # v3 - elevated user issue + provisioner "windows-restart" { + check_registry = true + restart_timeout = "10m" + } + provisioner "powershell" { elevated_password = "${var.install_password}" elevated_user = "${var.install_user}" @@ -284,7 +290,7 @@ build { ] } - # v3 + # v3 - elevated user issue provisioner "powershell" { inline = [ "Remove-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name AutoAdminLogon", From a0d26c52b42b946d19692c8c724b3051e0f79670 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Fri, 20 Mar 2026 12:12:27 +0100 Subject: [PATCH 09/55] Remove Install-ServiceFabricSDK.ps1 --- images/windows/templates/build.windows-11-arm64.pkr.hcl | 6 ------ 1 file changed, 6 deletions(-) diff --git a/images/windows/templates/build.windows-11-arm64.pkr.hcl b/images/windows/templates/build.windows-11-arm64.pkr.hcl index d17c439ee0..d4617c276d 100644 --- a/images/windows/templates/build.windows-11-arm64.pkr.hcl +++ b/images/windows/templates/build.windows-11-arm64.pkr.hcl @@ -210,12 +210,6 @@ build { ] } - provisioner "powershell" { - execution_policy = "remotesigned" - environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] - scripts = ["${path.root}/../scripts/build/Install-ServiceFabricSDK.ps1"] - } - provisioner "windows-restart" { restart_timeout = "10m" } From 1d8b7e6a14f1758d83135a462d1275e0421d7543 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Fri, 20 Mar 2026 17:36:59 +0100 Subject: [PATCH 10/55] Fix Install-Rust.ps1 --- images/windows/scripts/build/Install-Rust.ps1 | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/images/windows/scripts/build/Install-Rust.ps1 b/images/windows/scripts/build/Install-Rust.ps1 index adcce9008b..f622edda55 100644 --- a/images/windows/scripts/build/Install-Rust.ps1 +++ b/images/windows/scripts/build/Install-Rust.ps1 @@ -49,7 +49,8 @@ rustup component add rustfmt clippy if ($LASTEXITCODE -ne 0) { throw "Rust component installation failed with exit code $LASTEXITCODE" } -if (-not (Test-IsWin25)) { + +if (Test-IsWin22) { cargo install --locked bindgen-cli cbindgen cargo-audit cargo-outdated if ($LASTEXITCODE -ne 0) { throw "Rust tools installation failed with exit code $LASTEXITCODE" @@ -58,4 +59,13 @@ if (-not (Test-IsWin25)) { Remove-Item "${env:CARGO_HOME}\registry\*" -Recurse -Force } +if (Test-IsWin11) { + cargo install bindgen-cli cbindgen cargo-audit cargo-outdated + if ($LASTEXITCODE -ne 0) { + throw "Rust tools installation failed with exit code $LASTEXITCODE" + } + # Cleanup Cargo crates cache + Remove-Item "${env:CARGO_HOME}\registry\*" -Recurse -Force +} + Invoke-PesterTests -TestFile "Rust" From 23dd906c9dc7f00be96801074ff0b3fd5e2942c3 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Sat, 21 Mar 2026 11:53:57 +0100 Subject: [PATCH 11/55] TEMP: remove cargo-audit --- images/windows/scripts/build/Install-Rust.ps1 | 3 ++- images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 | 5 ++++- images/windows/scripts/tests/Rust.Tests.ps1 | 3 ++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/images/windows/scripts/build/Install-Rust.ps1 b/images/windows/scripts/build/Install-Rust.ps1 index f622edda55..88e4a8dab1 100644 --- a/images/windows/scripts/build/Install-Rust.ps1 +++ b/images/windows/scripts/build/Install-Rust.ps1 @@ -60,7 +60,8 @@ if (Test-IsWin22) { } if (Test-IsWin11) { - cargo install bindgen-cli cbindgen cargo-audit cargo-outdated + # TODO: test cargo-audit and bring back + cargo install bindgen-cli cbindgen cargo-outdated if ($LASTEXITCODE -ne 0) { throw "Rust tools installation failed with exit code $LASTEXITCODE" } diff --git a/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 b/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 index 2073e24de1..e98c75704a 100644 --- a/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 +++ b/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 @@ -146,7 +146,10 @@ $rustTools.AddToolVersion("Rustup", $(Get-RustupVersion)) $rustToolsPackages = $rustTools.AddHeader("Packages") if (-not (Test-IsWin25)) { $rustToolsPackages.AddToolVersion("bindgen", $(Get-BindgenVersion)) - $rustToolsPackages.AddToolVersion("cargo-audit", $(Get-CargoAuditVersion)) + # TODO: test cargo-audit and bring back + if (-not (Test-IsWin11)) { + $rustToolsPackages.AddToolVersion("cargo-audit", $(Get-CargoAuditVersion)) + } $rustToolsPackages.AddToolVersion("cargo-outdated", $(Get-CargoOutdatedVersion)) $rustToolsPackages.AddToolVersion("cbindgen", $(Get-CbindgenVersion)) } diff --git a/images/windows/scripts/tests/Rust.Tests.ps1 b/images/windows/scripts/tests/Rust.Tests.ps1 index 717e80e428..8058792662 100644 --- a/images/windows/scripts/tests/Rust.Tests.ps1 +++ b/images/windows/scripts/tests/Rust.Tests.ps1 @@ -12,13 +12,14 @@ Describe "Rust" { @{ToolName = "cargo"; binPath = "C:\Users\Default\.cargo\bin\cargo.exe"} ) } else { + # TODO: test cargo-audit and bring back $rustTools = @( @{ToolName = "rustup"; binPath = "C:\Users\Default\.cargo\bin\rustup.exe"} @{ToolName = "rustc"; binPath = "C:\Users\Default\.cargo\bin\rustc.exe"} @{ToolName = "bindgen.exe"; binPath = "C:\Users\Default\.cargo\bin\bindgen.exe"} @{ToolName = "cbindgen.exe"; binPath = "C:\Users\Default\.cargo\bin\cbindgen.exe"} @{ToolName = "cargo"; binPath = "C:\Users\Default\.cargo\bin\cargo.exe"} - @{ToolName = "cargo audit"; binPath = "C:\Users\Default\.cargo\bin\cargo-audit.exe"} + $(if (-not (Test-IsWin11)) { @{ToolName = "cargo audit"; binPath = "C:\Users\Default\.cargo\bin\cargo-audit.exe"} }) @{ToolName = "cargo outdated"; binPath = "C:\Users\Default\.cargo\bin\cargo-outdated.exe"} ) } From ca62df3e4211485ddb5d287ce7e70870e55f14ad Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Sat, 21 Mar 2026 17:53:10 +0100 Subject: [PATCH 12/55] Fix Install-Firefox.ps1 asset names --- images/windows/scripts/build/Install-Firefox.ps1 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/images/windows/scripts/build/Install-Firefox.ps1 b/images/windows/scripts/build/Install-Firefox.ps1 index ff9e952d61..5306e4ae65 100644 --- a/images/windows/scripts/build/Install-Firefox.ps1 +++ b/images/windows/scripts/build/Install-Firefox.ps1 @@ -6,8 +6,10 @@ if (Test-IsArm64) { $expectedArch = "win64-aarch64" + $driverSufix = "win-aarch64" } else { $expectedArch = "win64" + $driverSufix = "win64" } # Install and configure Firefox browser @@ -52,7 +54,7 @@ Write-Host "Download Gecko WebDriver WebDriver..." $geckoDriverDownloadUrl = Resolve-GithubReleaseAssetUrl ` -Repo "mozilla/geckodriver" ` -Version $geckoDriverVersion ` - -UrlMatchPattern "geckodriver-*-$expectedArch.zip" + -UrlMatchPattern "geckodriver-*-$driverSufix.zip" $geckoDriverArchPath = Invoke-DownloadWithRetry $geckoDriverDownloadUrl Write-Host "Expand Gecko WebDriver archive..." From b809ada69f89119077ba60fdc91fb1a97d4d7925 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Sun, 22 Mar 2026 10:08:00 +0100 Subject: [PATCH 13/55] Patch web browser scripts --- images/windows/scripts/build/Install-Apache.ps1 | 10 ++++++++-- images/windows/scripts/build/Install-Nginx.ps1 | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/images/windows/scripts/build/Install-Apache.ps1 b/images/windows/scripts/build/Install-Apache.ps1 index d5e85a6bc2..f36caeaf20 100644 --- a/images/windows/scripts/build/Install-Apache.ps1 +++ b/images/windows/scripts/build/Install-Apache.ps1 @@ -4,7 +4,10 @@ ################################################################################ # Stop w3svc service -Stop-Service -Name w3svc +$w3svcService = Get-Service -Name "w3svc" -ErrorAction SilentlyContinue +if ($w3svcService) { + Stop-Service $w3svcService +} # Install latest apache in chocolatey $installDir = "C:\tools" @@ -15,7 +18,10 @@ Stop-Service -Name Apache Set-Service -Name Apache -StartupType Disabled # Start w3svc service -Start-Service -Name w3svc +$w3svcService = Get-Service -Name "w3svc" -ErrorAction SilentlyContinue +if ($w3svcService) { + Start-Service $w3svcService +} # Invoke Pester Tests Invoke-PesterTests -TestFile "Apache" diff --git a/images/windows/scripts/build/Install-Nginx.ps1 b/images/windows/scripts/build/Install-Nginx.ps1 index 4b6f1bd503..4b790f8a86 100644 --- a/images/windows/scripts/build/Install-Nginx.ps1 +++ b/images/windows/scripts/build/Install-Nginx.ps1 @@ -4,7 +4,10 @@ ################################################################################ # Stop w3svc service -Stop-Service -Name w3svc +$w3svcService = Get-Service -Name "w3svc" -ErrorAction SilentlyContinue +if ($w3svcService) { + Stop-Service $w3svcService +} # Install latest nginx in chocolatey $installDir = "C:\tools" @@ -15,7 +18,10 @@ Stop-Service -Name nginx Set-Service -Name nginx -StartupType Disabled # Start w3svc service -Start-Service -Name w3svc +$w3svcService = Get-Service -Name "w3svc" -ErrorAction SilentlyContinue +if ($w3svcService) { + Start-Service $w3svcService +} # Invoke Pester Tests Invoke-PesterTests -TestFile "Nginx" From 5acc332d0a1a4be18285b6301ac48749ca409b28 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Sun, 22 Mar 2026 18:06:53 +0100 Subject: [PATCH 14/55] Fix pester tests --- .../windows/scripts/tests/Haskell.Tests.ps1 | 51 +++++++++---------- images/windows/scripts/tests/Shell.Tests.ps1 | 2 +- .../scripts/tests/WindowsFeatures.Tests.ps1 | 2 +- 3 files changed, 25 insertions(+), 30 deletions(-) diff --git a/images/windows/scripts/tests/Haskell.Tests.ps1 b/images/windows/scripts/tests/Haskell.Tests.ps1 index b89e4654c4..2791868422 100644 --- a/images/windows/scripts/tests/Haskell.Tests.ps1 +++ b/images/windows/scripts/tests/Haskell.Tests.ps1 @@ -1,33 +1,28 @@ Describe "Haskell" -Skip:(Test-IsWin11) { - $ghcPackagesPath = "c:\ghcup\ghc" - [array] $ghcVersionList = Get-ChildItem -Path $ghcPackagesPath -Filter "*" | ForEach-Object { $_.Name.Trim() } - $ghcCount = $ghcVersionList.Count - $defaultGhcVersion = $ghcVersionList | Sort-Object {[Version] $_} | Select-Object -Last 1 - $ghcDefaultCases = @{ - defaultGhcVersion = $defaultGhcVersion - defaultGhcShortVersion = ([version] $defaultGhcVersion).ToString(3) - } - - $ghcTestCases = $ghcVersionList | ForEach-Object { - $ghcVersion = $_ - $ghcShortVersion = ([version] $ghcVersion).ToString(3) - $binGhcPath = Join-Path $ghcPackagesPath "$ghcShortVersion\bin\ghc.exe" - @{ - ghcVersion = $ghcVersion - ghcShortVersion = $ghcShortVersion - binGhcPath = $binGhcPath + BeforeDiscovery { + $ghcPackagesPath = "c:\ghcup\ghc" + [array] $ghcVersionList = Get-ChildItem -Path $ghcPackagesPath -Filter "*" | ForEach-Object { $_.Name.Trim() } + $ghcCount = $ghcVersionList.Count + $defaultGhcVersion = $ghcVersionList | Sort-Object { [Version] $_ } | Select-Object -Last 1 + $ghcDefaultCases = @{ + defaultGhcVersion = $defaultGhcVersion + defaultGhcShortVersion = ([version] $defaultGhcVersion).ToString(3) } - } - - $ghcupEnvExists = @( - @{envVar = "GHCUP_INSTALL_BASE_PREFIX"} - @{envVar = "GHCUP_MSYS2"} - ) - - If (Test-IsWin25) { - $numberOfVersions = 1 - } else { - $numberOfVersions = 3 + $ghcTestCases = $ghcVersionList | ForEach-Object { + $ghcVersion = $_ + $ghcShortVersion = ([version] $ghcVersion).ToString(3) + $binGhcPath = Join-Path $ghcPackagesPath "$ghcShortVersion\bin\ghc.exe" + @{ + ghcVersion = $ghcVersion + ghcShortVersion = $ghcShortVersion + binGhcPath = $binGhcPath + } + } + $ghcupEnvExists = @( + @{envVar = "GHCUP_INSTALL_BASE_PREFIX"} + @{envVar = "GHCUP_MSYS2"} + ) + $numberOfVersions = if (Test-IsWin25) { 1 } else { 3 } } It " environment variable exists" -TestCases $ghcupEnvExists { diff --git a/images/windows/scripts/tests/Shell.Tests.ps1 b/images/windows/scripts/tests/Shell.Tests.ps1 index 10d40aa559..50e94b8e11 100644 --- a/images/windows/scripts/tests/Shell.Tests.ps1 +++ b/images/windows/scripts/tests/Shell.Tests.ps1 @@ -3,7 +3,7 @@ Describe "Shell" { @{Name = "C:\shells\gitbash.exe"; Target = "$env:ProgramFiles\Git\bin\bash.exe"}, $(if (-not (Test-IsWin11)) { @{Name = "C:\shells\msys2bash.cmd"; Target = $null} }), @{Name = "C:\shells\wslbash.exe"; Target = "$env:SystemRoot\System32\bash.exe"} - ) + ) | Where-Object { $_ } It " target to " -TestCases $shellTestCases { (Get-Item $Name).Target | Should -BeExactly $Target diff --git a/images/windows/scripts/tests/WindowsFeatures.Tests.ps1 b/images/windows/scripts/tests/WindowsFeatures.Tests.ps1 index ec8001b81a..22c2a5aff5 100644 --- a/images/windows/scripts/tests/WindowsFeatures.Tests.ps1 +++ b/images/windows/scripts/tests/WindowsFeatures.Tests.ps1 @@ -84,7 +84,7 @@ Describe "Windows Updates" { } } -Describe "WSL2" -Skip:(Test-IsWin22) { +Describe "WSL2" -Skip:((Test-IsWin22) -or (Test-IsWin11)) { It "WSL status should return zero exit code" { "wsl --status" | Should -ReturnZeroExitCode } From c7fea09c387a3523434326071998a5ff5c31d072 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Sun, 22 Mar 2026 23:47:14 +0100 Subject: [PATCH 15/55] Fix Install-Ruby.ps1 --- images/windows/scripts/build/Install-Ruby.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/images/windows/scripts/build/Install-Ruby.ps1 b/images/windows/scripts/build/Install-Ruby.ps1 index ad83e884bc..421e8bc233 100644 --- a/images/windows/scripts/build/Install-Ruby.ps1 +++ b/images/windows/scripts/build/Install-Ruby.ps1 @@ -87,7 +87,6 @@ foreach ($rubyVersion in $rubyToolVersions) { } else { Install-Ruby -PackagePath $packagePath -Architecture "x64" } - Install-Ruby -PackagePath $packagePath } Set-DefaultRubyVersion -Version $rubyTools.default -Arch $rubyTools.arch From 45f33fac15fee0218a58aa150a76761587a12eb9 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Sun, 22 Mar 2026 23:56:13 +0100 Subject: [PATCH 16/55] Fix Haskell.Tests.ps1 --- images/windows/scripts/tests/Haskell.Tests.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/images/windows/scripts/tests/Haskell.Tests.ps1 b/images/windows/scripts/tests/Haskell.Tests.ps1 index 2791868422..bf04f654f2 100644 --- a/images/windows/scripts/tests/Haskell.Tests.ps1 +++ b/images/windows/scripts/tests/Haskell.Tests.ps1 @@ -1,5 +1,6 @@ Describe "Haskell" -Skip:(Test-IsWin11) { BeforeDiscovery { + if (Test-IsWin11) { return } $ghcPackagesPath = "c:\ghcup\ghc" [array] $ghcVersionList = Get-ChildItem -Path $ghcPackagesPath -Filter "*" | ForEach-Object { $_.Name.Trim() } $ghcCount = $ghcVersionList.Count From 4407a2e8235821293132c3062a85715e0685a01a Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Mon, 23 Mar 2026 12:59:25 +0100 Subject: [PATCH 17/55] DEBUG: output windows updates state --- .../templates/build.windows-11-arm64.pkr.hcl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/images/windows/templates/build.windows-11-arm64.pkr.hcl b/images/windows/templates/build.windows-11-arm64.pkr.hcl index d4617c276d..311c1f8438 100644 --- a/images/windows/templates/build.windows-11-arm64.pkr.hcl +++ b/images/windows/templates/build.windows-11-arm64.pkr.hcl @@ -299,6 +299,22 @@ build { restart_timeout = "30m" } + # TODO: removes once debugging is done + provisioner "powershell" { + inline = [<<-EOF + $filter = @{ + LogName = "System" + Id = 19, 20, 43 + ProviderName = "Microsoft-Windows-WindowsUpdateClient" + } + $events = Get-WinEvent -FilterHashtable $filter -ErrorAction SilentlyContinue | Sort-Object Id + $events | sort TimeCreated | fl * + Write-Host "display appxpackages" + Get-AppxPackage + EOF + ] + } + provisioner "powershell" { pause_before = "2m0s" environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] From c94f45ae98ced21cee754e3273ec2743f4d56afe Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Mon, 23 Mar 2026 19:16:40 +0100 Subject: [PATCH 18/55] Skip MicrosoftWindows.Client.WebExperience update fails --- images/windows/scripts/tests/WindowsFeatures.Tests.ps1 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/images/windows/scripts/tests/WindowsFeatures.Tests.ps1 b/images/windows/scripts/tests/WindowsFeatures.Tests.ps1 index 22c2a5aff5..68ed297ee8 100644 --- a/images/windows/scripts/tests/WindowsFeatures.Tests.ps1 +++ b/images/windows/scripts/tests/WindowsFeatures.Tests.ps1 @@ -79,6 +79,9 @@ Describe "Windows Updates" { if ( $Title -match "Microsoft Defender Antivirus" ) { $expect = "Installed", "Failed", "Running" } + if ( $Title -match "MicrosoftWindows.Client.WebExperience" ) { + $expect = "Installed", "Failed", "Running" + } $State | Should -BeIn $expect } From 29ae1b47d34a14ab5c37a1890601e054fc015171 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Tue, 24 Mar 2026 13:43:55 +0100 Subject: [PATCH 19/55] Fix Build-PackageManagementEnvironmentTable --- images/windows/scripts/docs-gen/SoftwareReport.Common.psm1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/images/windows/scripts/docs-gen/SoftwareReport.Common.psm1 b/images/windows/scripts/docs-gen/SoftwareReport.Common.psm1 index 58d3a96db4..ebb83c8edf 100644 --- a/images/windows/scripts/docs-gen/SoftwareReport.Common.psm1 +++ b/images/windows/scripts/docs-gen/SoftwareReport.Common.psm1 @@ -297,9 +297,9 @@ function Build-PackageManagementEnvironmentTable { "Name" = "VCPKG_INSTALLATION_ROOT" "Value" = $env:VCPKG_INSTALLATION_ROOT }, - [PSCustomObject] @{ + $(if (-not (Test-IsWin11)) { [PSCustomObject] @{ "Name" = "CONDA" "Value" = $env:CONDA - } - ) + } }) + ) | Where-Object { $_ } } From 52a499fe9032a74eb891a7845507a3bdd7de3da6 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Tue, 24 Mar 2026 13:47:00 +0100 Subject: [PATCH 20/55] Revert "TEMP: remove cargo-audit" This reverts commit 23dd906c9dc7f00be96801074ff0b3fd5e2942c3. --- images/windows/scripts/build/Install-Rust.ps1 | 3 +-- images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 | 5 +---- images/windows/scripts/tests/Rust.Tests.ps1 | 3 +-- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/images/windows/scripts/build/Install-Rust.ps1 b/images/windows/scripts/build/Install-Rust.ps1 index 88e4a8dab1..f622edda55 100644 --- a/images/windows/scripts/build/Install-Rust.ps1 +++ b/images/windows/scripts/build/Install-Rust.ps1 @@ -60,8 +60,7 @@ if (Test-IsWin22) { } if (Test-IsWin11) { - # TODO: test cargo-audit and bring back - cargo install bindgen-cli cbindgen cargo-outdated + cargo install bindgen-cli cbindgen cargo-audit cargo-outdated if ($LASTEXITCODE -ne 0) { throw "Rust tools installation failed with exit code $LASTEXITCODE" } diff --git a/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 b/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 index e98c75704a..2073e24de1 100644 --- a/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 +++ b/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 @@ -146,10 +146,7 @@ $rustTools.AddToolVersion("Rustup", $(Get-RustupVersion)) $rustToolsPackages = $rustTools.AddHeader("Packages") if (-not (Test-IsWin25)) { $rustToolsPackages.AddToolVersion("bindgen", $(Get-BindgenVersion)) - # TODO: test cargo-audit and bring back - if (-not (Test-IsWin11)) { - $rustToolsPackages.AddToolVersion("cargo-audit", $(Get-CargoAuditVersion)) - } + $rustToolsPackages.AddToolVersion("cargo-audit", $(Get-CargoAuditVersion)) $rustToolsPackages.AddToolVersion("cargo-outdated", $(Get-CargoOutdatedVersion)) $rustToolsPackages.AddToolVersion("cbindgen", $(Get-CbindgenVersion)) } diff --git a/images/windows/scripts/tests/Rust.Tests.ps1 b/images/windows/scripts/tests/Rust.Tests.ps1 index 8058792662..717e80e428 100644 --- a/images/windows/scripts/tests/Rust.Tests.ps1 +++ b/images/windows/scripts/tests/Rust.Tests.ps1 @@ -12,14 +12,13 @@ Describe "Rust" { @{ToolName = "cargo"; binPath = "C:\Users\Default\.cargo\bin\cargo.exe"} ) } else { - # TODO: test cargo-audit and bring back $rustTools = @( @{ToolName = "rustup"; binPath = "C:\Users\Default\.cargo\bin\rustup.exe"} @{ToolName = "rustc"; binPath = "C:\Users\Default\.cargo\bin\rustc.exe"} @{ToolName = "bindgen.exe"; binPath = "C:\Users\Default\.cargo\bin\bindgen.exe"} @{ToolName = "cbindgen.exe"; binPath = "C:\Users\Default\.cargo\bin\cbindgen.exe"} @{ToolName = "cargo"; binPath = "C:\Users\Default\.cargo\bin\cargo.exe"} - $(if (-not (Test-IsWin11)) { @{ToolName = "cargo audit"; binPath = "C:\Users\Default\.cargo\bin\cargo-audit.exe"} }) + @{ToolName = "cargo audit"; binPath = "C:\Users\Default\.cargo\bin\cargo-audit.exe"} @{ToolName = "cargo outdated"; binPath = "C:\Users\Default\.cargo\bin\cargo-outdated.exe"} ) } From eaf680b28bde055891e423631421556013b18657 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Tue, 24 Mar 2026 13:58:11 +0100 Subject: [PATCH 21/55] Cleanup code --- .../templates/build.windows-11-arm64.pkr.hcl | 98 ------------------- 1 file changed, 98 deletions(-) diff --git a/images/windows/templates/build.windows-11-arm64.pkr.hcl b/images/windows/templates/build.windows-11-arm64.pkr.hcl index 311c1f8438..36db27fdd9 100644 --- a/images/windows/templates/build.windows-11-arm64.pkr.hcl +++ b/images/windows/templates/build.windows-11-arm64.pkr.hcl @@ -51,63 +51,6 @@ build { inline = ["if (-not ((net localgroup Administrators) -contains '${var.install_user}')) { exit 1 }"] } - # v1 - elevated user issue - # provisioner "powershell" { - # inline = [<<-EOF - # $sidStr = (New-Object Security.Principal.NTAccount("${var.install_user}")).Translate([Security.Principal.SecurityIdentifier]).Value - # $tmpFile = [IO.Path]::GetTempFileName() - # secedit /export /cfg $tmpFile /areas USER_RIGHTS /quiet - # $policy = Get-Content $tmpFile -Raw - # if ($policy -match 'SeBatchLogonRight\s*=\s*(.*)') { - # $policy = $policy -replace 'SeBatchLogonRight\s*=\s*(.*)', "SeBatchLogonRight = `$1,*$sidStr" - # } else { - # $policy += "`r`nSeBatchLogonRight = *$sidStr" - # } - # Set-Content $tmpFile $policy - # secedit /configure /db "$env:TEMP\secedit.sdb" /cfg $tmpFile /areas USER_RIGHTS /quiet - # Remove-Item $tmpFile - # EOF - # ] - # } - - # v2 - elevated user issue - # provisioner "powershell" { - # inline = [<<-EOF - # $code = @' - # using System; - # using System.Runtime.InteropServices; - # public class LsaUtil { - # [DllImport("advapi32.dll", SetLastError=true)] - # static extern uint LsaOpenPolicy(IntPtr SystemName, ref LSA_OBJECT_ATTRIBUTES ObjectAttributes, uint AccessMask, out IntPtr PolicyHandle); - # [DllImport("advapi32.dll", SetLastError=true)] - # static extern uint LsaAddAccountRights(IntPtr PolicyHandle, IntPtr AccountSid, LSA_UNICODE_STRING[] UserRights, long CountOfRights); - # [DllImport("advapi32.dll")] - # static extern uint LsaClose(IntPtr ObjectHandle); - # [StructLayout(LayoutKind.Sequential)] public struct LSA_OBJECT_ATTRIBUTES { public int Length; public IntPtr RootDirectory; public IntPtr ObjectName; public uint Attributes; public IntPtr SecurityDescriptor; public IntPtr SecurityQualityOfService; } - # [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct LSA_UNICODE_STRING { public ushort Length; public ushort MaximumLength; [MarshalAs(UnmanagedType.LPWStr)] public string Buffer; } - # public static void AddRight(string accountName, string rightName) { - # var attrs = new LSA_OBJECT_ATTRIBUTES(); - # IntPtr policy; - # LsaOpenPolicy(IntPtr.Zero, ref attrs, 0x00020000 | 0x00000800, out policy); - # var sid = new System.Security.Principal.NTAccount(accountName).Translate(typeof(System.Security.Principal.SecurityIdentifier)); - # var sidBytes = new byte[((System.Security.Principal.SecurityIdentifier)sid).BinaryLength]; - # ((System.Security.Principal.SecurityIdentifier)sid).GetBinaryForm(sidBytes, 0); - # var sidPtr = Marshal.AllocHGlobal(sidBytes.Length); - # Marshal.Copy(sidBytes, 0, sidPtr, sidBytes.Length); - # var rights = new[] { new LSA_UNICODE_STRING { Buffer = rightName, Length = (ushort)(rightName.Length * 2), MaximumLength = (ushort)(rightName.Length * 2 + 2) } }; - # LsaAddAccountRights(policy, sidPtr, rights, 1); - # Marshal.FreeHGlobal(sidPtr); - # LsaClose(policy); - # } - # } - # '@ - # Add-Type $code - # [LsaUtil]::AddRight("${var.install_user}", "SeBatchLogonRight") - # EOF - # ] - # } - - # v3 - set and remove after all elevated tasks are done, might need additional reboot provisioner "powershell" { inline = [ "Set-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name AutoAdminLogon -Value 1 -type String", @@ -116,7 +59,6 @@ build { ] } - # v3 - elevated user issue provisioner "windows-restart" { check_registry = true restart_timeout = "10m" @@ -135,7 +77,6 @@ build { "${path.root}/../scripts/build/Configure-WindowsDefender.ps1", "${path.root}/../scripts/build/Configure-PowerShell.ps1", "${path.root}/../scripts/build/Install-PowerShellModules.ps1", - # "${path.root}/../scripts/build/Install-WSL2.ps1", "${path.root}/../scripts/build/Install-WindowsFeatures.ps1", "${path.root}/../scripts/build/Install-Chocolatey.ps1", "${path.root}/../scripts/build/Configure-BaseImage.ps1", @@ -155,14 +96,9 @@ build { inline = ["Set-Service -Name wlansvc -StartupType Manual", "if ($(Get-Service -Name wlansvc).Status -eq 'Running') { Stop-Service -Name wlansvc}"] } - # TODO: - # 1. Double check if Install-Runner.ps1 is needed, should be taken care of during specialization. Left out for now provisioner "powershell" { environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] scripts = [ - # "${path.root}/../scripts/build/Install-Docker.ps1", - # "${path.root}/../scripts/build/Install-DockerWinCred.ps1", - # "${path.root}/../scripts/build/Install-DockerCompose.ps1", "${path.root}/../scripts/build/Install-PowershellCore.ps1", "${path.root}/../scripts/build/Install-WebPlatformInstaller.ps1" ] @@ -188,15 +124,10 @@ build { restart_timeout = "10m" } - # TODO: - # 1. Add ${path.root}/../scripts/build/Install-CMake.ps1 - Done, instead of Choco package, updated to latest - # 2. Add ${path.root}/../scripts/build/Install-Ninja.ps1 - Done, instead of Choco package, updated to latest - # 3. Check if need to move ${path.root}/../scripts/build/Install-LLVM.ps1 into this block provisioner "powershell" { pause_before = "2m0s" environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] scripts = [ - # "${path.root}/../scripts/build/Install-Wix.ps1", "${path.root}/../scripts/build/Install-WDK.ps1", "${path.root}/../scripts/build/Install-VSExtensions.ps1", "${path.root}/../scripts/build/Install-AzureCli.ps1", @@ -214,20 +145,14 @@ build { restart_timeout = "10m" } - # TODO: - # 1. Add ${path.root}/../scripts/build/Install-Mercurial.ps1 - Done - # 2. Add ${path.root}/../scripts/build/Install-NSIS.ps1 - Done - # 3. Add ${path.root}/../scripts/build/Install-AliyunCli.ps1 - Done provisioner "powershell" { environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] scripts = [ "${path.root}/../scripts/build/Install-ActionsCache.ps1", "${path.root}/../scripts/build/Install-Ruby.ps1", - # "${path.root}/../scripts/build/Install-PyPy.ps1", "${path.root}/../scripts/build/Install-Toolset.ps1", "${path.root}/../scripts/build/Configure-Toolset.ps1", "${path.root}/../scripts/build/Install-NodeJS.ps1", - # "${path.root}/../scripts/build/Install-AndroidSDK.ps1", "${path.root}/../scripts/build/Install-PowershellAzModules.ps1", "${path.root}/../scripts/build/Install-Pipx.ps1", "${path.root}/../scripts/build/Install-Git.ps1", @@ -242,7 +167,6 @@ build { "${path.root}/../scripts/build/Install-IEWebDriver.ps1", "${path.root}/../scripts/build/Install-Apache.ps1", "${path.root}/../scripts/build/Install-Nginx.ps1", - # "${path.root}/../scripts/build/Install-Msys2.ps1", "${path.root}/../scripts/build/Install-WinAppDriver.ps1", "${path.root}/../scripts/build/Install-R.ps1", "${path.root}/../scripts/build/Install-AWSTools.ps1", @@ -252,18 +176,14 @@ build { "${path.root}/../scripts/build/Install-SQLOLEDBDriver.ps1", "${path.root}/../scripts/build/Install-DotnetSDK.ps1", "${path.root}/../scripts/build/Install-Mingw64.ps1", - # "${path.root}/../scripts/build/Install-Haskell.ps1", "${path.root}/../scripts/build/Install-Stack.ps1", - # "${path.root}/../scripts/build/Install-Miniconda.ps1", "${path.root}/../scripts/build/Install-AzureCosmosDbEmulator.ps1", "${path.root}/../scripts/build/Install-Mercurial.ps1", "${path.root}/../scripts/build/Install-NSIS.ps1", - # "${path.root}/../scripts/build/Install-Zstd.ps1", "${path.root}/../scripts/build/Install-Vcpkg.ps1", "${path.root}/../scripts/build/Install-Bazel.ps1", "${path.root}/../scripts/build/Install-AliyunCli.ps1", "${path.root}/../scripts/build/Install-RootCA.ps1", - # "${path.root}/../scripts/build/Install-MongoDB.ps1", "${path.root}/../scripts/build/Install-CodeQLBundle.ps1", "${path.root}/../scripts/build/Configure-Diagnostics.ps1" ] @@ -274,7 +194,6 @@ build { elevated_user = "${var.install_user}" environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] scripts = [ - # "${path.root}/../scripts/build/Install-PostgreSQL.ps1", "${path.root}/../scripts/build/Install-WindowsUpdates.ps1", "${path.root}/../scripts/build/Configure-DynamicPort.ps1", "${path.root}/../scripts/build/Configure-GDIProcessHandleQuota.ps1", @@ -284,7 +203,6 @@ build { ] } - # v3 - elevated user issue provisioner "powershell" { inline = [ "Remove-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name AutoAdminLogon", @@ -299,22 +217,6 @@ build { restart_timeout = "30m" } - # TODO: removes once debugging is done - provisioner "powershell" { - inline = [<<-EOF - $filter = @{ - LogName = "System" - Id = 19, 20, 43 - ProviderName = "Microsoft-Windows-WindowsUpdateClient" - } - $events = Get-WinEvent -FilterHashtable $filter -ErrorAction SilentlyContinue | Sort-Object Id - $events | sort TimeCreated | fl * - Write-Host "display appxpackages" - Get-AppxPackage - EOF - ] - } - provisioner "powershell" { pause_before = "2m0s" environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] From fb1b0ddd690f9536f011c8f61e47ad744f9b0d11 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Tue, 24 Mar 2026 13:59:19 +0100 Subject: [PATCH 22/55] Fix LLVM install sequence --- images/windows/templates/build.windows-11-arm64.pkr.hcl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/images/windows/templates/build.windows-11-arm64.pkr.hcl b/images/windows/templates/build.windows-11-arm64.pkr.hcl index 36db27fdd9..2b6630a279 100644 --- a/images/windows/templates/build.windows-11-arm64.pkr.hcl +++ b/images/windows/templates/build.windows-11-arm64.pkr.hcl @@ -137,7 +137,8 @@ build { "${path.root}/../scripts/build/Install-Ninja.ps1", "${path.root}/../scripts/build/Install-JavaTools.ps1", "${path.root}/../scripts/build/Install-Kotlin.ps1", - "${path.root}/../scripts/build/Install-OpenSSL.ps1" + "${path.root}/../scripts/build/Install-OpenSSL.ps1", + "${path.root}/../scripts/build/Install-LLVM.ps1" ] } @@ -198,8 +199,7 @@ build { "${path.root}/../scripts/build/Configure-DynamicPort.ps1", "${path.root}/../scripts/build/Configure-GDIProcessHandleQuota.ps1", "${path.root}/../scripts/build/Configure-Shell.ps1", - "${path.root}/../scripts/build/Configure-DeveloperMode.ps1", - "${path.root}/../scripts/build/Install-LLVM.ps1" + "${path.root}/../scripts/build/Configure-DeveloperMode.ps1" ] } From c88da39674232573d26c33ffbe69c772a1423345 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Tue, 24 Mar 2026 20:22:32 +0100 Subject: [PATCH 23/55] Add win11-vs2026-arm64 code --- .../scripts/build/Configure-ImageDataFile.ps1 | 4 + .../build.windows-11-vs2026-arm64.pkr.hcl | 278 ++++++++++++++++ .../windows/templates/locals.windows.pkr.hcl | 6 +- .../toolsets/toolset-win-11-vs2026-arm64.json | 309 ++++++++++++++++++ 4 files changed, 596 insertions(+), 1 deletion(-) create mode 100644 images/windows/templates/build.windows-11-vs2026-arm64.pkr.hcl create mode 100644 images/windows/toolsets/toolset-win-11-vs2026-arm64.json diff --git a/images/windows/scripts/build/Configure-ImageDataFile.ps1 b/images/windows/scripts/build/Configure-ImageDataFile.ps1 index 5abbc42430..4b88302a0c 100644 --- a/images/windows/scripts/build/Configure-ImageDataFile.ps1 +++ b/images/windows/scripts/build/Configure-ImageDataFile.ps1 @@ -27,6 +27,10 @@ if ((Test-IsWin25) -and $env:INSTALL_VS_2026) { $imageLabel = "windows-2022" $softwareUrl = "${githubUrl}/win22/$imageMajorVersion.$imageMinorVersion/images/windows/Windows2022-Readme.md" $releaseUrl = "https://github.com/actions/runner-images/releases/tag/win22%2F$imageMajorVersion.$imageMinorVersion" +} if ((Test-IsWin11) -and (Test-IsArm64) -and $env:INSTALL_VS_2026) { + $imageLabel = "windows-11-vs2026-arm64" + $softwareUrl = "${githubUrl}/win11-vs2026-arm64/$imageMajorVersion.$imageMinorVersion/images/windows/Windows11-VS2026-Arm64-Readme.md" + $releaseUrl = "https://github.com/actions/runner-images/releases/tag/win11-vs2026-arm64%2F$imageMajorVersion.$imageMinorVersion" } elseif ((Test-IsWin11) -and (Test-IsArm64)) { $imageLabel = "windows-11-arm64" $softwareUrl = "${githubUrl}/win11-arm64/$imageMajorVersion.$imageMinorVersion/images/windows/Windows11-Arm64-Readme.md" diff --git a/images/windows/templates/build.windows-11-vs2026-arm64.pkr.hcl b/images/windows/templates/build.windows-11-vs2026-arm64.pkr.hcl new file mode 100644 index 0000000000..d67b34a7d6 --- /dev/null +++ b/images/windows/templates/build.windows-11-vs2026-arm64.pkr.hcl @@ -0,0 +1,278 @@ +build { + sources = ["source.azure-arm.image"] + name = "windows-11-vs2026-arm64" + + provisioner "powershell" { + inline = [ + "New-Item -Path ${var.image_folder} -ItemType Directory -Force", + "New-Item -Path ${var.temp_dir} -ItemType Directory -Force" + ] + } + + provisioner "file" { + destination = "${var.image_folder}\\" + sources = [ + "${path.root}/../assets", + "${path.root}/../scripts", + "${path.root}/../toolsets" + ] + } + + provisioner "file" { + destination = "${var.image_folder}\\scripts\\docs-gen\\" + source = "${path.root}/../../../helpers/software-report-base" + } + + provisioner "powershell" { + inline = [ + "Move-Item '${var.image_folder}\\assets\\post-gen' 'C:\\post-generation'", + "Remove-Item -Recurse '${var.image_folder}\\assets'", + "Move-Item '${var.image_folder}\\scripts\\docs-gen' '${var.image_folder}\\SoftwareReport'", + "Move-Item '${var.image_folder}\\scripts\\helpers' '${var.helper_script_folder}\\ImageHelpers'", + "New-Item -Type Directory -Path '${var.helper_script_folder}\\TestsHelpers\\'", + "Move-Item '${var.image_folder}\\scripts\\tests\\Helpers.psm1' '${var.helper_script_folder}\\TestsHelpers\\TestsHelpers.psm1'", + "Move-Item '${var.image_folder}\\scripts\\tests' '${var.image_folder}\\tests'", + "Remove-Item -Recurse '${var.image_folder}\\scripts'", + "Move-Item '${var.image_folder}\\toolsets\\toolset-win-11-vs2026-arm64.json' '${var.image_folder}\\toolset.json'", + "Remove-Item -Recurse '${var.image_folder}\\toolsets'" + ] + } + + provisioner "windows-shell" { + inline = [ + "net user ${var.install_user} ${var.install_password} /add /passwordchg:no /passwordreq:yes /active:yes /Y", + "net localgroup Administrators ${var.install_user} /add", + "winrm set winrm/config/service/auth @{Basic=\"true\"}", + "winrm get winrm/config/service/auth" + ] + } + + provisioner "powershell" { + inline = ["if (-not ((net localgroup Administrators) -contains '${var.install_user}')) { exit 1 }"] + } + + provisioner "powershell" { + inline = [ + "Set-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name AutoAdminLogon -Value 1 -type String", + "Set-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name DefaultUsername -Value \"${var.install_user}\" -type String", + "Set-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name DefaultPassword -Value \"${var.install_password}\" -type String", + ] + } + + provisioner "windows-restart" { + check_registry = true + restart_timeout = "10m" + } + + provisioner "powershell" { + elevated_password = "${var.install_password}" + elevated_user = "${var.install_user}" + inline = ["bcdedit.exe /set TESTSIGNING ON"] + } + + provisioner "powershell" { + environment_vars = ["IMAGE_VERSION=${var.image_version}", "IMAGE_OS=${var.image_os}", "AGENT_TOOLSDIRECTORY=${var.agent_tools_directory}", "IMAGEDATA_FILE=${var.imagedata_file}", "IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}", "INSTALL_VS_2026=true"] + execution_policy = "unrestricted" + scripts = [ + "${path.root}/../scripts/build/Configure-WindowsDefender.ps1", + "${path.root}/../scripts/build/Configure-PowerShell.ps1", + "${path.root}/../scripts/build/Install-PowerShellModules.ps1", + "${path.root}/../scripts/build/Install-WindowsFeatures.ps1", + "${path.root}/../scripts/build/Install-Chocolatey.ps1", + "${path.root}/../scripts/build/Configure-BaseImage.ps1", + "${path.root}/../scripts/build/Configure-ImageDataFile.ps1", + "${path.root}/../scripts/build/Configure-SystemEnvironment.ps1", + "${path.root}/../scripts/build/Configure-DotnetSecureChannel.ps1" + ] + } + + provisioner "windows-restart" { + check_registry = true + restart_check_command = "powershell -command \"& {while ( (Get-WindowsOptionalFeature -Online -FeatureName Containers -ErrorAction SilentlyContinue).State -ne 'Enabled' ) { Start-Sleep 30; Write-Output 'InProgress' }}\"" + restart_timeout = "10m" + } + + provisioner "powershell" { + inline = ["Set-Service -Name wlansvc -StartupType Manual", "if ($(Get-Service -Name wlansvc).Status -eq 'Running') { Stop-Service -Name wlansvc}"] + } + + provisioner "powershell" { + environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] + scripts = [ + "${path.root}/../scripts/build/Install-PowershellCore.ps1", + "${path.root}/../scripts/build/Install-WebPlatformInstaller.ps1" + ] + } + + provisioner "windows-restart" { + restart_timeout = "30m" + } + + provisioner "powershell" { + elevated_password = "${var.install_password}" + elevated_user = "${var.install_user}" + environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}", "INSTALL_VS_2026=true"] + scripts = [ + "${path.root}/../scripts/build/Install-VisualStudio.ps1", + "${path.root}/../scripts/build/Install-KubernetesTools.ps1" + ] + valid_exit_codes = [0, 3010] + } + + provisioner "windows-restart" { + check_registry = true + restart_timeout = "10m" + } + + provisioner "powershell" { + pause_before = "2m0s" + environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] + scripts = [ + "${path.root}/../scripts/build/Install-WDK.ps1", + "${path.root}/../scripts/build/Install-VSExtensions.ps1", + "${path.root}/../scripts/build/Install-AzureCli.ps1", + "${path.root}/../scripts/build/Install-AzureDevOpsCli.ps1", + "${path.root}/../scripts/build/Install-ChocolateyPackages.ps1", + "${path.root}/../scripts/build/Install-CMake.ps1", + "${path.root}/../scripts/build/Install-Ninja.ps1", + "${path.root}/../scripts/build/Install-JavaTools.ps1", + "${path.root}/../scripts/build/Install-Kotlin.ps1", + "${path.root}/../scripts/build/Install-OpenSSL.ps1", + "${path.root}/../scripts/build/Install-LLVM.ps1" + ] + } + + provisioner "windows-restart" { + restart_timeout = "10m" + } + + provisioner "powershell" { + environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] + scripts = [ + "${path.root}/../scripts/build/Install-ActionsCache.ps1", + "${path.root}/../scripts/build/Install-Ruby.ps1", + "${path.root}/../scripts/build/Install-Toolset.ps1", + "${path.root}/../scripts/build/Configure-Toolset.ps1", + "${path.root}/../scripts/build/Install-NodeJS.ps1", + "${path.root}/../scripts/build/Install-PowershellAzModules.ps1", + "${path.root}/../scripts/build/Install-Pipx.ps1", + "${path.root}/../scripts/build/Install-Git.ps1", + "${path.root}/../scripts/build/Install-GitHub-CLI.ps1", + "${path.root}/../scripts/build/Install-PHP.ps1", + "${path.root}/../scripts/build/Install-Rust.ps1", + "${path.root}/../scripts/build/Install-Sbt.ps1", + "${path.root}/../scripts/build/Install-Chrome.ps1", + "${path.root}/../scripts/build/Install-EdgeDriver.ps1", + "${path.root}/../scripts/build/Install-Firefox.ps1", + "${path.root}/../scripts/build/Install-Selenium.ps1", + "${path.root}/../scripts/build/Install-IEWebDriver.ps1", + "${path.root}/../scripts/build/Install-Apache.ps1", + "${path.root}/../scripts/build/Install-Nginx.ps1", + "${path.root}/../scripts/build/Install-WinAppDriver.ps1", + "${path.root}/../scripts/build/Install-R.ps1", + "${path.root}/../scripts/build/Install-AWSTools.ps1", + "${path.root}/../scripts/build/Install-DACFx.ps1", + "${path.root}/../scripts/build/Install-MysqlCli.ps1", + "${path.root}/../scripts/build/Install-SQLPowerShellTools.ps1", + "${path.root}/../scripts/build/Install-SQLOLEDBDriver.ps1", + "${path.root}/../scripts/build/Install-DotnetSDK.ps1", + "${path.root}/../scripts/build/Install-Mingw64.ps1", + "${path.root}/../scripts/build/Install-Stack.ps1", + "${path.root}/../scripts/build/Install-AzureCosmosDbEmulator.ps1", + "${path.root}/../scripts/build/Install-Mercurial.ps1", + "${path.root}/../scripts/build/Install-NSIS.ps1", + "${path.root}/../scripts/build/Install-Vcpkg.ps1", + "${path.root}/../scripts/build/Install-Bazel.ps1", + "${path.root}/../scripts/build/Install-AliyunCli.ps1", + "${path.root}/../scripts/build/Install-RootCA.ps1", + "${path.root}/../scripts/build/Install-CodeQLBundle.ps1", + "${path.root}/../scripts/build/Configure-Diagnostics.ps1" + ] + } + + provisioner "powershell" { + elevated_password = "${var.install_password}" + elevated_user = "${var.install_user}" + environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] + scripts = [ + "${path.root}/../scripts/build/Install-WindowsUpdates.ps1", + "${path.root}/../scripts/build/Configure-DynamicPort.ps1", + "${path.root}/../scripts/build/Configure-GDIProcessHandleQuota.ps1", + "${path.root}/../scripts/build/Configure-Shell.ps1", + "${path.root}/../scripts/build/Configure-DeveloperMode.ps1" + ] + } + + provisioner "powershell" { + inline = [ + "Remove-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name AutoAdminLogon", + "Remove-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name DefaultUsername", + "Remove-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name DefaultPassword", + ] + } + + provisioner "windows-restart" { + check_registry = true + restart_check_command = "powershell -command \"& {if ((-not (Get-Process TiWorker.exe -ErrorAction SilentlyContinue)) -and (-not [System.Environment]::HasShutdownStarted) ) { Write-Output 'Restart complete' }}\"" + restart_timeout = "30m" + } + + provisioner "powershell" { + pause_before = "2m0s" + environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] + scripts = [ + "${path.root}/../scripts/build/Install-WindowsUpdatesAfterReboot.ps1", + "${path.root}/../scripts/build/Invoke-Cleanup.ps1", + "${path.root}/../scripts/tests/RunAll-Tests.ps1" + ] + } + + provisioner "powershell" { + inline = ["if (-not (Test-Path ${var.image_folder}\\tests\\testResults.xml)) { throw '${var.image_folder}\\tests\\testResults.xml not found' }"] + } + + provisioner "powershell" { + environment_vars = ["IMAGE_VERSION=${var.image_version}", "IMAGE_FOLDER=${var.image_folder}"] + inline = ["pwsh -File '${var.image_folder}\\SoftwareReport\\Generate-SoftwareReport.ps1'"] + } + + provisioner "powershell" { + inline = ["if (-not (Test-Path C:\\software-report.md)) { throw 'C:\\software-report.md not found' }", "if (-not (Test-Path C:\\software-report.json)) { throw 'C:\\software-report.json not found' }"] + } + + provisioner "file" { + destination = "${path.root}/../Windows11-VS2026-Arm64-Readme.md" + direction = "download" + source = "C:\\software-report.md" + } + + provisioner "file" { + destination = "${path.root}/../software-report.json" + direction = "download" + source = "C:\\software-report.json" + } + + provisioner "powershell" { + environment_vars = ["INSTALL_USER=${var.install_user}"] + scripts = [ + "${path.root}/../scripts/build/Install-NativeImages.ps1", + "${path.root}/../scripts/build/Configure-System.ps1", + "${path.root}/../scripts/build/Configure-User.ps1", + "${path.root}/../scripts/build/Post-Build-Validation.ps1" + ] + skip_clean = true + } + + provisioner "windows-restart" { + restart_timeout = "10m" + } + + provisioner "powershell" { + inline = [ + "if( Test-Path $env:SystemRoot\\System32\\Sysprep\\unattend.xml ){ rm $env:SystemRoot\\System32\\Sysprep\\unattend.xml -Force}", + "& $env:SystemRoot\\System32\\Sysprep\\Sysprep.exe /oobe /generalize /mode:vm /quiet /quit", + "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 } }" + ] + } + +} diff --git a/images/windows/templates/locals.windows.pkr.hcl b/images/windows/templates/locals.windows.pkr.hcl index 9a671dc5dd..8a5f12993c 100644 --- a/images/windows/templates/locals.windows.pkr.hcl +++ b/images/windows/templates/locals.windows.pkr.hcl @@ -11,10 +11,14 @@ locals { "win25-vs2026" = { source_image_marketplace_sku = "MicrosoftWindowsServer:WindowsServer:2025-Datacenter-g2" os_disk_size_gb = 150 - } + }, "win11-arm64" = { source_image_marketplace_sku = "microsoftwindowsdesktop:windows11preview-arm64:win11-25h2-ent" os_disk_size_gb = 256 + }, + "win11-vs2026-arm64" = { + source_image_marketplace_sku = "microsoftwindowsdesktop:windows11preview-arm64:win11-25h2-ent" + os_disk_size_gb = 256 } } diff --git a/images/windows/toolsets/toolset-win-11-vs2026-arm64.json b/images/windows/toolsets/toolset-win-11-vs2026-arm64.json new file mode 100644 index 0000000000..b9a0edbb27 --- /dev/null +++ b/images/windows/toolsets/toolset-win-11-vs2026-arm64.json @@ -0,0 +1,309 @@ +{ + "toolcache": [ + { + "name": "Ruby", + "arch": "aarch64", + "platform" : "win32", + "versions": [ + "3.4" + ], + "default": "3.4" + }, + { + "name": "Python", + "url" : "https://raw.githubusercontent.com/actions/python-versions/main/versions-manifest.json", + "arch": "x64", + "platform" : "win32", + "versions": [ + "3.13.*" + ] + }, + { + "name": "Python", + "url" : "https://raw.githubusercontent.com/actions/python-versions/main/versions-manifest.json", + "arch": "arm64", + "platform" : "win32", + "versions": [ + "3.12.*", + "3.13.*", + "3.14.*" + ], + "default": "3.13.*" + }, + { + "name": "node", + "url" : "https://raw.githubusercontent.com/actions/node-versions/main/versions-manifest.json", + "arch": "arm64", + "platform" : "win32", + "versions": [ + "20.*", + "22.*", + "24.*" + ] + }, + { + "name": "go", + "url" : "https://raw.githubusercontent.com/actions/go-versions/main/versions-manifest.json", + "arch": "arm64", + "platform" : "win32", + "versions": [ + "1.22.*", + "1.23.*", + "1.24.*", + "1.25.*" + ], + "default": "1.24.*" + } + ], + "powershellModules": [ + { "name": "DockerMsftProvider" }, + { "name": "MarkdownPS" }, + { "name": "Pester" }, + { "name": "PowerShellGet" }, + { "name": "PSScriptAnalyzer" }, + { "name": "PSWindowsUpdate" }, + { "name": "SqlServer" }, + { "name": "VSSetup" }, + { "name": "Microsoft.Graph" }, + { "name": "AWSPowershell" } + ], + "azureModules": [ + { + "name": "az", + "versions": [ + "12.5.0" + ], + "zip_versions": [ + + ] + } + ], + "java": { + "default": "21", + "versions": [ "21", "23" ] + }, + "android": { + "commandline_tools_url": "https://dl.google.com/android/repository/commandlinetools-win-9123335_latest.zip", + "hash": "8A90E6A3DEB2FA13229B2E335EFD07687DCC8A55A3C544DA9F40B41404993E7D", + "platform_min_version": "31", + "build_tools_min_version": "31.0.0", + "extras": [ + "android;m2repository", + "google;m2repository", + "google;google_play_services" + ], + "addons": [], + "additional_tools": [ + "cmake;3.18.1", + "cmake;3.22.1" + ], + "ndk": { + "default": "27", + "versions": [ + "26", "27", "28" + ] + } + }, + "mingw": { + "version": "14.*", + "runtime": "ucrt" + }, + "MsysPackages": { + "msys2": [], + "mingw": [] + }, + "windowsFeatures": [ + { "name": "Containers", "optionalFeature": true }, + { "name": "Microsoft-Windows-Subsystem-Linux", "optionalFeature": true }, + { "name": "VirtualMachinePlatform", "optionalFeature": true }, + { "name": "NetFx4-AdvSrvs", "optionalFeature": true }, + { "name": "Client-ProjFS", "optionalFeature": true }, + { "name": "Microsoft-Hyper-V-All", "optionalFeature": true }, + { "name": "Microsoft-Hyper-V", "optionalFeature": true }, + { "name": "Microsoft-Hyper-V-Tools-All", "optionalFeature": true }, + { "name": "Microsoft-Hyper-V-Hypervisor", "optionalFeature": true }, + { "name": "Microsoft-Hyper-V-Management-PowerShell", "optionalFeature": true } + ], + "visualStudio": { + "version" : "2026", + "subversion" : "18", + "edition" : "Enterprise", + "channel": "stable", + "installChannelUri": "", + "workloads": [ + "Component.Linux.CMake", + "Component.Unreal.Android", + "Component.Xamarin", + "Microsoft.Component.VC.Runtime.UCRTSDK", + "Microsoft.Net.Component.4.7.2.SDK", + "Microsoft.Net.Component.4.7.TargetingPack", + "Microsoft.Net.Component.4.7.2.TargetingPack", + "Microsoft.Net.Component.4.8.1.SDK", + "Microsoft.Net.Component.4.8.1.TargetingPack", + "Microsoft.VisualStudio.Component.AspNet45", + "Microsoft.VisualStudio.Component.Debugger.JustInTime", + "Microsoft.VisualStudio.Component.EntityFramework", + "Microsoft.VisualStudio.Component.DslTools", + "Microsoft.VisualStudio.Component.SQL.SSDT", + "Microsoft.VisualStudio.Component.PortableLibrary", + "Microsoft.VisualStudio.Component.UWP.VC.ARM64", + "Microsoft.VisualStudio.Component.UWP.VC.ARM64EC", + "Microsoft.VisualStudio.Component.VC.CLI.Support", + "Microsoft.VisualStudio.Component.VC.CMake.Project", + "Microsoft.VisualStudio.Component.VC.DiagnosticTools", + "Microsoft.VisualStudio.Component.VC.Llvm.Clang", + "Microsoft.VisualStudio.Component.VC.Llvm.ClangToolset", + "Microsoft.VisualStudio.Component.VC.TestAdapterForBoostTest", + "Microsoft.VisualStudio.Component.VC.TestAdapterForGoogleTest", + "Microsoft.VisualStudio.Component.VC.Tools.ARM64", + "Microsoft.VisualStudio.Component.VC.Tools.ARM64EC", + "Microsoft.VisualStudio.Component.VC.Redist.MSM", + "Microsoft.VisualStudio.Component.VC.Runtimes.ARM64.Spectre", + "Microsoft.VisualStudio.Component.VC.Runtimes.ARM64EC.Spectre", + "Microsoft.VisualStudio.Component.VC.MFC.ARM64", + "Microsoft.VisualStudio.Component.VC.MFC.ARM64.Spectre", + "Microsoft.VisualStudio.Component.VC.ATLMFC", + "Microsoft.VisualStudio.Component.VC.ATLMFC.Spectre", + "Microsoft.VisualStudio.Component.VC.ATL", + "Microsoft.VisualStudio.Component.VC.ATL.Spectre", + "Microsoft.VisualStudio.Component.VC.ATL.ARM64", + "Microsoft.VisualStudio.Component.VC.ATL.ARM64.Spectre", + "Microsoft.VisualStudio.Component.VC.ASAN", + "Microsoft.VisualStudio.Component.VC.14.44.17.14.ARM64", + "Microsoft.VisualStudio.Component.Windows10SDK.19041", + "Microsoft.VisualStudio.Component.Windows11SDK.22621", + "Microsoft.VisualStudio.Component.Windows11SDK.26100", + "Microsoft.VisualStudio.ComponentGroup.NativeDesktop.Llvm.Clang", + "Microsoft.VisualStudio.ComponentGroup.UWP.VC.v142", + "Microsoft.VisualStudio.ComponentGroup.Web.CloudTools", + "Microsoft.VisualStudio.Workload.ManagedDesktop", + "Microsoft.VisualStudio.Workload.ManagedGame", + "Microsoft.VisualStudio.Workload.NativeCrossPlat", + "Microsoft.VisualStudio.Workload.NativeDesktop", + "Microsoft.VisualStudio.Workload.NativeGame", + "Microsoft.VisualStudio.Workload.NetCrossPlat", + "Microsoft.VisualStudio.Workload.NetWeb", + "Microsoft.VisualStudio.Workload.Node", + "Microsoft.VisualStudio.Workload.Universal", + "Microsoft.VisualStudio.Workload.VisualStudioExtension", + "Component.MDD.Linux", + "Component.Microsoft.Windows.DriverKit", + "wasm.tools", + "Microsoft.Component.MSBuild" + ], + "vsix": [ + "SSIS.MicrosoftDataToolsIntegrationServices", + "VisualStudioClient.MicrosoftVisualStudio2022InstallerProjectsArm64" + ] + }, + "docker": { + "images": [ + "mcr.microsoft.com/windows/servercore:ltsc2022", + "mcr.microsoft.com/windows/nanoserver:ltsc2022", + "mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2022", + "mcr.microsoft.com/dotnet/framework/runtime:4.8-windowsservercore-ltsc2022", + "mcr.microsoft.com/dotnet/framework/sdk:4.8-windowsservercore-ltsc2022" + ], + "components": { + "docker": "26.1.3", + "compose": "2.27.1" + } + }, + "pipx": [ + { + "package": "yamllint", + "cmd": "yamllint --version" + } + ], + "selenium": { + "version": "4" + }, + "npm": { + "global_packages": [ + { "name": "yarn", "test": "yarn --version" }, + { "name": "newman", "test": "newman --version" }, + { "name": "lerna", "test": "lerna --version" }, + { "name": "gulp-cli", "test": "gulp --version" }, + { "name": "grunt-cli", "test": "grunt --version" } + ] + }, + "serviceFabric": { + "runtime": { + "version": "10.1.2493.9590", + "checksum": "09C63A971BACDE338282C73B3C9174BED9AAD53E1D3A1B73D44515852C9C00CF" + }, + "sdk": { + "version": "7.1.2493", + "checksum": "0CB1084156C75CF5075EA91ABA330CF10B58648B8E036C9C2F286805263C497F" + } + }, + "dotnet": { + "versions": [ + "6.0", + "8.0", + "9.0", + "10.0" + ], + "tools": [ + { "name": "nbgv", "test": "nbgv --version", "getversion": "nbgv --version" } + ], + "warmup": false + }, + "choco": { + "common_packages": [ + { "name": "7zip.install" }, + { "name": "aria2" }, + { "name": "azcopy10" }, + { "name": "Bicep" }, + { "name": "innosetup" }, + { "name": "jq" }, + { "name": "NuGet.CommandLine" }, + { "name": "packer" }, + { + "name": "strawberryperl" , + "args": [ "--version", "5.32.1.1" ] + }, + { "name": "pulumi" }, + { "name": "swig" }, + { "name": "vswhere" }, + { + "name": "julia", + "args": [ "--ia", "/DIR=C:\\Julia" ] + }, + { "name": "imagemagick" } + ] + }, + "node": { + "default": "24.*" + }, + "maven": { + "version": "3.9" + }, + "mysql": { + "version": "8.0" + }, + "mongodb": { + "version": "5.0" + }, + "nsis": { + "version": "3.10" + }, + "llvm": { + "version": "20.1.6" + }, + "php": { + "version": "8.4" + }, + "postgresql": { + "version": "14" + }, + "kotlin": { + "version": "latest" + }, + "openssl": { + "version": "3.*" + }, + "pwsh": { + "version": "7.4" + } +} From 952ac23b4f0280676b6f95d0e6f3625733c7d73e Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Wed, 25 Mar 2026 00:54:39 +0100 Subject: [PATCH 24/55] remove vs workloads --- images/windows/toolsets/toolset-win-11-vs2026-arm64.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/images/windows/toolsets/toolset-win-11-vs2026-arm64.json b/images/windows/toolsets/toolset-win-11-vs2026-arm64.json index b9a0edbb27..642ac98df7 100644 --- a/images/windows/toolsets/toolset-win-11-vs2026-arm64.json +++ b/images/windows/toolsets/toolset-win-11-vs2026-arm64.json @@ -133,7 +133,6 @@ "workloads": [ "Component.Linux.CMake", "Component.Unreal.Android", - "Component.Xamarin", "Microsoft.Component.VC.Runtime.UCRTSDK", "Microsoft.Net.Component.4.7.2.SDK", "Microsoft.Net.Component.4.7.TargetingPack", @@ -170,7 +169,6 @@ "Microsoft.VisualStudio.Component.VC.ATL.ARM64.Spectre", "Microsoft.VisualStudio.Component.VC.ASAN", "Microsoft.VisualStudio.Component.VC.14.44.17.14.ARM64", - "Microsoft.VisualStudio.Component.Windows10SDK.19041", "Microsoft.VisualStudio.Component.Windows11SDK.22621", "Microsoft.VisualStudio.Component.Windows11SDK.26100", "Microsoft.VisualStudio.ComponentGroup.NativeDesktop.Llvm.Clang", From bb7bd5538a93229bab2424b2a29c9aee738c61da Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Mon, 16 Mar 2026 13:01:46 +0100 Subject: [PATCH 25/55] Add win11-arm template and toolset --- .../templates/build.windows-11-arm64.pkr.hcl | 279 ++++++++++++++++ .../windows/templates/locals.windows.pkr.hcl | 4 + .../toolsets/toolset-win-11-arm64.json | 315 ++++++++++++++++++ 3 files changed, 598 insertions(+) create mode 100644 images/windows/templates/build.windows-11-arm64.pkr.hcl create mode 100644 images/windows/toolsets/toolset-win-11-arm64.json diff --git a/images/windows/templates/build.windows-11-arm64.pkr.hcl b/images/windows/templates/build.windows-11-arm64.pkr.hcl new file mode 100644 index 0000000000..b37c591b4b --- /dev/null +++ b/images/windows/templates/build.windows-11-arm64.pkr.hcl @@ -0,0 +1,279 @@ +build { + sources = ["source.azure-arm.image"] + name = "windows-11-arm64" + + provisioner "powershell" { + inline = [ + "New-Item -Path ${var.image_folder} -ItemType Directory -Force", + "New-Item -Path ${var.temp_dir} -ItemType Directory -Force" + ] + } + + provisioner "file" { + destination = "${var.image_folder}\\" + sources = [ + "${path.root}/../assets", + "${path.root}/../scripts", + "${path.root}/../toolsets" + ] + } + + provisioner "file" { + destination = "${var.image_folder}\\scripts\\docs-gen\\" + source = "${path.root}/../../../helpers/software-report-base" + } + + provisioner "powershell" { + inline = [ + "Move-Item '${var.image_folder}\\assets\\post-gen' 'C:\\post-generation'", + "Remove-Item -Recurse '${var.image_folder}\\assets'", + "Move-Item '${var.image_folder}\\scripts\\docs-gen' '${var.image_folder}\\SoftwareReport'", + "Move-Item '${var.image_folder}\\scripts\\helpers' '${var.helper_script_folder}\\ImageHelpers'", + "New-Item -Type Directory -Path '${var.helper_script_folder}\\TestsHelpers\\'", + "Move-Item '${var.image_folder}\\scripts\\tests\\Helpers.psm1' '${var.helper_script_folder}\\TestsHelpers\\TestsHelpers.psm1'", + "Move-Item '${var.image_folder}\\scripts\\tests' '${var.image_folder}\\tests'", + "Remove-Item -Recurse '${var.image_folder}\\scripts'", + "Move-Item '${var.image_folder}\\toolsets\\toolset-win-11-arm64.json' '${var.image_folder}\\toolset.json'", + "Remove-Item -Recurse '${var.image_folder}\\toolsets'" + ] + } + + provisioner "windows-shell" { + inline = [ + "net user ${var.install_user} ${var.install_password} /add /passwordchg:no /passwordreq:yes /active:yes /Y", + "net localgroup Administrators ${var.install_user} /add", + "winrm set winrm/config/service/auth @{Basic=\"true\"}", + "winrm get winrm/config/service/auth" + ] + } + + provisioner "powershell" { + inline = ["if (-not ((net localgroup Administrators) -contains '${var.install_user}')) { exit 1 }"] + } + + provisioner "powershell" { + elevated_password = "${var.install_password}" + elevated_user = "${var.install_user}" + inline = ["bcdedit.exe /set TESTSIGNING ON"] + } + + provisioner "powershell" { + environment_vars = ["IMAGE_VERSION=${var.image_version}", "IMAGE_OS=${var.image_os}", "AGENT_TOOLSDIRECTORY=${var.agent_tools_directory}", "IMAGEDATA_FILE=${var.imagedata_file}", "IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] + execution_policy = "unrestricted" + scripts = [ + "${path.root}/../scripts/build/Configure-WindowsDefender.ps1", + "${path.root}/../scripts/build/Configure-PowerShell.ps1", + "${path.root}/../scripts/build/Install-PowerShellModules.ps1", + # "${path.root}/../scripts/build/Install-WSL2.ps1", + "${path.root}/../scripts/build/Install-WindowsFeatures.ps1", + "${path.root}/../scripts/build/Install-Chocolatey.ps1", + "${path.root}/../scripts/build/Configure-BaseImage.ps1", + "${path.root}/../scripts/build/Configure-ImageDataFile.ps1", + "${path.root}/../scripts/build/Configure-SystemEnvironment.ps1", + "${path.root}/../scripts/build/Configure-DotnetSecureChannel.ps1" + ] + } + + provisioner "windows-restart" { + check_registry = true + restart_check_command = "powershell -command \"& {while ( (Get-WindowsOptionalFeature -Online -FeatureName Containers -ErrorAction SilentlyContinue).State -ne 'Enabled' ) { Start-Sleep 30; Write-Output 'InProgress' }}\"" + restart_timeout = "10m" + } + + provisioner "powershell" { + inline = ["Set-Service -Name wlansvc -StartupType Manual", "if ($(Get-Service -Name wlansvc).Status -eq 'Running') { Stop-Service -Name wlansvc}"] + } + + provisioner "powershell" { + environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] + scripts = [ + # "${path.root}/../scripts/build/Install-Docker.ps1", + # "${path.root}/../scripts/build/Install-DockerWinCred.ps1", + # "${path.root}/../scripts/build/Install-DockerCompose.ps1", + "${path.root}/../scripts/build/Install-PowershellCore.ps1", + "${path.root}/../scripts/build/Install-WebPlatformInstaller.ps1" + ] + } + + provisioner "windows-restart" { + restart_timeout = "30m" + } + + provisioner "powershell" { + elevated_password = "${var.install_password}" + elevated_user = "${var.install_user}" + environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] + scripts = [ + "${path.root}/../scripts/build/Install-VisualStudio.ps1", + "${path.root}/../scripts/build/Install-KubernetesTools.ps1" + ] + valid_exit_codes = [0, 3010] + } + + provisioner "windows-restart" { + check_registry = true + restart_timeout = "10m" + } + + # TODO: + # 1. Add ${path.root}/../scripts/build/Install-CMake.ps1 + # 2. Add ${path.root}/../scripts/build/Install-Ninja.ps1 + # 3. Check if need to move ${path.root}/../scripts/build/Install-LLVM.ps1 into this block + provisioner "powershell" { + pause_before = "2m0s" + environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] + scripts = [ + # "${path.root}/../scripts/build/Install-Wix.ps1", + "${path.root}/../scripts/build/Install-WDK.ps1", + "${path.root}/../scripts/build/Install-VSExtensions.ps1", + "${path.root}/../scripts/build/Install-AzureCli.ps1", + "${path.root}/../scripts/build/Install-AzureDevOpsCli.ps1", + "${path.root}/../scripts/build/Install-ChocolateyPackages.ps1", + "${path.root}/../scripts/build/Install-JavaTools.ps1", + "${path.root}/../scripts/build/Install-Kotlin.ps1", + "${path.root}/../scripts/build/Install-OpenSSL.ps1" + ] + } + + provisioner "powershell" { + execution_policy = "remotesigned" + environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] + scripts = ["${path.root}/../scripts/build/Install-ServiceFabricSDK.ps1"] + } + + provisioner "windows-restart" { + restart_timeout = "10m" + } + + # TODO: + # 1. Add ${path.root}/../scripts/build/Install-Mercurial.ps1 + # 2. Add ${path.root}/../scripts/build/Install-NSIS.ps1 + # 3. Add ${path.root}/../scripts/build/Install-AliyunCli.ps1 + provisioner "powershell" { + environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] + scripts = [ + "${path.root}/../scripts/build/Install-ActionsCache.ps1", + "${path.root}/../scripts/build/Install-Ruby.ps1", + # "${path.root}/../scripts/build/Install-PyPy.ps1", + "${path.root}/../scripts/build/Install-Toolset.ps1", + "${path.root}/../scripts/build/Configure-Toolset.ps1", + "${path.root}/../scripts/build/Install-NodeJS.ps1", + # "${path.root}/../scripts/build/Install-AndroidSDK.ps1", + "${path.root}/../scripts/build/Install-PowershellAzModules.ps1", + "${path.root}/../scripts/build/Install-Pipx.ps1", + "${path.root}/../scripts/build/Install-Git.ps1", + "${path.root}/../scripts/build/Install-GitHub-CLI.ps1", + "${path.root}/../scripts/build/Install-PHP.ps1", + "${path.root}/../scripts/build/Install-Rust.ps1", + "${path.root}/../scripts/build/Install-Sbt.ps1", + "${path.root}/../scripts/build/Install-Chrome.ps1", + "${path.root}/../scripts/build/Install-EdgeDriver.ps1", + "${path.root}/../scripts/build/Install-Firefox.ps1", + "${path.root}/../scripts/build/Install-Selenium.ps1", + "${path.root}/../scripts/build/Install-IEWebDriver.ps1", + "${path.root}/../scripts/build/Install-Apache.ps1", + "${path.root}/../scripts/build/Install-Nginx.ps1", + # "${path.root}/../scripts/build/Install-Msys2.ps1", + "${path.root}/../scripts/build/Install-WinAppDriver.ps1", + "${path.root}/../scripts/build/Install-R.ps1", + "${path.root}/../scripts/build/Install-AWSTools.ps1", + "${path.root}/../scripts/build/Install-DACFx.ps1", + "${path.root}/../scripts/build/Install-MysqlCli.ps1", + "${path.root}/../scripts/build/Install-SQLPowerShellTools.ps1", + "${path.root}/../scripts/build/Install-SQLOLEDBDriver.ps1", + "${path.root}/../scripts/build/Install-DotnetSDK.ps1", + "${path.root}/../scripts/build/Install-Mingw64.ps1", + # "${path.root}/../scripts/build/Install-Haskell.ps1", + "${path.root}/../scripts/build/Install-Stack.ps1", + # "${path.root}/../scripts/build/Install-Miniconda.ps1", + "${path.root}/../scripts/build/Install-AzureCosmosDbEmulator.ps1", + # "${path.root}/../scripts/build/Install-Zstd.ps1", + "${path.root}/../scripts/build/Install-Vcpkg.ps1", + "${path.root}/../scripts/build/Install-Bazel.ps1", + "${path.root}/../scripts/build/Install-RootCA.ps1", + # "${path.root}/../scripts/build/Install-MongoDB.ps1", + "${path.root}/../scripts/build/Install-CodeQLBundle.ps1", + "${path.root}/../scripts/build/Configure-Diagnostics.ps1" + ] + } + + provisioner "powershell" { + elevated_password = "${var.install_password}" + elevated_user = "${var.install_user}" + environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] + scripts = [ + # "${path.root}/../scripts/build/Install-PostgreSQL.ps1", + "${path.root}/../scripts/build/Install-WindowsUpdates.ps1", + "${path.root}/../scripts/build/Configure-DynamicPort.ps1", + "${path.root}/../scripts/build/Configure-GDIProcessHandleQuota.ps1", + "${path.root}/../scripts/build/Configure-Shell.ps1", + "${path.root}/../scripts/build/Configure-DeveloperMode.ps1", + "${path.root}/../scripts/build/Install-LLVM.ps1" + ] + } + + provisioner "windows-restart" { + check_registry = true + restart_check_command = "powershell -command \"& {if ((-not (Get-Process TiWorker.exe -ErrorAction SilentlyContinue)) -and (-not [System.Environment]::HasShutdownStarted) ) { Write-Output 'Restart complete' }}\"" + restart_timeout = "30m" + } + + provisioner "powershell" { + pause_before = "2m0s" + environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] + scripts = [ + "${path.root}/../scripts/build/Install-WindowsUpdatesAfterReboot.ps1", + "${path.root}/../scripts/build/Invoke-Cleanup.ps1", + "${path.root}/../scripts/tests/RunAll-Tests.ps1" + ] + } + + provisioner "powershell" { + inline = ["if (-not (Test-Path ${var.image_folder}\\tests\\testResults.xml)) { throw '${var.image_folder}\\tests\\testResults.xml not found' }"] + } + + provisioner "powershell" { + environment_vars = ["IMAGE_VERSION=${var.image_version}", "IMAGE_FOLDER=${var.image_folder}"] + inline = ["pwsh -File '${var.image_folder}\\SoftwareReport\\Generate-SoftwareReport.ps1'"] + } + + provisioner "powershell" { + inline = ["if (-not (Test-Path C:\\software-report.md)) { throw 'C:\\software-report.md not found' }", "if (-not (Test-Path C:\\software-report.json)) { throw 'C:\\software-report.json not found' }"] + } + + provisioner "file" { + destination = "${path.root}/../Windows11-arm-Readme.md" + direction = "download" + source = "C:\\software-report.md" + } + + provisioner "file" { + destination = "${path.root}/../software-report.json" + direction = "download" + source = "C:\\software-report.json" + } + + provisioner "powershell" { + environment_vars = ["INSTALL_USER=${var.install_user}"] + scripts = [ + "${path.root}/../scripts/build/Install-NativeImages.ps1", + "${path.root}/../scripts/build/Configure-System.ps1", + "${path.root}/../scripts/build/Configure-User.ps1", + "${path.root}/../scripts/build/Post-Build-Validation.ps1" + ] + skip_clean = true + } + + provisioner "windows-restart" { + restart_timeout = "10m" + } + + provisioner "powershell" { + inline = [ + "if( Test-Path $env:SystemRoot\\System32\\Sysprep\\unattend.xml ){ rm $env:SystemRoot\\System32\\Sysprep\\unattend.xml -Force}", + "& $env:SystemRoot\\System32\\Sysprep\\Sysprep.exe /oobe /generalize /mode:vm /quiet /quit", + "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 } }" + ] + } + +} diff --git a/images/windows/templates/locals.windows.pkr.hcl b/images/windows/templates/locals.windows.pkr.hcl index 6cca76993e..9fb08913d9 100644 --- a/images/windows/templates/locals.windows.pkr.hcl +++ b/images/windows/templates/locals.windows.pkr.hcl @@ -12,6 +12,10 @@ locals { source_image_marketplace_sku = "MicrosoftWindowsServer:WindowsServer:2025-Datacenter-g2" os_disk_size_gb = 150 } + "win11-arm64" = { + source_image_marketplace_sku = "windows11preview-arm64:microsoftwindowsdesktop:win11-25h2-ent:latest" + os_disk_size_gb = 256 + } } source_image_marketplace_sku = local.image_properties_map[var.image_os].source_image_marketplace_sku diff --git a/images/windows/toolsets/toolset-win-11-arm64.json b/images/windows/toolsets/toolset-win-11-arm64.json new file mode 100644 index 0000000000..0aa1f7e7d5 --- /dev/null +++ b/images/windows/toolsets/toolset-win-11-arm64.json @@ -0,0 +1,315 @@ +{ + "toolcache": [ + { + "name": "Ruby", + "arch": "aarch64", + "platform" : "win32", + "versions": [ + "3.4" + ], + "default": "3.4" + }, + { + "name": "Python", + "url" : "https://raw.githubusercontent.com/actions/python-versions/main/versions-manifest.json", + "arch": "x64", + "platform" : "win32", + "versions": [ + "3.13.*" + ] + }, + { + "name": "Python", + "url" : "https://raw.githubusercontent.com/actions/python-versions/main/versions-manifest.json", + "arch": "arm64", + "platform" : "win32", + "versions": [ + "3.12.*", + "3.13.*", + "3.14.*" + ], + "default": "3.13.*" + }, + { + "name": "node", + "url" : "https://raw.githubusercontent.com/actions/node-versions/main/versions-manifest.json", + "arch": "arm64", + "platform" : "win32", + "versions": [ + "20.*", + "22.*", + "24.*" + ] + }, + { + "name": "go", + "url" : "https://raw.githubusercontent.com/actions/go-versions/main/versions-manifest.json", + "arch": "arm64", + "platform" : "win32", + "versions": [ + "1.22.*", + "1.23.*", + "1.24.*", + "1.25.*" + ], + "default": "1.24.*" + } + ], + "powershellModules": [ + { "name": "DockerMsftProvider" }, + { "name": "MarkdownPS" }, + { "name": "Pester" }, + { "name": "PowerShellGet" }, + { "name": "PSScriptAnalyzer" }, + { "name": "PSWindowsUpdate" }, + { "name": "SqlServer" }, + { "name": "VSSetup" }, + { "name": "Microsoft.Graph" }, + { "name": "AWSPowershell" } + ], + "azureModules": [ + { + "name": "az", + "versions": [ + "12.5.0" + ], + "zip_versions": [ + + ] + } + ], + "java": { + "default": "21", + "versions": [ "21", "23" ] + }, + "android": { + "commandline_tools_url": "https://dl.google.com/android/repository/commandlinetools-win-9123335_latest.zip", + "hash": "8A90E6A3DEB2FA13229B2E335EFD07687DCC8A55A3C544DA9F40B41404993E7D", + "platform_min_version": "31", + "build_tools_min_version": "31.0.0", + "extras": [ + "android;m2repository", + "google;m2repository", + "google;google_play_services" + ], + "addons": [], + "additional_tools": [ + "cmake;3.18.1", + "cmake;3.22.1" + ], + "ndk": { + "default": "27", + "versions": [ + "26", "27", "28" + ] + } + }, + "mingw": { + "version": "14.*", + "runtime": "ucrt" + }, + "MsysPackages": { + "msys2": [], + "mingw": [] + }, + "windowsFeatures": [ + { "name": "Containers", "optionalFeature": true }, + { "name": "Microsoft-Windows-Subsystem-Linux", "optionalFeature": true }, + { "name": "VirtualMachinePlatform", "optionalFeature": true }, + { "name": "NetFx4-AdvSrvs", "optionalFeature": true }, + { "name": "Client-ProjFS", "optionalFeature": true }, + { "name": "Microsoft-Hyper-V-All", "optionalFeature": true }, + { "name": "Microsoft-Hyper-V", "optionalFeature": true }, + { "name": "Microsoft-Hyper-V-Tools-All", "optionalFeature": true }, + { "name": "Microsoft-Hyper-V-Hypervisor", "optionalFeature": true }, + { "name": "Microsoft-Hyper-V-Management-PowerShell", "optionalFeature": true } + ], + "visualStudio": { + "version" : "2022", + "subversion" : "17", + "edition" : "Enterprise", + "channel": "release", + "installChannel": "", + "workloads": [ + "Component.Dotfuscator", + "Component.Linux.CMake", + "Component.Unreal.Android", + "Component.Xamarin", + "Microsoft.Component.VC.Runtime.UCRTSDK", + "Microsoft.Net.Component.4.7.2.SDK", + "Microsoft.Net.Component.4.7.TargetingPack", + "Microsoft.Net.Component.4.7.2.TargetingPack", + "Microsoft.Net.Component.4.8.1.SDK", + "Microsoft.Net.Component.4.8.1.TargetingPack", + "Microsoft.VisualStudio.Component.AspNet45", + "Microsoft.VisualStudio.Component.Debugger.JustInTime", + "Microsoft.VisualStudio.Component.EntityFramework", + "Microsoft.VisualStudio.Component.DslTools", + "Microsoft.VisualStudio.Component.SQL.SSDT", + "Microsoft.VisualStudio.Component.PortableLibrary", + "Microsoft.VisualStudio.Component.TestTools.CodedUITest", + "Microsoft.VisualStudio.Component.TestTools.WebLoadTest", + "Microsoft.VisualStudio.Component.UWP.VC.ARM64", + "Microsoft.VisualStudio.Component.UWP.VC.ARM64EC", + "Microsoft.VisualStudio.Component.VC.CLI.Support", + "Microsoft.VisualStudio.Component.VC.CMake.Project", + "Microsoft.VisualStudio.Component.VC.DiagnosticTools", + "Microsoft.VisualStudio.Component.VC.Llvm.Clang", + "Microsoft.VisualStudio.Component.VC.Llvm.ClangToolset", + "Microsoft.VisualStudio.Component.VC.TestAdapterForBoostTest", + "Microsoft.VisualStudio.Component.VC.TestAdapterForGoogleTest", + "Microsoft.VisualStudio.Component.VC.Tools.ARM", + "Microsoft.VisualStudio.Component.VC.Tools.ARM64", + "Microsoft.VisualStudio.Component.VC.Tools.ARM64EC", + "Microsoft.VisualStudio.Component.VC.Redist.MSM", + "Microsoft.VisualStudio.Component.VC.Runtimes.ARM.Spectre", + "Microsoft.VisualStudio.Component.VC.Runtimes.ARM64.Spectre", + "Microsoft.VisualStudio.Component.VC.Runtimes.ARM64EC.Spectre", + "Microsoft.VisualStudio.Component.VC.MFC.ARM64", + "Microsoft.VisualStudio.Component.VC.MFC.ARM64.Spectre", + "Microsoft.VisualStudio.Component.VC.ATLMFC", + "Microsoft.VisualStudio.Component.VC.ATLMFC.Spectre", + "Microsoft.VisualStudio.Component.VC.ATL", + "Microsoft.VisualStudio.Component.VC.ATL.Spectre", + "Microsoft.VisualStudio.Component.VC.ATL.ARM", + "Microsoft.VisualStudio.Component.VC.ATL.ARM.Spectre", + "Microsoft.VisualStudio.Component.VC.ATL.ARM64", + "Microsoft.VisualStudio.Component.VC.ATL.ARM64.Spectre", + "Microsoft.VisualStudio.Component.VC.ASAN", + "Microsoft.VisualStudio.Component.Windows10SDK.19041", + "Microsoft.VisualStudio.Component.Windows11SDK.22621", + "Microsoft.VisualStudio.Component.Windows11SDK.26100", + "Microsoft.VisualStudio.ComponentGroup.NativeDesktop.Llvm.Clang", + "Microsoft.VisualStudio.ComponentGroup.UWP.VC.v142", + "Microsoft.VisualStudio.ComponentGroup.Web.CloudTools", + "Microsoft.VisualStudio.Workload.ManagedDesktop", + "Microsoft.VisualStudio.Workload.ManagedGame", + "Microsoft.VisualStudio.Workload.NativeCrossPlat", + "Microsoft.VisualStudio.Workload.NativeDesktop", + "Microsoft.VisualStudio.Workload.NativeGame", + "Microsoft.VisualStudio.Workload.NetCrossPlat", + "Microsoft.VisualStudio.Workload.NetWeb", + "Microsoft.VisualStudio.Workload.Node", + "Microsoft.VisualStudio.Workload.Universal", + "Microsoft.VisualStudio.Workload.VisualStudioExtension", + "Component.MDD.Linux", + "Component.Microsoft.Windows.DriverKit", + "wasm.tools", + "Microsoft.Component.MSBuild" + ], + "vsix": [ + "SSIS.MicrosoftDataToolsIntegrationServices", + "VisualStudioClient.MicrosoftVisualStudio2022InstallerProjectsArm64" + ] + }, + "docker": { + "images": [ + "mcr.microsoft.com/windows/servercore:ltsc2022", + "mcr.microsoft.com/windows/nanoserver:ltsc2022", + "mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2022", + "mcr.microsoft.com/dotnet/framework/runtime:4.8-windowsservercore-ltsc2022", + "mcr.microsoft.com/dotnet/framework/sdk:4.8-windowsservercore-ltsc2022" + ], + "components": { + "docker": "26.1.3", + "compose": "2.27.1" + } + }, + "pipx": [ + { + "package": "yamllint", + "cmd": "yamllint --version" + } + ], + "selenium": { + "version": "4" + }, + "npm": { + "global_packages": [ + { "name": "yarn", "test": "yarn --version" }, + { "name": "newman", "test": "newman --version" }, + { "name": "lerna", "test": "lerna --version" }, + { "name": "gulp-cli", "test": "gulp --version" }, + { "name": "grunt-cli", "test": "grunt --version" } + ] + }, + "serviceFabric": { + "runtime": { + "version": "10.1.2493.9590", + "checksum": "09C63A971BACDE338282C73B3C9174BED9AAD53E1D3A1B73D44515852C9C00CF" + }, + "sdk": { + "version": "7.1.2493", + "checksum": "0CB1084156C75CF5075EA91ABA330CF10B58648B8E036C9C2F286805263C497F" + } + }, + "dotnet": { + "versions": [ + "6.0", + "8.0", + "9.0", + "10.0" + ], + "tools": [ + { "name": "nbgv", "test": "nbgv --version", "getversion": "nbgv --version" } + ], + "warmup": false + }, + "choco": { + "common_packages": [ + { "name": "7zip.install" }, + { "name": "aria2" }, + { "name": "azcopy10" }, + { "name": "Bicep" }, + { "name": "innosetup" }, + { "name": "jq" }, + { "name": "NuGet.CommandLine" }, + { "name": "packer" }, + { + "name": "strawberryperl" , + "args": [ "--version", "5.32.1.1" ] + }, + { "name": "pulumi" }, + { "name": "swig" }, + { "name": "vswhere" }, + { + "name": "julia", + "args": [ "--ia", "/DIR=C:\\Julia" ] + }, + { "name": "imagemagick" } + ] + }, + "node": { + "default": "24.*" + }, + "maven": { + "version": "3.9" + }, + "mysql": { + "version": "8.0" + }, + "mongodb": { + "version": "5.0" + }, + "nsis": { + "version": "3.10" + }, + "llvm": { + "version": "20.1.6" + }, + "php": { + "version": "8.4" + }, + "postgresql": { + "version": "14" + }, + "kotlin": { + "version": "latest" + }, + "openssl": { + "version": "3.*" + }, + "pwsh": { + "version": "7.4" + } +} From 65410c84031092f6ff91a7a9e9d4e77a9d7c1ef7 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Mon, 16 Mar 2026 13:46:06 +0100 Subject: [PATCH 26/55] Update Install Helpers --- images/windows/scripts/helpers/ImageHelpers.psm1 | 1 + .../windows/scripts/helpers/InstallHelpers.ps1 | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/images/windows/scripts/helpers/ImageHelpers.psm1 b/images/windows/scripts/helpers/ImageHelpers.psm1 index 4ebbd8fc88..8915ef9367 100644 --- a/images/windows/scripts/helpers/ImageHelpers.psm1 +++ b/images/windows/scripts/helpers/ImageHelpers.psm1 @@ -25,6 +25,7 @@ Export-ModuleMember -Function @( 'Get-TCToolVersionPath' 'Test-IsWin25' 'Test-IsWin22' + 'Test-IsWin11' 'Expand-7ZipArchive' 'Get-WindowsUpdateStates' 'Invoke-ScriptBlockWithRetry' diff --git a/images/windows/scripts/helpers/InstallHelpers.ps1 b/images/windows/scripts/helpers/InstallHelpers.ps1 index 032e8b58be..06b57609c0 100644 --- a/images/windows/scripts/helpers/InstallHelpers.ps1 +++ b/images/windows/scripts/helpers/InstallHelpers.ps1 @@ -356,6 +356,22 @@ function Test-IsWin22 { (Get-CimInstance -ClassName Win32_OperatingSystem).Caption -match "2022" } +function Test-IsWin11 { + <# + .SYNOPSIS + Checks if the current Windows operating system is Windows 11. + .DESCRIPTION + This function uses the Get-CimInstance cmdlet to retrieve information + about the current Windows operating system. It then checks if the Caption + property of the Win32_OperatingSystem class contains the string "Windows 11", + indicating that the operating system is Windows 11. + .OUTPUTS + Returns $true if the current Windows operating system is Windows 11. + Otherwise, returns $false. + #> + (Get-CimInstance -ClassName Win32_OperatingSystem).Caption -match "Windows 11" +} + function Expand-7ZipArchive { <# .SYNOPSIS From 045b85c3762b806af1aa995bd98263c3ab2acbec Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Wed, 18 Mar 2026 18:43:13 +0100 Subject: [PATCH 27/55] Modify codebase to support Arm --- .../scripts/build/Configure-BaseImage.ps1 | 5 +- .../scripts/build/Configure-ImageDataFile.ps1 | 6 +- .../windows/scripts/build/Configure-Shell.ps1 | 4 +- .../scripts/build/Configure-Toolset.ps1 | 8 ++- .../windows/scripts/build/Configure-User.ps1 | 4 +- .../windows/scripts/build/Install-CMake.ps1 | 35 +++++++++ .../windows/scripts/build/Install-Chrome.ps1 | 8 ++- .../scripts/build/Install-DotnetSDK.ps1 | 25 +++---- .../scripts/build/Install-EdgeDriver.ps1 | 8 ++- .../windows/scripts/build/Install-Firefox.ps1 | 12 +++- images/windows/scripts/build/Install-Git.ps1 | 9 ++- .../scripts/build/Install-GitHub-CLI.ps1 | 9 ++- .../scripts/build/Install-JavaTools.ps1 | 16 +++-- images/windows/scripts/build/Install-LLVM.ps1 | 32 ++++++++- .../scripts/build/Install-NativeImages.ps1 | 20 +++--- .../windows/scripts/build/Install-Ninja.ps1 | 28 ++++++++ .../windows/scripts/build/Install-NodeJS.ps1 | 8 ++- .../windows/scripts/build/Install-OpenSSL.ps1 | 8 ++- .../scripts/build/Install-PowershellCore.ps1 | 8 ++- images/windows/scripts/build/Install-R.ps1 | 9 ++- images/windows/scripts/build/Install-Ruby.ps1 | 14 +++- images/windows/scripts/build/Install-Rust.ps1 | 24 +++++-- .../scripts/build/Install-VisualStudio.ps1 | 9 ++- images/windows/scripts/build/Install-WDK.ps1 | 3 + .../docs-gen/Generate-SoftwareReport.ps1 | 71 ++++++++++++------- .../docs-gen/SoftwareReport.CachedTools.psm1 | 2 +- .../scripts/docs-gen/SoftwareReport.Java.psm1 | 6 +- .../windows/scripts/helpers/ImageHelpers.psm1 | 1 + .../scripts/helpers/InstallHelpers.ps1 | 16 +++++ .../scripts/helpers/VisualStudioHelpers.ps1 | 5 +- .../windows/scripts/tests/Android.Tests.ps1 | 2 +- .../scripts/tests/ChocoPackages.Tests.ps1 | 6 +- .../windows/scripts/tests/Databases.Tests.ps1 | 4 +- images/windows/scripts/tests/Docker.Tests.ps1 | 8 +-- .../windows/scripts/tests/Haskell.Tests.ps1 | 2 +- images/windows/scripts/tests/Java.Tests.ps1 | 12 +++- images/windows/scripts/tests/MSYS2.Tests.ps1 | 4 +- .../windows/scripts/tests/Miniconda.Tests.ps1 | 4 +- images/windows/scripts/tests/Shell.Tests.ps1 | 2 +- images/windows/scripts/tests/Tools.Tests.ps1 | 38 +++++++++- .../windows/scripts/tests/Toolset.Tests.ps1 | 4 ++ .../scripts/tests/VisualStudio.Tests.ps1 | 2 +- images/windows/scripts/tests/Wix.Tests.ps1 | 2 +- .../templates/build.windows-11-arm64.pkr.hcl | 19 +++-- .../toolsets/toolset-win-11-arm64.json | 2 +- 45 files changed, 409 insertions(+), 115 deletions(-) create mode 100644 images/windows/scripts/build/Install-CMake.ps1 create mode 100644 images/windows/scripts/build/Install-Ninja.ps1 diff --git a/images/windows/scripts/build/Configure-BaseImage.ps1 b/images/windows/scripts/build/Configure-BaseImage.ps1 index b1b963eb5a..8caf55460c 100644 --- a/images/windows/scripts/build/Configure-BaseImage.ps1 +++ b/images/windows/scripts/build/Configure-BaseImage.ps1 @@ -44,7 +44,10 @@ function Disable-WindowsUpdate { Add-Content -Path $profile.AllUsersAllHosts -Value '$ErrorActionPreference="Stop"' Write-Host "Disable Server Manager on Logon" -Get-ScheduledTask -TaskName ServerManager | Disable-ScheduledTask +$srvManagerTask = Get-ScheduledTask -TaskName ServerManager +if ($srvManagerTask) { + Disable-ScheduledTask -TaskName ServerManager +} Write-Host "Disable 'Allow your PC to be discoverable by other PCs' popup" New-Item -Path HKLM:\System\CurrentControlSet\Control\Network -Name NewNetworkWindowOff -Force diff --git a/images/windows/scripts/build/Configure-ImageDataFile.ps1 b/images/windows/scripts/build/Configure-ImageDataFile.ps1 index d0b73effa6..5abbc42430 100644 --- a/images/windows/scripts/build/Configure-ImageDataFile.ps1 +++ b/images/windows/scripts/build/Configure-ImageDataFile.ps1 @@ -27,8 +27,12 @@ if ((Test-IsWin25) -and $env:INSTALL_VS_2026) { $imageLabel = "windows-2022" $softwareUrl = "${githubUrl}/win22/$imageMajorVersion.$imageMinorVersion/images/windows/Windows2022-Readme.md" $releaseUrl = "https://github.com/actions/runner-images/releases/tag/win22%2F$imageMajorVersion.$imageMinorVersion" +} elseif ((Test-IsWin11) -and (Test-IsArm64)) { + $imageLabel = "windows-11-arm64" + $softwareUrl = "${githubUrl}/win11-arm64/$imageMajorVersion.$imageMinorVersion/images/windows/Windows11-Arm64-Readme.md" + $releaseUrl = "https://github.com/actions/runner-images/releases/tag/win11-arm64%2F$imageMajorVersion.$imageMinorVersion" } else { - throw "Invalid platform version is found. Either Windows Server 2022 or 2025 are required" + throw "Invalid platform version is found. Either Windows Server 2022, 2025 or Windows 11 are required" } $json = @" diff --git a/images/windows/scripts/build/Configure-Shell.ps1 b/images/windows/scripts/build/Configure-Shell.ps1 index f9ac961557..334d724a1f 100644 --- a/images/windows/scripts/build/Configure-Shell.ps1 +++ b/images/windows/scripts/build/Configure-Shell.ps1 @@ -2,7 +2,8 @@ $shellPath = "C:\shells" New-Item -Path $shellPath -ItemType Directory | Out-Null -# add a wrapper for C:\msys64\usr\bin\bash.exe +if (-not (Test-IsWin11)) { + # add a wrapper for C:\msys64\usr\bin\bash.exe @' @echo off setlocal @@ -11,6 +12,7 @@ IF NOT DEFINED MSYSTEM set MSYSTEM=mingw64 set CHERE_INVOKING=1 C:\msys64\usr\bin\bash.exe -leo pipefail %* '@ | Out-File -FilePath "$shellPath\msys2bash.cmd" -Encoding ascii +} # gitbash <--> C:\Program Files\Git\bin\bash.exe New-Item -ItemType SymbolicLink -Path "$shellPath\gitbash.exe" -Target "$env:ProgramFiles\Git\bin\bash.exe" | Out-Null diff --git a/images/windows/scripts/build/Configure-Toolset.ps1 b/images/windows/scripts/build/Configure-Toolset.ps1 index de8da36f0a..880f177e27 100644 --- a/images/windows/scripts/build/Configure-Toolset.ps1 +++ b/images/windows/scripts/build/Configure-Toolset.ps1 @@ -4,6 +4,12 @@ ## Desc: Configure Toolset ################################################################################ +if ( Test-IsArm64 ) { + $envVarTemplate = "GOROOT_{0}_{1}_AARCH64" +} else { + $envVarTemplate = "GOROOT_{0}_{1}_X64" +} + $toolEnvConfigs = @{ Python = @{ pathTemplates = @( @@ -15,7 +21,7 @@ $toolEnvConfigs = @{ pathTemplates = @( "{0}\bin" ) - envVarTemplate = "GOROOT_{0}_{1}_X64" + envVarTemplate = $envVarTemplate } } diff --git a/images/windows/scripts/build/Configure-User.ps1 b/images/windows/scripts/build/Configure-User.ps1 index 6ede0d8cc6..63c596c56a 100644 --- a/images/windows/scripts/build/Configure-User.ps1 +++ b/images/windows/scripts/build/Configure-User.ps1 @@ -27,8 +27,8 @@ if ($LASTEXITCODE -ne 0) { throw "Failed to copy HKCU\Software\Microsoft\VisualStudio to HKLM\DEFAULT\Software\Microsoft\VisualStudio" } -# TortoiseSVN not installed on Windows 2025 image due to Sysprep issues -if (-not (Test-IsWin25)) { +# TortoiseSVN not installed on Windows 2025 and Windows 11 due to Sysprep issues +if (-not (Test-IsWin25) -and -not (Test-IsWin11)) { # disable TSVNCache.exe $registryKeyPath = 'HKCU:\Software\TortoiseSVN' if (-not(Test-Path -Path $registryKeyPath)) { diff --git a/images/windows/scripts/build/Install-CMake.ps1 b/images/windows/scripts/build/Install-CMake.ps1 new file mode 100644 index 0000000000..13acab72ff --- /dev/null +++ b/images/windows/scripts/build/Install-CMake.ps1 @@ -0,0 +1,35 @@ +################################################################################ +## File: Install-CMake.ps1 +## Desc: Install CMake (ARM64 only; x64 is installed via Choco) +## Supply chain security: CMake - checksum validation +################################################################################ + +if (-not (Test-IsArm64)) { + exit 0 +} + +# Install CMake +$downloadUrl = Resolve-GithubReleaseAssetUrl ` + -Repo "Kitware/CMake" ` + -Version "latest" ` + -UrlMatchPattern "cmake-*-windows-arm64.msi" + +#region Supply chain security - CMake +$packageName = Split-Path $downloadUrl -Leaf +$checksumsUrl = Resolve-GithubReleaseAssetUrl ` + -Repo "Kitware/CMake" ` + -Version "latest" ` + -UrlMatchPattern "cmake-*-SHA-256.txt" +$externalHash = Get-ChecksumFromUrl -Type "SHA256" ` + -Url $checksumsUrl ` + -FileName $packageName +#endregion + +Install-Binary ` + -Url $downloadUrl ` + -ExtraInstallArgs @("ADD_CMAKE_TO_PATH=System") ` + -ExpectedSHA256Sum $externalHash + +Update-Environment + +Invoke-PesterTests -TestFile "Tools" -TestName "CMake" diff --git a/images/windows/scripts/build/Install-Chrome.ps1 b/images/windows/scripts/build/Install-Chrome.ps1 index f8c98c3fa1..54f5cdb265 100644 --- a/images/windows/scripts/build/Install-Chrome.ps1 +++ b/images/windows/scripts/build/Install-Chrome.ps1 @@ -3,9 +3,15 @@ ## Desc: Install Google Chrome browser and Chrome WebDriver ################################################################################ +if (Test-IsArm64) { + $browserDownloadUrl = "https://dl.google.com/tag/s/dl/chrome/install/googlechromestandaloneenterprise_arm64.msi" +} else { + $browserDownloadUrl = "https://dl.google.com/tag/s/dl/chrome/install/googlechromestandaloneenterprise64.msi" +} + # Download and install latest Chrome browser Install-Binary ` - -Url 'https://dl.google.com/tag/s/dl/chrome/install/googlechromestandaloneenterprise64.msi' ` + -Url $browserDownloadUrl ` -ExpectedSubject 'CN=Google LLC, O=Google LLC, L=Mountain View, S=California, C=US, SERIALNUMBER=3582691, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, OID.1.3.6.1.4.1.311.60.2.1.3=US' # Prepare firewall rules diff --git a/images/windows/scripts/build/Install-DotnetSDK.ps1 b/images/windows/scripts/build/Install-DotnetSDK.ps1 index 793c6a01c5..a1c3b3489c 100644 --- a/images/windows/scripts/build/Install-DotnetSDK.ps1 +++ b/images/windows/scripts/build/Install-DotnetSDK.ps1 @@ -82,9 +82,14 @@ function Install-DotnetSDK { # If installation failed, tests will fail anyway #region Supply chain security + if (Test-IsArm64) { + $expectedArch = "arm64" + } else { + $expectedArch = "x64" + } $releasesJsonUri = "https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/${DotnetVersion}/releases.json" $releasesData = (Invoke-DownloadWithRetry $releasesJsonUri) | Get-Item | Get-Content | ConvertFrom-Json - $distributorFileHash = $releasesData.releases.sdks.Where({ $_.version -eq $SDKVersion }).files.Where({ $_.name -eq 'dotnet-sdk-win-x64.zip' }).hash + $distributorFileHash = $releasesData.releases.sdks.Where({ $_.version -eq $SDKVersion }).files.Where({ $_.name -eq "dotnet-sdk-win-$expectedArch.zip" }).hash Test-FileChecksum $zipPath -ExpectedSHA512Sum $distributorFileHash #endregion } @@ -97,11 +102,9 @@ $installScriptPath = Invoke-DownloadWithRetry -Url "https://dot.net/v1/dotnet-in # Visual Studio 2022 pre-creates sdk-manifests/8.0.100 folder, causing dotnet-install to skip manifests creation # https://github.com/actions/runner-images/issues/11402 -if ((Test-IsWin22) -or (Test-IsWin25)) { - $sdkManifestPath = "C:\Program Files\dotnet\sdk-manifests\8.0.100" - if (Test-Path $sdkManifestPath) { - Move-Item -Path $sdkManifestPath -Destination $env:TEMP_DIR -ErrorAction Stop - } +$sdkManifestPath = "C:\Program Files\dotnet\sdk-manifests\8.0.100" +if (Test-Path $sdkManifestPath) { + Move-Item -Path $sdkManifestPath -Destination $env:TEMP_DIR -ErrorAction Stop } # Install and warm up dotnet @@ -122,12 +125,10 @@ foreach ($dotnetVersion in $dotnetToolset.versions) { # Replace manifests inside sdk-manifests/8.0.100 folder with ones from Visual Studio # https://github.com/actions/runner-images/issues/11402 -if ((Test-IsWin22) -or (Test-IsWin25)) { - if (Test-Path "${env:TEMP_DIR}\8.0.100") { - Get-ChildItem -Path "${env:TEMP_DIR}\8.0.100" | ForEach-Object { - Remove-Item -Path "$sdkManifestPath\$($_.BaseName)" -Recurse -Force | Out-Null - Move-Item -Path $_.FullName -Destination $sdkManifestPath -Force -ErrorAction Stop - } +if (Test-Path "${env:TEMP_DIR}\8.0.100") { + Get-ChildItem -Path "${env:TEMP_DIR}\8.0.100" | ForEach-Object { + Remove-Item -Path "$sdkManifestPath\$($_.BaseName)" -Recurse -Force | Out-Null + Move-Item -Path $_.FullName -Destination $sdkManifestPath -Force -ErrorAction Stop } } diff --git a/images/windows/scripts/build/Install-EdgeDriver.ps1 b/images/windows/scripts/build/Install-EdgeDriver.ps1 index f410ea688a..895f3fd3d7 100644 --- a/images/windows/scripts/build/Install-EdgeDriver.ps1 +++ b/images/windows/scripts/build/Install-EdgeDriver.ps1 @@ -3,6 +3,12 @@ ## Desc: Install Edge WebDriver and configure Microsoft Edge ################################################################################ +if (Test-IsArm64) { + $expectedArch = "arm64" +} else { + $expectedArch = "win64" +} + # Disable Edge auto-updates Rename-Item -Path "C:\Program Files (x86)\Microsoft\EdgeUpdate\MicrosoftEdgeUpdate.exe" -NewName "Disabled_MicrosoftEdgeUpdate.exe" -ErrorAction Stop @@ -20,7 +26,7 @@ $versionInfoFile = Invoke-DownloadWithRetry -Url $versionInfoUrl -Path "$edgeDri $latestVersion = Get-Content -Path $versionInfoFile Write-Host "Download Microsoft Edge WebDriver..." -$downloadUrl = "https://msedgedriver.microsoft.com/$latestVersion/edgedriver_win64.zip" +$downloadUrl = "https://msedgedriver.microsoft.com/$latestVersion/edgedriver_$expectedArch.zip" $archivePath = Invoke-DownloadWithRetry $downloadUrl Write-Host "Expand Microsoft Edge WebDriver archive..." diff --git a/images/windows/scripts/build/Install-Firefox.ps1 b/images/windows/scripts/build/Install-Firefox.ps1 index 984588a3b9..ff9e952d61 100644 --- a/images/windows/scripts/build/Install-Firefox.ps1 +++ b/images/windows/scripts/build/Install-Firefox.ps1 @@ -4,17 +4,23 @@ ## Supply chain security: Firefox browser - checksum validation ################################################################################ +if (Test-IsArm64) { + $expectedArch = "win64-aarch64" +} else { + $expectedArch = "win64" +} + # Install and configure Firefox browser Write-Host "Get the latest Firefox version..." $versionsManifest = Invoke-RestMethod "https://product-details.mozilla.org/1.0/firefox_versions.json" Write-Host "Install Firefox browser..." -$installerUrl = "https://download.mozilla.org/?product=firefox-$($versionsManifest.LATEST_FIREFOX_VERSION)&os=win64&lang=en-US" +$installerUrl = "https://download.mozilla.org/?product=firefox-$($versionsManifest.LATEST_FIREFOX_VERSION)&os=$expectedArch&lang=en-US" $hashUrl = "https://archive.mozilla.org/pub/firefox/releases/$($versionsManifest.LATEST_FIREFOX_VERSION)/SHA256SUMS" $externalHash = Get-ChecksumFromUrl -Type "SHA256" ` -Url $hashUrl ` - -FileName "win64/en-US/Firefox Setup*exe" + -FileName "$expectedArch/en-US/Firefox Setup*exe" Install-Binary -Type EXE ` -Url $installerUrl ` @@ -46,7 +52,7 @@ Write-Host "Download Gecko WebDriver WebDriver..." $geckoDriverDownloadUrl = Resolve-GithubReleaseAssetUrl ` -Repo "mozilla/geckodriver" ` -Version $geckoDriverVersion ` - -UrlMatchPattern "geckodriver-*-win64.zip" + -UrlMatchPattern "geckodriver-*-$expectedArch.zip" $geckoDriverArchPath = Invoke-DownloadWithRetry $geckoDriverDownloadUrl Write-Host "Expand Gecko WebDriver archive..." diff --git a/images/windows/scripts/build/Install-Git.ps1 b/images/windows/scripts/build/Install-Git.ps1 index 0e6843d79b..4be12ddc37 100644 --- a/images/windows/scripts/build/Install-Git.ps1 +++ b/images/windows/scripts/build/Install-Git.ps1 @@ -4,12 +4,17 @@ ## Supply chain security: Git - checksum validation, Hub CLI - managed by package manager ################################################################################ -# Install the latest version of Git for Windows +if (Test-IsArm64) { + $expectedArch = "arm64" +} else { + $expectedArch = "64-bit" +} +# Install the latest version of Git for Windows $downloadUrl = Resolve-GithubReleaseAssetUrl ` -Repo "git-for-windows/git" ` -Version "latest" ` - -UrlMatchPattern "Git-*-64-bit.exe" + -UrlMatchPattern "Git-*-$expectedArch.exe" $externalHash = Get-ChecksumFromGithubRelease ` -Repo "git-for-windows/git" ` diff --git a/images/windows/scripts/build/Install-GitHub-CLI.ps1 b/images/windows/scripts/build/Install-GitHub-CLI.ps1 index 0d1d80fd58..2df04861b8 100644 --- a/images/windows/scripts/build/Install-GitHub-CLI.ps1 +++ b/images/windows/scripts/build/Install-GitHub-CLI.ps1 @@ -4,12 +4,17 @@ ## Supply chain security: GitHub CLI - checksum validation ################################################################################ -Write-Host "Get the latest gh version..." +if (Test-IsArm64) { + $expectedArch = "arm64" +} else { + $expectedArch = "amd64" +} +Write-Host "Get the latest gh version..." $downloadUrl = Resolve-GithubReleaseAssetUrl ` -Repo "cli/cli" ` -Version "latest" ` - -UrlMatchPattern "gh_*_windows_amd64.msi" + -UrlMatchPattern "gh_*_windows_$expectedArch.msi" $checksumsUrl = Resolve-GithubReleaseAssetUrl ` -Repo "cli/cli" ` diff --git a/images/windows/scripts/build/Install-JavaTools.ps1 b/images/windows/scripts/build/Install-JavaTools.ps1 index 5a29a9a15f..7c272f6f81 100644 --- a/images/windows/scripts/build/Install-JavaTools.ps1 +++ b/images/windows/scripts/build/Install-JavaTools.ps1 @@ -19,8 +19,8 @@ function Set-JavaPath { exit 1 } - Write-Host "Set 'JAVA_HOME_${Version}_X64' environmental variable as $javaPath" - [Environment]::SetEnvironmentVariable("JAVA_HOME_${Version}_X64", $javaPath, "Machine") + Write-Host "Set 'JAVA_HOME_${Version}_$($Architecture.ToUpper())' environmental variable as $javaPath" + [Environment]::SetEnvironmentVariable("JAVA_HOME_${Version}_$($Architecture.ToUpper())", $javaPath, "Machine") if ($Default) { # Clean up any other Java folders from PATH to make sure that they won't conflict with each other @@ -91,6 +91,12 @@ function Install-JavaJDK { New-Item -ItemType File -Path $javaVersionPath -Name "$Architecture.complete" | Out-Null } +if (Test-IsArm64) { + $expectedArch = "aarch64" +} else { + $expectedArch = "x64" +} + $toolsetJava = (Get-ToolsetContent).java $defaultVersion = $toolsetJava.default $jdkVersionsToInstall = $toolsetJava.versions @@ -98,12 +104,12 @@ $jdkVersionsToInstall = $toolsetJava.versions foreach ($jdkVersionToInstall in $jdkVersionsToInstall) { $isDefaultVersion = $jdkVersionToInstall -eq $defaultVersion - Install-JavaJDK -JDKVersion $jdkVersionToInstall + Install-JavaJDK -JDKVersion $jdkVersionToInstall -Architecture $expectedArch if ($isDefaultVersion) { - Set-JavaPath -Version $jdkVersionToInstall -Default + Set-JavaPath -Version $jdkVersionToInstall -Architecture $expectedArch -Default } else { - Set-JavaPath -Version $jdkVersionToInstall + Set-JavaPath -Version $jdkVersionToInstall -Architecture $expectedArch } } diff --git a/images/windows/scripts/build/Install-LLVM.ps1 b/images/windows/scripts/build/Install-LLVM.ps1 index 41b8aef951..08883dc7c2 100644 --- a/images/windows/scripts/build/Install-LLVM.ps1 +++ b/images/windows/scripts/build/Install-LLVM.ps1 @@ -1,10 +1,36 @@ ################################################################################ ## File: Install-LLVM.ps1 -## Desc: Install the latest stable version of llvm and clang compilers +## Desc: Install the stable version of llvm and clang compilers ################################################################################ $llvmVersion = (Get-ToolsetContent).llvm.version -$latestChocoVersion = Resolve-ChocoPackageVersion -PackageName "llvm" -TargetVersion $llvmVersion -Install-ChocoPackage llvm -ArgumentList '--version', $latestChocoVersion + +if (Test-IsArm64) { + $installDir = "C:\Program Files\LLVM" + + Write-Host "Resolve LLVM $llvmVersion ARM64 download URL" + $downloadUrl = Resolve-GithubReleaseAssetUrl ` + -Repository "llvm/llvm-project" ` + -Version $llvmVersion ` + -UrlMatchPattern "clang*llvm-*-aarch64-pc-windows-msvc.tar.xz" + + Write-Host "Download LLVM $llvmVersion ARM64 archive" + $archivePath = Invoke-DownloadWithRetry $downloadUrl + + Write-Host "Extract LLVM archive" + $tarPath = $archivePath -replace '\.xz$' + Expand-7ZipArchive -Path $archivePath -DestinationPath (Split-Path $archivePath) + Expand-7ZipArchive -Path $tarPath -DestinationPath $env:TEMP_DIR + + Write-Host "Install LLVM to $installDir" + $extractedDir = Get-ChildItem -Path $env:TEMP_DIR -Directory -Filter "clang+llvm-*" | Select-Object -First 1 + Move-Item -Path $extractedDir.FullName -Destination $installDir -Force + + Add-MachinePathItem (Join-Path $installDir "bin") + Update-Environment +} else { + $latestChocoVersion = Resolve-ChocoPackageVersion -PackageName "llvm" -TargetVersion $llvmVersion + Install-ChocoPackage llvm -ArgumentList '--version', $latestChocoVersion +} Invoke-PesterTests -TestFile "LLVM" diff --git a/images/windows/scripts/build/Install-NativeImages.ps1 b/images/windows/scripts/build/Install-NativeImages.ps1 index 214a9577a6..71d159e151 100644 --- a/images/windows/scripts/build/Install-NativeImages.ps1 +++ b/images/windows/scripts/build/Install-NativeImages.ps1 @@ -9,14 +9,16 @@ if ($LASTEXITCODE -ne 0) { throw "Installation of Microsoft.PowerShell.Utility.Activities failed with exit code $LASTEXITCODE" } -Write-Host "NGen: update x64 native images..." -& $env:SystemRoot\Microsoft.NET\Framework64\v4.0.30319\ngen.exe update | Out-Null -if ($LASTEXITCODE -ne 0) { - throw "Update of x64 native images failed with exit code $LASTEXITCODE" -} +if (-not (Test-IsWin11)) { + Write-Host "NGen: update x64 native images..." + & $env:SystemRoot\Microsoft.NET\Framework64\v4.0.30319\ngen.exe update | Out-Null + if ($LASTEXITCODE -ne 0) { + throw "Update of x64 native images failed with exit code $LASTEXITCODE" + } -Write-Host "NGen: update x86 native images..." -& $env:SystemRoot\Microsoft.NET\Framework\v4.0.30319\ngen.exe update | Out-Null -if ($LASTEXITCODE -ne 0) { - throw "Update of x86 native images failed with exit code $LASTEXITCODE" + Write-Host "NGen: update x86 native images..." + & $env:SystemRoot\Microsoft.NET\Framework\v4.0.30319\ngen.exe update | Out-Null + if ($LASTEXITCODE -ne 0) { + throw "Update of x86 native images failed with exit code $LASTEXITCODE" + } } diff --git a/images/windows/scripts/build/Install-Ninja.ps1 b/images/windows/scripts/build/Install-Ninja.ps1 new file mode 100644 index 0000000000..21c509caae --- /dev/null +++ b/images/windows/scripts/build/Install-Ninja.ps1 @@ -0,0 +1,28 @@ +################################################################################ +## File: Install-Ninja.ps1 +## Desc: Install Ninja build system (ARM64 only; x64 is installed via Choco) +################################################################################ + +if (-not (Test-IsArm64)) { + exit 0 +} + +$installDir = "C:\Tools\Ninja" + +Write-Host "Resolve Ninja latest ARM64 download URL" +$downloadUrl = Resolve-GithubReleaseAssetUrl ` + -Repository "ninja-build/ninja" ` + -Version "latest" ` + -UrlMatchPattern "ninja-winarm64.zip" + +Write-Host "Download Ninja ARM64 archive" +$zipPath = Invoke-DownloadWithRetry $downloadUrl + +Write-Host "Install Ninja to $installDir" +New-Item -ItemType Directory -Path $installDir -Force | Out-Null +Expand-7ZipArchive -Path $zipPath -DestinationPath $installDir + +Add-MachinePathItem $installDir +Update-Environment + +Invoke-PesterTests -TestFile "Tools" -TestName "Ninja" diff --git a/images/windows/scripts/build/Install-NodeJS.ps1 b/images/windows/scripts/build/Install-NodeJS.ps1 index 1063ba8e9d..d65977a451 100644 --- a/images/windows/scripts/build/Install-NodeJS.ps1 +++ b/images/windows/scripts/build/Install-NodeJS.ps1 @@ -7,12 +7,18 @@ $prefixPath = 'C:\npm\prefix' $cachePath = 'C:\npm\cache' +if (Test-IsArm64) { + $expectedArch = "arm64" +} else { + $expectedArch = "x64" +} + New-Item -Path $prefixPath -Force -ItemType Directory New-Item -Path $cachePath -Force -ItemType Directory $defaultVersion = (Get-ToolsetContent).node.default $nodeVersion = (Get-GithubReleasesByVersion -Repo "nodejs/node" -Version "${defaultVersion}").version | Select-Object -First 1 -$downloadUrl = "https://nodejs.org/dist/v${nodeVersion}/node-v${nodeVersion}-x64.msi" +$downloadUrl = "https://nodejs.org/dist/v${nodeVersion}/node-v${nodeVersion}-${expectedArch}.msi" $packageName = Split-Path $downloadUrl -Leaf $externalHash = Get-ChecksumFromUrl -Type "SHA256" ` diff --git a/images/windows/scripts/build/Install-OpenSSL.ps1 b/images/windows/scripts/build/Install-OpenSSL.ps1 index 3717ddc545..f47103749b 100644 --- a/images/windows/scripts/build/Install-OpenSSL.ps1 +++ b/images/windows/scripts/build/Install-OpenSSL.ps1 @@ -4,7 +4,13 @@ ## Supply chain security: checksum validation ################################################################################ -$arch = 'INTEL' +if (Test-IsArm64) { + $expectedArch = "ARM" +} else { + $expectedArch = "INTEL" +} + +$arch = $expectedArch $bits = '64' $light = $false $installerType = "exe" diff --git a/images/windows/scripts/build/Install-PowershellCore.ps1 b/images/windows/scripts/build/Install-PowershellCore.ps1 index 68a3bc80ab..a479526d1b 100644 --- a/images/windows/scripts/build/Install-PowershellCore.ps1 +++ b/images/windows/scripts/build/Install-PowershellCore.ps1 @@ -6,6 +6,12 @@ $ErrorActionPreference = "Stop" +if (Test-IsArm64) { + $expectedArch = "arm64" +} else { + $expectedArch = "x64" +} + $tempDir = Join-Path ([System.IO.Path]::GetTempPath()) ([System.IO.Path]::GetRandomFileName()) New-Item -ItemType Directory -Path $tempDir -Force -ErrorAction SilentlyContinue | Out-Null try { @@ -18,7 +24,7 @@ try { $releases = $metadata.LTSReleaseTag -replace '^v' foreach ($release in $releases) { if ($release -like "${pwshMajorMinor}*") { - $downloadUrl = "https://github.com/PowerShell/PowerShell/releases/download/v${release}/PowerShell-${release}-win-x64.msi" + $downloadUrl = "https://github.com/PowerShell/PowerShell/releases/download/v${release}/PowerShell-${release}-win-${expectedArch}.msi" break } } diff --git a/images/windows/scripts/build/Install-R.ps1 b/images/windows/scripts/build/Install-R.ps1 index 96743d7256..0abd6e96c6 100644 --- a/images/windows/scripts/build/Install-R.ps1 +++ b/images/windows/scripts/build/Install-R.ps1 @@ -6,6 +6,13 @@ Install-ChocoPackage R.Project Install-ChocoPackage rtools -$rscriptPath = Resolve-Path "C:\Program Files\R\*\bin\x64" +if (Test-IsArm64) { + $rscriptPathPattern = "C:\Program Files (x86)\R\*\bin\x64" +} else { + $rscriptPathPattern = "C:\Program Files\R\*\bin\x64" +} + +$rscriptPath = Resolve-Path $rscriptPathPattern Add-MachinePathItem $rscriptPath + Invoke-PesterTests -TestFile "Tools" -TestName "R" diff --git a/images/windows/scripts/build/Install-Ruby.ps1 b/images/windows/scripts/build/Install-Ruby.ps1 index 01bd525bb1..ad83e884bc 100644 --- a/images/windows/scripts/build/Install-Ruby.ps1 +++ b/images/windows/scripts/build/Install-Ruby.ps1 @@ -63,6 +63,12 @@ function Set-DefaultRubyVersion { Add-MachinePathItem -PathItem $rubyDir | Out-Null } +if (Test-IsArm64) { + $expectedArch = "arm" +} else { + $expectedArch = "x64" +} + # Install Ruby $rubyTools = (Get-ToolsetContent).toolcache | Where-Object { $_.name -eq "Ruby" } $rubyToolVersions = $rubyTools.versions @@ -73,8 +79,14 @@ foreach ($rubyVersion in $rubyToolVersions) { $downloadUrl = Resolve-GithubReleaseAssetUrl ` -Repo "oneclick/rubyinstaller2" ` -Version "$rubyVersion*" ` - -UrlMatchPattern "*-x64.7z" + -UrlMatchPattern "*-${expectedArch}.7z" $packagePath = Invoke-DownloadWithRetry $downloadUrl + + if (Test-IsArm64) { + Install-Ruby -PackagePath $packagePath -Architecture "aarch64" + } else { + Install-Ruby -PackagePath $packagePath -Architecture "x64" + } Install-Ruby -PackagePath $packagePath } diff --git a/images/windows/scripts/build/Install-Rust.ps1 b/images/windows/scripts/build/Install-Rust.ps1 index cf35a74102..adcce9008b 100644 --- a/images/windows/scripts/build/Install-Rust.ps1 +++ b/images/windows/scripts/build/Install-Rust.ps1 @@ -4,16 +4,22 @@ ## Supply chain security: checksum validation for bootstrap, managed by rustup for workloads ################################################################################ +if (Test-IsArm64) { + $expectedArch = "aarch64" +} else { + $expectedArch = "x86_64" +} + # Rust Env $env:RUSTUP_HOME = "C:\Users\Default\.rustup" $env:CARGO_HOME = "C:\Users\Default\.cargo" -# Download the latest rustup-init.exe for Windows x64 +# Download the latest rustup-init.exe for Windows # See https://rustup.rs/# -$rustupPath = Invoke-DownloadWithRetry "https://static.rust-lang.org/rustup/dist/x86_64-pc-windows-msvc/rustup-init.exe" +$rustupPath = Invoke-DownloadWithRetry "https://static.rust-lang.org/rustup/dist/${expectedArch}-pc-windows-msvc/rustup-init.exe" #region Supply chain security -$distributorFileHash = (Invoke-RestMethod -Uri 'https://static.rust-lang.org/rustup/dist/x86_64-pc-windows-msvc/rustup-init.exe.sha256').Trim() +$distributorFileHash = (Invoke-RestMethod -Uri "https://static.rust-lang.org/rustup/dist/${expectedArch}-pc-windows-msvc/rustup-init.exe.sha256").Trim() Test-FileChecksum $rustupPath -ExpectedSHA256Sum $distributorFileHash #endregion @@ -28,11 +34,15 @@ Add-DefaultPathItem "%USERPROFILE%\.cargo\bin" # Add Rust binaries to the path $env:Path += ";$env:CARGO_HOME\bin" -# Add i686 target for building 32-bit binaries -rustup target add i686-pc-windows-msvc +if (Test-IsArm64) { + rustup target add aarch64-pc-windows-msvc +} else { + # Add i686 target for building 32-bit binaries + rustup target add i686-pc-windows-msvc -# Add target for building mingw-w64 binaries -rustup target add x86_64-pc-windows-gnu + # Add target for building mingw-w64 binaries + rustup target add x86_64-pc-windows-gnu +} # Install common tools rustup component add rustfmt clippy diff --git a/images/windows/scripts/build/Install-VisualStudio.ps1 b/images/windows/scripts/build/Install-VisualStudio.ps1 index e866ffeb65..492c000956 100644 --- a/images/windows/scripts/build/Install-VisualStudio.ps1 +++ b/images/windows/scripts/build/Install-VisualStudio.ps1 @@ -4,6 +4,12 @@ ################################################################################ $vsToolset = (Get-ToolsetContent).visualStudio +if (Test-IsArm64) { + $expectedArch = "arm64" +} else { + $expectedArch = "x64" +} + # Install Visual Studio for Windows 22 and 25 with InstallChannel Install-VisualStudio ` -Version $vsToolset.subversion ` @@ -11,7 +17,8 @@ Install-VisualStudio ` -Channel $vsToolset.channel ` -InstallChannelUri $vsToolset.installChannelUri ` -RequiredComponents $vsToolset.workloads ` - -ExtraArgs "--allWorkloads --includeRecommended --remove Component.CPython3.x64" + -ExtraArgs "--allWorkloads --includeRecommended --remove Component.CPython3.x64" ` + -Architecture $expectedArch # Find the version of VS installed for this instance # Only supports a single instance diff --git a/images/windows/scripts/build/Install-WDK.ps1 b/images/windows/scripts/build/Install-WDK.ps1 index 1cac470cf7..14a978e0ef 100644 --- a/images/windows/scripts/build/Install-WDK.ps1 +++ b/images/windows/scripts/build/Install-WDK.ps1 @@ -7,6 +7,9 @@ if (Test-IsWin22) { # SDK is available through Visual Studio $wdkUrl = "https://go.microsoft.com/fwlink/?linkid=2324617" +} elseif (Test-IsWin11) { + # SDK is available through Visual Studio + $wdkUrl = "https://go.microsoft.com/fwlink/?linkid=2335869" } else { throw "Invalid version of Visual Studio is found. Windows Server 2022 is required" } diff --git a/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 b/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 index 40fe4b1ca0..2073e24de1 100644 --- a/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 +++ b/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 @@ -44,7 +44,9 @@ $packageManagement = $installedSoftware.AddHeader("Package Management") $packageManagement.AddToolVersion("Chocolatey", $(Get-ChocoVersion)) $packageManagement.AddToolVersion("Composer", $(Get-ComposerVersion)) $packageManagement.AddToolVersion("Helm", $(Get-HelmVersion)) -$packageManagement.AddToolVersion("Miniconda", $(Get-CondaVersion)) +if (-not (Test-IsWin11)) { + $packageManagement.AddToolVersion("Miniconda", $(Get-CondaVersion)) +} $packageManagement.AddToolVersion("NPM", $(Get-NPMVersion)) $packageManagement.AddToolVersion("NuGet", $(Get-NugetVersion)) $packageManagement.AddToolVersion("pip", $(Get-PipVersion)) @@ -70,13 +72,17 @@ $tools.AddToolVersion("azcopy", $(Get-AzCopyVersion)) $tools.AddToolVersion("Bazel", $(Get-BazelVersion)) $tools.AddToolVersion("Bazelisk", $(Get-BazeliskVersion)) $tools.AddToolVersion("Bicep", $(Get-BicepVersion)) -$tools.AddToolVersion("Cabal", $(Get-CabalVersion)) +if (-not (Test-IsWin11)) { + $tools.AddToolVersion("Cabal", $(Get-CabalVersion)) +} $tools.AddToolVersion("CMake", $(Get-CMakeVersion)) $tools.AddToolVersion("CodeQL Action Bundle", $(Get-CodeQLBundleVersion)) -$tools.AddToolVersion("Docker", $(Get-DockerVersion)) -$tools.AddToolVersion("Docker Compose v2", $(Get-DockerComposeVersionV2)) -$tools.AddToolVersion("Docker-wincred", $(Get-DockerWincredVersion)) -$tools.AddToolVersion("ghc", $(Get-GHCVersion)) +if (-not (Test-IsWin11)) { + $tools.AddToolVersion("Docker", $(Get-DockerVersion)) + $tools.AddToolVersion("Docker Compose v2", $(Get-DockerComposeVersionV2)) + $tools.AddToolVersion("Docker-wincred", $(Get-DockerWincredVersion)) + $tools.AddToolVersion("ghc", $(Get-GHCVersion)) +} $tools.AddToolVersion("Git", $(Get-GitVersion)) $tools.AddToolVersion("Git LFS", $(Get-GitLFSVersion)) $tools.AddToolVersion("ImageMagick", $(Get-ImageMagickVersion)) @@ -98,17 +104,23 @@ $tools.AddToolVersion("OpenSSL", $(Get-OpenSSLVersion)) $tools.AddToolVersion("Packer", $(Get-PackerVersion)) $tools.AddToolVersion("Pulumi", $(Get-PulumiVersion)) $tools.AddToolVersion("R", $(Get-RVersion)) -$tools.AddToolVersion("Service Fabric SDK", $(Get-ServiceFabricSDKVersion)) +if (-not (Test-IsWin11)) { + $tools.AddToolVersion("Service Fabric SDK", $(Get-ServiceFabricSDKVersion)) +} $tools.AddToolVersion("Stack", $(Get-StackVersion)) -if (-not (Test-IsWin25)) { +if (-not (Test-IsWin25) -and -not (Test-IsWin11)) { $tools.AddToolVersion("Subversion (SVN)", $(Get-SVNVersion)) } $tools.AddToolVersion("Swig", $(Get-SwigVersion)) $tools.AddToolVersion("VSWhere", $(Get-VSWhereVersion)) $tools.AddToolVersion("WinAppDriver", $(Get-WinAppDriver)) -$tools.AddToolVersion("WiX Toolset", $(Get-WixVersion)) +if (-not (Test-IsWin11)) { + $tools.AddToolVersion("WiX Toolset", $(Get-WixVersion)) +} $tools.AddToolVersion("yamllint", $(Get-YAMLLintVersion)) -$tools.AddToolVersion("zstd", $(Get-ZstdVersion)) +if (-not (Test-IsWin11)) { + $tools.AddToolVersion("zstd", $(Get-ZstdVersion)) +} $tools.AddToolVersion("Ninja", $(Get-NinjaVersion)) # CLI Tools @@ -150,26 +162,32 @@ $browsersAndWebdrivers.AddHeader("Environment variables").AddTable($(Build-Brows $installedSoftware.AddHeader("Java").AddTable($(Get-JavaVersions)) # Shells -$installedSoftware.AddHeader("Shells").AddTable($(Get-ShellTarget)) +if (-not (Test-IsWin11)) { + $installedSoftware.AddHeader("Shells").AddTable($(Get-ShellTarget)) +} # MSYS2 -$msys2 = $installedSoftware.AddHeader("MSYS2") -$msys2.AddToolVersion("Pacman", $(Get-PacmanVersion)) +if (-not (Test-IsWin11)) { + $msys2 = $installedSoftware.AddHeader("MSYS2") + $msys2.AddToolVersion("Pacman", $(Get-PacmanVersion)) -$notes = @' + $notes = @' Location: C:\msys64 Note: MSYS2 is pre-installed on image but not added to PATH. '@ -$msys2.AddHeader("Notes").AddNote($notes) + $msys2.AddHeader("Notes").AddNote($notes) +} # Cached Tools $installedSoftware.AddHeader("Cached Tools").AddNodes($(Build-CachedToolsSection)) # Databases -$databases = $installedSoftware.AddHeader("Databases") -$databases.AddHeader("PostgreSQL").AddTable($(Get-PostgreSQLTable)) -$databases.AddHeader("MongoDB").AddTable($(Get-MongoDBTable)) +if (-not (Test-IsWin11)) { + $databases = $installedSoftware.AddHeader("Databases") + $databases.AddHeader("PostgreSQL").AddTable($(Get-PostgreSQLTable)) + $databases.AddHeader("MongoDB").AddTable($(Get-MongoDBTable)) +} # Database tools $databaseTools = $installedSoftware.AddHeader("Database tools") @@ -178,9 +196,10 @@ $databaseTools.AddToolVersion("DacFx", $(Get-DacFxVersion)) $databaseTools.AddToolVersion("MySQL", $(Get-MySQLVersion)) $databaseTools.AddToolVersion("SQL OLEDB Driver 18", $(Get-SQLOLEDBDriver18Version)) $databaseTools.AddToolVersion("SQL OLEDB Driver 19", $(Get-SQLOLEDBDriver19Version)) -$databaseTools.AddToolVersion("SQLPS", $(Get-SQLPSVersion)) -$databaseTools.AddToolVersion("MongoDB Shell (mongosh)", $(Get-MongoshVersion)) - +if (-not (Test-IsWin11)) { + $databaseTools.AddToolVersion("SQLPS", $(Get-SQLPSVersion)) + $databaseTools.AddToolVersion("MongoDB Shell (mongosh)", $(Get-MongoshVersion)) +} # Web Servers $installedSoftware.AddHeader("Web Servers").AddTable($(Build-WebServersSection)) @@ -216,13 +235,15 @@ $psModules.AddNodes($(Get-PowerShellModules)) # Android -$android = $installedSoftware.AddHeader("Android") -$android.AddTable($(Build-AndroidTable)) +if (-not (Test-IsWin11)) { + $android = $installedSoftware.AddHeader("Android") + $android.AddTable($(Build-AndroidTable)) -$android.AddHeader("Environment variables").AddTable($(Build-AndroidEnvironmentTable)) + $android.AddHeader("Environment variables").AddTable($(Build-AndroidEnvironmentTable)) +} # Cached Docker images -if (-not (Test-IsWin25)) { +if (-not (Test-IsWin25) -and -not (Test-IsWin11)) { $installedSoftware.AddHeader("Cached Docker images").AddTable($(Get-CachedDockerImagesTableData)) } diff --git a/images/windows/scripts/docs-gen/SoftwareReport.CachedTools.psm1 b/images/windows/scripts/docs-gen/SoftwareReport.CachedTools.psm1 index a62ed45257..7ecf866822 100644 --- a/images/windows/scripts/docs-gen/SoftwareReport.CachedTools.psm1 +++ b/images/windows/scripts/docs-gen/SoftwareReport.CachedTools.psm1 @@ -34,7 +34,7 @@ function Build-CachedToolsSection [ToolVersionsListNode]::new("Go", $(Get-ToolcacheGoVersions), '^\d+\.\d+', 'List'), [ToolVersionsListNode]::new("Node.js", $(Get-ToolcacheNodeVersions), '^\d+', 'List'), [ToolVersionsListNode]::new("Python", $(Get-ToolcachePythonVersions), '^\d+\.\d+', 'List'), - [ToolVersionsListNode]::new("PyPy", $(Get-ToolcachePyPyVersions), '^\d+\.\d+', 'List'), + $(if (-not (Test-IsWin11)) { [ToolVersionsListNode]::new("PyPy", $(Get-ToolcachePyPyVersions), '^\d+\.\d+', 'List') }), [ToolVersionsListNode]::new("Ruby", $(Get-ToolcacheRubyVersions), '^\d+\.\d+', 'List') ) } diff --git a/images/windows/scripts/docs-gen/SoftwareReport.Java.psm1 b/images/windows/scripts/docs-gen/SoftwareReport.Java.psm1 index cd6c077d3e..2249451744 100644 --- a/images/windows/scripts/docs-gen/SoftwareReport.Java.psm1 +++ b/images/windows/scripts/docs-gen/SoftwareReport.Java.psm1 @@ -1,6 +1,10 @@ function Get-JavaVersions { $defaultJavaPath = $env:JAVA_HOME - $javaVersions = Get-Item env:JAVA_HOME_*_X64 + if (Test-IsArm64) { + $javaVersions = Get-Item env:JAVA_HOME_*_AARCH64 + } else { + $javaVersions = Get-Item env:JAVA_HOME_*_X64 + } $sortRules = @{ Expression = { [Int32] $_.Name.Split("_")[2] } Descending = $false diff --git a/images/windows/scripts/helpers/ImageHelpers.psm1 b/images/windows/scripts/helpers/ImageHelpers.psm1 index 8915ef9367..07e4b022d4 100644 --- a/images/windows/scripts/helpers/ImageHelpers.psm1 +++ b/images/windows/scripts/helpers/ImageHelpers.psm1 @@ -26,6 +26,7 @@ Export-ModuleMember -Function @( 'Test-IsWin25' 'Test-IsWin22' 'Test-IsWin11' + 'Test-IsArm64' 'Expand-7ZipArchive' 'Get-WindowsUpdateStates' 'Invoke-ScriptBlockWithRetry' diff --git a/images/windows/scripts/helpers/InstallHelpers.ps1 b/images/windows/scripts/helpers/InstallHelpers.ps1 index 06b57609c0..83abfbd0b0 100644 --- a/images/windows/scripts/helpers/InstallHelpers.ps1 +++ b/images/windows/scripts/helpers/InstallHelpers.ps1 @@ -322,6 +322,22 @@ function Get-TCToolVersionPath { return Join-Path $foundVersion $Arch } +function Test-IsArm64 { + <# + .SYNOPSIS + Checks if the current Windows operating system is running on an ARM64 architecture. + .DESCRIPTION + This function uses the Get-CimInstance cmdlet to retrieve information + about the current Windows operating system. It then checks if the OSArchitecture + property of the Win32_OperatingSystem class contains the string "ARM 64-bit", + indicating that the operating system is running on an ARM64 processor. + .OUTPUTS + Returns $true if the current Windows operating system is running on ARM64. + Otherwise, returns $false. + #> + (Get-CimInstance -ClassName Win32_OperatingSystem).OSArchitecture -match "ARM 64-bit" +} + function Test-IsWin25 { <# .SYNOPSIS diff --git a/images/windows/scripts/helpers/VisualStudioHelpers.ps1 b/images/windows/scripts/helpers/VisualStudioHelpers.ps1 index db02591a71..fd9eff81bd 100644 --- a/images/windows/scripts/helpers/VisualStudioHelpers.ps1 +++ b/images/windows/scripts/helpers/VisualStudioHelpers.ps1 @@ -32,7 +32,8 @@ Function Install-VisualStudio { [Parameter(Mandatory)] [String] $Channel, [String] $InstallChannelUri = "", [Parameter(Mandatory)] [String[]] $RequiredComponents, - [String] $ExtraArgs = "" + [String] $ExtraArgs = "", + [String] $Architecture = "x64" ) if ($env:INSTALL_VS_2026) { @@ -61,7 +62,7 @@ Function Install-VisualStudio { "channelUri" = $channelUri "channelId" = $channelId "productId" = $productId - "arch" = "x64" + "arch" = $Architecture "add" = $RequiredComponents | ForEach-Object { "$_;includeRecommended" } } diff --git a/images/windows/scripts/tests/Android.Tests.ps1 b/images/windows/scripts/tests/Android.Tests.ps1 index c53f99b3e3..1a092ac2a0 100644 --- a/images/windows/scripts/tests/Android.Tests.ps1 +++ b/images/windows/scripts/tests/Android.Tests.ps1 @@ -1,4 +1,4 @@ -Describe "Android SDK" { +Describe "Android SDK" -Skip:(Test-IsWin11) { $androidToolset = (Get-ToolsetContent).android $androidInstalledPackages = Get-AndroidInstalledPackages diff --git a/images/windows/scripts/tests/ChocoPackages.Tests.ps1 b/images/windows/scripts/tests/ChocoPackages.Tests.ps1 index 1f283ca804..b088a0a822 100644 --- a/images/windows/scripts/tests/ChocoPackages.Tests.ps1 +++ b/images/windows/scripts/tests/ChocoPackages.Tests.ps1 @@ -58,7 +58,7 @@ Describe "Pulumi" { } } -Describe "Svn" -Skip:(Test-IsWin25) { +Describe "Svn" -Skip:((Test-IsWin25) -or (Test-IsWin11)) { It "svn" { "svn --version --quiet" | Should -ReturnZeroExitCode } @@ -86,7 +86,7 @@ Describe "Julia" { } } -Describe "CMake" { +Describe "CMake" -Skip:(Test-IsArm64) { It "cmake" { "cmake --version" | Should -ReturnZeroExitCode } @@ -98,7 +98,7 @@ Describe "ImageMagick" { } } -Describe "Ninja" { +Describe "Ninja" -Skip:(Test-IsArm64) { BeforeAll { $ninjaProjectPath = $(Join-Path $env:TEMP_DIR "ninjaproject") New-item -Path $ninjaProjectPath -ItemType Directory -Force diff --git a/images/windows/scripts/tests/Databases.Tests.ps1 b/images/windows/scripts/tests/Databases.Tests.ps1 index 03d8921084..aa58e7c5e3 100644 --- a/images/windows/scripts/tests/Databases.Tests.ps1 +++ b/images/windows/scripts/tests/Databases.Tests.ps1 @@ -1,4 +1,4 @@ -Describe "MongoDB" { +Describe "MongoDB" -Skip:(Test-IsWin11) { Context "Version" { It "" -TestCases @( @{ ToolName = "mongos" } @@ -33,7 +33,7 @@ Describe "MongoDB" { } } -Describe "PostgreSQL" { +Describe "PostgreSQL" -Skip:(Test-IsWin11) { $psqlTests = @( @{envVar = "PGROOT"; pgPath = Get-EnvironmentVariable "PGROOT" } @{envVar = "PGBIN"; pgPath = Get-EnvironmentVariable "PGBIN" } diff --git a/images/windows/scripts/tests/Docker.Tests.ps1 b/images/windows/scripts/tests/Docker.Tests.ps1 index b994430e3f..cf2a6acaa4 100644 --- a/images/windows/scripts/tests/Docker.Tests.ps1 +++ b/images/windows/scripts/tests/Docker.Tests.ps1 @@ -1,4 +1,4 @@ -Describe "Docker" { +Describe "Docker" -Skip:(Test-IsWin11) { It "docker is installed" { "docker --version" | Should -ReturnZeroExitCode } @@ -12,20 +12,20 @@ Describe "Docker" { } } -Describe "DockerCompose" { +Describe "DockerCompose" -Skip:(Test-IsWin11) { It "docker compose v2" { "docker compose version" | Should -ReturnZeroExitCode } } -Describe "DockerWinCred" { +Describe "DockerWinCred" -Skip:(Test-IsWin11) { It "docker-wincred" { "docker-credential-wincred version" | Should -ReturnZeroExitCode } } -Describe "DockerImages" -Skip:(Test-IsWin25) { +Describe "DockerImages" -Skip:((Test-IsWin25) -or (Test-IsWin11)) { Context "docker images" { $testCases = (Get-ToolsetContent).docker.images | ForEach-Object { @{ ImageName = $_ } } diff --git a/images/windows/scripts/tests/Haskell.Tests.ps1 b/images/windows/scripts/tests/Haskell.Tests.ps1 index 866ef5dca6..b89e4654c4 100644 --- a/images/windows/scripts/tests/Haskell.Tests.ps1 +++ b/images/windows/scripts/tests/Haskell.Tests.ps1 @@ -1,4 +1,4 @@ -Describe "Haskell" { +Describe "Haskell" -Skip:(Test-IsWin11) { $ghcPackagesPath = "c:\ghcup\ghc" [array] $ghcVersionList = Get-ChildItem -Path $ghcPackagesPath -Filter "*" | ForEach-Object { $_.Name.Trim() } $ghcCount = $ghcVersionList.Count diff --git a/images/windows/scripts/tests/Java.Tests.ps1 b/images/windows/scripts/tests/Java.Tests.ps1 index bf40a8d430..b8194967fa 100644 --- a/images/windows/scripts/tests/Java.Tests.ps1 +++ b/images/windows/scripts/tests/Java.Tests.ps1 @@ -5,9 +5,17 @@ Describe "Java" { [array] $testCases = $jdkVersions | ForEach-Object { @{Version = $_ } } + BeforeAll { + if (Test-IsArm64) { + $expectedArch = "AARCH64" + } else { + $expectedArch = "X64" + } + } + It "Java is default" -TestCases @(@{ DefaultJavaVersion = $defaultVersion }) { $actualJavaPath = Get-EnvironmentVariable "JAVA_HOME" - $expectedJavaPath = Get-EnvironmentVariable "JAVA_HOME_${DefaultJavaVersion}_X64" + $expectedJavaPath = Get-EnvironmentVariable "JAVA_HOME_${DefaultJavaVersion}_${expectedArch}" $actualJavaPath | Should -Not -BeNullOrEmpty $expectedJavaPath | Should -Not -BeNullOrEmpty @@ -24,7 +32,7 @@ Describe "Java" { } It "Java " -TestCases $testCases { - $javaVariableValue = Get-EnvironmentVariable "JAVA_HOME_${Version}_X64" + $javaVariableValue = Get-EnvironmentVariable "JAVA_HOME_${Version}_${expectedArch}" $javaVariableValue | Should -Not -BeNullOrEmpty $javaPath = Join-Path $javaVariableValue "bin\java" diff --git a/images/windows/scripts/tests/MSYS2.Tests.ps1 b/images/windows/scripts/tests/MSYS2.Tests.ps1 index c92e7a8da5..760b5c8674 100644 --- a/images/windows/scripts/tests/MSYS2.Tests.ps1 +++ b/images/windows/scripts/tests/MSYS2.Tests.ps1 @@ -3,7 +3,7 @@ BeforeAll { $originalPath = $env:PATH } -Describe "MSYS2 packages" { +Describe "MSYS2 packages" -Skip:(Test-IsWin11) { BeforeEach { $env:PATH = "$msys2Dir;$env:PATH" } @@ -31,7 +31,7 @@ Describe "MSYS2 packages" { $mingwTypes = (Get-ToolsetContent).MsysPackages.mingw foreach ($mingwType in $mingwTypes) { - Describe "$($mingwType.arch) packages" { + Describe "$($mingwType.arch) packages" -Skip:(Test-IsWin11) { $tools = $mingwType.runtime_packages $execDir = Join-Path "C:\msys64" $mingwType.exec_dir | Join-Path -ChildPath "bin" diff --git a/images/windows/scripts/tests/Miniconda.Tests.ps1 b/images/windows/scripts/tests/Miniconda.Tests.ps1 index 763a158e23..3284204d31 100644 --- a/images/windows/scripts/tests/Miniconda.Tests.ps1 +++ b/images/windows/scripts/tests/Miniconda.Tests.ps1 @@ -1,4 +1,4 @@ -Describe "Miniconda" { +Describe "Miniconda" -Skip:(Test-IsWin11) { It "Miniconda Environment variables is set. " { ${env:CONDA} | Should -Not -BeNullOrEmpty } @@ -11,4 +11,4 @@ Describe "Miniconda" { $condaPath | Should -Exist "$condaPath --version" | Should -ReturnZeroExitCode } -} \ No newline at end of file +} diff --git a/images/windows/scripts/tests/Shell.Tests.ps1 b/images/windows/scripts/tests/Shell.Tests.ps1 index caddaf7fb7..10d40aa559 100644 --- a/images/windows/scripts/tests/Shell.Tests.ps1 +++ b/images/windows/scripts/tests/Shell.Tests.ps1 @@ -1,7 +1,7 @@ Describe "Shell" { $shellTestCases = @( @{Name = "C:\shells\gitbash.exe"; Target = "$env:ProgramFiles\Git\bin\bash.exe"}, - @{Name = "C:\shells\msys2bash.cmd"; Target = $null} + $(if (-not (Test-IsWin11)) { @{Name = "C:\shells\msys2bash.cmd"; Target = $null} }), @{Name = "C:\shells\wslbash.exe"; Target = "$env:SystemRoot\System32\bash.exe"} ) diff --git a/images/windows/scripts/tests/Tools.Tests.ps1 b/images/windows/scripts/tests/Tools.Tests.ps1 index 3c6301613a..d5dd358fde 100644 --- a/images/windows/scripts/tests/Tools.Tests.ps1 +++ b/images/windows/scripts/tests/Tools.Tests.ps1 @@ -118,7 +118,7 @@ Describe "Sbt" { } } -Describe "ServiceFabricSDK" { +Describe "ServiceFabricSDK" -Skip:(Test-IsWin11) { It "PowerShell Module" { # Ignore PowerShell version check if running in PowerShell Core # https://github.com/microsoft/service-fabric/issues/1343 @@ -160,7 +160,7 @@ Describe "WebPlatformInstaller" { } } -Describe "Zstd" { +Describe "Zstd" -Skip:(Test-IsWin11) { It "zstd" { "zstd -V" | Should -ReturnZeroExitCode } @@ -213,3 +213,37 @@ Describe "OpenSSL" { Get-ChildItem -Path "$env:SystemRoot\System32" -Filter "libssl-*.dll" -File -ErrorAction SilentlyContinue | Should -BeNullOrEmpty } } + +Describe "CMake" { + It "cmake" { + "cmake --version" | Should -ReturnZeroExitCode + } +} + +Describe "Ninja" { + BeforeAll { + $ninjaProjectPath = $(Join-Path $env:TEMP_DIR "ninjaproject") + New-item -Path $ninjaProjectPath -ItemType Directory -Force +@' +cmake_minimum_required(VERSION 3.10) +project(NinjaTest NONE) +'@ | Out-File -FilePath "$ninjaProjectPath/CMakeLists.txt" -Encoding utf8 + + $ninjaProjectBuildPath = $(Join-Path $ninjaProjectPath "build") + New-item -Path $ninjaProjectBuildPath -ItemType Directory -Force + Set-Location $ninjaProjectBuildPath + } + + It "Make a simple ninja project" { + "cmake -GNinja $ninjaProjectPath" | Should -ReturnZeroExitCode + } + + It "build.ninja file should exist" { + $buildFilePath = $(Join-Path $ninjaProjectBuildPath "build.ninja") + $buildFilePath | Should -Exist + } + + It "Ninja" { + "ninja --version" | Should -ReturnZeroExitCode + } +} diff --git a/images/windows/scripts/tests/Toolset.Tests.ps1 b/images/windows/scripts/tests/Toolset.Tests.ps1 index 83d4b9a40f..7dd0b7020e 100644 --- a/images/windows/scripts/tests/Toolset.Tests.ps1 +++ b/images/windows/scripts/tests/Toolset.Tests.ps1 @@ -19,6 +19,10 @@ $toolsExecutables = @{ ) } +if (Test-IsWin11) { + $toolsExecutables.Remove("PyPy") +} + function Get-ToolExecutables { Param ([String] $Name) if ($toolsExecutables.ContainsKey($Name)) { $toolsExecutables[$Name] } else { @() } diff --git a/images/windows/scripts/tests/VisualStudio.Tests.ps1 b/images/windows/scripts/tests/VisualStudio.Tests.ps1 index bc26c77236..c2bf867ae8 100644 --- a/images/windows/scripts/tests/VisualStudio.Tests.ps1 +++ b/images/windows/scripts/tests/VisualStudio.Tests.ps1 @@ -25,7 +25,7 @@ Describe "Visual Studio" { } } -Describe "Windows 10 SDK" -Skip:(Test-IsWin25) { +Describe "Windows 10 SDK" -Skip:((Test-IsWin25) -or (Test-IsWin11)) { It "Verifies 17763 SDK is installed" { "${env:ProgramFiles(x86)}\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\10.0.17763.0\UAP.props" | Should -Exist } diff --git a/images/windows/scripts/tests/Wix.Tests.ps1 b/images/windows/scripts/tests/Wix.Tests.ps1 index cf6fc2fdf1..5f1ff0314e 100644 --- a/images/windows/scripts/tests/Wix.Tests.ps1 +++ b/images/windows/scripts/tests/Wix.Tests.ps1 @@ -1,4 +1,4 @@ -Describe "Wix" { +Describe "Wix" -Skip:(Test-IsWin11) { BeforeAll { $regKey = "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" $installedApplications = Get-ItemProperty -Path $regKey diff --git a/images/windows/templates/build.windows-11-arm64.pkr.hcl b/images/windows/templates/build.windows-11-arm64.pkr.hcl index b37c591b4b..fb9c5b7df8 100644 --- a/images/windows/templates/build.windows-11-arm64.pkr.hcl +++ b/images/windows/templates/build.windows-11-arm64.pkr.hcl @@ -84,6 +84,8 @@ build { inline = ["Set-Service -Name wlansvc -StartupType Manual", "if ($(Get-Service -Name wlansvc).Status -eq 'Running') { Stop-Service -Name wlansvc}"] } + # TODO: + # 1. Double check if Install-Runner.ps1 is needed, should be taken care of during specialization. Left out for now provisioner "powershell" { environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] scripts = [ @@ -116,8 +118,8 @@ build { } # TODO: - # 1. Add ${path.root}/../scripts/build/Install-CMake.ps1 - # 2. Add ${path.root}/../scripts/build/Install-Ninja.ps1 + # 1. Add ${path.root}/../scripts/build/Install-CMake.ps1 - Done, instead of Choco package, updated to latest + # 2. Add ${path.root}/../scripts/build/Install-Ninja.ps1 - Done, instead of Choco package, updated to latest # 3. Check if need to move ${path.root}/../scripts/build/Install-LLVM.ps1 into this block provisioner "powershell" { pause_before = "2m0s" @@ -129,6 +131,8 @@ build { "${path.root}/../scripts/build/Install-AzureCli.ps1", "${path.root}/../scripts/build/Install-AzureDevOpsCli.ps1", "${path.root}/../scripts/build/Install-ChocolateyPackages.ps1", + "${path.root}/../scripts/build/Install-CMake.ps1", + "${path.root}/../scripts/build/Install-Ninja.ps1", "${path.root}/../scripts/build/Install-JavaTools.ps1", "${path.root}/../scripts/build/Install-Kotlin.ps1", "${path.root}/../scripts/build/Install-OpenSSL.ps1" @@ -146,9 +150,9 @@ build { } # TODO: - # 1. Add ${path.root}/../scripts/build/Install-Mercurial.ps1 - # 2. Add ${path.root}/../scripts/build/Install-NSIS.ps1 - # 3. Add ${path.root}/../scripts/build/Install-AliyunCli.ps1 + # 1. Add ${path.root}/../scripts/build/Install-Mercurial.ps1 - Done + # 2. Add ${path.root}/../scripts/build/Install-NSIS.ps1 - Done + # 3. Add ${path.root}/../scripts/build/Install-AliyunCli.ps1 - Done provisioner "powershell" { environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] scripts = [ @@ -187,9 +191,12 @@ build { "${path.root}/../scripts/build/Install-Stack.ps1", # "${path.root}/../scripts/build/Install-Miniconda.ps1", "${path.root}/../scripts/build/Install-AzureCosmosDbEmulator.ps1", + "${path.root}/../scripts/build/Install-Mercurial.ps1", + "${path.root}/../scripts/build/Install-NSIS.ps1", # "${path.root}/../scripts/build/Install-Zstd.ps1", "${path.root}/../scripts/build/Install-Vcpkg.ps1", "${path.root}/../scripts/build/Install-Bazel.ps1", + "${path.root}/../scripts/build/Install-AliyunCli.ps1", "${path.root}/../scripts/build/Install-RootCA.ps1", # "${path.root}/../scripts/build/Install-MongoDB.ps1", "${path.root}/../scripts/build/Install-CodeQLBundle.ps1", @@ -242,7 +249,7 @@ build { } provisioner "file" { - destination = "${path.root}/../Windows11-arm-Readme.md" + destination = "${path.root}/../Windows11-Arm64-Readme.md" direction = "download" source = "C:\\software-report.md" } diff --git a/images/windows/toolsets/toolset-win-11-arm64.json b/images/windows/toolsets/toolset-win-11-arm64.json index 0aa1f7e7d5..0a8421cb47 100644 --- a/images/windows/toolsets/toolset-win-11-arm64.json +++ b/images/windows/toolsets/toolset-win-11-arm64.json @@ -129,7 +129,7 @@ "subversion" : "17", "edition" : "Enterprise", "channel": "release", - "installChannel": "", + "installChannelUri": "", "workloads": [ "Component.Dotfuscator", "Component.Linux.CMake", From 46988f36b2df98880f40882034dca6c8f4ec75bf Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Wed, 18 Mar 2026 19:57:28 +0100 Subject: [PATCH 28/55] Fix source_image_marketplace_sku --- images/windows/templates/locals.windows.pkr.hcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images/windows/templates/locals.windows.pkr.hcl b/images/windows/templates/locals.windows.pkr.hcl index 9fb08913d9..9a671dc5dd 100644 --- a/images/windows/templates/locals.windows.pkr.hcl +++ b/images/windows/templates/locals.windows.pkr.hcl @@ -13,7 +13,7 @@ locals { os_disk_size_gb = 150 } "win11-arm64" = { - source_image_marketplace_sku = "windows11preview-arm64:microsoftwindowsdesktop:win11-25h2-ent:latest" + source_image_marketplace_sku = "microsoftwindowsdesktop:windows11preview-arm64:win11-25h2-ent" os_disk_size_gb = 256 } } From 649e7dccddefab5b3f3cba26d1e681bfd4d7c0f0 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Thu, 19 Mar 2026 13:00:51 +0100 Subject: [PATCH 29/55] DEBUG: elevated packer, add SeBatchLogonRight --- .../templates/build.windows-11-arm64.pkr.hcl | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/images/windows/templates/build.windows-11-arm64.pkr.hcl b/images/windows/templates/build.windows-11-arm64.pkr.hcl index fb9c5b7df8..7d10cead26 100644 --- a/images/windows/templates/build.windows-11-arm64.pkr.hcl +++ b/images/windows/templates/build.windows-11-arm64.pkr.hcl @@ -51,6 +51,24 @@ build { inline = ["if (-not ((net localgroup Administrators) -contains '${var.install_user}')) { exit 1 }"] } + provisioner "powershell" { + inline = [<<-EOF + $sidStr = (New-Object Security.Principal.NTAccount("${var.install_user}")).Translate([Security.Principal.SecurityIdentifier]).Value + $tmpFile = [IO.Path]::GetTempFileName() + secedit /export /cfg $tmpFile /areas USER_RIGHTS /quiet + $policy = Get-Content $tmpFile -Raw + if ($policy -match 'SeBatchLogonRight\s*=\s*(.*)') { + $policy = $policy -replace 'SeBatchLogonRight\s*=\s*(.*)', "SeBatchLogonRight = `$1,*$sidStr" + } else { + $policy += "`r`nSeBatchLogonRight = *$sidStr" + } + Set-Content $tmpFile $policy + secedit /configure /db "$env:TEMP\secedit.sdb" /cfg $tmpFile /areas USER_RIGHTS /quiet + Remove-Item $tmpFile + EOF + ] + } + provisioner "powershell" { elevated_password = "${var.install_password}" elevated_user = "${var.install_user}" From 84ef25f84e93df8c25c8703799a218df13ce37df Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Thu, 19 Mar 2026 16:38:11 +0100 Subject: [PATCH 30/55] DEBUG:V2 elevated packer, add SeBatchLogonRight --- .../templates/build.windows-11-arm64.pkr.hcl | 60 +++++++++++++++---- 1 file changed, 49 insertions(+), 11 deletions(-) diff --git a/images/windows/templates/build.windows-11-arm64.pkr.hcl b/images/windows/templates/build.windows-11-arm64.pkr.hcl index 7d10cead26..eabf8735cd 100644 --- a/images/windows/templates/build.windows-11-arm64.pkr.hcl +++ b/images/windows/templates/build.windows-11-arm64.pkr.hcl @@ -51,20 +51,58 @@ build { inline = ["if (-not ((net localgroup Administrators) -contains '${var.install_user}')) { exit 1 }"] } + # v1 + # provisioner "powershell" { + # inline = [<<-EOF + # $sidStr = (New-Object Security.Principal.NTAccount("${var.install_user}")).Translate([Security.Principal.SecurityIdentifier]).Value + # $tmpFile = [IO.Path]::GetTempFileName() + # secedit /export /cfg $tmpFile /areas USER_RIGHTS /quiet + # $policy = Get-Content $tmpFile -Raw + # if ($policy -match 'SeBatchLogonRight\s*=\s*(.*)') { + # $policy = $policy -replace 'SeBatchLogonRight\s*=\s*(.*)', "SeBatchLogonRight = `$1,*$sidStr" + # } else { + # $policy += "`r`nSeBatchLogonRight = *$sidStr" + # } + # Set-Content $tmpFile $policy + # secedit /configure /db "$env:TEMP\secedit.sdb" /cfg $tmpFile /areas USER_RIGHTS /quiet + # Remove-Item $tmpFile + # EOF + # ] + # } + + # v2 provisioner "powershell" { inline = [<<-EOF - $sidStr = (New-Object Security.Principal.NTAccount("${var.install_user}")).Translate([Security.Principal.SecurityIdentifier]).Value - $tmpFile = [IO.Path]::GetTempFileName() - secedit /export /cfg $tmpFile /areas USER_RIGHTS /quiet - $policy = Get-Content $tmpFile -Raw - if ($policy -match 'SeBatchLogonRight\s*=\s*(.*)') { - $policy = $policy -replace 'SeBatchLogonRight\s*=\s*(.*)', "SeBatchLogonRight = `$1,*$sidStr" - } else { - $policy += "`r`nSeBatchLogonRight = *$sidStr" + $code = @' + using System; + using System.Runtime.InteropServices; + public class LsaUtil { + [DllImport("advapi32.dll", SetLastError=true)] + static extern uint LsaOpenPolicy(IntPtr SystemName, ref LSA_OBJECT_ATTRIBUTES ObjectAttributes, uint AccessMask, out IntPtr PolicyHandle); + [DllImport("advapi32.dll", SetLastError=true)] + static extern uint LsaAddAccountRights(IntPtr PolicyHandle, IntPtr AccountSid, LSA_UNICODE_STRING[] UserRights, long CountOfRights); + [DllImport("advapi32.dll")] + static extern uint LsaClose(IntPtr ObjectHandle); + [StructLayout(LayoutKind.Sequential)] public struct LSA_OBJECT_ATTRIBUTES { public int Length; public IntPtr RootDirectory; public IntPtr ObjectName; public uint Attributes; public IntPtr SecurityDescriptor; public IntPtr SecurityQualityOfService; } + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct LSA_UNICODE_STRING { public ushort Length; public ushort MaximumLength; [MarshalAs(UnmanagedType.LPWStr)] public string Buffer; } + public static void AddRight(string accountName, string rightName) { + var attrs = new LSA_OBJECT_ATTRIBUTES(); + IntPtr policy; + LsaOpenPolicy(IntPtr.Zero, ref attrs, 0x00020000 | 0x00000800, out policy); + var sid = new System.Security.Principal.NTAccount(accountName).Translate(typeof(System.Security.Principal.SecurityIdentifier)); + var sidBytes = new byte[((System.Security.Principal.SecurityIdentifier)sid).BinaryLength]; + ((System.Security.Principal.SecurityIdentifier)sid).GetBinaryForm(sidBytes, 0); + var sidPtr = Marshal.AllocHGlobal(sidBytes.Length); + Marshal.Copy(sidBytes, 0, sidPtr, sidBytes.Length); + var rights = new[] { new LSA_UNICODE_STRING { Buffer = rightName, Length = (ushort)(rightName.Length * 2), MaximumLength = (ushort)(rightName.Length * 2 + 2) } }; + LsaAddAccountRights(policy, sidPtr, rights, 1); + Marshal.FreeHGlobal(sidPtr); + LsaClose(policy); + } } - Set-Content $tmpFile $policy - secedit /configure /db "$env:TEMP\secedit.sdb" /cfg $tmpFile /areas USER_RIGHTS /quiet - Remove-Item $tmpFile + '@ + Add-Type $code + [LsaUtil]::AddRight("${var.install_user}", "SeBatchLogonRight") EOF ] } From aff033d702fefc59c30fb1ade3ef7295e41c2028 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Fri, 20 Mar 2026 09:34:19 +0100 Subject: [PATCH 31/55] DEBUG:V3 elevated packer, test auto logon --- .../templates/build.windows-11-arm64.pkr.hcl | 82 +++++++++++-------- 1 file changed, 50 insertions(+), 32 deletions(-) diff --git a/images/windows/templates/build.windows-11-arm64.pkr.hcl b/images/windows/templates/build.windows-11-arm64.pkr.hcl index eabf8735cd..47e3c716e5 100644 --- a/images/windows/templates/build.windows-11-arm64.pkr.hcl +++ b/images/windows/templates/build.windows-11-arm64.pkr.hcl @@ -71,39 +71,48 @@ build { # } # v2 + # provisioner "powershell" { + # inline = [<<-EOF + # $code = @' + # using System; + # using System.Runtime.InteropServices; + # public class LsaUtil { + # [DllImport("advapi32.dll", SetLastError=true)] + # static extern uint LsaOpenPolicy(IntPtr SystemName, ref LSA_OBJECT_ATTRIBUTES ObjectAttributes, uint AccessMask, out IntPtr PolicyHandle); + # [DllImport("advapi32.dll", SetLastError=true)] + # static extern uint LsaAddAccountRights(IntPtr PolicyHandle, IntPtr AccountSid, LSA_UNICODE_STRING[] UserRights, long CountOfRights); + # [DllImport("advapi32.dll")] + # static extern uint LsaClose(IntPtr ObjectHandle); + # [StructLayout(LayoutKind.Sequential)] public struct LSA_OBJECT_ATTRIBUTES { public int Length; public IntPtr RootDirectory; public IntPtr ObjectName; public uint Attributes; public IntPtr SecurityDescriptor; public IntPtr SecurityQualityOfService; } + # [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct LSA_UNICODE_STRING { public ushort Length; public ushort MaximumLength; [MarshalAs(UnmanagedType.LPWStr)] public string Buffer; } + # public static void AddRight(string accountName, string rightName) { + # var attrs = new LSA_OBJECT_ATTRIBUTES(); + # IntPtr policy; + # LsaOpenPolicy(IntPtr.Zero, ref attrs, 0x00020000 | 0x00000800, out policy); + # var sid = new System.Security.Principal.NTAccount(accountName).Translate(typeof(System.Security.Principal.SecurityIdentifier)); + # var sidBytes = new byte[((System.Security.Principal.SecurityIdentifier)sid).BinaryLength]; + # ((System.Security.Principal.SecurityIdentifier)sid).GetBinaryForm(sidBytes, 0); + # var sidPtr = Marshal.AllocHGlobal(sidBytes.Length); + # Marshal.Copy(sidBytes, 0, sidPtr, sidBytes.Length); + # var rights = new[] { new LSA_UNICODE_STRING { Buffer = rightName, Length = (ushort)(rightName.Length * 2), MaximumLength = (ushort)(rightName.Length * 2 + 2) } }; + # LsaAddAccountRights(policy, sidPtr, rights, 1); + # Marshal.FreeHGlobal(sidPtr); + # LsaClose(policy); + # } + # } + # '@ + # Add-Type $code + # [LsaUtil]::AddRight("${var.install_user}", "SeBatchLogonRight") + # EOF + # ] + # } + + # v3 - set and remove after all elevated tasks are done, might need additional reboot provisioner "powershell" { - inline = [<<-EOF - $code = @' - using System; - using System.Runtime.InteropServices; - public class LsaUtil { - [DllImport("advapi32.dll", SetLastError=true)] - static extern uint LsaOpenPolicy(IntPtr SystemName, ref LSA_OBJECT_ATTRIBUTES ObjectAttributes, uint AccessMask, out IntPtr PolicyHandle); - [DllImport("advapi32.dll", SetLastError=true)] - static extern uint LsaAddAccountRights(IntPtr PolicyHandle, IntPtr AccountSid, LSA_UNICODE_STRING[] UserRights, long CountOfRights); - [DllImport("advapi32.dll")] - static extern uint LsaClose(IntPtr ObjectHandle); - [StructLayout(LayoutKind.Sequential)] public struct LSA_OBJECT_ATTRIBUTES { public int Length; public IntPtr RootDirectory; public IntPtr ObjectName; public uint Attributes; public IntPtr SecurityDescriptor; public IntPtr SecurityQualityOfService; } - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct LSA_UNICODE_STRING { public ushort Length; public ushort MaximumLength; [MarshalAs(UnmanagedType.LPWStr)] public string Buffer; } - public static void AddRight(string accountName, string rightName) { - var attrs = new LSA_OBJECT_ATTRIBUTES(); - IntPtr policy; - LsaOpenPolicy(IntPtr.Zero, ref attrs, 0x00020000 | 0x00000800, out policy); - var sid = new System.Security.Principal.NTAccount(accountName).Translate(typeof(System.Security.Principal.SecurityIdentifier)); - var sidBytes = new byte[((System.Security.Principal.SecurityIdentifier)sid).BinaryLength]; - ((System.Security.Principal.SecurityIdentifier)sid).GetBinaryForm(sidBytes, 0); - var sidPtr = Marshal.AllocHGlobal(sidBytes.Length); - Marshal.Copy(sidBytes, 0, sidPtr, sidBytes.Length); - var rights = new[] { new LSA_UNICODE_STRING { Buffer = rightName, Length = (ushort)(rightName.Length * 2), MaximumLength = (ushort)(rightName.Length * 2 + 2) } }; - LsaAddAccountRights(policy, sidPtr, rights, 1); - Marshal.FreeHGlobal(sidPtr); - LsaClose(policy); - } - } - '@ - Add-Type $code - [LsaUtil]::AddRight("${var.install_user}", "SeBatchLogonRight") - EOF + inline = [ + "Set-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name AutoAdminLogon -Value 1 -type String", + "Set-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name DefaultUsername -Value \"${var.install_user}\" -type String", + "Set-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name DefaultPassword -Value \"${var.install_password}\" -type String", ] } @@ -275,6 +284,15 @@ build { ] } + # v3 + provisioner "powershell" { + inline = [ + "Remove-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name AutoAdminLogon", + "Remove-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name DefaultUsername", + "Remove-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name DefaultPassword", + ] + } + provisioner "windows-restart" { check_registry = true restart_check_command = "powershell -command \"& {if ((-not (Get-Process TiWorker.exe -ErrorAction SilentlyContinue)) -and (-not [System.Environment]::HasShutdownStarted) ) { Write-Output 'Restart complete' }}\"" From 056c08176533865801e4670f434c32a4fb0c6154 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Fri, 20 Mar 2026 09:48:50 +0100 Subject: [PATCH 32/55] DEBUG:V3 elevated packer, test auto logon with reboot --- .../windows/templates/build.windows-11-arm64.pkr.hcl | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/images/windows/templates/build.windows-11-arm64.pkr.hcl b/images/windows/templates/build.windows-11-arm64.pkr.hcl index 47e3c716e5..d17c439ee0 100644 --- a/images/windows/templates/build.windows-11-arm64.pkr.hcl +++ b/images/windows/templates/build.windows-11-arm64.pkr.hcl @@ -51,7 +51,7 @@ build { inline = ["if (-not ((net localgroup Administrators) -contains '${var.install_user}')) { exit 1 }"] } - # v1 + # v1 - elevated user issue # provisioner "powershell" { # inline = [<<-EOF # $sidStr = (New-Object Security.Principal.NTAccount("${var.install_user}")).Translate([Security.Principal.SecurityIdentifier]).Value @@ -70,7 +70,7 @@ build { # ] # } - # v2 + # v2 - elevated user issue # provisioner "powershell" { # inline = [<<-EOF # $code = @' @@ -116,6 +116,12 @@ build { ] } + # v3 - elevated user issue + provisioner "windows-restart" { + check_registry = true + restart_timeout = "10m" + } + provisioner "powershell" { elevated_password = "${var.install_password}" elevated_user = "${var.install_user}" @@ -284,7 +290,7 @@ build { ] } - # v3 + # v3 - elevated user issue provisioner "powershell" { inline = [ "Remove-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name AutoAdminLogon", From fc73540d9e296eb6de8f8b36bf723eb9937901b2 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Fri, 20 Mar 2026 12:12:27 +0100 Subject: [PATCH 33/55] Remove Install-ServiceFabricSDK.ps1 --- images/windows/templates/build.windows-11-arm64.pkr.hcl | 6 ------ 1 file changed, 6 deletions(-) diff --git a/images/windows/templates/build.windows-11-arm64.pkr.hcl b/images/windows/templates/build.windows-11-arm64.pkr.hcl index d17c439ee0..d4617c276d 100644 --- a/images/windows/templates/build.windows-11-arm64.pkr.hcl +++ b/images/windows/templates/build.windows-11-arm64.pkr.hcl @@ -210,12 +210,6 @@ build { ] } - provisioner "powershell" { - execution_policy = "remotesigned" - environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] - scripts = ["${path.root}/../scripts/build/Install-ServiceFabricSDK.ps1"] - } - provisioner "windows-restart" { restart_timeout = "10m" } From 55b37959c5750fb57316b4b4ac5399b653378d95 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Fri, 20 Mar 2026 17:36:59 +0100 Subject: [PATCH 34/55] Fix Install-Rust.ps1 --- images/windows/scripts/build/Install-Rust.ps1 | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/images/windows/scripts/build/Install-Rust.ps1 b/images/windows/scripts/build/Install-Rust.ps1 index adcce9008b..f622edda55 100644 --- a/images/windows/scripts/build/Install-Rust.ps1 +++ b/images/windows/scripts/build/Install-Rust.ps1 @@ -49,7 +49,8 @@ rustup component add rustfmt clippy if ($LASTEXITCODE -ne 0) { throw "Rust component installation failed with exit code $LASTEXITCODE" } -if (-not (Test-IsWin25)) { + +if (Test-IsWin22) { cargo install --locked bindgen-cli cbindgen cargo-audit cargo-outdated if ($LASTEXITCODE -ne 0) { throw "Rust tools installation failed with exit code $LASTEXITCODE" @@ -58,4 +59,13 @@ if (-not (Test-IsWin25)) { Remove-Item "${env:CARGO_HOME}\registry\*" -Recurse -Force } +if (Test-IsWin11) { + cargo install bindgen-cli cbindgen cargo-audit cargo-outdated + if ($LASTEXITCODE -ne 0) { + throw "Rust tools installation failed with exit code $LASTEXITCODE" + } + # Cleanup Cargo crates cache + Remove-Item "${env:CARGO_HOME}\registry\*" -Recurse -Force +} + Invoke-PesterTests -TestFile "Rust" From a464377e6b2dc96cf5d17fd3fed07fdfc072e592 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Sat, 21 Mar 2026 11:53:57 +0100 Subject: [PATCH 35/55] TEMP: remove cargo-audit --- images/windows/scripts/build/Install-Rust.ps1 | 3 ++- images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 | 5 ++++- images/windows/scripts/tests/Rust.Tests.ps1 | 3 ++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/images/windows/scripts/build/Install-Rust.ps1 b/images/windows/scripts/build/Install-Rust.ps1 index f622edda55..88e4a8dab1 100644 --- a/images/windows/scripts/build/Install-Rust.ps1 +++ b/images/windows/scripts/build/Install-Rust.ps1 @@ -60,7 +60,8 @@ if (Test-IsWin22) { } if (Test-IsWin11) { - cargo install bindgen-cli cbindgen cargo-audit cargo-outdated + # TODO: test cargo-audit and bring back + cargo install bindgen-cli cbindgen cargo-outdated if ($LASTEXITCODE -ne 0) { throw "Rust tools installation failed with exit code $LASTEXITCODE" } diff --git a/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 b/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 index 2073e24de1..e98c75704a 100644 --- a/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 +++ b/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 @@ -146,7 +146,10 @@ $rustTools.AddToolVersion("Rustup", $(Get-RustupVersion)) $rustToolsPackages = $rustTools.AddHeader("Packages") if (-not (Test-IsWin25)) { $rustToolsPackages.AddToolVersion("bindgen", $(Get-BindgenVersion)) - $rustToolsPackages.AddToolVersion("cargo-audit", $(Get-CargoAuditVersion)) + # TODO: test cargo-audit and bring back + if (-not (Test-IsWin11)) { + $rustToolsPackages.AddToolVersion("cargo-audit", $(Get-CargoAuditVersion)) + } $rustToolsPackages.AddToolVersion("cargo-outdated", $(Get-CargoOutdatedVersion)) $rustToolsPackages.AddToolVersion("cbindgen", $(Get-CbindgenVersion)) } diff --git a/images/windows/scripts/tests/Rust.Tests.ps1 b/images/windows/scripts/tests/Rust.Tests.ps1 index 717e80e428..8058792662 100644 --- a/images/windows/scripts/tests/Rust.Tests.ps1 +++ b/images/windows/scripts/tests/Rust.Tests.ps1 @@ -12,13 +12,14 @@ Describe "Rust" { @{ToolName = "cargo"; binPath = "C:\Users\Default\.cargo\bin\cargo.exe"} ) } else { + # TODO: test cargo-audit and bring back $rustTools = @( @{ToolName = "rustup"; binPath = "C:\Users\Default\.cargo\bin\rustup.exe"} @{ToolName = "rustc"; binPath = "C:\Users\Default\.cargo\bin\rustc.exe"} @{ToolName = "bindgen.exe"; binPath = "C:\Users\Default\.cargo\bin\bindgen.exe"} @{ToolName = "cbindgen.exe"; binPath = "C:\Users\Default\.cargo\bin\cbindgen.exe"} @{ToolName = "cargo"; binPath = "C:\Users\Default\.cargo\bin\cargo.exe"} - @{ToolName = "cargo audit"; binPath = "C:\Users\Default\.cargo\bin\cargo-audit.exe"} + $(if (-not (Test-IsWin11)) { @{ToolName = "cargo audit"; binPath = "C:\Users\Default\.cargo\bin\cargo-audit.exe"} }) @{ToolName = "cargo outdated"; binPath = "C:\Users\Default\.cargo\bin\cargo-outdated.exe"} ) } From 811ac68c1b59d1b47e725259b3569ee08ff978ea Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Sat, 21 Mar 2026 17:53:10 +0100 Subject: [PATCH 36/55] Fix Install-Firefox.ps1 asset names --- images/windows/scripts/build/Install-Firefox.ps1 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/images/windows/scripts/build/Install-Firefox.ps1 b/images/windows/scripts/build/Install-Firefox.ps1 index ff9e952d61..5306e4ae65 100644 --- a/images/windows/scripts/build/Install-Firefox.ps1 +++ b/images/windows/scripts/build/Install-Firefox.ps1 @@ -6,8 +6,10 @@ if (Test-IsArm64) { $expectedArch = "win64-aarch64" + $driverSufix = "win-aarch64" } else { $expectedArch = "win64" + $driverSufix = "win64" } # Install and configure Firefox browser @@ -52,7 +54,7 @@ Write-Host "Download Gecko WebDriver WebDriver..." $geckoDriverDownloadUrl = Resolve-GithubReleaseAssetUrl ` -Repo "mozilla/geckodriver" ` -Version $geckoDriverVersion ` - -UrlMatchPattern "geckodriver-*-$expectedArch.zip" + -UrlMatchPattern "geckodriver-*-$driverSufix.zip" $geckoDriverArchPath = Invoke-DownloadWithRetry $geckoDriverDownloadUrl Write-Host "Expand Gecko WebDriver archive..." From ec190088576f4dbb8b4ffc11ffc13eb06804d059 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Sun, 22 Mar 2026 10:08:00 +0100 Subject: [PATCH 37/55] Patch web browser scripts --- images/windows/scripts/build/Install-Apache.ps1 | 10 ++++++++-- images/windows/scripts/build/Install-Nginx.ps1 | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/images/windows/scripts/build/Install-Apache.ps1 b/images/windows/scripts/build/Install-Apache.ps1 index d5e85a6bc2..f36caeaf20 100644 --- a/images/windows/scripts/build/Install-Apache.ps1 +++ b/images/windows/scripts/build/Install-Apache.ps1 @@ -4,7 +4,10 @@ ################################################################################ # Stop w3svc service -Stop-Service -Name w3svc +$w3svcService = Get-Service -Name "w3svc" -ErrorAction SilentlyContinue +if ($w3svcService) { + Stop-Service $w3svcService +} # Install latest apache in chocolatey $installDir = "C:\tools" @@ -15,7 +18,10 @@ Stop-Service -Name Apache Set-Service -Name Apache -StartupType Disabled # Start w3svc service -Start-Service -Name w3svc +$w3svcService = Get-Service -Name "w3svc" -ErrorAction SilentlyContinue +if ($w3svcService) { + Start-Service $w3svcService +} # Invoke Pester Tests Invoke-PesterTests -TestFile "Apache" diff --git a/images/windows/scripts/build/Install-Nginx.ps1 b/images/windows/scripts/build/Install-Nginx.ps1 index 4b6f1bd503..4b790f8a86 100644 --- a/images/windows/scripts/build/Install-Nginx.ps1 +++ b/images/windows/scripts/build/Install-Nginx.ps1 @@ -4,7 +4,10 @@ ################################################################################ # Stop w3svc service -Stop-Service -Name w3svc +$w3svcService = Get-Service -Name "w3svc" -ErrorAction SilentlyContinue +if ($w3svcService) { + Stop-Service $w3svcService +} # Install latest nginx in chocolatey $installDir = "C:\tools" @@ -15,7 +18,10 @@ Stop-Service -Name nginx Set-Service -Name nginx -StartupType Disabled # Start w3svc service -Start-Service -Name w3svc +$w3svcService = Get-Service -Name "w3svc" -ErrorAction SilentlyContinue +if ($w3svcService) { + Start-Service $w3svcService +} # Invoke Pester Tests Invoke-PesterTests -TestFile "Nginx" From eb9ce8bc25f5ae2dd10638bfc9558988e8cc0dd5 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Sun, 22 Mar 2026 18:06:53 +0100 Subject: [PATCH 38/55] Fix pester tests --- .../windows/scripts/tests/Haskell.Tests.ps1 | 51 +++++++++---------- images/windows/scripts/tests/Shell.Tests.ps1 | 2 +- .../scripts/tests/WindowsFeatures.Tests.ps1 | 2 +- 3 files changed, 25 insertions(+), 30 deletions(-) diff --git a/images/windows/scripts/tests/Haskell.Tests.ps1 b/images/windows/scripts/tests/Haskell.Tests.ps1 index b89e4654c4..2791868422 100644 --- a/images/windows/scripts/tests/Haskell.Tests.ps1 +++ b/images/windows/scripts/tests/Haskell.Tests.ps1 @@ -1,33 +1,28 @@ Describe "Haskell" -Skip:(Test-IsWin11) { - $ghcPackagesPath = "c:\ghcup\ghc" - [array] $ghcVersionList = Get-ChildItem -Path $ghcPackagesPath -Filter "*" | ForEach-Object { $_.Name.Trim() } - $ghcCount = $ghcVersionList.Count - $defaultGhcVersion = $ghcVersionList | Sort-Object {[Version] $_} | Select-Object -Last 1 - $ghcDefaultCases = @{ - defaultGhcVersion = $defaultGhcVersion - defaultGhcShortVersion = ([version] $defaultGhcVersion).ToString(3) - } - - $ghcTestCases = $ghcVersionList | ForEach-Object { - $ghcVersion = $_ - $ghcShortVersion = ([version] $ghcVersion).ToString(3) - $binGhcPath = Join-Path $ghcPackagesPath "$ghcShortVersion\bin\ghc.exe" - @{ - ghcVersion = $ghcVersion - ghcShortVersion = $ghcShortVersion - binGhcPath = $binGhcPath + BeforeDiscovery { + $ghcPackagesPath = "c:\ghcup\ghc" + [array] $ghcVersionList = Get-ChildItem -Path $ghcPackagesPath -Filter "*" | ForEach-Object { $_.Name.Trim() } + $ghcCount = $ghcVersionList.Count + $defaultGhcVersion = $ghcVersionList | Sort-Object { [Version] $_ } | Select-Object -Last 1 + $ghcDefaultCases = @{ + defaultGhcVersion = $defaultGhcVersion + defaultGhcShortVersion = ([version] $defaultGhcVersion).ToString(3) } - } - - $ghcupEnvExists = @( - @{envVar = "GHCUP_INSTALL_BASE_PREFIX"} - @{envVar = "GHCUP_MSYS2"} - ) - - If (Test-IsWin25) { - $numberOfVersions = 1 - } else { - $numberOfVersions = 3 + $ghcTestCases = $ghcVersionList | ForEach-Object { + $ghcVersion = $_ + $ghcShortVersion = ([version] $ghcVersion).ToString(3) + $binGhcPath = Join-Path $ghcPackagesPath "$ghcShortVersion\bin\ghc.exe" + @{ + ghcVersion = $ghcVersion + ghcShortVersion = $ghcShortVersion + binGhcPath = $binGhcPath + } + } + $ghcupEnvExists = @( + @{envVar = "GHCUP_INSTALL_BASE_PREFIX"} + @{envVar = "GHCUP_MSYS2"} + ) + $numberOfVersions = if (Test-IsWin25) { 1 } else { 3 } } It " environment variable exists" -TestCases $ghcupEnvExists { diff --git a/images/windows/scripts/tests/Shell.Tests.ps1 b/images/windows/scripts/tests/Shell.Tests.ps1 index 10d40aa559..50e94b8e11 100644 --- a/images/windows/scripts/tests/Shell.Tests.ps1 +++ b/images/windows/scripts/tests/Shell.Tests.ps1 @@ -3,7 +3,7 @@ Describe "Shell" { @{Name = "C:\shells\gitbash.exe"; Target = "$env:ProgramFiles\Git\bin\bash.exe"}, $(if (-not (Test-IsWin11)) { @{Name = "C:\shells\msys2bash.cmd"; Target = $null} }), @{Name = "C:\shells\wslbash.exe"; Target = "$env:SystemRoot\System32\bash.exe"} - ) + ) | Where-Object { $_ } It " target to " -TestCases $shellTestCases { (Get-Item $Name).Target | Should -BeExactly $Target diff --git a/images/windows/scripts/tests/WindowsFeatures.Tests.ps1 b/images/windows/scripts/tests/WindowsFeatures.Tests.ps1 index ec8001b81a..22c2a5aff5 100644 --- a/images/windows/scripts/tests/WindowsFeatures.Tests.ps1 +++ b/images/windows/scripts/tests/WindowsFeatures.Tests.ps1 @@ -84,7 +84,7 @@ Describe "Windows Updates" { } } -Describe "WSL2" -Skip:(Test-IsWin22) { +Describe "WSL2" -Skip:((Test-IsWin22) -or (Test-IsWin11)) { It "WSL status should return zero exit code" { "wsl --status" | Should -ReturnZeroExitCode } From b5c33c465251937ed17451bbaec0bacba50d6404 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Sun, 22 Mar 2026 23:47:14 +0100 Subject: [PATCH 39/55] Fix Install-Ruby.ps1 --- images/windows/scripts/build/Install-Ruby.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/images/windows/scripts/build/Install-Ruby.ps1 b/images/windows/scripts/build/Install-Ruby.ps1 index ad83e884bc..421e8bc233 100644 --- a/images/windows/scripts/build/Install-Ruby.ps1 +++ b/images/windows/scripts/build/Install-Ruby.ps1 @@ -87,7 +87,6 @@ foreach ($rubyVersion in $rubyToolVersions) { } else { Install-Ruby -PackagePath $packagePath -Architecture "x64" } - Install-Ruby -PackagePath $packagePath } Set-DefaultRubyVersion -Version $rubyTools.default -Arch $rubyTools.arch From 6d309dfff9a17cbb3368e410225dd977f2d06f60 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Sun, 22 Mar 2026 23:56:13 +0100 Subject: [PATCH 40/55] Fix Haskell.Tests.ps1 --- images/windows/scripts/tests/Haskell.Tests.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/images/windows/scripts/tests/Haskell.Tests.ps1 b/images/windows/scripts/tests/Haskell.Tests.ps1 index 2791868422..bf04f654f2 100644 --- a/images/windows/scripts/tests/Haskell.Tests.ps1 +++ b/images/windows/scripts/tests/Haskell.Tests.ps1 @@ -1,5 +1,6 @@ Describe "Haskell" -Skip:(Test-IsWin11) { BeforeDiscovery { + if (Test-IsWin11) { return } $ghcPackagesPath = "c:\ghcup\ghc" [array] $ghcVersionList = Get-ChildItem -Path $ghcPackagesPath -Filter "*" | ForEach-Object { $_.Name.Trim() } $ghcCount = $ghcVersionList.Count From 3ce8ab8fd21047065054bb1b75ebedaa84527117 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Mon, 23 Mar 2026 12:59:25 +0100 Subject: [PATCH 41/55] DEBUG: output windows updates state --- .../templates/build.windows-11-arm64.pkr.hcl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/images/windows/templates/build.windows-11-arm64.pkr.hcl b/images/windows/templates/build.windows-11-arm64.pkr.hcl index d4617c276d..311c1f8438 100644 --- a/images/windows/templates/build.windows-11-arm64.pkr.hcl +++ b/images/windows/templates/build.windows-11-arm64.pkr.hcl @@ -299,6 +299,22 @@ build { restart_timeout = "30m" } + # TODO: removes once debugging is done + provisioner "powershell" { + inline = [<<-EOF + $filter = @{ + LogName = "System" + Id = 19, 20, 43 + ProviderName = "Microsoft-Windows-WindowsUpdateClient" + } + $events = Get-WinEvent -FilterHashtable $filter -ErrorAction SilentlyContinue | Sort-Object Id + $events | sort TimeCreated | fl * + Write-Host "display appxpackages" + Get-AppxPackage + EOF + ] + } + provisioner "powershell" { pause_before = "2m0s" environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] From 1d04e42fc912de5957a42077b6cb5f6835cea41b Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Mon, 23 Mar 2026 19:16:40 +0100 Subject: [PATCH 42/55] Skip MicrosoftWindows.Client.WebExperience update fails --- images/windows/scripts/tests/WindowsFeatures.Tests.ps1 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/images/windows/scripts/tests/WindowsFeatures.Tests.ps1 b/images/windows/scripts/tests/WindowsFeatures.Tests.ps1 index 22c2a5aff5..68ed297ee8 100644 --- a/images/windows/scripts/tests/WindowsFeatures.Tests.ps1 +++ b/images/windows/scripts/tests/WindowsFeatures.Tests.ps1 @@ -79,6 +79,9 @@ Describe "Windows Updates" { if ( $Title -match "Microsoft Defender Antivirus" ) { $expect = "Installed", "Failed", "Running" } + if ( $Title -match "MicrosoftWindows.Client.WebExperience" ) { + $expect = "Installed", "Failed", "Running" + } $State | Should -BeIn $expect } From 1ce128c1233924b61a95aa69dc3b5a6a98a99ff4 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Tue, 24 Mar 2026 13:43:55 +0100 Subject: [PATCH 43/55] Fix Build-PackageManagementEnvironmentTable --- images/windows/scripts/docs-gen/SoftwareReport.Common.psm1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/images/windows/scripts/docs-gen/SoftwareReport.Common.psm1 b/images/windows/scripts/docs-gen/SoftwareReport.Common.psm1 index 58d3a96db4..ebb83c8edf 100644 --- a/images/windows/scripts/docs-gen/SoftwareReport.Common.psm1 +++ b/images/windows/scripts/docs-gen/SoftwareReport.Common.psm1 @@ -297,9 +297,9 @@ function Build-PackageManagementEnvironmentTable { "Name" = "VCPKG_INSTALLATION_ROOT" "Value" = $env:VCPKG_INSTALLATION_ROOT }, - [PSCustomObject] @{ + $(if (-not (Test-IsWin11)) { [PSCustomObject] @{ "Name" = "CONDA" "Value" = $env:CONDA - } - ) + } }) + ) | Where-Object { $_ } } From e9bec78939bc954333841d69d38e573f365b995e Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Tue, 24 Mar 2026 13:47:00 +0100 Subject: [PATCH 44/55] Revert "TEMP: remove cargo-audit" This reverts commit 23dd906c9dc7f00be96801074ff0b3fd5e2942c3. --- images/windows/scripts/build/Install-Rust.ps1 | 3 +-- images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 | 5 +---- images/windows/scripts/tests/Rust.Tests.ps1 | 3 +-- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/images/windows/scripts/build/Install-Rust.ps1 b/images/windows/scripts/build/Install-Rust.ps1 index 88e4a8dab1..f622edda55 100644 --- a/images/windows/scripts/build/Install-Rust.ps1 +++ b/images/windows/scripts/build/Install-Rust.ps1 @@ -60,8 +60,7 @@ if (Test-IsWin22) { } if (Test-IsWin11) { - # TODO: test cargo-audit and bring back - cargo install bindgen-cli cbindgen cargo-outdated + cargo install bindgen-cli cbindgen cargo-audit cargo-outdated if ($LASTEXITCODE -ne 0) { throw "Rust tools installation failed with exit code $LASTEXITCODE" } diff --git a/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 b/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 index e98c75704a..2073e24de1 100644 --- a/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 +++ b/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 @@ -146,10 +146,7 @@ $rustTools.AddToolVersion("Rustup", $(Get-RustupVersion)) $rustToolsPackages = $rustTools.AddHeader("Packages") if (-not (Test-IsWin25)) { $rustToolsPackages.AddToolVersion("bindgen", $(Get-BindgenVersion)) - # TODO: test cargo-audit and bring back - if (-not (Test-IsWin11)) { - $rustToolsPackages.AddToolVersion("cargo-audit", $(Get-CargoAuditVersion)) - } + $rustToolsPackages.AddToolVersion("cargo-audit", $(Get-CargoAuditVersion)) $rustToolsPackages.AddToolVersion("cargo-outdated", $(Get-CargoOutdatedVersion)) $rustToolsPackages.AddToolVersion("cbindgen", $(Get-CbindgenVersion)) } diff --git a/images/windows/scripts/tests/Rust.Tests.ps1 b/images/windows/scripts/tests/Rust.Tests.ps1 index 8058792662..717e80e428 100644 --- a/images/windows/scripts/tests/Rust.Tests.ps1 +++ b/images/windows/scripts/tests/Rust.Tests.ps1 @@ -12,14 +12,13 @@ Describe "Rust" { @{ToolName = "cargo"; binPath = "C:\Users\Default\.cargo\bin\cargo.exe"} ) } else { - # TODO: test cargo-audit and bring back $rustTools = @( @{ToolName = "rustup"; binPath = "C:\Users\Default\.cargo\bin\rustup.exe"} @{ToolName = "rustc"; binPath = "C:\Users\Default\.cargo\bin\rustc.exe"} @{ToolName = "bindgen.exe"; binPath = "C:\Users\Default\.cargo\bin\bindgen.exe"} @{ToolName = "cbindgen.exe"; binPath = "C:\Users\Default\.cargo\bin\cbindgen.exe"} @{ToolName = "cargo"; binPath = "C:\Users\Default\.cargo\bin\cargo.exe"} - $(if (-not (Test-IsWin11)) { @{ToolName = "cargo audit"; binPath = "C:\Users\Default\.cargo\bin\cargo-audit.exe"} }) + @{ToolName = "cargo audit"; binPath = "C:\Users\Default\.cargo\bin\cargo-audit.exe"} @{ToolName = "cargo outdated"; binPath = "C:\Users\Default\.cargo\bin\cargo-outdated.exe"} ) } From 18fec9227bc409b549b22c122de03f1c7f5739d0 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Tue, 24 Mar 2026 13:58:11 +0100 Subject: [PATCH 45/55] Cleanup code --- .../templates/build.windows-11-arm64.pkr.hcl | 98 ------------------- 1 file changed, 98 deletions(-) diff --git a/images/windows/templates/build.windows-11-arm64.pkr.hcl b/images/windows/templates/build.windows-11-arm64.pkr.hcl index 311c1f8438..36db27fdd9 100644 --- a/images/windows/templates/build.windows-11-arm64.pkr.hcl +++ b/images/windows/templates/build.windows-11-arm64.pkr.hcl @@ -51,63 +51,6 @@ build { inline = ["if (-not ((net localgroup Administrators) -contains '${var.install_user}')) { exit 1 }"] } - # v1 - elevated user issue - # provisioner "powershell" { - # inline = [<<-EOF - # $sidStr = (New-Object Security.Principal.NTAccount("${var.install_user}")).Translate([Security.Principal.SecurityIdentifier]).Value - # $tmpFile = [IO.Path]::GetTempFileName() - # secedit /export /cfg $tmpFile /areas USER_RIGHTS /quiet - # $policy = Get-Content $tmpFile -Raw - # if ($policy -match 'SeBatchLogonRight\s*=\s*(.*)') { - # $policy = $policy -replace 'SeBatchLogonRight\s*=\s*(.*)', "SeBatchLogonRight = `$1,*$sidStr" - # } else { - # $policy += "`r`nSeBatchLogonRight = *$sidStr" - # } - # Set-Content $tmpFile $policy - # secedit /configure /db "$env:TEMP\secedit.sdb" /cfg $tmpFile /areas USER_RIGHTS /quiet - # Remove-Item $tmpFile - # EOF - # ] - # } - - # v2 - elevated user issue - # provisioner "powershell" { - # inline = [<<-EOF - # $code = @' - # using System; - # using System.Runtime.InteropServices; - # public class LsaUtil { - # [DllImport("advapi32.dll", SetLastError=true)] - # static extern uint LsaOpenPolicy(IntPtr SystemName, ref LSA_OBJECT_ATTRIBUTES ObjectAttributes, uint AccessMask, out IntPtr PolicyHandle); - # [DllImport("advapi32.dll", SetLastError=true)] - # static extern uint LsaAddAccountRights(IntPtr PolicyHandle, IntPtr AccountSid, LSA_UNICODE_STRING[] UserRights, long CountOfRights); - # [DllImport("advapi32.dll")] - # static extern uint LsaClose(IntPtr ObjectHandle); - # [StructLayout(LayoutKind.Sequential)] public struct LSA_OBJECT_ATTRIBUTES { public int Length; public IntPtr RootDirectory; public IntPtr ObjectName; public uint Attributes; public IntPtr SecurityDescriptor; public IntPtr SecurityQualityOfService; } - # [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct LSA_UNICODE_STRING { public ushort Length; public ushort MaximumLength; [MarshalAs(UnmanagedType.LPWStr)] public string Buffer; } - # public static void AddRight(string accountName, string rightName) { - # var attrs = new LSA_OBJECT_ATTRIBUTES(); - # IntPtr policy; - # LsaOpenPolicy(IntPtr.Zero, ref attrs, 0x00020000 | 0x00000800, out policy); - # var sid = new System.Security.Principal.NTAccount(accountName).Translate(typeof(System.Security.Principal.SecurityIdentifier)); - # var sidBytes = new byte[((System.Security.Principal.SecurityIdentifier)sid).BinaryLength]; - # ((System.Security.Principal.SecurityIdentifier)sid).GetBinaryForm(sidBytes, 0); - # var sidPtr = Marshal.AllocHGlobal(sidBytes.Length); - # Marshal.Copy(sidBytes, 0, sidPtr, sidBytes.Length); - # var rights = new[] { new LSA_UNICODE_STRING { Buffer = rightName, Length = (ushort)(rightName.Length * 2), MaximumLength = (ushort)(rightName.Length * 2 + 2) } }; - # LsaAddAccountRights(policy, sidPtr, rights, 1); - # Marshal.FreeHGlobal(sidPtr); - # LsaClose(policy); - # } - # } - # '@ - # Add-Type $code - # [LsaUtil]::AddRight("${var.install_user}", "SeBatchLogonRight") - # EOF - # ] - # } - - # v3 - set and remove after all elevated tasks are done, might need additional reboot provisioner "powershell" { inline = [ "Set-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name AutoAdminLogon -Value 1 -type String", @@ -116,7 +59,6 @@ build { ] } - # v3 - elevated user issue provisioner "windows-restart" { check_registry = true restart_timeout = "10m" @@ -135,7 +77,6 @@ build { "${path.root}/../scripts/build/Configure-WindowsDefender.ps1", "${path.root}/../scripts/build/Configure-PowerShell.ps1", "${path.root}/../scripts/build/Install-PowerShellModules.ps1", - # "${path.root}/../scripts/build/Install-WSL2.ps1", "${path.root}/../scripts/build/Install-WindowsFeatures.ps1", "${path.root}/../scripts/build/Install-Chocolatey.ps1", "${path.root}/../scripts/build/Configure-BaseImage.ps1", @@ -155,14 +96,9 @@ build { inline = ["Set-Service -Name wlansvc -StartupType Manual", "if ($(Get-Service -Name wlansvc).Status -eq 'Running') { Stop-Service -Name wlansvc}"] } - # TODO: - # 1. Double check if Install-Runner.ps1 is needed, should be taken care of during specialization. Left out for now provisioner "powershell" { environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] scripts = [ - # "${path.root}/../scripts/build/Install-Docker.ps1", - # "${path.root}/../scripts/build/Install-DockerWinCred.ps1", - # "${path.root}/../scripts/build/Install-DockerCompose.ps1", "${path.root}/../scripts/build/Install-PowershellCore.ps1", "${path.root}/../scripts/build/Install-WebPlatformInstaller.ps1" ] @@ -188,15 +124,10 @@ build { restart_timeout = "10m" } - # TODO: - # 1. Add ${path.root}/../scripts/build/Install-CMake.ps1 - Done, instead of Choco package, updated to latest - # 2. Add ${path.root}/../scripts/build/Install-Ninja.ps1 - Done, instead of Choco package, updated to latest - # 3. Check if need to move ${path.root}/../scripts/build/Install-LLVM.ps1 into this block provisioner "powershell" { pause_before = "2m0s" environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] scripts = [ - # "${path.root}/../scripts/build/Install-Wix.ps1", "${path.root}/../scripts/build/Install-WDK.ps1", "${path.root}/../scripts/build/Install-VSExtensions.ps1", "${path.root}/../scripts/build/Install-AzureCli.ps1", @@ -214,20 +145,14 @@ build { restart_timeout = "10m" } - # TODO: - # 1. Add ${path.root}/../scripts/build/Install-Mercurial.ps1 - Done - # 2. Add ${path.root}/../scripts/build/Install-NSIS.ps1 - Done - # 3. Add ${path.root}/../scripts/build/Install-AliyunCli.ps1 - Done provisioner "powershell" { environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] scripts = [ "${path.root}/../scripts/build/Install-ActionsCache.ps1", "${path.root}/../scripts/build/Install-Ruby.ps1", - # "${path.root}/../scripts/build/Install-PyPy.ps1", "${path.root}/../scripts/build/Install-Toolset.ps1", "${path.root}/../scripts/build/Configure-Toolset.ps1", "${path.root}/../scripts/build/Install-NodeJS.ps1", - # "${path.root}/../scripts/build/Install-AndroidSDK.ps1", "${path.root}/../scripts/build/Install-PowershellAzModules.ps1", "${path.root}/../scripts/build/Install-Pipx.ps1", "${path.root}/../scripts/build/Install-Git.ps1", @@ -242,7 +167,6 @@ build { "${path.root}/../scripts/build/Install-IEWebDriver.ps1", "${path.root}/../scripts/build/Install-Apache.ps1", "${path.root}/../scripts/build/Install-Nginx.ps1", - # "${path.root}/../scripts/build/Install-Msys2.ps1", "${path.root}/../scripts/build/Install-WinAppDriver.ps1", "${path.root}/../scripts/build/Install-R.ps1", "${path.root}/../scripts/build/Install-AWSTools.ps1", @@ -252,18 +176,14 @@ build { "${path.root}/../scripts/build/Install-SQLOLEDBDriver.ps1", "${path.root}/../scripts/build/Install-DotnetSDK.ps1", "${path.root}/../scripts/build/Install-Mingw64.ps1", - # "${path.root}/../scripts/build/Install-Haskell.ps1", "${path.root}/../scripts/build/Install-Stack.ps1", - # "${path.root}/../scripts/build/Install-Miniconda.ps1", "${path.root}/../scripts/build/Install-AzureCosmosDbEmulator.ps1", "${path.root}/../scripts/build/Install-Mercurial.ps1", "${path.root}/../scripts/build/Install-NSIS.ps1", - # "${path.root}/../scripts/build/Install-Zstd.ps1", "${path.root}/../scripts/build/Install-Vcpkg.ps1", "${path.root}/../scripts/build/Install-Bazel.ps1", "${path.root}/../scripts/build/Install-AliyunCli.ps1", "${path.root}/../scripts/build/Install-RootCA.ps1", - # "${path.root}/../scripts/build/Install-MongoDB.ps1", "${path.root}/../scripts/build/Install-CodeQLBundle.ps1", "${path.root}/../scripts/build/Configure-Diagnostics.ps1" ] @@ -274,7 +194,6 @@ build { elevated_user = "${var.install_user}" environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] scripts = [ - # "${path.root}/../scripts/build/Install-PostgreSQL.ps1", "${path.root}/../scripts/build/Install-WindowsUpdates.ps1", "${path.root}/../scripts/build/Configure-DynamicPort.ps1", "${path.root}/../scripts/build/Configure-GDIProcessHandleQuota.ps1", @@ -284,7 +203,6 @@ build { ] } - # v3 - elevated user issue provisioner "powershell" { inline = [ "Remove-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name AutoAdminLogon", @@ -299,22 +217,6 @@ build { restart_timeout = "30m" } - # TODO: removes once debugging is done - provisioner "powershell" { - inline = [<<-EOF - $filter = @{ - LogName = "System" - Id = 19, 20, 43 - ProviderName = "Microsoft-Windows-WindowsUpdateClient" - } - $events = Get-WinEvent -FilterHashtable $filter -ErrorAction SilentlyContinue | Sort-Object Id - $events | sort TimeCreated | fl * - Write-Host "display appxpackages" - Get-AppxPackage - EOF - ] - } - provisioner "powershell" { pause_before = "2m0s" environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] From 9c0fdaa497cc3e584094e239bfdbd0d436e21b7b Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Tue, 24 Mar 2026 13:59:19 +0100 Subject: [PATCH 46/55] Fix LLVM install sequence --- images/windows/templates/build.windows-11-arm64.pkr.hcl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/images/windows/templates/build.windows-11-arm64.pkr.hcl b/images/windows/templates/build.windows-11-arm64.pkr.hcl index 36db27fdd9..2b6630a279 100644 --- a/images/windows/templates/build.windows-11-arm64.pkr.hcl +++ b/images/windows/templates/build.windows-11-arm64.pkr.hcl @@ -137,7 +137,8 @@ build { "${path.root}/../scripts/build/Install-Ninja.ps1", "${path.root}/../scripts/build/Install-JavaTools.ps1", "${path.root}/../scripts/build/Install-Kotlin.ps1", - "${path.root}/../scripts/build/Install-OpenSSL.ps1" + "${path.root}/../scripts/build/Install-OpenSSL.ps1", + "${path.root}/../scripts/build/Install-LLVM.ps1" ] } @@ -198,8 +199,7 @@ build { "${path.root}/../scripts/build/Configure-DynamicPort.ps1", "${path.root}/../scripts/build/Configure-GDIProcessHandleQuota.ps1", "${path.root}/../scripts/build/Configure-Shell.ps1", - "${path.root}/../scripts/build/Configure-DeveloperMode.ps1", - "${path.root}/../scripts/build/Install-LLVM.ps1" + "${path.root}/../scripts/build/Configure-DeveloperMode.ps1" ] } From f4226910df616747e0f7fb57550e402a91090da4 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Tue, 24 Mar 2026 20:22:32 +0100 Subject: [PATCH 47/55] Add win11-vs2026-arm64 code --- .../scripts/build/Configure-ImageDataFile.ps1 | 4 + .../build.windows-11-vs2026-arm64.pkr.hcl | 278 ++++++++++++++++ .../windows/templates/locals.windows.pkr.hcl | 6 +- .../toolsets/toolset-win-11-vs2026-arm64.json | 309 ++++++++++++++++++ 4 files changed, 596 insertions(+), 1 deletion(-) create mode 100644 images/windows/templates/build.windows-11-vs2026-arm64.pkr.hcl create mode 100644 images/windows/toolsets/toolset-win-11-vs2026-arm64.json diff --git a/images/windows/scripts/build/Configure-ImageDataFile.ps1 b/images/windows/scripts/build/Configure-ImageDataFile.ps1 index 5abbc42430..4b88302a0c 100644 --- a/images/windows/scripts/build/Configure-ImageDataFile.ps1 +++ b/images/windows/scripts/build/Configure-ImageDataFile.ps1 @@ -27,6 +27,10 @@ if ((Test-IsWin25) -and $env:INSTALL_VS_2026) { $imageLabel = "windows-2022" $softwareUrl = "${githubUrl}/win22/$imageMajorVersion.$imageMinorVersion/images/windows/Windows2022-Readme.md" $releaseUrl = "https://github.com/actions/runner-images/releases/tag/win22%2F$imageMajorVersion.$imageMinorVersion" +} if ((Test-IsWin11) -and (Test-IsArm64) -and $env:INSTALL_VS_2026) { + $imageLabel = "windows-11-vs2026-arm64" + $softwareUrl = "${githubUrl}/win11-vs2026-arm64/$imageMajorVersion.$imageMinorVersion/images/windows/Windows11-VS2026-Arm64-Readme.md" + $releaseUrl = "https://github.com/actions/runner-images/releases/tag/win11-vs2026-arm64%2F$imageMajorVersion.$imageMinorVersion" } elseif ((Test-IsWin11) -and (Test-IsArm64)) { $imageLabel = "windows-11-arm64" $softwareUrl = "${githubUrl}/win11-arm64/$imageMajorVersion.$imageMinorVersion/images/windows/Windows11-Arm64-Readme.md" diff --git a/images/windows/templates/build.windows-11-vs2026-arm64.pkr.hcl b/images/windows/templates/build.windows-11-vs2026-arm64.pkr.hcl new file mode 100644 index 0000000000..d67b34a7d6 --- /dev/null +++ b/images/windows/templates/build.windows-11-vs2026-arm64.pkr.hcl @@ -0,0 +1,278 @@ +build { + sources = ["source.azure-arm.image"] + name = "windows-11-vs2026-arm64" + + provisioner "powershell" { + inline = [ + "New-Item -Path ${var.image_folder} -ItemType Directory -Force", + "New-Item -Path ${var.temp_dir} -ItemType Directory -Force" + ] + } + + provisioner "file" { + destination = "${var.image_folder}\\" + sources = [ + "${path.root}/../assets", + "${path.root}/../scripts", + "${path.root}/../toolsets" + ] + } + + provisioner "file" { + destination = "${var.image_folder}\\scripts\\docs-gen\\" + source = "${path.root}/../../../helpers/software-report-base" + } + + provisioner "powershell" { + inline = [ + "Move-Item '${var.image_folder}\\assets\\post-gen' 'C:\\post-generation'", + "Remove-Item -Recurse '${var.image_folder}\\assets'", + "Move-Item '${var.image_folder}\\scripts\\docs-gen' '${var.image_folder}\\SoftwareReport'", + "Move-Item '${var.image_folder}\\scripts\\helpers' '${var.helper_script_folder}\\ImageHelpers'", + "New-Item -Type Directory -Path '${var.helper_script_folder}\\TestsHelpers\\'", + "Move-Item '${var.image_folder}\\scripts\\tests\\Helpers.psm1' '${var.helper_script_folder}\\TestsHelpers\\TestsHelpers.psm1'", + "Move-Item '${var.image_folder}\\scripts\\tests' '${var.image_folder}\\tests'", + "Remove-Item -Recurse '${var.image_folder}\\scripts'", + "Move-Item '${var.image_folder}\\toolsets\\toolset-win-11-vs2026-arm64.json' '${var.image_folder}\\toolset.json'", + "Remove-Item -Recurse '${var.image_folder}\\toolsets'" + ] + } + + provisioner "windows-shell" { + inline = [ + "net user ${var.install_user} ${var.install_password} /add /passwordchg:no /passwordreq:yes /active:yes /Y", + "net localgroup Administrators ${var.install_user} /add", + "winrm set winrm/config/service/auth @{Basic=\"true\"}", + "winrm get winrm/config/service/auth" + ] + } + + provisioner "powershell" { + inline = ["if (-not ((net localgroup Administrators) -contains '${var.install_user}')) { exit 1 }"] + } + + provisioner "powershell" { + inline = [ + "Set-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name AutoAdminLogon -Value 1 -type String", + "Set-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name DefaultUsername -Value \"${var.install_user}\" -type String", + "Set-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name DefaultPassword -Value \"${var.install_password}\" -type String", + ] + } + + provisioner "windows-restart" { + check_registry = true + restart_timeout = "10m" + } + + provisioner "powershell" { + elevated_password = "${var.install_password}" + elevated_user = "${var.install_user}" + inline = ["bcdedit.exe /set TESTSIGNING ON"] + } + + provisioner "powershell" { + environment_vars = ["IMAGE_VERSION=${var.image_version}", "IMAGE_OS=${var.image_os}", "AGENT_TOOLSDIRECTORY=${var.agent_tools_directory}", "IMAGEDATA_FILE=${var.imagedata_file}", "IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}", "INSTALL_VS_2026=true"] + execution_policy = "unrestricted" + scripts = [ + "${path.root}/../scripts/build/Configure-WindowsDefender.ps1", + "${path.root}/../scripts/build/Configure-PowerShell.ps1", + "${path.root}/../scripts/build/Install-PowerShellModules.ps1", + "${path.root}/../scripts/build/Install-WindowsFeatures.ps1", + "${path.root}/../scripts/build/Install-Chocolatey.ps1", + "${path.root}/../scripts/build/Configure-BaseImage.ps1", + "${path.root}/../scripts/build/Configure-ImageDataFile.ps1", + "${path.root}/../scripts/build/Configure-SystemEnvironment.ps1", + "${path.root}/../scripts/build/Configure-DotnetSecureChannel.ps1" + ] + } + + provisioner "windows-restart" { + check_registry = true + restart_check_command = "powershell -command \"& {while ( (Get-WindowsOptionalFeature -Online -FeatureName Containers -ErrorAction SilentlyContinue).State -ne 'Enabled' ) { Start-Sleep 30; Write-Output 'InProgress' }}\"" + restart_timeout = "10m" + } + + provisioner "powershell" { + inline = ["Set-Service -Name wlansvc -StartupType Manual", "if ($(Get-Service -Name wlansvc).Status -eq 'Running') { Stop-Service -Name wlansvc}"] + } + + provisioner "powershell" { + environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] + scripts = [ + "${path.root}/../scripts/build/Install-PowershellCore.ps1", + "${path.root}/../scripts/build/Install-WebPlatformInstaller.ps1" + ] + } + + provisioner "windows-restart" { + restart_timeout = "30m" + } + + provisioner "powershell" { + elevated_password = "${var.install_password}" + elevated_user = "${var.install_user}" + environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}", "INSTALL_VS_2026=true"] + scripts = [ + "${path.root}/../scripts/build/Install-VisualStudio.ps1", + "${path.root}/../scripts/build/Install-KubernetesTools.ps1" + ] + valid_exit_codes = [0, 3010] + } + + provisioner "windows-restart" { + check_registry = true + restart_timeout = "10m" + } + + provisioner "powershell" { + pause_before = "2m0s" + environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] + scripts = [ + "${path.root}/../scripts/build/Install-WDK.ps1", + "${path.root}/../scripts/build/Install-VSExtensions.ps1", + "${path.root}/../scripts/build/Install-AzureCli.ps1", + "${path.root}/../scripts/build/Install-AzureDevOpsCli.ps1", + "${path.root}/../scripts/build/Install-ChocolateyPackages.ps1", + "${path.root}/../scripts/build/Install-CMake.ps1", + "${path.root}/../scripts/build/Install-Ninja.ps1", + "${path.root}/../scripts/build/Install-JavaTools.ps1", + "${path.root}/../scripts/build/Install-Kotlin.ps1", + "${path.root}/../scripts/build/Install-OpenSSL.ps1", + "${path.root}/../scripts/build/Install-LLVM.ps1" + ] + } + + provisioner "windows-restart" { + restart_timeout = "10m" + } + + provisioner "powershell" { + environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] + scripts = [ + "${path.root}/../scripts/build/Install-ActionsCache.ps1", + "${path.root}/../scripts/build/Install-Ruby.ps1", + "${path.root}/../scripts/build/Install-Toolset.ps1", + "${path.root}/../scripts/build/Configure-Toolset.ps1", + "${path.root}/../scripts/build/Install-NodeJS.ps1", + "${path.root}/../scripts/build/Install-PowershellAzModules.ps1", + "${path.root}/../scripts/build/Install-Pipx.ps1", + "${path.root}/../scripts/build/Install-Git.ps1", + "${path.root}/../scripts/build/Install-GitHub-CLI.ps1", + "${path.root}/../scripts/build/Install-PHP.ps1", + "${path.root}/../scripts/build/Install-Rust.ps1", + "${path.root}/../scripts/build/Install-Sbt.ps1", + "${path.root}/../scripts/build/Install-Chrome.ps1", + "${path.root}/../scripts/build/Install-EdgeDriver.ps1", + "${path.root}/../scripts/build/Install-Firefox.ps1", + "${path.root}/../scripts/build/Install-Selenium.ps1", + "${path.root}/../scripts/build/Install-IEWebDriver.ps1", + "${path.root}/../scripts/build/Install-Apache.ps1", + "${path.root}/../scripts/build/Install-Nginx.ps1", + "${path.root}/../scripts/build/Install-WinAppDriver.ps1", + "${path.root}/../scripts/build/Install-R.ps1", + "${path.root}/../scripts/build/Install-AWSTools.ps1", + "${path.root}/../scripts/build/Install-DACFx.ps1", + "${path.root}/../scripts/build/Install-MysqlCli.ps1", + "${path.root}/../scripts/build/Install-SQLPowerShellTools.ps1", + "${path.root}/../scripts/build/Install-SQLOLEDBDriver.ps1", + "${path.root}/../scripts/build/Install-DotnetSDK.ps1", + "${path.root}/../scripts/build/Install-Mingw64.ps1", + "${path.root}/../scripts/build/Install-Stack.ps1", + "${path.root}/../scripts/build/Install-AzureCosmosDbEmulator.ps1", + "${path.root}/../scripts/build/Install-Mercurial.ps1", + "${path.root}/../scripts/build/Install-NSIS.ps1", + "${path.root}/../scripts/build/Install-Vcpkg.ps1", + "${path.root}/../scripts/build/Install-Bazel.ps1", + "${path.root}/../scripts/build/Install-AliyunCli.ps1", + "${path.root}/../scripts/build/Install-RootCA.ps1", + "${path.root}/../scripts/build/Install-CodeQLBundle.ps1", + "${path.root}/../scripts/build/Configure-Diagnostics.ps1" + ] + } + + provisioner "powershell" { + elevated_password = "${var.install_password}" + elevated_user = "${var.install_user}" + environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] + scripts = [ + "${path.root}/../scripts/build/Install-WindowsUpdates.ps1", + "${path.root}/../scripts/build/Configure-DynamicPort.ps1", + "${path.root}/../scripts/build/Configure-GDIProcessHandleQuota.ps1", + "${path.root}/../scripts/build/Configure-Shell.ps1", + "${path.root}/../scripts/build/Configure-DeveloperMode.ps1" + ] + } + + provisioner "powershell" { + inline = [ + "Remove-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name AutoAdminLogon", + "Remove-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name DefaultUsername", + "Remove-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name DefaultPassword", + ] + } + + provisioner "windows-restart" { + check_registry = true + restart_check_command = "powershell -command \"& {if ((-not (Get-Process TiWorker.exe -ErrorAction SilentlyContinue)) -and (-not [System.Environment]::HasShutdownStarted) ) { Write-Output 'Restart complete' }}\"" + restart_timeout = "30m" + } + + provisioner "powershell" { + pause_before = "2m0s" + environment_vars = ["IMAGE_FOLDER=${var.image_folder}", "TEMP_DIR=${var.temp_dir}"] + scripts = [ + "${path.root}/../scripts/build/Install-WindowsUpdatesAfterReboot.ps1", + "${path.root}/../scripts/build/Invoke-Cleanup.ps1", + "${path.root}/../scripts/tests/RunAll-Tests.ps1" + ] + } + + provisioner "powershell" { + inline = ["if (-not (Test-Path ${var.image_folder}\\tests\\testResults.xml)) { throw '${var.image_folder}\\tests\\testResults.xml not found' }"] + } + + provisioner "powershell" { + environment_vars = ["IMAGE_VERSION=${var.image_version}", "IMAGE_FOLDER=${var.image_folder}"] + inline = ["pwsh -File '${var.image_folder}\\SoftwareReport\\Generate-SoftwareReport.ps1'"] + } + + provisioner "powershell" { + inline = ["if (-not (Test-Path C:\\software-report.md)) { throw 'C:\\software-report.md not found' }", "if (-not (Test-Path C:\\software-report.json)) { throw 'C:\\software-report.json not found' }"] + } + + provisioner "file" { + destination = "${path.root}/../Windows11-VS2026-Arm64-Readme.md" + direction = "download" + source = "C:\\software-report.md" + } + + provisioner "file" { + destination = "${path.root}/../software-report.json" + direction = "download" + source = "C:\\software-report.json" + } + + provisioner "powershell" { + environment_vars = ["INSTALL_USER=${var.install_user}"] + scripts = [ + "${path.root}/../scripts/build/Install-NativeImages.ps1", + "${path.root}/../scripts/build/Configure-System.ps1", + "${path.root}/../scripts/build/Configure-User.ps1", + "${path.root}/../scripts/build/Post-Build-Validation.ps1" + ] + skip_clean = true + } + + provisioner "windows-restart" { + restart_timeout = "10m" + } + + provisioner "powershell" { + inline = [ + "if( Test-Path $env:SystemRoot\\System32\\Sysprep\\unattend.xml ){ rm $env:SystemRoot\\System32\\Sysprep\\unattend.xml -Force}", + "& $env:SystemRoot\\System32\\Sysprep\\Sysprep.exe /oobe /generalize /mode:vm /quiet /quit", + "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 } }" + ] + } + +} diff --git a/images/windows/templates/locals.windows.pkr.hcl b/images/windows/templates/locals.windows.pkr.hcl index 9a671dc5dd..8a5f12993c 100644 --- a/images/windows/templates/locals.windows.pkr.hcl +++ b/images/windows/templates/locals.windows.pkr.hcl @@ -11,10 +11,14 @@ locals { "win25-vs2026" = { source_image_marketplace_sku = "MicrosoftWindowsServer:WindowsServer:2025-Datacenter-g2" os_disk_size_gb = 150 - } + }, "win11-arm64" = { source_image_marketplace_sku = "microsoftwindowsdesktop:windows11preview-arm64:win11-25h2-ent" os_disk_size_gb = 256 + }, + "win11-vs2026-arm64" = { + source_image_marketplace_sku = "microsoftwindowsdesktop:windows11preview-arm64:win11-25h2-ent" + os_disk_size_gb = 256 } } diff --git a/images/windows/toolsets/toolset-win-11-vs2026-arm64.json b/images/windows/toolsets/toolset-win-11-vs2026-arm64.json new file mode 100644 index 0000000000..b9a0edbb27 --- /dev/null +++ b/images/windows/toolsets/toolset-win-11-vs2026-arm64.json @@ -0,0 +1,309 @@ +{ + "toolcache": [ + { + "name": "Ruby", + "arch": "aarch64", + "platform" : "win32", + "versions": [ + "3.4" + ], + "default": "3.4" + }, + { + "name": "Python", + "url" : "https://raw.githubusercontent.com/actions/python-versions/main/versions-manifest.json", + "arch": "x64", + "platform" : "win32", + "versions": [ + "3.13.*" + ] + }, + { + "name": "Python", + "url" : "https://raw.githubusercontent.com/actions/python-versions/main/versions-manifest.json", + "arch": "arm64", + "platform" : "win32", + "versions": [ + "3.12.*", + "3.13.*", + "3.14.*" + ], + "default": "3.13.*" + }, + { + "name": "node", + "url" : "https://raw.githubusercontent.com/actions/node-versions/main/versions-manifest.json", + "arch": "arm64", + "platform" : "win32", + "versions": [ + "20.*", + "22.*", + "24.*" + ] + }, + { + "name": "go", + "url" : "https://raw.githubusercontent.com/actions/go-versions/main/versions-manifest.json", + "arch": "arm64", + "platform" : "win32", + "versions": [ + "1.22.*", + "1.23.*", + "1.24.*", + "1.25.*" + ], + "default": "1.24.*" + } + ], + "powershellModules": [ + { "name": "DockerMsftProvider" }, + { "name": "MarkdownPS" }, + { "name": "Pester" }, + { "name": "PowerShellGet" }, + { "name": "PSScriptAnalyzer" }, + { "name": "PSWindowsUpdate" }, + { "name": "SqlServer" }, + { "name": "VSSetup" }, + { "name": "Microsoft.Graph" }, + { "name": "AWSPowershell" } + ], + "azureModules": [ + { + "name": "az", + "versions": [ + "12.5.0" + ], + "zip_versions": [ + + ] + } + ], + "java": { + "default": "21", + "versions": [ "21", "23" ] + }, + "android": { + "commandline_tools_url": "https://dl.google.com/android/repository/commandlinetools-win-9123335_latest.zip", + "hash": "8A90E6A3DEB2FA13229B2E335EFD07687DCC8A55A3C544DA9F40B41404993E7D", + "platform_min_version": "31", + "build_tools_min_version": "31.0.0", + "extras": [ + "android;m2repository", + "google;m2repository", + "google;google_play_services" + ], + "addons": [], + "additional_tools": [ + "cmake;3.18.1", + "cmake;3.22.1" + ], + "ndk": { + "default": "27", + "versions": [ + "26", "27", "28" + ] + } + }, + "mingw": { + "version": "14.*", + "runtime": "ucrt" + }, + "MsysPackages": { + "msys2": [], + "mingw": [] + }, + "windowsFeatures": [ + { "name": "Containers", "optionalFeature": true }, + { "name": "Microsoft-Windows-Subsystem-Linux", "optionalFeature": true }, + { "name": "VirtualMachinePlatform", "optionalFeature": true }, + { "name": "NetFx4-AdvSrvs", "optionalFeature": true }, + { "name": "Client-ProjFS", "optionalFeature": true }, + { "name": "Microsoft-Hyper-V-All", "optionalFeature": true }, + { "name": "Microsoft-Hyper-V", "optionalFeature": true }, + { "name": "Microsoft-Hyper-V-Tools-All", "optionalFeature": true }, + { "name": "Microsoft-Hyper-V-Hypervisor", "optionalFeature": true }, + { "name": "Microsoft-Hyper-V-Management-PowerShell", "optionalFeature": true } + ], + "visualStudio": { + "version" : "2026", + "subversion" : "18", + "edition" : "Enterprise", + "channel": "stable", + "installChannelUri": "", + "workloads": [ + "Component.Linux.CMake", + "Component.Unreal.Android", + "Component.Xamarin", + "Microsoft.Component.VC.Runtime.UCRTSDK", + "Microsoft.Net.Component.4.7.2.SDK", + "Microsoft.Net.Component.4.7.TargetingPack", + "Microsoft.Net.Component.4.7.2.TargetingPack", + "Microsoft.Net.Component.4.8.1.SDK", + "Microsoft.Net.Component.4.8.1.TargetingPack", + "Microsoft.VisualStudio.Component.AspNet45", + "Microsoft.VisualStudio.Component.Debugger.JustInTime", + "Microsoft.VisualStudio.Component.EntityFramework", + "Microsoft.VisualStudio.Component.DslTools", + "Microsoft.VisualStudio.Component.SQL.SSDT", + "Microsoft.VisualStudio.Component.PortableLibrary", + "Microsoft.VisualStudio.Component.UWP.VC.ARM64", + "Microsoft.VisualStudio.Component.UWP.VC.ARM64EC", + "Microsoft.VisualStudio.Component.VC.CLI.Support", + "Microsoft.VisualStudio.Component.VC.CMake.Project", + "Microsoft.VisualStudio.Component.VC.DiagnosticTools", + "Microsoft.VisualStudio.Component.VC.Llvm.Clang", + "Microsoft.VisualStudio.Component.VC.Llvm.ClangToolset", + "Microsoft.VisualStudio.Component.VC.TestAdapterForBoostTest", + "Microsoft.VisualStudio.Component.VC.TestAdapterForGoogleTest", + "Microsoft.VisualStudio.Component.VC.Tools.ARM64", + "Microsoft.VisualStudio.Component.VC.Tools.ARM64EC", + "Microsoft.VisualStudio.Component.VC.Redist.MSM", + "Microsoft.VisualStudio.Component.VC.Runtimes.ARM64.Spectre", + "Microsoft.VisualStudio.Component.VC.Runtimes.ARM64EC.Spectre", + "Microsoft.VisualStudio.Component.VC.MFC.ARM64", + "Microsoft.VisualStudio.Component.VC.MFC.ARM64.Spectre", + "Microsoft.VisualStudio.Component.VC.ATLMFC", + "Microsoft.VisualStudio.Component.VC.ATLMFC.Spectre", + "Microsoft.VisualStudio.Component.VC.ATL", + "Microsoft.VisualStudio.Component.VC.ATL.Spectre", + "Microsoft.VisualStudio.Component.VC.ATL.ARM64", + "Microsoft.VisualStudio.Component.VC.ATL.ARM64.Spectre", + "Microsoft.VisualStudio.Component.VC.ASAN", + "Microsoft.VisualStudio.Component.VC.14.44.17.14.ARM64", + "Microsoft.VisualStudio.Component.Windows10SDK.19041", + "Microsoft.VisualStudio.Component.Windows11SDK.22621", + "Microsoft.VisualStudio.Component.Windows11SDK.26100", + "Microsoft.VisualStudio.ComponentGroup.NativeDesktop.Llvm.Clang", + "Microsoft.VisualStudio.ComponentGroup.UWP.VC.v142", + "Microsoft.VisualStudio.ComponentGroup.Web.CloudTools", + "Microsoft.VisualStudio.Workload.ManagedDesktop", + "Microsoft.VisualStudio.Workload.ManagedGame", + "Microsoft.VisualStudio.Workload.NativeCrossPlat", + "Microsoft.VisualStudio.Workload.NativeDesktop", + "Microsoft.VisualStudio.Workload.NativeGame", + "Microsoft.VisualStudio.Workload.NetCrossPlat", + "Microsoft.VisualStudio.Workload.NetWeb", + "Microsoft.VisualStudio.Workload.Node", + "Microsoft.VisualStudio.Workload.Universal", + "Microsoft.VisualStudio.Workload.VisualStudioExtension", + "Component.MDD.Linux", + "Component.Microsoft.Windows.DriverKit", + "wasm.tools", + "Microsoft.Component.MSBuild" + ], + "vsix": [ + "SSIS.MicrosoftDataToolsIntegrationServices", + "VisualStudioClient.MicrosoftVisualStudio2022InstallerProjectsArm64" + ] + }, + "docker": { + "images": [ + "mcr.microsoft.com/windows/servercore:ltsc2022", + "mcr.microsoft.com/windows/nanoserver:ltsc2022", + "mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2022", + "mcr.microsoft.com/dotnet/framework/runtime:4.8-windowsservercore-ltsc2022", + "mcr.microsoft.com/dotnet/framework/sdk:4.8-windowsservercore-ltsc2022" + ], + "components": { + "docker": "26.1.3", + "compose": "2.27.1" + } + }, + "pipx": [ + { + "package": "yamllint", + "cmd": "yamllint --version" + } + ], + "selenium": { + "version": "4" + }, + "npm": { + "global_packages": [ + { "name": "yarn", "test": "yarn --version" }, + { "name": "newman", "test": "newman --version" }, + { "name": "lerna", "test": "lerna --version" }, + { "name": "gulp-cli", "test": "gulp --version" }, + { "name": "grunt-cli", "test": "grunt --version" } + ] + }, + "serviceFabric": { + "runtime": { + "version": "10.1.2493.9590", + "checksum": "09C63A971BACDE338282C73B3C9174BED9AAD53E1D3A1B73D44515852C9C00CF" + }, + "sdk": { + "version": "7.1.2493", + "checksum": "0CB1084156C75CF5075EA91ABA330CF10B58648B8E036C9C2F286805263C497F" + } + }, + "dotnet": { + "versions": [ + "6.0", + "8.0", + "9.0", + "10.0" + ], + "tools": [ + { "name": "nbgv", "test": "nbgv --version", "getversion": "nbgv --version" } + ], + "warmup": false + }, + "choco": { + "common_packages": [ + { "name": "7zip.install" }, + { "name": "aria2" }, + { "name": "azcopy10" }, + { "name": "Bicep" }, + { "name": "innosetup" }, + { "name": "jq" }, + { "name": "NuGet.CommandLine" }, + { "name": "packer" }, + { + "name": "strawberryperl" , + "args": [ "--version", "5.32.1.1" ] + }, + { "name": "pulumi" }, + { "name": "swig" }, + { "name": "vswhere" }, + { + "name": "julia", + "args": [ "--ia", "/DIR=C:\\Julia" ] + }, + { "name": "imagemagick" } + ] + }, + "node": { + "default": "24.*" + }, + "maven": { + "version": "3.9" + }, + "mysql": { + "version": "8.0" + }, + "mongodb": { + "version": "5.0" + }, + "nsis": { + "version": "3.10" + }, + "llvm": { + "version": "20.1.6" + }, + "php": { + "version": "8.4" + }, + "postgresql": { + "version": "14" + }, + "kotlin": { + "version": "latest" + }, + "openssl": { + "version": "3.*" + }, + "pwsh": { + "version": "7.4" + } +} From 1613b62fcbdd1373233c965230f69bc06a13b13f Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Wed, 25 Mar 2026 00:54:39 +0100 Subject: [PATCH 48/55] remove vs workloads --- images/windows/toolsets/toolset-win-11-vs2026-arm64.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/images/windows/toolsets/toolset-win-11-vs2026-arm64.json b/images/windows/toolsets/toolset-win-11-vs2026-arm64.json index b9a0edbb27..642ac98df7 100644 --- a/images/windows/toolsets/toolset-win-11-vs2026-arm64.json +++ b/images/windows/toolsets/toolset-win-11-vs2026-arm64.json @@ -133,7 +133,6 @@ "workloads": [ "Component.Linux.CMake", "Component.Unreal.Android", - "Component.Xamarin", "Microsoft.Component.VC.Runtime.UCRTSDK", "Microsoft.Net.Component.4.7.2.SDK", "Microsoft.Net.Component.4.7.TargetingPack", @@ -170,7 +169,6 @@ "Microsoft.VisualStudio.Component.VC.ATL.ARM64.Spectre", "Microsoft.VisualStudio.Component.VC.ASAN", "Microsoft.VisualStudio.Component.VC.14.44.17.14.ARM64", - "Microsoft.VisualStudio.Component.Windows10SDK.19041", "Microsoft.VisualStudio.Component.Windows11SDK.22621", "Microsoft.VisualStudio.Component.Windows11SDK.26100", "Microsoft.VisualStudio.ComponentGroup.NativeDesktop.Llvm.Clang", From aaa3859f1d4a6e5692da22b841a83b6029c41775 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Thu, 2 Apr 2026 21:12:41 +0200 Subject: [PATCH 49/55] Fix BaseImage and ImageDataFile scripts --- images/windows/scripts/build/Configure-BaseImage.ps1 | 5 +---- images/windows/scripts/build/Configure-ImageDataFile.ps1 | 2 +- .../windows/scripts/docs-gen/SoftwareReport.CachedTools.psm1 | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/images/windows/scripts/build/Configure-BaseImage.ps1 b/images/windows/scripts/build/Configure-BaseImage.ps1 index 8caf55460c..78be1b5885 100644 --- a/images/windows/scripts/build/Configure-BaseImage.ps1 +++ b/images/windows/scripts/build/Configure-BaseImage.ps1 @@ -44,10 +44,7 @@ function Disable-WindowsUpdate { Add-Content -Path $profile.AllUsersAllHosts -Value '$ErrorActionPreference="Stop"' Write-Host "Disable Server Manager on Logon" -$srvManagerTask = Get-ScheduledTask -TaskName ServerManager -if ($srvManagerTask) { - Disable-ScheduledTask -TaskName ServerManager -} +Get-ScheduledTask -TaskName ServerManager -ErrorAction SilentlyContinue | Disable-ScheduledTask Write-Host "Disable 'Allow your PC to be discoverable by other PCs' popup" New-Item -Path HKLM:\System\CurrentControlSet\Control\Network -Name NewNetworkWindowOff -Force diff --git a/images/windows/scripts/build/Configure-ImageDataFile.ps1 b/images/windows/scripts/build/Configure-ImageDataFile.ps1 index 4b88302a0c..aabf736146 100644 --- a/images/windows/scripts/build/Configure-ImageDataFile.ps1 +++ b/images/windows/scripts/build/Configure-ImageDataFile.ps1 @@ -27,7 +27,7 @@ if ((Test-IsWin25) -and $env:INSTALL_VS_2026) { $imageLabel = "windows-2022" $softwareUrl = "${githubUrl}/win22/$imageMajorVersion.$imageMinorVersion/images/windows/Windows2022-Readme.md" $releaseUrl = "https://github.com/actions/runner-images/releases/tag/win22%2F$imageMajorVersion.$imageMinorVersion" -} if ((Test-IsWin11) -and (Test-IsArm64) -and $env:INSTALL_VS_2026) { +} elseif ((Test-IsWin11) -and (Test-IsArm64) -and $env:INSTALL_VS_2026) { $imageLabel = "windows-11-vs2026-arm64" $softwareUrl = "${githubUrl}/win11-vs2026-arm64/$imageMajorVersion.$imageMinorVersion/images/windows/Windows11-VS2026-Arm64-Readme.md" $releaseUrl = "https://github.com/actions/runner-images/releases/tag/win11-vs2026-arm64%2F$imageMajorVersion.$imageMinorVersion" diff --git a/images/windows/scripts/docs-gen/SoftwareReport.CachedTools.psm1 b/images/windows/scripts/docs-gen/SoftwareReport.CachedTools.psm1 index 7ecf866822..170cf85800 100644 --- a/images/windows/scripts/docs-gen/SoftwareReport.CachedTools.psm1 +++ b/images/windows/scripts/docs-gen/SoftwareReport.CachedTools.psm1 @@ -36,5 +36,5 @@ function Build-CachedToolsSection [ToolVersionsListNode]::new("Python", $(Get-ToolcachePythonVersions), '^\d+\.\d+', 'List'), $(if (-not (Test-IsWin11)) { [ToolVersionsListNode]::new("PyPy", $(Get-ToolcachePyPyVersions), '^\d+\.\d+', 'List') }), [ToolVersionsListNode]::new("Ruby", $(Get-ToolcacheRubyVersions), '^\d+\.\d+', 'List') - ) + ) | Where-Object { $_ } } From caa84c5f4e9024bc1ae0f32b9b418917d6928f5d Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Mon, 6 Apr 2026 15:33:52 +0200 Subject: [PATCH 50/55] OS Helper overhaul: add x64 arch variants --- .../windows/scripts/helpers/ImageHelpers.psm1 | 4 ++ .../scripts/helpers/InstallHelpers.ps1 | 57 +++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/images/windows/scripts/helpers/ImageHelpers.psm1 b/images/windows/scripts/helpers/ImageHelpers.psm1 index 07e4b022d4..92f3346f15 100644 --- a/images/windows/scripts/helpers/ImageHelpers.psm1 +++ b/images/windows/scripts/helpers/ImageHelpers.psm1 @@ -27,6 +27,10 @@ Export-ModuleMember -Function @( 'Test-IsWin22' 'Test-IsWin11' 'Test-IsArm64' + 'Test-IsX64' + 'Test-IsWin25-X64' + 'Test-IsWin22-X64' + 'Test-IsWin11-Arm64' 'Expand-7ZipArchive' 'Get-WindowsUpdateStates' 'Invoke-ScriptBlockWithRetry' diff --git a/images/windows/scripts/helpers/InstallHelpers.ps1 b/images/windows/scripts/helpers/InstallHelpers.ps1 index 83abfbd0b0..1569af5519 100644 --- a/images/windows/scripts/helpers/InstallHelpers.ps1 +++ b/images/windows/scripts/helpers/InstallHelpers.ps1 @@ -338,6 +338,22 @@ function Test-IsArm64 { (Get-CimInstance -ClassName Win32_OperatingSystem).OSArchitecture -match "ARM 64-bit" } +function Test-IsX64 { + <# + .SYNOPSIS + Checks if the current Windows operating system is running on an x64 architecture. + .DESCRIPTION + This function uses the Get-CimInstance cmdlet to retrieve information + about the current Windows operating system. It then checks if the OSArchitecture + property of the Win32_OperatingSystem class contains the string "x64", + indicating that the operating system is running on an x64 processor. + .OUTPUTS + Returns $true if the current Windows operating system is running on x64. + Otherwise, returns $false. + #> + (Get-CimInstance -ClassName Win32_OperatingSystem).OSArchitecture -eq "64-bit" +} + function Test-IsWin25 { <# .SYNOPSIS @@ -388,6 +404,47 @@ function Test-IsWin11 { (Get-CimInstance -ClassName Win32_OperatingSystem).Caption -match "Windows 11" } +function Test-IsWin25-X64 { + <# + .SYNOPSIS + Checks if the current Windows operating system is Windows Server 2025 running on x64 architecture. + .DESCRIPTION + This function combines the checks from Test-IsWin25 and Test-IsX64 functions to determine if the current Windows operating system is Windows Server 2025 running on an x64 architecture. + .OUTPUTS + Returns $true if the current Windows operating system is Windows Server 2025 running on x64 architecture. + Otherwise, returns $false. + #> + (Test-IsWin25) -and (Test-IsX64) +} + +function Test-IsWin22-X64 { + <# + .SYNOPSIS + Checks if the current Windows operating system is Windows Server 2022 running on x64 architecture. + + .DESCRIPTION + This function combines the checks from Test-IsWin22 and Test-IsX64 functions to determine if the current Windows operating system is Windows Server 2022 running on an x64 architecture. + + .OUTPUTS + Returns $true if the current Windows operating system is Windows Server 2022 running on x64 architecture. + Otherwise, returns $false. + #> + (Test-IsWin22) -and (Test-IsX64) +} + +function Test-IsWin11-Arm64 { + <# + .SYNOPSIS + Checks if the current Windows operating system is Windows 11 running on ARM64 architecture. + .DESCRIPTION + This function combines the checks from Test-IsWin11 and Test-IsArm64 functions to determine if the current Windows operating system is Windows 11 running on an ARM64 architecture. + .OUTPUTS + Returns $true if the current Windows operating system is Windows 11 running on ARM64 architecture. + Otherwise, returns $false. + #> + (Test-IsWin11) -and (Test-IsArm64) +} + function Expand-7ZipArchive { <# .SYNOPSIS From 6304f883e4390b490aec519ec285ae94685d06a4 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Mon, 6 Apr 2026 16:24:09 +0200 Subject: [PATCH 51/55] OS Helper overhaul: replace function calls --- .../scripts/build/Configure-ImageDataFile.ps1 | 10 +++--- .../windows/scripts/build/Configure-Shell.ps1 | 2 +- .../scripts/build/Configure-System.ps1 | 8 ++--- .../windows/scripts/build/Configure-User.ps1 | 6 ++-- .../windows/scripts/build/Install-Docker.ps1 | 2 +- .../windows/scripts/build/Install-Haskell.ps1 | 2 +- .../scripts/build/Install-NativeImages.ps1 | 2 +- images/windows/scripts/build/Install-Rust.ps1 | 4 +-- .../scripts/build/Install-VisualStudio.ps1 | 4 +-- images/windows/scripts/build/Install-WDK.ps1 | 4 +-- .../windows/scripts/build/Invoke-Cleanup.ps1 | 2 +- .../docs-gen/Generate-SoftwareReport.ps1 | 36 +++++++++---------- .../docs-gen/SoftwareReport.CachedTools.psm1 | 2 +- .../docs-gen/SoftwareReport.Common.psm1 | 2 +- .../docs-gen/SoftwareReport.VisualStudio.psm1 | 2 +- .../windows/scripts/tests/Android.Tests.ps1 | 2 +- .../windows/scripts/tests/CLI.Tools.Tests.ps1 | 2 +- .../scripts/tests/ChocoPackages.Tests.ps1 | 2 +- .../windows/scripts/tests/Databases.Tests.ps1 | 4 +-- images/windows/scripts/tests/Docker.Tests.ps1 | 8 ++--- .../windows/scripts/tests/Haskell.Tests.ps1 | 6 ++-- images/windows/scripts/tests/MSYS2.Tests.ps1 | 4 +-- .../windows/scripts/tests/Miniconda.Tests.ps1 | 2 +- images/windows/scripts/tests/Rust.Tests.ps1 | 2 +- images/windows/scripts/tests/Shell.Tests.ps1 | 2 +- images/windows/scripts/tests/Tools.Tests.ps1 | 8 ++--- .../windows/scripts/tests/Toolset.Tests.ps1 | 2 +- .../scripts/tests/VisualStudio.Tests.ps1 | 2 +- images/windows/scripts/tests/WDK.Tests.ps1 | 2 +- .../scripts/tests/WindowsFeatures.Tests.ps1 | 2 +- images/windows/scripts/tests/Wix.Tests.ps1 | 2 +- 31 files changed, 70 insertions(+), 70 deletions(-) diff --git a/images/windows/scripts/build/Configure-ImageDataFile.ps1 b/images/windows/scripts/build/Configure-ImageDataFile.ps1 index aabf736146..1d381a0563 100644 --- a/images/windows/scripts/build/Configure-ImageDataFile.ps1 +++ b/images/windows/scripts/build/Configure-ImageDataFile.ps1 @@ -15,23 +15,23 @@ $imageMinorVersion = $imageVersionComponents[1] $imageDataFile = $env:IMAGEDATA_FILE $githubUrl = "https://github.com/actions/runner-images/blob" -if ((Test-IsWin25) -and $env:INSTALL_VS_2026) { +if ((Test-IsWin25-X64) -and $env:INSTALL_VS_2026) { $imageLabel = "windows-2025-vs2026" $softwareUrl = "${githubUrl}/win25-vs2026/$imageMajorVersion.$imageMinorVersion/images/windows/Windows2025-VS2026-Readme.md" $releaseUrl = "https://github.com/actions/runner-images/releases/tag/win25-vs2026%2F$imageMajorVersion.$imageMinorVersion" -} elseif (Test-IsWin25) { +} elseif (Test-IsWin25-X64) { $imageLabel = "windows-2025" $softwareUrl = "${githubUrl}/win25/$imageMajorVersion.$imageMinorVersion/images/windows/Windows2025-Readme.md" $releaseUrl = "https://github.com/actions/runner-images/releases/tag/win25%2F$imageMajorVersion.$imageMinorVersion" -} elseif (Test-IsWin22) { +} elseif (Test-IsWin22-X64) { $imageLabel = "windows-2022" $softwareUrl = "${githubUrl}/win22/$imageMajorVersion.$imageMinorVersion/images/windows/Windows2022-Readme.md" $releaseUrl = "https://github.com/actions/runner-images/releases/tag/win22%2F$imageMajorVersion.$imageMinorVersion" -} elseif ((Test-IsWin11) -and (Test-IsArm64) -and $env:INSTALL_VS_2026) { +} elseif ((Test-IsWin11-Arm64) -and (Test-IsArm64) -and $env:INSTALL_VS_2026) { $imageLabel = "windows-11-vs2026-arm64" $softwareUrl = "${githubUrl}/win11-vs2026-arm64/$imageMajorVersion.$imageMinorVersion/images/windows/Windows11-VS2026-Arm64-Readme.md" $releaseUrl = "https://github.com/actions/runner-images/releases/tag/win11-vs2026-arm64%2F$imageMajorVersion.$imageMinorVersion" -} elseif ((Test-IsWin11) -and (Test-IsArm64)) { +} elseif ((Test-IsWin11-Arm64) -and (Test-IsArm64)) { $imageLabel = "windows-11-arm64" $softwareUrl = "${githubUrl}/win11-arm64/$imageMajorVersion.$imageMinorVersion/images/windows/Windows11-Arm64-Readme.md" $releaseUrl = "https://github.com/actions/runner-images/releases/tag/win11-arm64%2F$imageMajorVersion.$imageMinorVersion" diff --git a/images/windows/scripts/build/Configure-Shell.ps1 b/images/windows/scripts/build/Configure-Shell.ps1 index 334d724a1f..3f4d6f0733 100644 --- a/images/windows/scripts/build/Configure-Shell.ps1 +++ b/images/windows/scripts/build/Configure-Shell.ps1 @@ -2,7 +2,7 @@ $shellPath = "C:\shells" New-Item -Path $shellPath -ItemType Directory | Out-Null -if (-not (Test-IsWin11)) { +if (Test-IsX64) { # add a wrapper for C:\msys64\usr\bin\bash.exe @' @echo off diff --git a/images/windows/scripts/build/Configure-System.ps1 b/images/windows/scripts/build/Configure-System.ps1 index dee40ab611..2f10b8a3b3 100644 --- a/images/windows/scripts/build/Configure-System.ps1 +++ b/images/windows/scripts/build/Configure-System.ps1 @@ -6,7 +6,7 @@ # Set default version to 1 for WSL (aka LXSS - Linux Subsystem) # The value should be set in the default user registry hive # https://github.com/actions/runner-images/issues/5760 -if (Test-IsWin22) { +if (Test-IsWin22-X64) { Write-Host "Setting WSL default version to 1" Mount-RegistryHive ` @@ -37,7 +37,7 @@ if ($LASTEXITCODE -ne 0) { } # Enable inheritance for the entire C:\ drive -if (Test-IsWin25) { +if (Test-IsWin25-X64) { cmd /c "icacls C:\ /inheritance:e /c /q 2>&1" | Out-Null if ($LASTEXITCODE -ne 0) { throw "Failed to enable inheritance for C:\ drive" @@ -101,11 +101,11 @@ $servicesToDisable = @( 'wuauserv' 'DiagTrack' 'dmwappushservice' - $(if(-not (Test-IsWin25)){'PcaSvc'}) + $(if(-not (Test-IsWin25-X64)){'PcaSvc'}) 'SysMain' 'gupdate' 'gupdatem' - $(if(-not (Test-IsWin25)){'StorSvc'}) + $(if(-not (Test-IsWin25-X64)){'StorSvc'}) ) | Get-Service -ErrorAction SilentlyContinue Stop-Service $servicesToDisable $servicesToDisable.WaitForStatus('Stopped', "00:01:00") diff --git a/images/windows/scripts/build/Configure-User.ps1 b/images/windows/scripts/build/Configure-User.ps1 index 63c596c56a..e2a58ae4e4 100644 --- a/images/windows/scripts/build/Configure-User.ps1 +++ b/images/windows/scripts/build/Configure-User.ps1 @@ -28,7 +28,7 @@ if ($LASTEXITCODE -ne 0) { } # TortoiseSVN not installed on Windows 2025 and Windows 11 due to Sysprep issues -if (-not (Test-IsWin25) -and -not (Test-IsWin11)) { +if (-not (Test-IsWin25-X64) -and -not (Test-IsWin11-Arm64)) { # disable TSVNCache.exe $registryKeyPath = 'HKCU:\Software\TortoiseSVN' if (-not(Test-Path -Path $registryKeyPath)) { @@ -42,7 +42,7 @@ if (-not (Test-IsWin25) -and -not (Test-IsWin11)) { } } # Accept by default "Send Diagnostic data to Microsoft" consent. -if (Test-IsWin25) { +if (Test-IsWin25-X64) { $registryKeyPath = 'HKLM:\DEFAULT\SOFTWARE\Microsoft\Windows\CurrentVersion\Privacy' New-ItemProperty -Path $registryKeyPath -Name PrivacyConsentPresentationVersion -PropertyType DWORD -Value 3 | Out-Null New-ItemProperty -Path $registryKeyPath -Name PrivacyConsentSettingsValidMask -PropertyType DWORD -Value 4 | Out-Null @@ -52,7 +52,7 @@ if (Test-IsWin25) { Dismount-RegistryHive "HKLM\DEFAULT" # Remove the "installer" (var.install_user) user profile for Windows 2025 image -if (Test-IsWin25) { +if (Test-IsWin25-X64) { Get-CimInstance -ClassName Win32_UserProfile | where-object {$_.LocalPath -match $env:INSTALL_USER} | Remove-CimInstance -Confirm:$false & net user $env:INSTALL_USER /DELETE } diff --git a/images/windows/scripts/build/Install-Docker.ps1 b/images/windows/scripts/build/Install-Docker.ps1 index f87e6069de..29aa39e27a 100644 --- a/images/windows/scripts/build/Install-Docker.ps1 +++ b/images/windows/scripts/build/Install-Docker.ps1 @@ -41,7 +41,7 @@ if ($LastExitCode -ne 0) { # https://github.com/Azure/azure-cli/issues/18766 New-Item -ItemType SymbolicLink -Path "C:\Windows\SysWOW64\docker.exe" -Target "C:\Windows\System32\docker.exe" -if (-not (Test-IsWin25)) { +if (-not (Test-IsWin25-X64)) { Write-Host "Download docker images" $dockerImages = (Get-ToolsetContent).docker.images foreach ($dockerImage in $dockerImages) { diff --git a/images/windows/scripts/build/Install-Haskell.ps1 b/images/windows/scripts/build/Install-Haskell.ps1 index 33a958d7b9..9fdd14c3dd 100644 --- a/images/windows/scripts/build/Install-Haskell.ps1 +++ b/images/windows/scripts/build/Install-Haskell.ps1 @@ -30,7 +30,7 @@ Add-MachinePathItem "$cabalDir\bin" Update-Environment # Get 1 or 3 latest versions of GHC depending on the OS version -If (Test-IsWin25) { +If (Test-IsWin25-X64) { $numberOfVersions = 1 } else { $numberOfVersions = 3 diff --git a/images/windows/scripts/build/Install-NativeImages.ps1 b/images/windows/scripts/build/Install-NativeImages.ps1 index 71d159e151..71a13c5b58 100644 --- a/images/windows/scripts/build/Install-NativeImages.ps1 +++ b/images/windows/scripts/build/Install-NativeImages.ps1 @@ -9,7 +9,7 @@ if ($LASTEXITCODE -ne 0) { throw "Installation of Microsoft.PowerShell.Utility.Activities failed with exit code $LASTEXITCODE" } -if (-not (Test-IsWin11)) { +if (-not (Test-IsWin11-Arm64)) { Write-Host "NGen: update x64 native images..." & $env:SystemRoot\Microsoft.NET\Framework64\v4.0.30319\ngen.exe update | Out-Null if ($LASTEXITCODE -ne 0) { diff --git a/images/windows/scripts/build/Install-Rust.ps1 b/images/windows/scripts/build/Install-Rust.ps1 index f622edda55..503823913c 100644 --- a/images/windows/scripts/build/Install-Rust.ps1 +++ b/images/windows/scripts/build/Install-Rust.ps1 @@ -50,7 +50,7 @@ if ($LASTEXITCODE -ne 0) { throw "Rust component installation failed with exit code $LASTEXITCODE" } -if (Test-IsWin22) { +if (Test-IsWin22-X64) { cargo install --locked bindgen-cli cbindgen cargo-audit cargo-outdated if ($LASTEXITCODE -ne 0) { throw "Rust tools installation failed with exit code $LASTEXITCODE" @@ -59,7 +59,7 @@ if (Test-IsWin22) { Remove-Item "${env:CARGO_HOME}\registry\*" -Recurse -Force } -if (Test-IsWin11) { +if (Test-IsWin11-Arm64) { cargo install bindgen-cli cbindgen cargo-audit cargo-outdated if ($LASTEXITCODE -ne 0) { throw "Rust tools installation failed with exit code $LASTEXITCODE" diff --git a/images/windows/scripts/build/Install-VisualStudio.ps1 b/images/windows/scripts/build/Install-VisualStudio.ps1 index 492c000956..c5f1cba6b4 100644 --- a/images/windows/scripts/build/Install-VisualStudio.ps1 +++ b/images/windows/scripts/build/Install-VisualStudio.ps1 @@ -34,7 +34,7 @@ $vsInstallRoot = (Get-VisualStudioInstance).InstallationPath $newContent = '{"Extensions":[{"Key":"1e906ff5-9da8-4091-a299-5c253c55fdc9","Value":{"ShouldAutoUpdate":false}},{"Key":"Microsoft.VisualStudio.Web.AzureFunctions","Value":{"ShouldAutoUpdate":false}}],"ShouldAutoUpdate":false,"ShouldCheckForUpdates":false}' Set-Content -Path "$vsInstallRoot\Common7\IDE\Extensions\MachineState.json" -Value $newContent -if (Test-IsWin22) { +if (Test-IsWin22-X64) { # Install Windows 10 SDK version 10.0.17763 Install-Binary -Type EXE ` -Url 'https://go.microsoft.com/fwlink/p/?LinkID=2033908' ` @@ -49,7 +49,7 @@ Install-Binary -Type EXE ` -ExpectedSubject $(Get-MicrosoftPublisher) # Enable Windows Desktop Debuggers (cdb.exe) on Windows Server 2025 -if (Test-IsWin25) { +if (Test-IsWin25-X64) { $installerEntry = Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* ` | Where-Object { $_.DisplayName -match "Windows Software Development Kit" } ` | Sort-Object DisplayVersion -Descending | Select-Object -First 1 diff --git a/images/windows/scripts/build/Install-WDK.ps1 b/images/windows/scripts/build/Install-WDK.ps1 index 14a978e0ef..6560cb3465 100644 --- a/images/windows/scripts/build/Install-WDK.ps1 +++ b/images/windows/scripts/build/Install-WDK.ps1 @@ -4,10 +4,10 @@ ################################################################################ # Requires Windows SDK with the same version number as the WDK -if (Test-IsWin22) { +if (Test-IsWin22-X64) { # SDK is available through Visual Studio $wdkUrl = "https://go.microsoft.com/fwlink/?linkid=2324617" -} elseif (Test-IsWin11) { +} elseif (Test-IsWin11-Arm64) { # SDK is available through Visual Studio $wdkUrl = "https://go.microsoft.com/fwlink/?linkid=2335869" } else { diff --git a/images/windows/scripts/build/Invoke-Cleanup.ps1 b/images/windows/scripts/build/Invoke-Cleanup.ps1 index 7616c218e2..2cc6151163 100644 --- a/images/windows/scripts/build/Invoke-Cleanup.ps1 +++ b/images/windows/scripts/build/Invoke-Cleanup.ps1 @@ -49,7 +49,7 @@ if ($LASTEXITCODE -ne 0) { throw "Failed to clean npm cache" } -if (Test-IsWin25) { +if (Test-IsWin25-X64) { $directoriesToCompact = @( "C:\Program Files (x86)\Android", "C:\Program Files\dotnet", diff --git a/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 b/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 index 2073e24de1..b6bb80be57 100644 --- a/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 +++ b/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 @@ -21,7 +21,7 @@ Import-Module (Join-Path $PSScriptRoot "SoftwareReport.VisualStudio.psm1") -Disa $softwareReport = [SoftwareReport]::new($(Build-OSInfoSection)) $optionalFeatures = $softwareReport.Root.AddHeader("Windows features") $optionalFeatures.AddToolVersion("Windows Subsystem for Linux (WSLv1):", "Enabled") -if (Test-IsWin25) { +if (Test-IsWin25-X64) { $optionalFeatures.AddToolVersion("Windows Subsystem for Linux (Default, WSLv2):", $(Get-WSL2Version)) } $installedSoftware = $softwareReport.Root.AddHeader("Installed Software") @@ -44,7 +44,7 @@ $packageManagement = $installedSoftware.AddHeader("Package Management") $packageManagement.AddToolVersion("Chocolatey", $(Get-ChocoVersion)) $packageManagement.AddToolVersion("Composer", $(Get-ComposerVersion)) $packageManagement.AddToolVersion("Helm", $(Get-HelmVersion)) -if (-not (Test-IsWin11)) { +if (-not (Test-IsWin11-Arm64)) { $packageManagement.AddToolVersion("Miniconda", $(Get-CondaVersion)) } $packageManagement.AddToolVersion("NPM", $(Get-NPMVersion)) @@ -72,12 +72,12 @@ $tools.AddToolVersion("azcopy", $(Get-AzCopyVersion)) $tools.AddToolVersion("Bazel", $(Get-BazelVersion)) $tools.AddToolVersion("Bazelisk", $(Get-BazeliskVersion)) $tools.AddToolVersion("Bicep", $(Get-BicepVersion)) -if (-not (Test-IsWin11)) { +if (-not (Test-IsWin11-Arm64)) { $tools.AddToolVersion("Cabal", $(Get-CabalVersion)) } $tools.AddToolVersion("CMake", $(Get-CMakeVersion)) $tools.AddToolVersion("CodeQL Action Bundle", $(Get-CodeQLBundleVersion)) -if (-not (Test-IsWin11)) { +if (-not (Test-IsWin11-Arm64)) { $tools.AddToolVersion("Docker", $(Get-DockerVersion)) $tools.AddToolVersion("Docker Compose v2", $(Get-DockerComposeVersionV2)) $tools.AddToolVersion("Docker-wincred", $(Get-DockerWincredVersion)) @@ -90,42 +90,42 @@ $tools.AddToolVersion("InnoSetup", $(Get-InnoSetupVersion)) $tools.AddToolVersion("jq", $(Get-JQVersion)) $tools.AddToolVersion("Kind", $(Get-KindVersion)) $tools.AddToolVersion("Kubectl", $(Get-KubectlVersion)) -if (-not (Test-IsWin25)) { +if (-not (Test-IsWin25-X64)) { $tools.AddToolVersion("Mercurial", $(Get-MercurialVersion)) } $tools.AddToolVersion("gcc", $(Get-GCCVersion)) $tools.AddToolVersion("gdb", $(Get-GDBVersion)) $tools.AddToolVersion("GNU Binutils", $(Get-GNUBinutilsVersion)) $tools.AddToolVersion("Newman", $(Get-NewmanVersion)) -if (-not (Test-IsWin25)) { +if (-not (Test-IsWin25-X64)) { $tools.AddToolVersion("NSIS", $(Get-NSISVersion)) } $tools.AddToolVersion("OpenSSL", $(Get-OpenSSLVersion)) $tools.AddToolVersion("Packer", $(Get-PackerVersion)) $tools.AddToolVersion("Pulumi", $(Get-PulumiVersion)) $tools.AddToolVersion("R", $(Get-RVersion)) -if (-not (Test-IsWin11)) { +if (-not (Test-IsWin11-Arm64)) { $tools.AddToolVersion("Service Fabric SDK", $(Get-ServiceFabricSDKVersion)) } $tools.AddToolVersion("Stack", $(Get-StackVersion)) -if (-not (Test-IsWin25) -and -not (Test-IsWin11)) { +if (-not (Test-IsWin25-X64) -and -not (Test-IsWin11-Arm64)) { $tools.AddToolVersion("Subversion (SVN)", $(Get-SVNVersion)) } $tools.AddToolVersion("Swig", $(Get-SwigVersion)) $tools.AddToolVersion("VSWhere", $(Get-VSWhereVersion)) $tools.AddToolVersion("WinAppDriver", $(Get-WinAppDriver)) -if (-not (Test-IsWin11)) { +if (-not (Test-IsWin11-Arm64)) { $tools.AddToolVersion("WiX Toolset", $(Get-WixVersion)) } $tools.AddToolVersion("yamllint", $(Get-YAMLLintVersion)) -if (-not (Test-IsWin11)) { +if (-not (Test-IsWin11-Arm64)) { $tools.AddToolVersion("zstd", $(Get-ZstdVersion)) } $tools.AddToolVersion("Ninja", $(Get-NinjaVersion)) # CLI Tools $cliTools = $installedSoftware.AddHeader("CLI Tools") -if (-not (Test-IsWin25)) { +if (-not (Test-IsWin25-X64)) { $cliTools.AddToolVersion("Alibaba Cloud CLI", $(Get-AlibabaCLIVersion)) } $cliTools.AddToolVersion("AWS CLI", $(Get-AWSCLIVersion)) @@ -144,7 +144,7 @@ $rustTools.AddToolVersion("Rustdoc", $(Get-RustdocVersion)) $rustTools.AddToolVersion("Rustup", $(Get-RustupVersion)) $rustToolsPackages = $rustTools.AddHeader("Packages") -if (-not (Test-IsWin25)) { +if (-not (Test-IsWin25-X64)) { $rustToolsPackages.AddToolVersion("bindgen", $(Get-BindgenVersion)) $rustToolsPackages.AddToolVersion("cargo-audit", $(Get-CargoAuditVersion)) $rustToolsPackages.AddToolVersion("cargo-outdated", $(Get-CargoOutdatedVersion)) @@ -162,12 +162,12 @@ $browsersAndWebdrivers.AddHeader("Environment variables").AddTable($(Build-Brows $installedSoftware.AddHeader("Java").AddTable($(Get-JavaVersions)) # Shells -if (-not (Test-IsWin11)) { +if (-not (Test-IsWin11-Arm64)) { $installedSoftware.AddHeader("Shells").AddTable($(Get-ShellTarget)) } # MSYS2 -if (-not (Test-IsWin11)) { +if (-not (Test-IsWin11-Arm64)) { $msys2 = $installedSoftware.AddHeader("MSYS2") $msys2.AddToolVersion("Pacman", $(Get-PacmanVersion)) @@ -183,7 +183,7 @@ Note: MSYS2 is pre-installed on image but not added to PATH. $installedSoftware.AddHeader("Cached Tools").AddNodes($(Build-CachedToolsSection)) # Databases -if (-not (Test-IsWin11)) { +if (-not (Test-IsWin11-Arm64)) { $databases = $installedSoftware.AddHeader("Databases") $databases.AddHeader("PostgreSQL").AddTable($(Get-PostgreSQLTable)) $databases.AddHeader("MongoDB").AddTable($(Get-MongoDBTable)) @@ -196,7 +196,7 @@ $databaseTools.AddToolVersion("DacFx", $(Get-DacFxVersion)) $databaseTools.AddToolVersion("MySQL", $(Get-MySQLVersion)) $databaseTools.AddToolVersion("SQL OLEDB Driver 18", $(Get-SQLOLEDBDriver18Version)) $databaseTools.AddToolVersion("SQL OLEDB Driver 19", $(Get-SQLOLEDBDriver19Version)) -if (-not (Test-IsWin11)) { +if (-not (Test-IsWin11-Arm64)) { $databaseTools.AddToolVersion("SQLPS", $(Get-SQLPSVersion)) $databaseTools.AddToolVersion("MongoDB Shell (mongosh)", $(Get-MongoshVersion)) } @@ -235,7 +235,7 @@ $psModules.AddNodes($(Get-PowerShellModules)) # Android -if (-not (Test-IsWin11)) { +if (-not (Test-IsWin11-Arm64)) { $android = $installedSoftware.AddHeader("Android") $android.AddTable($(Build-AndroidTable)) @@ -243,7 +243,7 @@ if (-not (Test-IsWin11)) { } # Cached Docker images -if (-not (Test-IsWin25) -and -not (Test-IsWin11)) { +if (-not (Test-IsWin25-X64) -and -not (Test-IsWin11-Arm64)) { $installedSoftware.AddHeader("Cached Docker images").AddTable($(Get-CachedDockerImagesTableData)) } diff --git a/images/windows/scripts/docs-gen/SoftwareReport.CachedTools.psm1 b/images/windows/scripts/docs-gen/SoftwareReport.CachedTools.psm1 index 170cf85800..a5cd816d3c 100644 --- a/images/windows/scripts/docs-gen/SoftwareReport.CachedTools.psm1 +++ b/images/windows/scripts/docs-gen/SoftwareReport.CachedTools.psm1 @@ -34,7 +34,7 @@ function Build-CachedToolsSection [ToolVersionsListNode]::new("Go", $(Get-ToolcacheGoVersions), '^\d+\.\d+', 'List'), [ToolVersionsListNode]::new("Node.js", $(Get-ToolcacheNodeVersions), '^\d+', 'List'), [ToolVersionsListNode]::new("Python", $(Get-ToolcachePythonVersions), '^\d+\.\d+', 'List'), - $(if (-not (Test-IsWin11)) { [ToolVersionsListNode]::new("PyPy", $(Get-ToolcachePyPyVersions), '^\d+\.\d+', 'List') }), + $(if (-not (Test-IsWin11-Arm64)) { [ToolVersionsListNode]::new("PyPy", $(Get-ToolcachePyPyVersions), '^\d+\.\d+', 'List') }), [ToolVersionsListNode]::new("Ruby", $(Get-ToolcacheRubyVersions), '^\d+\.\d+', 'List') ) | Where-Object { $_ } } diff --git a/images/windows/scripts/docs-gen/SoftwareReport.Common.psm1 b/images/windows/scripts/docs-gen/SoftwareReport.Common.psm1 index ebb83c8edf..f480c546cb 100644 --- a/images/windows/scripts/docs-gen/SoftwareReport.Common.psm1 +++ b/images/windows/scripts/docs-gen/SoftwareReport.Common.psm1 @@ -297,7 +297,7 @@ function Build-PackageManagementEnvironmentTable { "Name" = "VCPKG_INSTALLATION_ROOT" "Value" = $env:VCPKG_INSTALLATION_ROOT }, - $(if (-not (Test-IsWin11)) { [PSCustomObject] @{ + $(if (-not (Test-IsWin11-Arm64)) { [PSCustomObject] @{ "Name" = "CONDA" "Value" = $env:CONDA } }) diff --git a/images/windows/scripts/docs-gen/SoftwareReport.VisualStudio.psm1 b/images/windows/scripts/docs-gen/SoftwareReport.VisualStudio.psm1 index 082a840b11..241898169c 100644 --- a/images/windows/scripts/docs-gen/SoftwareReport.VisualStudio.psm1 +++ b/images/windows/scripts/docs-gen/SoftwareReport.VisualStudio.psm1 @@ -43,7 +43,7 @@ function Get-VisualStudioExtensions { ) # WDK - if (-not (Test-IsWin25)) { + if (-not (Test-IsWin25-X64)) { $wdkVersion = Get-WDKVersion $wdkPackages = @( @{Package = 'Windows Driver Kit'; Version = $wdkVersion } diff --git a/images/windows/scripts/tests/Android.Tests.ps1 b/images/windows/scripts/tests/Android.Tests.ps1 index 1a092ac2a0..653b4aba00 100644 --- a/images/windows/scripts/tests/Android.Tests.ps1 +++ b/images/windows/scripts/tests/Android.Tests.ps1 @@ -1,4 +1,4 @@ -Describe "Android SDK" -Skip:(Test-IsWin11) { +Describe "Android SDK" -Skip:(Test-IsWin11-Arm64) { $androidToolset = (Get-ToolsetContent).android $androidInstalledPackages = Get-AndroidInstalledPackages diff --git a/images/windows/scripts/tests/CLI.Tools.Tests.ps1 b/images/windows/scripts/tests/CLI.Tools.Tests.ps1 index f97dc7c744..b9584da81f 100644 --- a/images/windows/scripts/tests/CLI.Tools.Tests.ps1 +++ b/images/windows/scripts/tests/CLI.Tools.Tests.ps1 @@ -11,7 +11,7 @@ Describe "Azure DevOps CLI" { } } -Describe "Aliyun CLI" -Skip:(Test-IsWin25) { +Describe "Aliyun CLI" -Skip:(Test-IsWin25-X64) { It "Aliyun CLI" { "aliyun version" | Should -ReturnZeroExitCode } diff --git a/images/windows/scripts/tests/ChocoPackages.Tests.ps1 b/images/windows/scripts/tests/ChocoPackages.Tests.ps1 index b088a0a822..5b22e4248f 100644 --- a/images/windows/scripts/tests/ChocoPackages.Tests.ps1 +++ b/images/windows/scripts/tests/ChocoPackages.Tests.ps1 @@ -58,7 +58,7 @@ Describe "Pulumi" { } } -Describe "Svn" -Skip:((Test-IsWin25) -or (Test-IsWin11)) { +Describe "Svn" -Skip:((Test-IsWin25-X64) -or (Test-IsWin11-Arm64)) { It "svn" { "svn --version --quiet" | Should -ReturnZeroExitCode } diff --git a/images/windows/scripts/tests/Databases.Tests.ps1 b/images/windows/scripts/tests/Databases.Tests.ps1 index aa58e7c5e3..37eebe7818 100644 --- a/images/windows/scripts/tests/Databases.Tests.ps1 +++ b/images/windows/scripts/tests/Databases.Tests.ps1 @@ -1,4 +1,4 @@ -Describe "MongoDB" -Skip:(Test-IsWin11) { +Describe "MongoDB" -Skip:(Test-IsWin11-Arm64) { Context "Version" { It "" -TestCases @( @{ ToolName = "mongos" } @@ -33,7 +33,7 @@ Describe "MongoDB" -Skip:(Test-IsWin11) { } } -Describe "PostgreSQL" -Skip:(Test-IsWin11) { +Describe "PostgreSQL" -Skip:(Test-IsWin11-Arm64) { $psqlTests = @( @{envVar = "PGROOT"; pgPath = Get-EnvironmentVariable "PGROOT" } @{envVar = "PGBIN"; pgPath = Get-EnvironmentVariable "PGBIN" } diff --git a/images/windows/scripts/tests/Docker.Tests.ps1 b/images/windows/scripts/tests/Docker.Tests.ps1 index cf2a6acaa4..30a34a4a36 100644 --- a/images/windows/scripts/tests/Docker.Tests.ps1 +++ b/images/windows/scripts/tests/Docker.Tests.ps1 @@ -1,4 +1,4 @@ -Describe "Docker" -Skip:(Test-IsWin11) { +Describe "Docker" -Skip:(Test-IsWin11-Arm64) { It "docker is installed" { "docker --version" | Should -ReturnZeroExitCode } @@ -12,20 +12,20 @@ Describe "Docker" -Skip:(Test-IsWin11) { } } -Describe "DockerCompose" -Skip:(Test-IsWin11) { +Describe "DockerCompose" -Skip:(Test-IsWin11-Arm64) { It "docker compose v2" { "docker compose version" | Should -ReturnZeroExitCode } } -Describe "DockerWinCred" -Skip:(Test-IsWin11) { +Describe "DockerWinCred" -Skip:(Test-IsWin11-Arm64) { It "docker-wincred" { "docker-credential-wincred version" | Should -ReturnZeroExitCode } } -Describe "DockerImages" -Skip:((Test-IsWin25) -or (Test-IsWin11)) { +Describe "DockerImages" -Skip:((Test-IsWin25-X64) -or (Test-IsWin11-Arm64)) { Context "docker images" { $testCases = (Get-ToolsetContent).docker.images | ForEach-Object { @{ ImageName = $_ } } diff --git a/images/windows/scripts/tests/Haskell.Tests.ps1 b/images/windows/scripts/tests/Haskell.Tests.ps1 index bf04f654f2..328b06f803 100644 --- a/images/windows/scripts/tests/Haskell.Tests.ps1 +++ b/images/windows/scripts/tests/Haskell.Tests.ps1 @@ -1,6 +1,6 @@ -Describe "Haskell" -Skip:(Test-IsWin11) { +Describe "Haskell" -Skip:(Test-IsWin11-Arm64) { BeforeDiscovery { - if (Test-IsWin11) { return } + if (Test-IsWin11-Arm64) { return } $ghcPackagesPath = "c:\ghcup\ghc" [array] $ghcVersionList = Get-ChildItem -Path $ghcPackagesPath -Filter "*" | ForEach-Object { $_.Name.Trim() } $ghcCount = $ghcVersionList.Count @@ -23,7 +23,7 @@ Describe "Haskell" -Skip:(Test-IsWin11) { @{envVar = "GHCUP_INSTALL_BASE_PREFIX"} @{envVar = "GHCUP_MSYS2"} ) - $numberOfVersions = if (Test-IsWin25) { 1 } else { 3 } + $numberOfVersions = if (Test-IsWin25-X64) { 1 } else { 3 } } It " environment variable exists" -TestCases $ghcupEnvExists { diff --git a/images/windows/scripts/tests/MSYS2.Tests.ps1 b/images/windows/scripts/tests/MSYS2.Tests.ps1 index 760b5c8674..9f6089fb7e 100644 --- a/images/windows/scripts/tests/MSYS2.Tests.ps1 +++ b/images/windows/scripts/tests/MSYS2.Tests.ps1 @@ -3,7 +3,7 @@ BeforeAll { $originalPath = $env:PATH } -Describe "MSYS2 packages" -Skip:(Test-IsWin11) { +Describe "MSYS2 packages" -Skip:(Test-IsWin11-Arm64) { BeforeEach { $env:PATH = "$msys2Dir;$env:PATH" } @@ -31,7 +31,7 @@ Describe "MSYS2 packages" -Skip:(Test-IsWin11) { $mingwTypes = (Get-ToolsetContent).MsysPackages.mingw foreach ($mingwType in $mingwTypes) { - Describe "$($mingwType.arch) packages" -Skip:(Test-IsWin11) { + Describe "$($mingwType.arch) packages" -Skip:(Test-IsWin11-Arm64) { $tools = $mingwType.runtime_packages $execDir = Join-Path "C:\msys64" $mingwType.exec_dir | Join-Path -ChildPath "bin" diff --git a/images/windows/scripts/tests/Miniconda.Tests.ps1 b/images/windows/scripts/tests/Miniconda.Tests.ps1 index 3284204d31..5a3894a344 100644 --- a/images/windows/scripts/tests/Miniconda.Tests.ps1 +++ b/images/windows/scripts/tests/Miniconda.Tests.ps1 @@ -1,4 +1,4 @@ -Describe "Miniconda" -Skip:(Test-IsWin11) { +Describe "Miniconda" -Skip:(Test-IsWin11-Arm64) { It "Miniconda Environment variables is set. " { ${env:CONDA} | Should -Not -BeNullOrEmpty } diff --git a/images/windows/scripts/tests/Rust.Tests.ps1 b/images/windows/scripts/tests/Rust.Tests.ps1 index 717e80e428..4449d40561 100644 --- a/images/windows/scripts/tests/Rust.Tests.ps1 +++ b/images/windows/scripts/tests/Rust.Tests.ps1 @@ -5,7 +5,7 @@ Describe "Rust" { $env:Path += ";$env:CARGO_HOME\bin" } - if (Test-IsWin25) { + if (Test-IsWin25-X64) { $rustTools = @( @{ToolName = "rustup"; binPath = "C:\Users\Default\.cargo\bin\rustup.exe"} @{ToolName = "rustc"; binPath = "C:\Users\Default\.cargo\bin\rustc.exe"} diff --git a/images/windows/scripts/tests/Shell.Tests.ps1 b/images/windows/scripts/tests/Shell.Tests.ps1 index 50e94b8e11..9736da919d 100644 --- a/images/windows/scripts/tests/Shell.Tests.ps1 +++ b/images/windows/scripts/tests/Shell.Tests.ps1 @@ -1,7 +1,7 @@ Describe "Shell" { $shellTestCases = @( @{Name = "C:\shells\gitbash.exe"; Target = "$env:ProgramFiles\Git\bin\bash.exe"}, - $(if (-not (Test-IsWin11)) { @{Name = "C:\shells\msys2bash.cmd"; Target = $null} }), + $(if (-not (Test-IsWin11-Arm64)) { @{Name = "C:\shells\msys2bash.cmd"; Target = $null} }), @{Name = "C:\shells\wslbash.exe"; Target = "$env:SystemRoot\System32\bash.exe"} ) | Where-Object { $_ } diff --git a/images/windows/scripts/tests/Tools.Tests.ps1 b/images/windows/scripts/tests/Tools.Tests.ps1 index d5dd358fde..55baf4d3d9 100644 --- a/images/windows/scripts/tests/Tools.Tests.ps1 +++ b/images/windows/scripts/tests/Tools.Tests.ps1 @@ -56,7 +56,7 @@ Describe "DACFx" { } } -Describe "Mercurial" -Skip:(Test-IsWin25) { +Describe "Mercurial" -Skip:(Test-IsWin25-X64) { It "Mercurial" { "hg --version" | Should -ReturnZeroExitCode } @@ -96,7 +96,7 @@ Describe "NET48" { } } -Describe "NSIS" -Skip:(Test-IsWin25) { +Describe "NSIS" -Skip:(Test-IsWin25-X64) { It "NSIS" { "makensis /VERSION" | Should -ReturnZeroExitCode } @@ -118,7 +118,7 @@ Describe "Sbt" { } } -Describe "ServiceFabricSDK" -Skip:(Test-IsWin11) { +Describe "ServiceFabricSDK" -Skip:(Test-IsWin11-Arm64) { It "PowerShell Module" { # Ignore PowerShell version check if running in PowerShell Core # https://github.com/microsoft/service-fabric/issues/1343 @@ -160,7 +160,7 @@ Describe "WebPlatformInstaller" { } } -Describe "Zstd" -Skip:(Test-IsWin11) { +Describe "Zstd" -Skip:(Test-IsWin11-Arm64) { It "zstd" { "zstd -V" | Should -ReturnZeroExitCode } diff --git a/images/windows/scripts/tests/Toolset.Tests.ps1 b/images/windows/scripts/tests/Toolset.Tests.ps1 index 7dd0b7020e..eba2c394d8 100644 --- a/images/windows/scripts/tests/Toolset.Tests.ps1 +++ b/images/windows/scripts/tests/Toolset.Tests.ps1 @@ -19,7 +19,7 @@ $toolsExecutables = @{ ) } -if (Test-IsWin11) { +if (Test-IsWin11-Arm64) { $toolsExecutables.Remove("PyPy") } diff --git a/images/windows/scripts/tests/VisualStudio.Tests.ps1 b/images/windows/scripts/tests/VisualStudio.Tests.ps1 index c2bf867ae8..2ce4de1ddd 100644 --- a/images/windows/scripts/tests/VisualStudio.Tests.ps1 +++ b/images/windows/scripts/tests/VisualStudio.Tests.ps1 @@ -25,7 +25,7 @@ Describe "Visual Studio" { } } -Describe "Windows 10 SDK" -Skip:((Test-IsWin25) -or (Test-IsWin11)) { +Describe "Windows 10 SDK" -Skip:((Test-IsWin25-X64) -or (Test-IsWin11-Arm64)) { It "Verifies 17763 SDK is installed" { "${env:ProgramFiles(x86)}\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\10.0.17763.0\UAP.props" | Should -Exist } diff --git a/images/windows/scripts/tests/WDK.Tests.ps1 b/images/windows/scripts/tests/WDK.Tests.ps1 index 139670dace..8988e9b76a 100644 --- a/images/windows/scripts/tests/WDK.Tests.ps1 +++ b/images/windows/scripts/tests/WDK.Tests.ps1 @@ -1,4 +1,4 @@ -Describe "WDK" -Skip:(Test-IsWin25) { +Describe "WDK" -Skip:(Test-IsWin25-X64) { It "WDK exists" { $regKey = "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" $installedApplications = Get-ItemProperty -Path $regKey diff --git a/images/windows/scripts/tests/WindowsFeatures.Tests.ps1 b/images/windows/scripts/tests/WindowsFeatures.Tests.ps1 index 68ed297ee8..a3b8f1cea7 100644 --- a/images/windows/scripts/tests/WindowsFeatures.Tests.ps1 +++ b/images/windows/scripts/tests/WindowsFeatures.Tests.ps1 @@ -87,7 +87,7 @@ Describe "Windows Updates" { } } -Describe "WSL2" -Skip:((Test-IsWin22) -or (Test-IsWin11)) { +Describe "WSL2" -Skip:((Test-IsWin22-X64) -or (Test-IsWin11-Arm64)) { It "WSL status should return zero exit code" { "wsl --status" | Should -ReturnZeroExitCode } diff --git a/images/windows/scripts/tests/Wix.Tests.ps1 b/images/windows/scripts/tests/Wix.Tests.ps1 index 5f1ff0314e..7534915fca 100644 --- a/images/windows/scripts/tests/Wix.Tests.ps1 +++ b/images/windows/scripts/tests/Wix.Tests.ps1 @@ -1,4 +1,4 @@ -Describe "Wix" -Skip:(Test-IsWin11) { +Describe "Wix" -Skip:(Test-IsWin11-Arm64) { BeforeAll { $regKey = "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" $installedApplications = Get-ItemProperty -Path $regKey From 6b8ec8aeccb0f582f861baacba42696e48f79811 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Mon, 6 Apr 2026 16:51:06 +0200 Subject: [PATCH 52/55] OS Helper overhaul: update extra calls --- .../scripts/build/Configure-ImageDataFile.ps1 | 4 +-- .../windows/scripts/build/Configure-User.ps1 | 2 +- .../windows/scripts/build/Install-CMake.ps1 | 4 --- .../scripts/build/Install-NativeImages.ps1 | 2 +- .../windows/scripts/build/Install-Ninja.ps1 | 4 --- .../docs-gen/Generate-SoftwareReport.ps1 | 26 +++++++++---------- .../windows/scripts/tests/Android.Tests.ps1 | 2 +- .../scripts/tests/ChocoPackages.Tests.ps1 | 2 +- images/windows/scripts/tests/Tools.Tests.ps1 | 2 +- .../windows/scripts/tests/Toolset.Tests.ps1 | 11 ++++---- 10 files changed, 25 insertions(+), 34 deletions(-) diff --git a/images/windows/scripts/build/Configure-ImageDataFile.ps1 b/images/windows/scripts/build/Configure-ImageDataFile.ps1 index 1d381a0563..6a7af26f8a 100644 --- a/images/windows/scripts/build/Configure-ImageDataFile.ps1 +++ b/images/windows/scripts/build/Configure-ImageDataFile.ps1 @@ -27,11 +27,11 @@ if ((Test-IsWin25-X64) -and $env:INSTALL_VS_2026) { $imageLabel = "windows-2022" $softwareUrl = "${githubUrl}/win22/$imageMajorVersion.$imageMinorVersion/images/windows/Windows2022-Readme.md" $releaseUrl = "https://github.com/actions/runner-images/releases/tag/win22%2F$imageMajorVersion.$imageMinorVersion" -} elseif ((Test-IsWin11-Arm64) -and (Test-IsArm64) -and $env:INSTALL_VS_2026) { +} elseif ((Test-IsWin11-Arm64) -and $env:INSTALL_VS_2026) { $imageLabel = "windows-11-vs2026-arm64" $softwareUrl = "${githubUrl}/win11-vs2026-arm64/$imageMajorVersion.$imageMinorVersion/images/windows/Windows11-VS2026-Arm64-Readme.md" $releaseUrl = "https://github.com/actions/runner-images/releases/tag/win11-vs2026-arm64%2F$imageMajorVersion.$imageMinorVersion" -} elseif ((Test-IsWin11-Arm64) -and (Test-IsArm64)) { +} elseif (Test-IsWin11-Arm64) { $imageLabel = "windows-11-arm64" $softwareUrl = "${githubUrl}/win11-arm64/$imageMajorVersion.$imageMinorVersion/images/windows/Windows11-Arm64-Readme.md" $releaseUrl = "https://github.com/actions/runner-images/releases/tag/win11-arm64%2F$imageMajorVersion.$imageMinorVersion" diff --git a/images/windows/scripts/build/Configure-User.ps1 b/images/windows/scripts/build/Configure-User.ps1 index e2a58ae4e4..9965e7e075 100644 --- a/images/windows/scripts/build/Configure-User.ps1 +++ b/images/windows/scripts/build/Configure-User.ps1 @@ -28,7 +28,7 @@ if ($LASTEXITCODE -ne 0) { } # TortoiseSVN not installed on Windows 2025 and Windows 11 due to Sysprep issues -if (-not (Test-IsWin25-X64) -and -not (Test-IsWin11-Arm64)) { +if (Test-IsWin22-X64) { # disable TSVNCache.exe $registryKeyPath = 'HKCU:\Software\TortoiseSVN' if (-not(Test-Path -Path $registryKeyPath)) { diff --git a/images/windows/scripts/build/Install-CMake.ps1 b/images/windows/scripts/build/Install-CMake.ps1 index 13acab72ff..3c3b63f4fe 100644 --- a/images/windows/scripts/build/Install-CMake.ps1 +++ b/images/windows/scripts/build/Install-CMake.ps1 @@ -4,10 +4,6 @@ ## Supply chain security: CMake - checksum validation ################################################################################ -if (-not (Test-IsArm64)) { - exit 0 -} - # Install CMake $downloadUrl = Resolve-GithubReleaseAssetUrl ` -Repo "Kitware/CMake" ` diff --git a/images/windows/scripts/build/Install-NativeImages.ps1 b/images/windows/scripts/build/Install-NativeImages.ps1 index 71a13c5b58..1b2b84ad66 100644 --- a/images/windows/scripts/build/Install-NativeImages.ps1 +++ b/images/windows/scripts/build/Install-NativeImages.ps1 @@ -9,7 +9,7 @@ if ($LASTEXITCODE -ne 0) { throw "Installation of Microsoft.PowerShell.Utility.Activities failed with exit code $LASTEXITCODE" } -if (-not (Test-IsWin11-Arm64)) { +if (Test-IsX64) { Write-Host "NGen: update x64 native images..." & $env:SystemRoot\Microsoft.NET\Framework64\v4.0.30319\ngen.exe update | Out-Null if ($LASTEXITCODE -ne 0) { diff --git a/images/windows/scripts/build/Install-Ninja.ps1 b/images/windows/scripts/build/Install-Ninja.ps1 index 21c509caae..b8c04e6939 100644 --- a/images/windows/scripts/build/Install-Ninja.ps1 +++ b/images/windows/scripts/build/Install-Ninja.ps1 @@ -3,10 +3,6 @@ ## Desc: Install Ninja build system (ARM64 only; x64 is installed via Choco) ################################################################################ -if (-not (Test-IsArm64)) { - exit 0 -} - $installDir = "C:\Tools\Ninja" Write-Host "Resolve Ninja latest ARM64 download URL" diff --git a/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 b/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 index b6bb80be57..0a84fc3d51 100644 --- a/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 +++ b/images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1 @@ -44,7 +44,7 @@ $packageManagement = $installedSoftware.AddHeader("Package Management") $packageManagement.AddToolVersion("Chocolatey", $(Get-ChocoVersion)) $packageManagement.AddToolVersion("Composer", $(Get-ComposerVersion)) $packageManagement.AddToolVersion("Helm", $(Get-HelmVersion)) -if (-not (Test-IsWin11-Arm64)) { +if (Test-IsX64) { $packageManagement.AddToolVersion("Miniconda", $(Get-CondaVersion)) } $packageManagement.AddToolVersion("NPM", $(Get-NPMVersion)) @@ -72,12 +72,12 @@ $tools.AddToolVersion("azcopy", $(Get-AzCopyVersion)) $tools.AddToolVersion("Bazel", $(Get-BazelVersion)) $tools.AddToolVersion("Bazelisk", $(Get-BazeliskVersion)) $tools.AddToolVersion("Bicep", $(Get-BicepVersion)) -if (-not (Test-IsWin11-Arm64)) { +if (Test-IsX64) { $tools.AddToolVersion("Cabal", $(Get-CabalVersion)) } $tools.AddToolVersion("CMake", $(Get-CMakeVersion)) $tools.AddToolVersion("CodeQL Action Bundle", $(Get-CodeQLBundleVersion)) -if (-not (Test-IsWin11-Arm64)) { +if (Test-IsX64) { $tools.AddToolVersion("Docker", $(Get-DockerVersion)) $tools.AddToolVersion("Docker Compose v2", $(Get-DockerComposeVersionV2)) $tools.AddToolVersion("Docker-wincred", $(Get-DockerWincredVersion)) @@ -104,21 +104,21 @@ $tools.AddToolVersion("OpenSSL", $(Get-OpenSSLVersion)) $tools.AddToolVersion("Packer", $(Get-PackerVersion)) $tools.AddToolVersion("Pulumi", $(Get-PulumiVersion)) $tools.AddToolVersion("R", $(Get-RVersion)) -if (-not (Test-IsWin11-Arm64)) { +if (Test-IsX64) { $tools.AddToolVersion("Service Fabric SDK", $(Get-ServiceFabricSDKVersion)) } $tools.AddToolVersion("Stack", $(Get-StackVersion)) -if (-not (Test-IsWin25-X64) -and -not (Test-IsWin11-Arm64)) { +if (Test-IsWin22-X64) { $tools.AddToolVersion("Subversion (SVN)", $(Get-SVNVersion)) } $tools.AddToolVersion("Swig", $(Get-SwigVersion)) $tools.AddToolVersion("VSWhere", $(Get-VSWhereVersion)) $tools.AddToolVersion("WinAppDriver", $(Get-WinAppDriver)) -if (-not (Test-IsWin11-Arm64)) { +if (Test-IsX64) { $tools.AddToolVersion("WiX Toolset", $(Get-WixVersion)) } $tools.AddToolVersion("yamllint", $(Get-YAMLLintVersion)) -if (-not (Test-IsWin11-Arm64)) { +if (Test-IsX64) { $tools.AddToolVersion("zstd", $(Get-ZstdVersion)) } $tools.AddToolVersion("Ninja", $(Get-NinjaVersion)) @@ -162,12 +162,12 @@ $browsersAndWebdrivers.AddHeader("Environment variables").AddTable($(Build-Brows $installedSoftware.AddHeader("Java").AddTable($(Get-JavaVersions)) # Shells -if (-not (Test-IsWin11-Arm64)) { +if (Test-IsX64) { $installedSoftware.AddHeader("Shells").AddTable($(Get-ShellTarget)) } # MSYS2 -if (-not (Test-IsWin11-Arm64)) { +if (Test-IsX64) { $msys2 = $installedSoftware.AddHeader("MSYS2") $msys2.AddToolVersion("Pacman", $(Get-PacmanVersion)) @@ -183,7 +183,7 @@ Note: MSYS2 is pre-installed on image but not added to PATH. $installedSoftware.AddHeader("Cached Tools").AddNodes($(Build-CachedToolsSection)) # Databases -if (-not (Test-IsWin11-Arm64)) { +if (Test-IsX64) { $databases = $installedSoftware.AddHeader("Databases") $databases.AddHeader("PostgreSQL").AddTable($(Get-PostgreSQLTable)) $databases.AddHeader("MongoDB").AddTable($(Get-MongoDBTable)) @@ -196,7 +196,7 @@ $databaseTools.AddToolVersion("DacFx", $(Get-DacFxVersion)) $databaseTools.AddToolVersion("MySQL", $(Get-MySQLVersion)) $databaseTools.AddToolVersion("SQL OLEDB Driver 18", $(Get-SQLOLEDBDriver18Version)) $databaseTools.AddToolVersion("SQL OLEDB Driver 19", $(Get-SQLOLEDBDriver19Version)) -if (-not (Test-IsWin11-Arm64)) { +if (Test-IsX64) { $databaseTools.AddToolVersion("SQLPS", $(Get-SQLPSVersion)) $databaseTools.AddToolVersion("MongoDB Shell (mongosh)", $(Get-MongoshVersion)) } @@ -235,7 +235,7 @@ $psModules.AddNodes($(Get-PowerShellModules)) # Android -if (-not (Test-IsWin11-Arm64)) { +if (Test-IsX64) { $android = $installedSoftware.AddHeader("Android") $android.AddTable($(Build-AndroidTable)) @@ -243,7 +243,7 @@ if (-not (Test-IsWin11-Arm64)) { } # Cached Docker images -if (-not (Test-IsWin25-X64) -and -not (Test-IsWin11-Arm64)) { +if (Test-IsWin22-X64) { $installedSoftware.AddHeader("Cached Docker images").AddTable($(Get-CachedDockerImagesTableData)) } diff --git a/images/windows/scripts/tests/Android.Tests.ps1 b/images/windows/scripts/tests/Android.Tests.ps1 index 653b4aba00..791696827d 100644 --- a/images/windows/scripts/tests/Android.Tests.ps1 +++ b/images/windows/scripts/tests/Android.Tests.ps1 @@ -1,4 +1,4 @@ -Describe "Android SDK" -Skip:(Test-IsWin11-Arm64) { +Describe "Android SDK" -Skip:(Test-IsArm64) { $androidToolset = (Get-ToolsetContent).android $androidInstalledPackages = Get-AndroidInstalledPackages diff --git a/images/windows/scripts/tests/ChocoPackages.Tests.ps1 b/images/windows/scripts/tests/ChocoPackages.Tests.ps1 index 5b22e4248f..3de123b438 100644 --- a/images/windows/scripts/tests/ChocoPackages.Tests.ps1 +++ b/images/windows/scripts/tests/ChocoPackages.Tests.ps1 @@ -58,7 +58,7 @@ Describe "Pulumi" { } } -Describe "Svn" -Skip:((Test-IsWin25-X64) -or (Test-IsWin11-Arm64)) { +Describe "Svn" -Skip:(-not(Test-IsWin22-X64)) { It "svn" { "svn --version --quiet" | Should -ReturnZeroExitCode } diff --git a/images/windows/scripts/tests/Tools.Tests.ps1 b/images/windows/scripts/tests/Tools.Tests.ps1 index 55baf4d3d9..bc739ef5c0 100644 --- a/images/windows/scripts/tests/Tools.Tests.ps1 +++ b/images/windows/scripts/tests/Tools.Tests.ps1 @@ -235,7 +235,7 @@ project(NinjaTest NONE) } It "Make a simple ninja project" { - "cmake -GNinja $ninjaProjectPath" | Should -ReturnZeroExitCode + "cmake -GNinja $ninjaProjectPath" | Should -ReturnZeroExitCode } It "build.ninja file should exist" { diff --git a/images/windows/scripts/tests/Toolset.Tests.ps1 b/images/windows/scripts/tests/Toolset.Tests.ps1 index eba2c394d8..40401d2c6c 100644 --- a/images/windows/scripts/tests/Toolset.Tests.ps1 +++ b/images/windows/scripts/tests/Toolset.Tests.ps1 @@ -3,10 +3,6 @@ $toolsExecutables = @{ @{ Binary = "python.exe"; Arguments = "--version" }, @{ Binary = "Scripts\pip.exe"; Arguments = "--version" } ) - PyPy = @( - @{ Binary = "python.exe"; Arguments = "--version" }, - @{ Binary = "Scripts\pip.exe"; Arguments = "--version" } - ) Node = @( @{ Binary = "node.exe"; Arguments = "--version" }, @{ Binary = "npm"; Arguments = "--version" } @@ -19,8 +15,11 @@ $toolsExecutables = @{ ) } -if (Test-IsWin11-Arm64) { - $toolsExecutables.Remove("PyPy") +if (Test-IsX64) { + $toolsExecutables.Add("PyPy", @( + @{ Binary = "python.exe"; Arguments = "--version" }, + @{ Binary = "Scripts\pip.exe"; Arguments = "--version" } + )) } function Get-ToolExecutables { From 87115efabd4ee7b12c8a57048f064e0dde1b7df6 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Mon, 6 Apr 2026 17:27:50 +0200 Subject: [PATCH 53/55] Update arch variables for install scripts --- images/windows/scripts/build/Install-DotnetSDK.ps1 | 6 +++--- .../windows/scripts/build/Install-EdgeDriver.ps1 | 6 +++--- images/windows/scripts/build/Install-Firefox.ps1 | 14 +++++++------- images/windows/scripts/build/Install-Git.ps1 | 6 +++--- .../windows/scripts/build/Install-GitHub-CLI.ps1 | 6 +++--- images/windows/scripts/build/Install-JavaTools.ps1 | 10 +++++----- images/windows/scripts/build/Install-NodeJS.ps1 | 6 +++--- images/windows/scripts/build/Install-OpenSSL.ps1 | 7 +++---- .../scripts/build/Install-PowershellCore.ps1 | 6 +++--- images/windows/scripts/build/Install-Ruby.ps1 | 12 +++++++----- images/windows/scripts/build/Install-Rust.ps1 | 8 ++++---- .../windows/scripts/build/Install-VisualStudio.ps1 | 6 +++--- 12 files changed, 47 insertions(+), 46 deletions(-) diff --git a/images/windows/scripts/build/Install-DotnetSDK.ps1 b/images/windows/scripts/build/Install-DotnetSDK.ps1 index a1c3b3489c..8a09887a97 100644 --- a/images/windows/scripts/build/Install-DotnetSDK.ps1 +++ b/images/windows/scripts/build/Install-DotnetSDK.ps1 @@ -83,13 +83,13 @@ function Install-DotnetSDK { #region Supply chain security if (Test-IsArm64) { - $expectedArch = "arm64" + $dotnetArch = "arm64" } else { - $expectedArch = "x64" + $dotnetArch = "x64" } $releasesJsonUri = "https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/${DotnetVersion}/releases.json" $releasesData = (Invoke-DownloadWithRetry $releasesJsonUri) | Get-Item | Get-Content | ConvertFrom-Json - $distributorFileHash = $releasesData.releases.sdks.Where({ $_.version -eq $SDKVersion }).files.Where({ $_.name -eq "dotnet-sdk-win-$expectedArch.zip" }).hash + $distributorFileHash = $releasesData.releases.sdks.Where({ $_.version -eq $SDKVersion }).files.Where({ $_.name -eq "dotnet-sdk-win-$dotnetArch.zip" }).hash Test-FileChecksum $zipPath -ExpectedSHA512Sum $distributorFileHash #endregion } diff --git a/images/windows/scripts/build/Install-EdgeDriver.ps1 b/images/windows/scripts/build/Install-EdgeDriver.ps1 index 895f3fd3d7..31ae98a517 100644 --- a/images/windows/scripts/build/Install-EdgeDriver.ps1 +++ b/images/windows/scripts/build/Install-EdgeDriver.ps1 @@ -4,9 +4,9 @@ ################################################################################ if (Test-IsArm64) { - $expectedArch = "arm64" + $driverArch = "arm64" } else { - $expectedArch = "win64" + $driverArch = "win64" } # Disable Edge auto-updates @@ -26,7 +26,7 @@ $versionInfoFile = Invoke-DownloadWithRetry -Url $versionInfoUrl -Path "$edgeDri $latestVersion = Get-Content -Path $versionInfoFile Write-Host "Download Microsoft Edge WebDriver..." -$downloadUrl = "https://msedgedriver.microsoft.com/$latestVersion/edgedriver_$expectedArch.zip" +$downloadUrl = "https://msedgedriver.microsoft.com/$latestVersion/edgedriver_$driverArch.zip" $archivePath = Invoke-DownloadWithRetry $downloadUrl Write-Host "Expand Microsoft Edge WebDriver archive..." diff --git a/images/windows/scripts/build/Install-Firefox.ps1 b/images/windows/scripts/build/Install-Firefox.ps1 index 5306e4ae65..ad235da0d0 100644 --- a/images/windows/scripts/build/Install-Firefox.ps1 +++ b/images/windows/scripts/build/Install-Firefox.ps1 @@ -5,11 +5,11 @@ ################################################################################ if (Test-IsArm64) { - $expectedArch = "win64-aarch64" - $driverSufix = "win-aarch64" + $browserArch = "win64-aarch64" + $driverArch = "win-aarch64" } else { - $expectedArch = "win64" - $driverSufix = "win64" + $browserArch = "win64" + $driverArch = "win64" } # Install and configure Firefox browser @@ -17,12 +17,12 @@ Write-Host "Get the latest Firefox version..." $versionsManifest = Invoke-RestMethod "https://product-details.mozilla.org/1.0/firefox_versions.json" Write-Host "Install Firefox browser..." -$installerUrl = "https://download.mozilla.org/?product=firefox-$($versionsManifest.LATEST_FIREFOX_VERSION)&os=$expectedArch&lang=en-US" +$installerUrl = "https://download.mozilla.org/?product=firefox-$($versionsManifest.LATEST_FIREFOX_VERSION)&os=$browserArch&lang=en-US" $hashUrl = "https://archive.mozilla.org/pub/firefox/releases/$($versionsManifest.LATEST_FIREFOX_VERSION)/SHA256SUMS" $externalHash = Get-ChecksumFromUrl -Type "SHA256" ` -Url $hashUrl ` - -FileName "$expectedArch/en-US/Firefox Setup*exe" + -FileName "$browserArch/en-US/Firefox Setup*exe" Install-Binary -Type EXE ` -Url $installerUrl ` @@ -54,7 +54,7 @@ Write-Host "Download Gecko WebDriver WebDriver..." $geckoDriverDownloadUrl = Resolve-GithubReleaseAssetUrl ` -Repo "mozilla/geckodriver" ` -Version $geckoDriverVersion ` - -UrlMatchPattern "geckodriver-*-$driverSufix.zip" + -UrlMatchPattern "geckodriver-*-$driverArch.zip" $geckoDriverArchPath = Invoke-DownloadWithRetry $geckoDriverDownloadUrl Write-Host "Expand Gecko WebDriver archive..." diff --git a/images/windows/scripts/build/Install-Git.ps1 b/images/windows/scripts/build/Install-Git.ps1 index 4be12ddc37..29c63d596a 100644 --- a/images/windows/scripts/build/Install-Git.ps1 +++ b/images/windows/scripts/build/Install-Git.ps1 @@ -5,16 +5,16 @@ ################################################################################ if (Test-IsArm64) { - $expectedArch = "arm64" + $gitArch = "arm64" } else { - $expectedArch = "64-bit" + $gitArch = "64-bit" } # Install the latest version of Git for Windows $downloadUrl = Resolve-GithubReleaseAssetUrl ` -Repo "git-for-windows/git" ` -Version "latest" ` - -UrlMatchPattern "Git-*-$expectedArch.exe" + -UrlMatchPattern "Git-*-$gitArch.exe" $externalHash = Get-ChecksumFromGithubRelease ` -Repo "git-for-windows/git" ` diff --git a/images/windows/scripts/build/Install-GitHub-CLI.ps1 b/images/windows/scripts/build/Install-GitHub-CLI.ps1 index 2df04861b8..c5c0dc244e 100644 --- a/images/windows/scripts/build/Install-GitHub-CLI.ps1 +++ b/images/windows/scripts/build/Install-GitHub-CLI.ps1 @@ -5,16 +5,16 @@ ################################################################################ if (Test-IsArm64) { - $expectedArch = "arm64" + $ghArch = "arm64" } else { - $expectedArch = "amd64" + $ghArch = "amd64" } Write-Host "Get the latest gh version..." $downloadUrl = Resolve-GithubReleaseAssetUrl ` -Repo "cli/cli" ` -Version "latest" ` - -UrlMatchPattern "gh_*_windows_$expectedArch.msi" + -UrlMatchPattern "gh_*_windows_$ghArch.msi" $checksumsUrl = Resolve-GithubReleaseAssetUrl ` -Repo "cli/cli" ` diff --git a/images/windows/scripts/build/Install-JavaTools.ps1 b/images/windows/scripts/build/Install-JavaTools.ps1 index 7c272f6f81..881d813493 100644 --- a/images/windows/scripts/build/Install-JavaTools.ps1 +++ b/images/windows/scripts/build/Install-JavaTools.ps1 @@ -92,9 +92,9 @@ function Install-JavaJDK { } if (Test-IsArm64) { - $expectedArch = "aarch64" + $javaArch = "aarch64" } else { - $expectedArch = "x64" + $javaArch = "x64" } $toolsetJava = (Get-ToolsetContent).java @@ -104,12 +104,12 @@ $jdkVersionsToInstall = $toolsetJava.versions foreach ($jdkVersionToInstall in $jdkVersionsToInstall) { $isDefaultVersion = $jdkVersionToInstall -eq $defaultVersion - Install-JavaJDK -JDKVersion $jdkVersionToInstall -Architecture $expectedArch + Install-JavaJDK -JDKVersion $jdkVersionToInstall -Architecture $javaArch if ($isDefaultVersion) { - Set-JavaPath -Version $jdkVersionToInstall -Architecture $expectedArch -Default + Set-JavaPath -Version $jdkVersionToInstall -Architecture $javaArch -Default } else { - Set-JavaPath -Version $jdkVersionToInstall -Architecture $expectedArch + Set-JavaPath -Version $jdkVersionToInstall -Architecture $javaArch } } diff --git a/images/windows/scripts/build/Install-NodeJS.ps1 b/images/windows/scripts/build/Install-NodeJS.ps1 index d65977a451..d288ba18bd 100644 --- a/images/windows/scripts/build/Install-NodeJS.ps1 +++ b/images/windows/scripts/build/Install-NodeJS.ps1 @@ -8,9 +8,9 @@ $prefixPath = 'C:\npm\prefix' $cachePath = 'C:\npm\cache' if (Test-IsArm64) { - $expectedArch = "arm64" + $nodeArch = "arm64" } else { - $expectedArch = "x64" + $nodeArch = "x64" } New-Item -Path $prefixPath -Force -ItemType Directory @@ -18,7 +18,7 @@ New-Item -Path $cachePath -Force -ItemType Directory $defaultVersion = (Get-ToolsetContent).node.default $nodeVersion = (Get-GithubReleasesByVersion -Repo "nodejs/node" -Version "${defaultVersion}").version | Select-Object -First 1 -$downloadUrl = "https://nodejs.org/dist/v${nodeVersion}/node-v${nodeVersion}-${expectedArch}.msi" +$downloadUrl = "https://nodejs.org/dist/v${nodeVersion}/node-v${nodeVersion}-${nodeArch}.msi" $packageName = Split-Path $downloadUrl -Leaf $externalHash = Get-ChecksumFromUrl -Type "SHA256" ` diff --git a/images/windows/scripts/build/Install-OpenSSL.ps1 b/images/windows/scripts/build/Install-OpenSSL.ps1 index f47103749b..21518b01b3 100644 --- a/images/windows/scripts/build/Install-OpenSSL.ps1 +++ b/images/windows/scripts/build/Install-OpenSSL.ps1 @@ -5,12 +5,11 @@ ################################################################################ if (Test-IsArm64) { - $expectedArch = "ARM" + $openSSLArch = "ARM" } else { - $expectedArch = "INTEL" + $openSSLArch = "INTEL" } -$arch = $expectedArch $bits = '64' $light = $false $installerType = "exe" @@ -28,7 +27,7 @@ $installerHash = $null foreach ($key in $installerNames) { $installer = $installersAvailable.$key - if (($installer.light -eq $light) -and ($installer.arch -eq $arch) -and ($installer.bits -eq $bits) -and ($installer.installer -eq $installerType) -and ($installer.basever -like $version)) { + if (($installer.light -eq $light) -and ($installer.arch -eq $openSSLArch) -and ($installer.bits -eq $bits) -and ($installer.installer -eq $installerType) -and ($installer.basever -like $version)) { $installerUrl = $installer.url $installerHash = $installer.sha512 } diff --git a/images/windows/scripts/build/Install-PowershellCore.ps1 b/images/windows/scripts/build/Install-PowershellCore.ps1 index a479526d1b..921543b05a 100644 --- a/images/windows/scripts/build/Install-PowershellCore.ps1 +++ b/images/windows/scripts/build/Install-PowershellCore.ps1 @@ -7,9 +7,9 @@ $ErrorActionPreference = "Stop" if (Test-IsArm64) { - $expectedArch = "arm64" + $pwshArch = "arm64" } else { - $expectedArch = "x64" + $pwshArch = "x64" } $tempDir = Join-Path ([System.IO.Path]::GetTempPath()) ([System.IO.Path]::GetRandomFileName()) @@ -24,7 +24,7 @@ try { $releases = $metadata.LTSReleaseTag -replace '^v' foreach ($release in $releases) { if ($release -like "${pwshMajorMinor}*") { - $downloadUrl = "https://github.com/PowerShell/PowerShell/releases/download/v${release}/PowerShell-${release}-win-${expectedArch}.msi" + $downloadUrl = "https://github.com/PowerShell/PowerShell/releases/download/v${release}/PowerShell-${release}-win-${pwshArch}.msi" break } } diff --git a/images/windows/scripts/build/Install-Ruby.ps1 b/images/windows/scripts/build/Install-Ruby.ps1 index 421e8bc233..f867f0bf62 100644 --- a/images/windows/scripts/build/Install-Ruby.ps1 +++ b/images/windows/scripts/build/Install-Ruby.ps1 @@ -64,9 +64,11 @@ function Set-DefaultRubyVersion { } if (Test-IsArm64) { - $expectedArch = "arm" + $downloadArch = "arm" + $toolcacheArch = "aarch64" } else { - $expectedArch = "x64" + $downloadArch = "x64" + $toolcacheArch = "x64" } # Install Ruby @@ -79,13 +81,13 @@ foreach ($rubyVersion in $rubyToolVersions) { $downloadUrl = Resolve-GithubReleaseAssetUrl ` -Repo "oneclick/rubyinstaller2" ` -Version "$rubyVersion*" ` - -UrlMatchPattern "*-${expectedArch}.7z" + -UrlMatchPattern "*-${downloadArch}.7z" $packagePath = Invoke-DownloadWithRetry $downloadUrl if (Test-IsArm64) { - Install-Ruby -PackagePath $packagePath -Architecture "aarch64" + Install-Ruby -PackagePath $packagePath -Architecture $toolcacheArch } else { - Install-Ruby -PackagePath $packagePath -Architecture "x64" + Install-Ruby -PackagePath $packagePath -Architecture $toolcacheArch } } diff --git a/images/windows/scripts/build/Install-Rust.ps1 b/images/windows/scripts/build/Install-Rust.ps1 index 503823913c..84bcfd3fc0 100644 --- a/images/windows/scripts/build/Install-Rust.ps1 +++ b/images/windows/scripts/build/Install-Rust.ps1 @@ -5,9 +5,9 @@ ################################################################################ if (Test-IsArm64) { - $expectedArch = "aarch64" + $rustArch = "aarch64" } else { - $expectedArch = "x86_64" + $rustArch = "x86_64" } # Rust Env @@ -16,10 +16,10 @@ $env:CARGO_HOME = "C:\Users\Default\.cargo" # Download the latest rustup-init.exe for Windows # See https://rustup.rs/# -$rustupPath = Invoke-DownloadWithRetry "https://static.rust-lang.org/rustup/dist/${expectedArch}-pc-windows-msvc/rustup-init.exe" +$rustupPath = Invoke-DownloadWithRetry "https://static.rust-lang.org/rustup/dist/${rustArch}-pc-windows-msvc/rustup-init.exe" #region Supply chain security -$distributorFileHash = (Invoke-RestMethod -Uri "https://static.rust-lang.org/rustup/dist/${expectedArch}-pc-windows-msvc/rustup-init.exe.sha256").Trim() +$distributorFileHash = (Invoke-RestMethod -Uri "https://static.rust-lang.org/rustup/dist/${rustArch}-pc-windows-msvc/rustup-init.exe.sha256").Trim() Test-FileChecksum $rustupPath -ExpectedSHA256Sum $distributorFileHash #endregion diff --git a/images/windows/scripts/build/Install-VisualStudio.ps1 b/images/windows/scripts/build/Install-VisualStudio.ps1 index c5f1cba6b4..5e28bffdd7 100644 --- a/images/windows/scripts/build/Install-VisualStudio.ps1 +++ b/images/windows/scripts/build/Install-VisualStudio.ps1 @@ -5,9 +5,9 @@ $vsToolset = (Get-ToolsetContent).visualStudio if (Test-IsArm64) { - $expectedArch = "arm64" + $vsArch = "arm64" } else { - $expectedArch = "x64" + $vsArch = "x64" } # Install Visual Studio for Windows 22 and 25 with InstallChannel @@ -18,7 +18,7 @@ Install-VisualStudio ` -InstallChannelUri $vsToolset.installChannelUri ` -RequiredComponents $vsToolset.workloads ` -ExtraArgs "--allWorkloads --includeRecommended --remove Component.CPython3.x64" ` - -Architecture $expectedArch + -Architecture $vsArch # Find the version of VS installed for this instance # Only supports a single instance From c71d41f2c370a7f684115b633d7da160c156fe5a Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Mon, 6 Apr 2026 21:21:54 +0200 Subject: [PATCH 54/55] Add comments for AutoAdminLogon --- images/windows/templates/build.windows-11-arm64.pkr.hcl | 4 ++++ .../windows/templates/build.windows-11-vs2026-arm64.pkr.hcl | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/images/windows/templates/build.windows-11-arm64.pkr.hcl b/images/windows/templates/build.windows-11-arm64.pkr.hcl index 2b6630a279..53ec3bbedc 100644 --- a/images/windows/templates/build.windows-11-arm64.pkr.hcl +++ b/images/windows/templates/build.windows-11-arm64.pkr.hcl @@ -51,6 +51,8 @@ build { inline = ["if (-not ((net localgroup Administrators) -contains '${var.install_user}')) { exit 1 }"] } + # Scheduled tasks spawned when using elevated_user provisioners requires the user to log in interactively on Windows Desktop + # Set AutoAdminLogon for elevated_user and reboot as a workaround provisioner "powershell" { inline = [ "Set-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name AutoAdminLogon -Value 1 -type String", @@ -203,6 +205,8 @@ build { ] } + # Scheduled tasks spawned when using elevated_user provisioners requires the user to log in interactively on Windows Desktop + # Remove AutoAdminLogon after all elevated_user tasks are completed and reboot provisioner "powershell" { inline = [ "Remove-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name AutoAdminLogon", diff --git a/images/windows/templates/build.windows-11-vs2026-arm64.pkr.hcl b/images/windows/templates/build.windows-11-vs2026-arm64.pkr.hcl index d67b34a7d6..f0f3d8e8fe 100644 --- a/images/windows/templates/build.windows-11-vs2026-arm64.pkr.hcl +++ b/images/windows/templates/build.windows-11-vs2026-arm64.pkr.hcl @@ -51,6 +51,8 @@ build { inline = ["if (-not ((net localgroup Administrators) -contains '${var.install_user}')) { exit 1 }"] } + # Scheduled tasks spawned when using elevated_user provisioners requires the user to log in interactively on Windows Desktop + # Set AutoAdminLogon for elevated_user and reboot as a workaround provisioner "powershell" { inline = [ "Set-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name AutoAdminLogon -Value 1 -type String", @@ -203,6 +205,8 @@ build { ] } + # Scheduled tasks spawned when using elevated_user provisioners requires the user to log in interactively on Windows Desktop + # Remove AutoAdminLogon after all elevated_user tasks are completed and reboot provisioner "powershell" { inline = [ "Remove-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name AutoAdminLogon", From 305691afd03511a2b0b1aa37ab122c46dcbdd1f4 Mon Sep 17 00:00:00 2001 From: Shamil Mubarakshin Date: Mon, 6 Apr 2026 21:25:42 +0200 Subject: [PATCH 55/55] wip: adjust rust cargo install --- images/windows/scripts/build/Install-Rust.ps1 | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/images/windows/scripts/build/Install-Rust.ps1 b/images/windows/scripts/build/Install-Rust.ps1 index 84bcfd3fc0..890b4103af 100644 --- a/images/windows/scripts/build/Install-Rust.ps1 +++ b/images/windows/scripts/build/Install-Rust.ps1 @@ -50,7 +50,7 @@ if ($LASTEXITCODE -ne 0) { throw "Rust component installation failed with exit code $LASTEXITCODE" } -if (Test-IsWin22-X64) { +if ((Test-IsWin22-X64) -or (Test-IsWin11-Arm64)) { cargo install --locked bindgen-cli cbindgen cargo-audit cargo-outdated if ($LASTEXITCODE -ne 0) { throw "Rust tools installation failed with exit code $LASTEXITCODE" @@ -59,13 +59,4 @@ if (Test-IsWin22-X64) { Remove-Item "${env:CARGO_HOME}\registry\*" -Recurse -Force } -if (Test-IsWin11-Arm64) { - cargo install bindgen-cli cbindgen cargo-audit cargo-outdated - if ($LASTEXITCODE -ne 0) { - throw "Rust tools installation failed with exit code $LASTEXITCODE" - } - # Cleanup Cargo crates cache - Remove-Item "${env:CARGO_HOME}\registry\*" -Recurse -Force -} - Invoke-PesterTests -TestFile "Rust"