[windows] Add windows-11-arm64 image generation code (#13879)

This commit is contained in:
Shamil Mubarakshin
2026-04-07 17:32:00 +02:00
committed by GitHub
parent c722443db7
commit 1b60920cc9
60 changed files with 1744 additions and 179 deletions
@@ -44,7 +44,7 @@ function Disable-WindowsUpdate {
Add-Content -Path $profile.AllUsersAllHosts -Value '$ErrorActionPreference="Stop"'
Write-Host "Disable Server Manager on Logon"
Get-ScheduledTask -TaskName ServerManager | Disable-ScheduledTask
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
@@ -15,20 +15,28 @@ $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-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) {
$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 = @"
@@ -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 (Test-IsX64) {
# 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
@@ -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")
@@ -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
}
}
@@ -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 (Test-IsWin22-X64) {
# disable TSVNCache.exe
$registryKeyPath = 'HKCU:\Software\TortoiseSVN'
if (-not(Test-Path -Path $registryKeyPath)) {
@@ -42,7 +42,7 @@ if (-not (Test-IsWin25)) {
}
}
# 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
}
@@ -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"
@@ -0,0 +1,31 @@
################################################################################
## File: Install-CMake.ps1
## Desc: Install CMake (ARM64 only; x64 is installed via Choco)
## Supply chain security: CMake - checksum validation
################################################################################
# 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"
@@ -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
@@ -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) {
@@ -82,9 +82,14 @@ function Install-DotnetSDK {
# If installation failed, tests will fail anyway
#region Supply chain security
if (Test-IsArm64) {
$dotnetArch = "arm64"
} else {
$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-x64.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
}
@@ -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
}
}
@@ -3,6 +3,12 @@
## Desc: Install Edge WebDriver and configure Microsoft Edge
################################################################################
if (Test-IsArm64) {
$driverArch = "arm64"
} else {
$driverArch = "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_$driverArch.zip"
$archivePath = Invoke-DownloadWithRetry $downloadUrl
Write-Host "Expand Microsoft Edge WebDriver archive..."
@@ -4,17 +4,25 @@
## Supply chain security: Firefox browser - checksum validation
################################################################################
if (Test-IsArm64) {
$browserArch = "win64-aarch64"
$driverArch = "win-aarch64"
} else {
$browserArch = "win64"
$driverArch = "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=$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 "win64/en-US/Firefox Setup*exe"
-FileName "$browserArch/en-US/Firefox Setup*exe"
Install-Binary -Type EXE `
-Url $installerUrl `
@@ -46,7 +54,7 @@ Write-Host "Download Gecko WebDriver WebDriver..."
$geckoDriverDownloadUrl = Resolve-GithubReleaseAssetUrl `
-Repo "mozilla/geckodriver" `
-Version $geckoDriverVersion `
-UrlMatchPattern "geckodriver-*-win64.zip"
-UrlMatchPattern "geckodriver-*-$driverArch.zip"
$geckoDriverArchPath = Invoke-DownloadWithRetry $geckoDriverDownloadUrl
Write-Host "Expand Gecko WebDriver archive..."
+7 -2
View File
@@ -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) {
$gitArch = "arm64"
} else {
$gitArch = "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-*-$gitArch.exe"
$externalHash = Get-ChecksumFromGithubRelease `
-Repo "git-for-windows/git" `
@@ -4,12 +4,17 @@
## Supply chain security: GitHub CLI - checksum validation
################################################################################
Write-Host "Get the latest gh version..."
if (Test-IsArm64) {
$ghArch = "arm64"
} else {
$ghArch = "amd64"
}
Write-Host "Get the latest gh version..."
$downloadUrl = Resolve-GithubReleaseAssetUrl `
-Repo "cli/cli" `
-Version "latest" `
-UrlMatchPattern "gh_*_windows_amd64.msi"
-UrlMatchPattern "gh_*_windows_$ghArch.msi"
$checksumsUrl = Resolve-GithubReleaseAssetUrl `
-Repo "cli/cli" `
@@ -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
@@ -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) {
$javaArch = "aarch64"
} else {
$javaArch = "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 $javaArch
if ($isDefaultVersion) {
Set-JavaPath -Version $jdkVersionToInstall -Default
Set-JavaPath -Version $jdkVersionToInstall -Architecture $javaArch -Default
} else {
Set-JavaPath -Version $jdkVersionToInstall
Set-JavaPath -Version $jdkVersionToInstall -Architecture $javaArch
}
}
+29 -3
View File
@@ -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"
@@ -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 (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) {
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"
}
}
@@ -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"
@@ -0,0 +1,24 @@
################################################################################
## File: Install-Ninja.ps1
## Desc: Install Ninja build system (ARM64 only; x64 is installed via Choco)
################################################################################
$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"
@@ -7,12 +7,18 @@
$prefixPath = 'C:\npm\prefix'
$cachePath = 'C:\npm\cache'
if (Test-IsArm64) {
$nodeArch = "arm64"
} else {
$nodeArch = "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}-${nodeArch}.msi"
$packageName = Split-Path $downloadUrl -Leaf
$externalHash = Get-ChecksumFromUrl -Type "SHA256" `
@@ -4,7 +4,12 @@
## Supply chain security: checksum validation
################################################################################
$arch = 'INTEL'
if (Test-IsArm64) {
$openSSLArch = "ARM"
} else {
$openSSLArch = "INTEL"
}
$bits = '64'
$light = $false
$installerType = "exe"
@@ -22,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
}
@@ -6,6 +6,12 @@
$ErrorActionPreference = "Stop"
if (Test-IsArm64) {
$pwshArch = "arm64"
} else {
$pwshArch = "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-${pwshArch}.msi"
break
}
}
+8 -1
View File
@@ -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"
+15 -2
View File
@@ -63,6 +63,14 @@ function Set-DefaultRubyVersion {
Add-MachinePathItem -PathItem $rubyDir | Out-Null
}
if (Test-IsArm64) {
$downloadArch = "arm"
$toolcacheArch = "aarch64"
} else {
$downloadArch = "x64"
$toolcacheArch = "x64"
}
# Install Ruby
$rubyTools = (Get-ToolsetContent).toolcache | Where-Object { $_.name -eq "Ruby" }
$rubyToolVersions = $rubyTools.versions
@@ -73,9 +81,14 @@ foreach ($rubyVersion in $rubyToolVersions) {
$downloadUrl = Resolve-GithubReleaseAssetUrl `
-Repo "oneclick/rubyinstaller2" `
-Version "$rubyVersion*" `
-UrlMatchPattern "*-x64.7z"
-UrlMatchPattern "*-${downloadArch}.7z"
$packagePath = Invoke-DownloadWithRetry $downloadUrl
Install-Ruby -PackagePath $packagePath
if (Test-IsArm64) {
Install-Ruby -PackagePath $packagePath -Architecture $toolcacheArch
} else {
Install-Ruby -PackagePath $packagePath -Architecture $toolcacheArch
}
}
Set-DefaultRubyVersion -Version $rubyTools.default -Arch $rubyTools.arch
+19 -8
View File
@@ -4,16 +4,22 @@
## Supply chain security: checksum validation for bootstrap, managed by rustup for workloads
################################################################################
if (Test-IsArm64) {
$rustArch = "aarch64"
} else {
$rustArch = "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/${rustArch}-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/${rustArch}-pc-windows-msvc/rustup-init.exe.sha256").Trim()
Test-FileChecksum $rustupPath -ExpectedSHA256Sum $distributorFileHash
#endregion
@@ -28,18 +34,23 @@ 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
if ($LASTEXITCODE -ne 0) {
throw "Rust component installation failed with exit code $LASTEXITCODE"
}
if (-not (Test-IsWin25)) {
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"
@@ -4,6 +4,12 @@
################################################################################
$vsToolset = (Get-ToolsetContent).visualStudio
if (Test-IsArm64) {
$vsArch = "arm64"
} else {
$vsArch = "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 $vsArch
# Find the version of VS installed for this instance
# Only supports a single instance
@@ -27,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' `
@@ -42,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
+4 -1
View File
@@ -4,9 +4,12 @@
################################################################################
# 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-Arm64) {
# 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"
}
@@ -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",
@@ -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,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 (Test-IsX64) {
$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 (Test-IsX64) {
$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 (Test-IsX64) {
$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))
@@ -84,36 +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))
$tools.AddToolVersion("Service Fabric SDK", $(Get-ServiceFabricSDKVersion))
if (Test-IsX64) {
$tools.AddToolVersion("Service Fabric SDK", $(Get-ServiceFabricSDKVersion))
}
$tools.AddToolVersion("Stack", $(Get-StackVersion))
if (-not (Test-IsWin25)) {
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))
$tools.AddToolVersion("WiX Toolset", $(Get-WixVersion))
if (Test-IsX64) {
$tools.AddToolVersion("WiX Toolset", $(Get-WixVersion))
}
$tools.AddToolVersion("yamllint", $(Get-YAMLLintVersion))
$tools.AddToolVersion("zstd", $(Get-ZstdVersion))
if (Test-IsX64) {
$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))
@@ -132,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))
@@ -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 (Test-IsX64) {
$installedSoftware.AddHeader("Shells").AddTable($(Get-ShellTarget))
}
# MSYS2
$msys2 = $installedSoftware.AddHeader("MSYS2")
$msys2.AddToolVersion("Pacman", $(Get-PacmanVersion))
if (Test-IsX64) {
$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 (Test-IsX64) {
$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 (Test-IsX64) {
$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 (Test-IsX64) {
$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 (Test-IsWin22-X64) {
$installedSoftware.AddHeader("Cached Docker images").AddTable($(Get-CachedDockerImagesTableData))
}
@@ -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-Arm64)) { [ToolVersionsListNode]::new("PyPy", $(Get-ToolcachePyPyVersions), '^\d+\.\d+', 'List') }),
[ToolVersionsListNode]::new("Ruby", $(Get-ToolcacheRubyVersions), '^\d+\.\d+', 'List')
)
) | Where-Object { $_ }
}
@@ -297,9 +297,9 @@ function Build-PackageManagementEnvironmentTable {
"Name" = "VCPKG_INSTALLATION_ROOT"
"Value" = $env:VCPKG_INSTALLATION_ROOT
},
[PSCustomObject] @{
$(if (-not (Test-IsWin11-Arm64)) { [PSCustomObject] @{
"Name" = "CONDA"
"Value" = $env:CONDA
}
)
} })
) | Where-Object { $_ }
}
@@ -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
@@ -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 }
@@ -25,6 +25,12 @@ Export-ModuleMember -Function @(
'Get-TCToolVersionPath'
'Test-IsWin25'
'Test-IsWin22'
'Test-IsWin11'
'Test-IsArm64'
'Test-IsX64'
'Test-IsWin25-X64'
'Test-IsWin22-X64'
'Test-IsWin11-Arm64'
'Expand-7ZipArchive'
'Get-WindowsUpdateStates'
'Invoke-ScriptBlockWithRetry'
@@ -322,6 +322,38 @@ 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-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
@@ -356,6 +388,63 @@ 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 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
@@ -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" }
}
@@ -1,4 +1,4 @@
Describe "Android SDK" {
Describe "Android SDK" -Skip:(Test-IsArm64) {
$androidToolset = (Get-ToolsetContent).android
$androidInstalledPackages = Get-AndroidInstalledPackages
@@ -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
}
@@ -58,7 +58,7 @@ Describe "Pulumi" {
}
}
Describe "Svn" -Skip:(Test-IsWin25) {
Describe "Svn" -Skip:(-not(Test-IsWin22-X64)) {
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
@@ -1,4 +1,4 @@
Describe "MongoDB" {
Describe "MongoDB" -Skip:(Test-IsWin11-Arm64) {
Context "Version" {
It "<ToolName>" -TestCases @(
@{ ToolName = "mongos" }
@@ -33,7 +33,7 @@ Describe "MongoDB" {
}
}
Describe "PostgreSQL" {
Describe "PostgreSQL" -Skip:(Test-IsWin11-Arm64) {
$psqlTests = @(
@{envVar = "PGROOT"; pgPath = Get-EnvironmentVariable "PGROOT" }
@{envVar = "PGBIN"; pgPath = Get-EnvironmentVariable "PGBIN" }
@@ -1,4 +1,4 @@
Describe "Docker" {
Describe "Docker" -Skip:(Test-IsWin11-Arm64) {
It "docker is installed" {
"docker --version" | Should -ReturnZeroExitCode
}
@@ -12,20 +12,20 @@ Describe "Docker" {
}
}
Describe "DockerCompose" {
Describe "DockerCompose" -Skip:(Test-IsWin11-Arm64) {
It "docker compose v2" {
"docker compose version" | Should -ReturnZeroExitCode
}
}
Describe "DockerWinCred" {
Describe "DockerWinCred" -Skip:(Test-IsWin11-Arm64) {
It "docker-wincred" {
"docker-credential-wincred version" | Should -ReturnZeroExitCode
}
}
Describe "DockerImages" -Skip:(Test-IsWin25) {
Describe "DockerImages" -Skip:((Test-IsWin25-X64) -or (Test-IsWin11-Arm64)) {
Context "docker images" {
$testCases = (Get-ToolsetContent).docker.images | ForEach-Object { @{ ImageName = $_ } }
+25 -29
View File
@@ -1,33 +1,29 @@
Describe "Haskell" {
$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
Describe "Haskell" -Skip:(Test-IsWin11-Arm64) {
BeforeDiscovery {
if (Test-IsWin11-Arm64) { return }
$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-X64) { 1 } else { 3 }
}
It "<envVar> environment variable exists" -TestCases $ghcupEnvExists {
+10 -2
View File
@@ -5,9 +5,17 @@ Describe "Java" {
[array] $testCases = $jdkVersions | ForEach-Object { @{Version = $_ } }
BeforeAll {
if (Test-IsArm64) {
$expectedArch = "AARCH64"
} else {
$expectedArch = "X64"
}
}
It "Java <DefaultJavaVersion> 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 <Version>" -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"
+2 -2
View File
@@ -3,7 +3,7 @@ BeforeAll {
$originalPath = $env:PATH
}
Describe "MSYS2 packages" {
Describe "MSYS2 packages" -Skip:(Test-IsWin11-Arm64) {
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-Arm64) {
$tools = $mingwType.runtime_packages
$execDir = Join-Path "C:\msys64" $mingwType.exec_dir | Join-Path -ChildPath "bin"
@@ -1,4 +1,4 @@
Describe "Miniconda" {
Describe "Miniconda" -Skip:(Test-IsWin11-Arm64) {
It "Miniconda Environment variables is set. " {
${env:CONDA} | Should -Not -BeNullOrEmpty
}
@@ -11,4 +11,4 @@ Describe "Miniconda" {
$condaPath | Should -Exist
"$condaPath --version" | Should -ReturnZeroExitCode
}
}
}
+1 -1
View File
@@ -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"}
+2 -2
View File
@@ -1,9 +1,9 @@
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-Arm64)) { @{Name = "C:\shells\msys2bash.cmd"; Target = $null} }),
@{Name = "C:\shells\wslbash.exe"; Target = "$env:SystemRoot\System32\bash.exe"}
)
) | Where-Object { $_ }
It "<Name> target to <Target>" -TestCases $shellTestCases {
(Get-Item $Name).Target | Should -BeExactly $Target
+38 -4
View File
@@ -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" {
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" {
Describe "Zstd" -Skip:(Test-IsWin11-Arm64) {
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
}
}
@@ -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,6 +15,13 @@ $toolsExecutables = @{
)
}
if (Test-IsX64) {
$toolsExecutables.Add("PyPy", @(
@{ Binary = "python.exe"; Arguments = "--version" },
@{ Binary = "Scripts\pip.exe"; Arguments = "--version" }
))
}
function Get-ToolExecutables {
Param ([String] $Name)
if ($toolsExecutables.ContainsKey($Name)) { $toolsExecutables[$Name] } else { @() }
@@ -25,7 +25,7 @@ Describe "Visual Studio" {
}
}
Describe "Windows 10 SDK" -Skip:(Test-IsWin25) {
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
}
+1 -1
View File
@@ -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
@@ -79,12 +79,15 @@ 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
}
}
Describe "WSL2" -Skip:(Test-IsWin22) {
Describe "WSL2" -Skip:((Test-IsWin22-X64) -or (Test-IsWin11-Arm64)) {
It "WSL status should return zero exit code" {
"wsl --status" | Should -ReturnZeroExitCode
}
+1 -1
View File
@@ -1,4 +1,4 @@
Describe "Wix" {
Describe "Wix" -Skip:(Test-IsWin11-Arm64) {
BeforeAll {
$regKey = "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
$installedApplications = Get-ItemProperty -Path $regKey
@@ -0,0 +1,282 @@
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 }"]
}
# 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",
"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}"]
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}"]
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"
]
}
# 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",
"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-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 } }"
]
}
}
@@ -0,0 +1,282 @@
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 }"]
}
# 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",
"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"
]
}
# 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",
"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 } }"
]
}
}
@@ -11,6 +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
}
}
@@ -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",
"installChannelUri": "",
"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"
}
}
@@ -0,0 +1,307 @@
{
"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",
"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.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"
}
}