feature: initial commit for all new image changes
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
################################################################################
|
||||
## File: Configure-BaseImage.ps1
|
||||
## Desc: Prepare the base image for software installation
|
||||
################################################################################
|
||||
|
||||
function Disable-InternetExplorerESC {
|
||||
$adminKey = "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A7-37EF-4b3f-8CFC-4F3A74704073}"
|
||||
$userKey = "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A8-37EF-4b3f-8CFC-4F3A74704073}"
|
||||
Set-ItemProperty -Path $adminKey -Name "IsInstalled" -Value 0 -Force
|
||||
Set-ItemProperty -Path $userKey -Name "IsInstalled" -Value 0 -Force
|
||||
|
||||
$ieProcess = Get-Process -Name Explorer -ErrorAction SilentlyContinue
|
||||
|
||||
if ($ieProcess) {
|
||||
Stop-Process -Name Explorer -Force -ErrorAction Continue
|
||||
}
|
||||
|
||||
Write-Host "IE Enhanced Security Configuration (ESC) has been disabled."
|
||||
}
|
||||
|
||||
function Disable-InternetExplorerWelcomeScreen {
|
||||
$adminKey = "HKLM:\Software\Policies\Microsoft\Internet Explorer\Main"
|
||||
New-Item -Path $adminKey -Value 1 -Force
|
||||
Set-ItemProperty -Path $adminKey -Name "DisableFirstRunCustomize" -Value 1 -Force
|
||||
Write-Host "Disabled IE Welcome screen"
|
||||
}
|
||||
|
||||
function Disable-UserAccessControl {
|
||||
Set-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "ConsentPromptBehaviorAdmin" -Value 00000000 -Force
|
||||
Write-Host "User Access Control (UAC) has been disabled."
|
||||
}
|
||||
|
||||
function Disable-WindowsUpdate {
|
||||
$autoUpdatePath = "HKLM:SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU"
|
||||
if (Test-Path -Path $autoUpdatePath) {
|
||||
Set-ItemProperty -Path $autoUpdatePath -Name NoAutoUpdate -Value 1
|
||||
Write-Host "Disabled Windows Update"
|
||||
} else {
|
||||
Write-Host "Windows Update key does not exist"
|
||||
}
|
||||
}
|
||||
|
||||
# Enable $ErrorActionPreference='Stop' for AllUsersAllHosts
|
||||
Add-Content -Path $profile.AllUsersAllHosts -Value '$ErrorActionPreference="Stop"'
|
||||
|
||||
Write-Host "Disable Server Manager on Logon"
|
||||
Get-ScheduledTask -TaskName ServerManager | 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
|
||||
|
||||
Write-Host 'Disable Windows Update Medic Service'
|
||||
Set-ItemProperty -Path HKLM:\System\CurrentControlSet\Services\WaaSMedicSvc -Name Start -Value 4 -Force
|
||||
|
||||
Write-Host "Disable Windows Update"
|
||||
Disable-WindowsUpdate
|
||||
|
||||
Write-Host "Disable UAC"
|
||||
Disable-UserAccessControl
|
||||
|
||||
Write-Host "Disable IE Welcome Screen"
|
||||
Disable-InternetExplorerWelcomeScreen
|
||||
|
||||
Write-Host "Disable IE ESC"
|
||||
Disable-InternetExplorerESC
|
||||
|
||||
Write-Host "Setting local execution policy"
|
||||
Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope LocalMachine -ErrorAction Continue | Out-Null
|
||||
Get-ExecutionPolicy -List
|
||||
|
||||
Write-Host "Enable long path behavior"
|
||||
# See https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file#maximum-path-length-limitation
|
||||
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem' -Name 'LongPathsEnabled' -Value 1
|
||||
|
||||
# Expand disk size of OS drive
|
||||
$driveLetter = "C"
|
||||
$size = Get-PartitionSupportedSize -DriveLetter $driveLetter
|
||||
Resize-Partition -DriveLetter $driveLetter -Size $size.SizeMax
|
||||
Get-Volume | Select-Object DriveLetter, SizeRemaining, Size | Sort-Object DriveLetter
|
||||
@@ -0,0 +1,13 @@
|
||||
################################################################################
|
||||
## File: Configure-DeveloperMode.ps1
|
||||
## Desc: Enables Developer Mode by toggling registry setting. Developer Mode is required to enable certain tools (e.g. WinAppDriver).
|
||||
################################################################################
|
||||
|
||||
# Create AppModelUnlock if it doesn't exist, required for enabling Developer Mode
|
||||
$registryKeyPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock"
|
||||
if (-not(Test-Path -Path $registryKeyPath)) {
|
||||
New-Item -Path $registryKeyPath -ItemType Directory -Force
|
||||
}
|
||||
|
||||
# Add registry value to enable Developer Mode
|
||||
New-ItemProperty -Path $registryKeyPath -Name AllowDevelopmentWithoutDevLicense -PropertyType DWORD -Value 1
|
||||
@@ -0,0 +1,21 @@
|
||||
################################################################################
|
||||
## File: Configure-Diagnostics.ps1
|
||||
## Desc: Disables Just-In-Time Debugger and Windows Error Reporting
|
||||
################################################################################
|
||||
|
||||
Write-Host "Disable Just-In-Time Debugger"
|
||||
|
||||
# Turn off Application Error Debugger
|
||||
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug" -Name Debugger -Value "-" -Type String -Force
|
||||
New-ItemProperty -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug" -Name Debugger -Value "-" -Type String -Force
|
||||
|
||||
# Turn off the Debug dialog
|
||||
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\.NETFramework" -Name DbgManagedDebugger -Value "-" -Type String -Force
|
||||
New-ItemProperty -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\.NETFramework" -Name DbgManagedDebugger -Value "-" -Type String -Force
|
||||
|
||||
# Disable the WER UI
|
||||
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting" -Name DontShowUI -Value 1 -Type DWORD -Force
|
||||
# Send all reports to the user's queue
|
||||
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting" -Name ForceQueue -Value 1 -Type DWORD -Force
|
||||
# Default consent choice 1 - Always ask (default)
|
||||
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\Consent" -Name DefaultConsent -Value 1 -Type DWORD -Force
|
||||
@@ -0,0 +1,16 @@
|
||||
################################################################################
|
||||
## File: Configure-DotnetSecureChannel.ps1
|
||||
## Desc: Configure .NET to use TLS 1.2
|
||||
################################################################################
|
||||
|
||||
$registryPath = "HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319"
|
||||
$name = "SchUseStrongCrypto"
|
||||
$value = "1"
|
||||
if (Test-Path $registryPath) {
|
||||
Set-ItemProperty -Path $registryPath -Name $name -Value $value -Type DWORD
|
||||
}
|
||||
|
||||
$registryPath = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319"
|
||||
if (Test-Path $registryPath) {
|
||||
Set-ItemProperty -Path $registryPath -Name $name -Value $value -Type DWORD
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
################################################################################
|
||||
## File: Configure-DynamicPort.ps1
|
||||
## Desc: Configure dynamic port range for TCP and UDP to start at port 49152
|
||||
## and to end at the 65536 (16384 ports)
|
||||
################################################################################
|
||||
|
||||
# https://support.microsoft.com/en-us/help/929851/the-default-dynamic-port-range-for-tcp-ip-has-changed-in-windows-vista
|
||||
# The new default start port is 49152, and the new default end port is 65535.
|
||||
# Default port configuration was changed during image generation by Visual Studio Enterprise Installer to:
|
||||
# Protocol tcp Dynamic Port Range
|
||||
# ---------------------------------
|
||||
# Start Port : 1024
|
||||
# Number of Ports : 64511
|
||||
|
||||
Write-Host "Set the dynamic port range to start at port 49152 and to end at the 65536 (16384 ports)"
|
||||
foreach ($ipVersion in @("ipv4", "ipv6")) {
|
||||
foreach ($protocol in @("tcp", "udp")) {
|
||||
$command = "netsh int $ipVersion set dynamicport $protocol start=49152 num=16384"
|
||||
Invoke-Expression $command | Out-Null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "Failed to set dynamic port range for $ipVersion $protocol"
|
||||
exit $LASTEXITCODE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Invoke-PesterTests -TestFile "WindowsFeatures" -TestName "DynamicPorts"
|
||||
@@ -0,0 +1,14 @@
|
||||
################################################################################
|
||||
## File: Configure-GDIProcessHandleQuota.ps1
|
||||
## Desc: Set the GDIProcessHandleQuota value to 20000
|
||||
################################################################################
|
||||
|
||||
# https://docs.microsoft.com/en-us/windows/win32/sysinfo/gdi-objects
|
||||
# This value can be set to a number between 256 and 65,536
|
||||
|
||||
$defaultValue = 20000
|
||||
Write-Host "Set the GDIProcessHandleQuota value to $defaultValue"
|
||||
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows" -Name GDIProcessHandleQuota -Value $defaultValue
|
||||
Set-ItemProperty -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\Windows" -Name GDIProcessHandleQuota -Value $defaultValue
|
||||
|
||||
Invoke-PesterTests -TestFile "WindowsFeatures" -TestName "GDIProcessHandleQuota"
|
||||
@@ -0,0 +1,50 @@
|
||||
################################################################################
|
||||
## File: Configure-ImageDataFile.ps1
|
||||
## Desc: Creates a JSON file with information about the image
|
||||
################################################################################
|
||||
|
||||
$os = Get-CimInstance -ClassName Win32_OperatingSystem
|
||||
$caption = $os.Caption
|
||||
$osName = $caption.Substring(0, $caption.LastIndexOf(" "))
|
||||
$osEdition = $caption.Substring($caption.LastIndexOf(" ") + 1)
|
||||
$osVersion = $os.Version
|
||||
$imageVersion = $env:IMAGE_VERSION
|
||||
$imageVersionComponents = $imageVersion.Split('.')
|
||||
$imageMajorVersion = $imageVersionComponents[0]
|
||||
$imageMinorVersion = $imageVersionComponents[1]
|
||||
$imageDataFile = $env:IMAGEDATA_FILE
|
||||
$githubUrl = "https://github.com/actions/runner-images/blob"
|
||||
|
||||
if (Test-IsWin25) {
|
||||
$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) {
|
||||
$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-IsWin19) {
|
||||
$imageLabel = "windows-2019"
|
||||
$softwareUrl = "${githubUrl}/win19/$imageMajorVersion.$imageMinorVersion/images/windows/Windows2019-Readme.md"
|
||||
$releaseUrl = "https://github.com/actions/runner-images/releases/tag/win19%2F$imageMajorVersion.$imageMinorVersion"
|
||||
|
||||
} else {
|
||||
throw "Invalid platform version is found. Either Windows Server 2019 or 2022 are required"
|
||||
}
|
||||
|
||||
$json = @"
|
||||
[
|
||||
{
|
||||
"group": "Operating System",
|
||||
"detail": "${osName}\n${osVersion}\n${osEdition}"
|
||||
},
|
||||
{
|
||||
"group": "Runner Image",
|
||||
"detail": "Image: ${imageLabel}\nVersion: ${imageVersion}\nIncluded Software: ${softwareUrl}\nImage Release: ${releaseUrl}"
|
||||
}
|
||||
]
|
||||
"@
|
||||
|
||||
$json | Out-File -FilePath $imageDataFile
|
||||
@@ -0,0 +1,38 @@
|
||||
################################################################################
|
||||
## File: Configure-Powershell.ps1
|
||||
## Desc: Manage PowerShell configuration
|
||||
################################################################################
|
||||
|
||||
#region System
|
||||
Write-Host "Setup PowerShellGet"
|
||||
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
|
||||
|
||||
# Specifies the installation policy
|
||||
Set-PSRepository -InstallationPolicy Trusted -Name PSGallery
|
||||
|
||||
Write-Host 'Warmup PSModuleAnalysisCachePath (speedup first powershell invocation by 20s)'
|
||||
$PSModuleAnalysisCachePath = 'C:\PSModuleAnalysisCachePath\ModuleAnalysisCache'
|
||||
|
||||
[Environment]::SetEnvironmentVariable('PSModuleAnalysisCachePath', $PSModuleAnalysisCachePath, "Machine")
|
||||
# make variable to be available in the current session
|
||||
${env:PSModuleAnalysisCachePath} = $PSModuleAnalysisCachePath
|
||||
|
||||
New-Item -Path $PSModuleAnalysisCachePath -ItemType 'File' -Force | Out-Null
|
||||
#endregion
|
||||
|
||||
#region User (current user, image generation only)
|
||||
if (-not (Test-Path $profile)) {
|
||||
New-Item $profile -ItemType File -Force
|
||||
}
|
||||
|
||||
@"
|
||||
if ( -not(Get-Module -ListAvailable -Name PowerHTML)) {
|
||||
Install-Module PowerHTML -Scope CurrentUser
|
||||
}
|
||||
|
||||
if ( -not(Get-Module -Name PowerHTML)) {
|
||||
Import-Module PowerHTML
|
||||
}
|
||||
"@ | Add-Content -Path $profile -Force
|
||||
|
||||
#endregion
|
||||
@@ -0,0 +1,19 @@
|
||||
# Create shells folder
|
||||
$shellPath = "C:\shells"
|
||||
New-Item -Path $shellPath -ItemType Directory | Out-Null
|
||||
|
||||
# add a wrapper for C:\msys64\usr\bin\bash.exe
|
||||
@'
|
||||
@echo off
|
||||
setlocal
|
||||
IF NOT DEFINED MSYS2_PATH_TYPE set MSYS2_PATH_TYPE=strict
|
||||
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
|
||||
|
||||
# wslbash <--> C:\Windows\System32\bash.exe
|
||||
New-Item -ItemType SymbolicLink -Path "$shellPath\wslbash.exe" -Target "$env:SystemRoot\System32\bash.exe" | Out-Null
|
||||
@@ -0,0 +1,196 @@
|
||||
################################################################################
|
||||
## File: Configure-System.ps1
|
||||
## Desc: Applies various configuration settings to the final image
|
||||
################################################################################
|
||||
|
||||
Write-Host "Cleanup WinSxS"
|
||||
dism.exe /online /Cleanup-Image /StartComponentCleanup /ResetBase
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Failed to cleanup WinSxS"
|
||||
}
|
||||
|
||||
# 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) {
|
||||
Write-Host "Setting WSL default version to 1"
|
||||
|
||||
Mount-RegistryHive `
|
||||
-FileName "C:\Users\Default\NTUSER.DAT" `
|
||||
-SubKey "HKLM\DEFAULT"
|
||||
|
||||
# Create the key if it doesn't exist
|
||||
$keyPath = "DEFAULT\Software\Microsoft\Windows\CurrentVersion\Lxss"
|
||||
if (-not (Test-Path $keyPath)) {
|
||||
Write-Host "Creating $keyPath key"
|
||||
New-Item -Path (Join-Path "HKLM:\" $keyPath) -Force | Out-Null
|
||||
}
|
||||
|
||||
# Set the DefaultVersion value to 1
|
||||
$key = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey($keyPath, $true)
|
||||
$key.SetValue("DefaultVersion", "1", "DWord")
|
||||
$key.Handle.Close()
|
||||
[System.GC]::Collect()
|
||||
|
||||
Dismount-RegistryHive "HKLM\DEFAULT"
|
||||
}
|
||||
|
||||
Write-Host "Clean up various directories"
|
||||
@(
|
||||
"$env:SystemDrive\Recovery",
|
||||
"$env:SystemRoot\logs",
|
||||
"$env:SystemRoot\winsxs\manifestcache",
|
||||
"$env:SystemRoot\Temp",
|
||||
"$env:SystemDrive\Users\$env:INSTALL_USER\AppData\Local\Temp",
|
||||
"$env:TEMP",
|
||||
"$env:AZURE_CONFIG_DIR\logs",
|
||||
"$env:AZURE_CONFIG_DIR\commands",
|
||||
"$env:AZURE_CONFIG_DIR\telemetry"
|
||||
) | ForEach-Object {
|
||||
if (Test-Path $_) {
|
||||
Write-Host "Removing $_"
|
||||
cmd /c "takeown /d Y /R /f $_ 2>&1" | Out-Null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Failed to take ownership of $_"
|
||||
}
|
||||
cmd /c "icacls $_ /grant:r administrators:f /t /c /q 2>&1" | Out-Null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Failed to grant administrators full control of $_"
|
||||
}
|
||||
Remove-Item $_ -Recurse -Force -ErrorAction SilentlyContinue | Out-Null
|
||||
}
|
||||
}
|
||||
|
||||
$winInstallDir = "$env:SystemRoot\Installer"
|
||||
New-Item -Path $winInstallDir -ItemType Directory -Force | Out-Null
|
||||
|
||||
# Remove AllUsersAllHosts profile
|
||||
Remove-Item $profile.AllUsersAllHosts -Force -ErrorAction SilentlyContinue | Out-Null
|
||||
|
||||
# Clean yarn and npm cache
|
||||
cmd /c "yarn cache clean 2>&1" | Out-Null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Failed to clean yarn cache"
|
||||
}
|
||||
|
||||
cmd /c "npm cache clean --force 2>&1" | Out-Null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Failed to clean npm cache"
|
||||
}
|
||||
|
||||
# allow msi to write to temp folder
|
||||
# see https://github.com/actions/runner-images/issues/1704
|
||||
cmd /c "icacls $env:SystemRoot\Temp /grant Users:f /t /c /q 2>&1" | Out-Null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Failed to grant Users full control of $env:SystemRoot\Temp"
|
||||
}
|
||||
|
||||
# Registry settings
|
||||
$registrySettings = @(
|
||||
@{Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU"; Name = "AUOptions"; Value = 1; PropertyType = "DWORD" }
|
||||
@{Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU"; Name = "NoAutoUpdate"; Value = 1; PropertyType = "DWORD" }
|
||||
@{Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"; Name = "DoNotConnectToWindowsUpdateInternetLocations"; Value = 1; PropertyType = "DWORD" }
|
||||
@{Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"; Name = "DisableWindowsUpdateAccess"; Value = 1; PropertyType = "DWORD" }
|
||||
@{Path = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Device Metadata"; Name = "PreventDeviceMetadataFromNetwork"; Value = 1; PropertyType = "DWORD" }
|
||||
@{Path = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\DataCollection"; Name = "AllowTelemetry"; Value = 0; PropertyType = "DWORD" }
|
||||
@{Path = "HKLM:\SOFTWARE\Policies\Microsoft\SQMClient\Windows"; Name = "CEIPEnable"; Value = 0; PropertyType = "DWORD" }
|
||||
@{Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppCompat"; Name = "AITEnable"; Value = 0; PropertyType = "DWORD" }
|
||||
@{Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppCompat"; Name = "DisableUAR"; Value = 1; PropertyType = "DWORD" }
|
||||
@{Path = "HKLM:\Software\Policies\Microsoft\Windows\DataCollection"; Name = "AllowTelemetry"; Value = 0; PropertyType = "DWORD" }
|
||||
@{Path = "HKLM:\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\DataCollection"; Name = "AllowTelemetry"; Value = 0; PropertyType = "DWORD" }
|
||||
@{Path = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\Maintenance"; Name = "MaintenanceDisabled"; Value = 1; PropertyType = "DWORD" }
|
||||
@{Path = "HKLM:\SOFTWARE\Policies\Microsoft\MRT"; Name = "DontOfferThroughWUAU"; Value = 1; PropertyType = "DWORD" }
|
||||
@{Path = "HKLM:\SOFTWARE\Policies\Microsoft\MRT"; Name = "DontReportInfectionInformation"; Value = 1; PropertyType = "DWORD" }
|
||||
@{Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search"; Name = "AllowCortana"; Value = 0; PropertyType = "DWORD" }
|
||||
@{Path = "HKLM:\SYSTEM\CurrentControlSet\Control"; Name = "ServicesPipeTimeout"; Value = 120000; PropertyType = "DWORD" }
|
||||
@{Path = "HKLM:\SYSTEM\CurrentControlSet\Control\WMI\AutoLogger\AutoLogger-Diagtrack-Listener"; Name = "Start"; Value = 0; PropertyType = "DWORD" }
|
||||
@{Path = "HKLM:\SYSTEM\CurrentControlSet\Control\WMI\AutoLogger\SQMLogger"; Name = "Start"; Value = 0; PropertyType = "DWORD" }
|
||||
)
|
||||
|
||||
$registrySettings | ForEach-Object {
|
||||
$regPath = $_.Path
|
||||
if (-not (Test-Path $regPath)) {
|
||||
New-Item -Path $regPath -Force -ErrorAction Ignore | Out-Null
|
||||
}
|
||||
New-ItemProperty @_ -Force -ErrorAction Ignore
|
||||
} | Out-Null
|
||||
|
||||
# Disable Template Services / User Services added by Desktop Experience
|
||||
$regUserServicesToDisables = @(
|
||||
"HKLM:\SYSTEM\CurrentControlSet\Services\CDPUserSvc"
|
||||
"HKLM:\SYSTEM\CurrentControlSet\Services\OneSyncSvc"
|
||||
"HKLM:\SYSTEM\CurrentControlSet\Services\PimIndexMaintenanceSvc"
|
||||
"HKLM:\SYSTEM\CurrentControlSet\Services\UnistoreSvc"
|
||||
"HKLM:\SYSTEM\CurrentControlSet\Services\UserDataSvc"
|
||||
)
|
||||
|
||||
$regUserServicesToDisables | ForEach-Object {
|
||||
$regPath = $_
|
||||
if (-not (Test-Path $regPath)) {
|
||||
New-Item -Path $regPath -Force -ErrorAction Ignore | Out-Null
|
||||
}
|
||||
New-ItemProperty -Path $regPath -Name "Start" -Value 4 -PropertyType DWORD -Force -ErrorAction Ignore
|
||||
New-ItemProperty -Path $regPath -Name "UserServiceFlags" -Value 0 -PropertyType DWORD -Force -ErrorAction Ignore
|
||||
} | Out-Null
|
||||
|
||||
|
||||
Write-Host 'Disable Windows Update Service'
|
||||
Set-ItemProperty -Path HKLM:\System\CurrentControlSet\Services\wuauserv -Name Start -Value 4 -Force
|
||||
|
||||
# Disabled services
|
||||
$servicesToDisable = @(
|
||||
'wuauserv'
|
||||
'DiagTrack'
|
||||
'dmwappushservice'
|
||||
'PcaSvc'
|
||||
'SysMain'
|
||||
'gupdate'
|
||||
'gupdatem'
|
||||
'StorSvc'
|
||||
) | Get-Service -ErrorAction SilentlyContinue
|
||||
Stop-Service $servicesToDisable
|
||||
$servicesToDisable.WaitForStatus('Stopped', "00:01:00")
|
||||
$servicesToDisable | Set-Service -StartupType Disabled
|
||||
|
||||
# Disable scheduled tasks
|
||||
$allTasksInTaskPath = @(
|
||||
"\"
|
||||
"\Microsoft\Azure\Security\"
|
||||
"\Microsoft\VisualStudio\"
|
||||
"\Microsoft\VisualStudio\Updates\"
|
||||
"\Microsoft\Windows\Application Experience\"
|
||||
"\Microsoft\Windows\ApplicationData\"
|
||||
"\Microsoft\Windows\Autochk\"
|
||||
"\Microsoft\Windows\Chkdsk\"
|
||||
"\Microsoft\Windows\Customer Experience Improvement Program\"
|
||||
"\Microsoft\Windows\Data Integrity Scan\"
|
||||
"\Microsoft\Windows\Defrag\"
|
||||
"\Microsoft\Windows\Diagnosis\"
|
||||
"\Microsoft\Windows\DiskCleanup\"
|
||||
"\Microsoft\Windows\DiskDiagnostic\"
|
||||
"\Microsoft\Windows\Maintenance\"
|
||||
"\Microsoft\Windows\PI\"
|
||||
"\Microsoft\Windows\Power Efficiency Diagnostics\"
|
||||
"\Microsoft\Windows\Server Manager\"
|
||||
"\Microsoft\Windows\Speech\"
|
||||
"\Microsoft\Windows\UpdateOrchestrator\"
|
||||
"\Microsoft\Windows\Windows Error Reporting\"
|
||||
"\Microsoft\Windows\WindowsUpdate\"
|
||||
"\Microsoft\XblGameSave\"
|
||||
)
|
||||
|
||||
$allTasksInTaskPath | ForEach-Object {
|
||||
Get-ScheduledTask -TaskPath $_ -ErrorAction Ignore | Disable-ScheduledTask -ErrorAction Ignore
|
||||
} | Out-Null
|
||||
|
||||
$disableTaskNames = @(
|
||||
@{TaskPath = "\Microsoft\Windows\.NET Framework\"; TaskName = ".NET Framework NGEN v4.0.30319" }
|
||||
@{TaskPath = "\Microsoft\Windows\.NET Framework\"; TaskName = ".NET Framework NGEN v4.0.30319 64" }
|
||||
@{TaskPath = "\Microsoft\Windows\AppID\"; TaskName = "SmartScreenSpecific" }
|
||||
)
|
||||
|
||||
$disableTaskNames | ForEach-Object {
|
||||
Disable-ScheduledTask @PSItem -ErrorAction Ignore
|
||||
} | Out-Null
|
||||
|
||||
Write-Host "Configure-System.ps1 - completed"
|
||||
@@ -0,0 +1,15 @@
|
||||
################################################################################
|
||||
## File: Configure-SystemEnvironment.ps1
|
||||
## Desc: Configures system environment variables
|
||||
################################################################################
|
||||
|
||||
$variables = @{
|
||||
"ImageVersion" = $env:IMAGE_VERSION
|
||||
"ImageOS" = $env:IMAGE_OS
|
||||
"AGENT_TOOLSDIRECTORY" = $env:AGENT_TOOLSDIRECTORY
|
||||
"RUNNER_TOOL_CACHE" = $env:AGENT_TOOLSDIRECTORY
|
||||
}
|
||||
|
||||
$variables.GetEnumerator() | ForEach-Object {
|
||||
[Environment]::SetEnvironmentVariable($_.Key, $_.Value, "Machine")
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
################################################################################
|
||||
## File: Configure-Toolset.ps1
|
||||
## Team: CI-Build
|
||||
## Desc: Configure Toolset
|
||||
################################################################################
|
||||
|
||||
$toolEnvConfigs = @{
|
||||
Python = @{
|
||||
pathTemplates = @(
|
||||
"{0}"
|
||||
"{0}\Scripts"
|
||||
)
|
||||
}
|
||||
go = @{
|
||||
pathTemplates = @(
|
||||
"{0}\bin"
|
||||
)
|
||||
envVarTemplate = "GOROOT_{0}_{1}_X64"
|
||||
}
|
||||
}
|
||||
|
||||
$tools = Get-ToolsetContent `
|
||||
| Select-Object -ExpandProperty toolcache `
|
||||
| Where-Object { $toolEnvConfigs.Keys -contains $_.name }
|
||||
|
||||
Write-Host "Configure toolset tools environment..."
|
||||
foreach ($tool in $tools) {
|
||||
$toolEnvConfig = $toolEnvConfigs[$tool.name]
|
||||
|
||||
if (-not ([string]::IsNullOrEmpty($toolEnvConfig.envVarTemplate))) {
|
||||
foreach ($version in $tool.versions) {
|
||||
Write-Host "Set $($tool.name) $version environment variable..."
|
||||
|
||||
$foundVersionArchPath = Get-TCToolVersionPath -Name $tool.name -Version $version -Arch $tool.arch
|
||||
$envName = $toolEnvConfig.envVarTemplate -f $version.Split(".")
|
||||
|
||||
Write-Host "Set $envName to $foundVersionArchPath"
|
||||
[Environment]::SetEnvironmentVariable($envName, $foundVersionArchPath, "Machine")
|
||||
}
|
||||
}
|
||||
|
||||
if (-not ([string]::IsNullOrEmpty($tool.default))) {
|
||||
Write-Host "Use $($tool.name) $($tool.default) as a system $($tool.name)..."
|
||||
|
||||
$toolVersionPath = Get-TCToolVersionPath -Name $tool.name -Version $tool.default -Arch $tool.arch
|
||||
|
||||
foreach ($template in $toolEnvConfig.pathTemplates) {
|
||||
$toolSystemPath = $template -f $toolVersionPath
|
||||
Write-Host "Add $toolSystemPath to system PATH..."
|
||||
Add-MachinePathItem -PathItem $toolSystemPath | Out-Null
|
||||
}
|
||||
|
||||
if (-not ([string]::IsNullOrEmpty($tool.defaultVariable))) {
|
||||
Write-Host "Set $($tool.name) $($tool.default) $($tool.defaultVariable) environment variable..."
|
||||
[Environment]::SetEnvironmentVariable($tool.defaultVariable, $toolVersionPath, "Machine")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Invoke-PesterTests -TestFile "Toolset"
|
||||
@@ -0,0 +1,47 @@
|
||||
################################################################################
|
||||
## File: Configure-User.ps1
|
||||
## Desc: Performs user part of warm up and moves data to C:\Users\Default
|
||||
################################################################################
|
||||
|
||||
#
|
||||
# more: https://github.com/actions/runner-images-internal/issues/5320
|
||||
# https://github.com/actions/runner-images/issues/5301#issuecomment-1648292990
|
||||
#
|
||||
|
||||
Write-Host "Warmup 'devenv.exe /updateconfiguration'"
|
||||
$vsInstallRoot = (Get-VisualStudioInstance).InstallationPath
|
||||
cmd.exe /c "`"$vsInstallRoot\Common7\IDE\devenv.exe`" /updateconfiguration"
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Failed to warmup 'devenv.exe /updateconfiguration'"
|
||||
}
|
||||
|
||||
# we are fine if some file is locked and cannot be copied
|
||||
Copy-Item ${env:USERPROFILE}\AppData\Local\Microsoft\VisualStudio -Destination c:\users\default\AppData\Local\Microsoft\VisualStudio -Recurse -ErrorAction SilentlyContinue
|
||||
|
||||
Mount-RegistryHive `
|
||||
-FileName "C:\Users\Default\NTUSER.DAT" `
|
||||
-SubKey "HKLM\DEFAULT"
|
||||
|
||||
reg.exe copy HKCU\Software\Microsoft\VisualStudio HKLM\DEFAULT\Software\Microsoft\VisualStudio /s
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Failed to copy HKCU\Software\Microsoft\VisualStudio to HKLM\DEFAULT\Software\Microsoft\VisualStudio"
|
||||
}
|
||||
|
||||
if (-not (Test-IsWin25)) {
|
||||
# disable TSVNCache.exe
|
||||
$registryKeyPath = 'HKCU:\Software\TortoiseSVN'
|
||||
if (-not(Test-Path -Path $registryKeyPath)) {
|
||||
New-Item -Path $registryKeyPath -ItemType Directory -Force
|
||||
}
|
||||
|
||||
|
||||
New-ItemProperty -Path $registryKeyPath -Name CacheType -PropertyType DWORD -Value 0
|
||||
reg.exe copy HKCU\Software\TortoiseSVN HKLM\DEFAULT\Software\TortoiseSVN /s
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Failed to copy HKCU\Software\TortoiseSVN to HKLM\DEFAULT\Software\TortoiseSVN"
|
||||
}
|
||||
}
|
||||
|
||||
Dismount-RegistryHive "HKLM\DEFAULT"
|
||||
|
||||
Write-Host "Configure-User.ps1 - completed"
|
||||
@@ -0,0 +1,44 @@
|
||||
################################################################################
|
||||
## File: Configure-WindowsDefender.ps1
|
||||
## Desc: Disables Windows Defender
|
||||
################################################################################
|
||||
|
||||
Write-Host "Disable Windows Defender..."
|
||||
$avPreference = @(
|
||||
@{DisableArchiveScanning = $true}
|
||||
@{DisableAutoExclusions = $true}
|
||||
@{DisableBehaviorMonitoring = $true}
|
||||
@{DisableBlockAtFirstSeen = $true}
|
||||
@{DisableCatchupFullScan = $true}
|
||||
@{DisableCatchupQuickScan = $true}
|
||||
@{DisableIntrusionPreventionSystem = $true}
|
||||
@{DisableIOAVProtection = $true}
|
||||
@{DisablePrivacyMode = $true}
|
||||
@{DisableScanningNetworkFiles = $true}
|
||||
@{DisableScriptScanning = $true}
|
||||
@{MAPSReporting = 0}
|
||||
@{PUAProtection = 0}
|
||||
@{SignatureDisableUpdateOnStartupWithoutEngine = $true}
|
||||
@{SubmitSamplesConsent = 2}
|
||||
@{ScanAvgCPULoadFactor = 5; ExclusionPath = @("D:\", "C:\")}
|
||||
@{DisableRealtimeMonitoring = $true}
|
||||
@{ScanScheduleDay = 8}
|
||||
)
|
||||
|
||||
$avPreference += @(
|
||||
@{EnableControlledFolderAccess = "Disable"}
|
||||
@{EnableNetworkProtection = "Disabled"}
|
||||
)
|
||||
|
||||
$avPreference | Foreach-Object {
|
||||
$avParams = $_
|
||||
Set-MpPreference @avParams
|
||||
}
|
||||
|
||||
# https://github.com/actions/runner-images/issues/4277
|
||||
# https://docs.microsoft.com/en-us/microsoft-365/security/defender-endpoint/microsoft-defender-antivirus-compatibility?view=o365-worldwide
|
||||
$atpRegPath = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows Advanced Threat Protection'
|
||||
if (Test-Path $atpRegPath) {
|
||||
Write-Host "Set Microsoft Defender Antivirus to passive mode"
|
||||
Set-ItemProperty -Path $atpRegPath -Name 'ForceDefenderPassiveMode' -Value '1' -Type 'DWORD'
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
################################################################################
|
||||
## File: Install-AWSTools.ps1
|
||||
## Desc: Install AWS tools: CLI, Session Manager Plugin, AWS SAM CLI
|
||||
## Supply chain security: AWS CLI - managed by package manager, Session Manager Plugin for the AWS CLI - missing, AWS SAM CLI - checksum validation
|
||||
################################################################################
|
||||
|
||||
# Install AWS CLI
|
||||
Install-ChocoPackage awscli
|
||||
|
||||
# Install Session Manager Plugin for the AWS CLI
|
||||
Install-Binary `
|
||||
-Url "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/windows/SessionManagerPluginSetup.exe" `
|
||||
-InstallArgs ("/silent", "/install") `
|
||||
-ExpectedSignature "75A5FB4D02FCB2AB799718F315BAAA3103E9D60C"
|
||||
$env:Path = $env:Path + ";$env:ProgramFiles\Amazon\SessionManagerPlugin\bin"
|
||||
|
||||
# Install AWS SAM CLI
|
||||
$downloadUrl = Resolve-GithubReleaseAssetUrl `
|
||||
-Repo "awslabs/aws-sam-cli" `
|
||||
-Version "latest" `
|
||||
-UrlMatchPattern "AWS_SAM_CLI_64_PY3.msi"
|
||||
$externalHash = Get-ChecksumFromGithubRelease `
|
||||
-Repo "awslabs/aws-sam-cli" `
|
||||
-Version "latest" `
|
||||
-FileName (Split-Path $downloadUrl -Leaf) `
|
||||
-HashType "SHA256"
|
||||
|
||||
Install-Binary `
|
||||
-Url $downloadUrl `
|
||||
-ExpectedSHA256Sum $externalHash
|
||||
|
||||
Invoke-PesterTests -TestFile "CLI.Tools" -TestName "AWS"
|
||||
@@ -0,0 +1,27 @@
|
||||
################################################################################
|
||||
## File: Install-ActionsCache.ps1
|
||||
## Desc: Downloads latest release from https://github.com/actions/action-versions
|
||||
## Maintainer: #actions-runtime and @TingluoHuang
|
||||
################################################################################
|
||||
|
||||
$actionArchiveCache = "C:\actionarchivecache\"
|
||||
|
||||
if (-not (Test-Path $actionArchiveCache)) {
|
||||
Write-Host "Creating action archive cache folder"
|
||||
New-Item -ItemType Directory -Path $actionArchiveCache | Out-Null
|
||||
}
|
||||
|
||||
$downloadUrl = Resolve-GithubReleaseAssetUrl `
|
||||
-Repo "actions/action-versions" `
|
||||
-Version "latest" `
|
||||
-Asset "action-versions.zip"
|
||||
|
||||
Write-Host "Download Latest action-versions archive from $downloadUrl"
|
||||
$actionVersionsArchivePath = Invoke-DownloadWithRetry $downloadUrl
|
||||
|
||||
Write-Host "Expand action-versions archive"
|
||||
Expand-7ZipArchive -Path $actionVersionsArchivePath -DestinationPath $actionArchiveCache
|
||||
|
||||
[Environment]::SetEnvironmentVariable("ACTIONS_RUNNER_ACTION_ARCHIVE_CACHE", $actionArchiveCache, "Machine")
|
||||
|
||||
Invoke-PesterTests -TestFile "ActionArchiveCache"
|
||||
@@ -0,0 +1,30 @@
|
||||
################################################################################
|
||||
## File: Install-AliyunCli.ps1
|
||||
## Desc: Install Alibaba Cloud CLI
|
||||
## Supply chain security: Alibaba Cloud CLI - checksum validation
|
||||
################################################################################
|
||||
|
||||
Write-Host "Download Latest aliyun-cli archive"
|
||||
$downloadUrl = Resolve-GithubReleaseAssetUrl `
|
||||
-Repo "aliyun/aliyun-cli" `
|
||||
-Version "latest" `
|
||||
-UrlMatchPattern "aliyun-cli-windows-*-amd64.zip"
|
||||
$packagePath = Invoke-DownloadWithRetry $downloadUrl
|
||||
|
||||
#region Supply chain security - Alibaba Cloud CLI
|
||||
$packageName = Split-Path $downloadUrl -Leaf
|
||||
$externalHash = Get-ChecksumFromUrl -Type "SHA256" `
|
||||
-Url ($downloadUrl -replace $packageName, "SHASUMS256.txt") `
|
||||
-FileName $packageName
|
||||
Test-FileChecksum $packagePath -ExpectedSHA256Sum $externalHash
|
||||
#endregion
|
||||
|
||||
Write-Host "Expand aliyun-cli archive"
|
||||
$aliyunPath = "C:\aliyun-cli"
|
||||
New-Item -Path $aliyunPath -ItemType Directory -Force
|
||||
Expand-7ZipArchive -Path $packagePath -DestinationPath $aliyunPath
|
||||
|
||||
# Add aliyun-cli to path
|
||||
Add-MachinePathItem $aliyunPath
|
||||
|
||||
Invoke-PesterTests -TestFile "CLI.Tools" -TestName "Aliyun CLI"
|
||||
@@ -0,0 +1,166 @@
|
||||
################################################################################
|
||||
## File: Install-AndroidSDK.ps1
|
||||
## Desc: Install and update Android SDK and tools
|
||||
## Supply chain security: checksum validation
|
||||
################################################################################
|
||||
|
||||
# Actual Android SDK installation directory
|
||||
$SDKInstallRoot = "C:\Program Files (x86)\Android\android-sdk"
|
||||
|
||||
# Hardlink to the Android SDK installation directory with no spaces in the path.
|
||||
# ANDROID_NDK* env vars should not contain spaces, otherwise ndk-build.cmd gives an error
|
||||
# https://github.com/actions/runner-images/issues/1122
|
||||
$SDKRootPath = "C:\Android\android-sdk"
|
||||
|
||||
#region functions
|
||||
function Install-AndroidSDKPackages {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
This function installs the specified Android SDK packages.
|
||||
|
||||
.DESCRIPTION
|
||||
The Install-AndroidSDKPackages function takes an array of package names as a parameter and installs each of them using the sdkmanager.bat script.
|
||||
|
||||
.PARAMETER Packages
|
||||
An array of package names in the format of SDK-style paths to be installed.
|
||||
|
||||
.EXAMPLE
|
||||
Install-AndroidSDKPackages -Packages "platforms;android-29", "build-tools;29.0.2"
|
||||
|
||||
This command installs the Android SDK Platform 29 and Build-Tools 29.0.2.
|
||||
|
||||
#>
|
||||
Param
|
||||
(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[AllowEmptyCollection()]
|
||||
[AllowNull()]
|
||||
[string[]] $Packages
|
||||
)
|
||||
|
||||
# The sdkmanager.bat script is used to install Android SDK packages.
|
||||
$SDKManager = "$SDKRootPath\cmdline-tools\latest\bin\sdkmanager.bat"
|
||||
|
||||
$errors = @()
|
||||
|
||||
foreach ($package in $Packages) {
|
||||
& $SDKManager --install "$package" --sdk_root=$SDKRootPath
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
$errors += "Failed to install package $package with exit code $LASTEXITCODE"
|
||||
}
|
||||
}
|
||||
|
||||
if ($errors.Count -gt 0) {
|
||||
throw $errors
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
# get packages to install from the toolset
|
||||
$androidToolset = (Get-ToolsetContent).android
|
||||
# Newer version(s) require Java 11 by default
|
||||
# See https://github.com/actions/runner-images/issues/6960
|
||||
$cmdlineToolsUrl = $androidToolset.commandline_tools_url
|
||||
$cmdlineToolsArchPath = Invoke-DownloadWithRetry $cmdlineToolsUrl
|
||||
|
||||
Test-FileChecksum $cmdlineToolsArchPath -ExpectedSHA256Sum $androidToolset.hash
|
||||
|
||||
Expand-7ZipArchive -Path $cmdlineToolsArchPath -DestinationPath "${SDKInstallRoot}\cmdline-tools"
|
||||
|
||||
# cmdline tools should be installed in ${SDKInstallRoot}\cmdline-tools\latest\bin, but archive contains ${SDKInstallRoot}\cmdline-tools\bin
|
||||
# we need to create the proper folder structure
|
||||
Invoke-ScriptBlockWithRetry -Command {
|
||||
Rename-Item "${SDKInstallRoot}\cmdline-tools\cmdline-tools" "latest" -ErrorAction Stop
|
||||
}
|
||||
|
||||
# Create hardlink at $SDKRootPath pointing to SDK installation directory in Program Files
|
||||
New-Item -Path (Split-Path $SDKRootPath -Parent) -ItemType Directory -Force
|
||||
New-Item -Path "$SDKRootPath" -ItemType SymbolicLink -Value "$SDKInstallRoot"
|
||||
|
||||
# Install the standard Android SDK licenses. Currently, there isn't a better way to do this,
|
||||
# so we are base64-encoded a zip of the licenses directory from another installation.
|
||||
# To create this base64 string, create a zip file that contains nothing but a 'licenses' folder,
|
||||
# which folder contains the accepted license files found in 'C:\Program Files (x86)\Android\android-sdk\licenses'.
|
||||
# Then, run this in PowerShell:
|
||||
# $LicensesZipFileName = 'C:\Program Files (x86)\Android\android-sdk\Licenses.zip'
|
||||
# $base64Content = [Convert]::ToBase64String([IO.File]::ReadAllBytes($LicensesZipFileName))
|
||||
# echo $base64Content
|
||||
# Another possible solution that works in powershell core:
|
||||
# Write-Ouptut "y" | $sdkmanager.bat <packagename>
|
||||
$licenseContentBase64 = "UEsDBBQAAAAAAKNK11IAAAAAAAAAAAAAAAAJAAAAbGljZW5zZXMvUEsDBAoAAAAAAJ1K11K7n0IrKgAAACoAAAAhAAAAbGljZW5zZXMvYW5kcm9pZC1nb29nbGV0di1saWNlbnNlDQo2MDEwODViOTRjZDc3ZjBiNTRmZjg2NDA2OTU3MDk5ZWJlNzljNGQ2UEsDBAoAAAAAAKBK11LzQumJKgAAACoAAAAkAAAAbGljZW5zZXMvYW5kcm9pZC1zZGstYXJtLWRidC1saWNlbnNlDQo4NTlmMzE3Njk2ZjY3ZWYzZDdmMzBhNTBhNTU2MGU3ODM0YjQzOTAzUEsDBAoAAAAAAKFK11IKSOJFKgAAACoAAAAcAAAAbGljZW5zZXMvYW5kcm9pZC1zZGstbGljZW5zZQ0KMjQzMzNmOGE2M2I2ODI1ZWE5YzU1MTRmODNjMjgyOWIwMDRkMWZlZVBLAwQKAAAAAACiStdSec1a4SoAAAAqAAAAJAAAAGxpY2Vuc2VzL2FuZHJvaWQtc2RrLXByZXZpZXctbGljZW5zZQ0KODQ4MzFiOTQwOTY0NmE5MThlMzA1NzNiYWI0YzljOTEzNDZkOGFiZFBLAwQKAAAAAACiStdSk6vQKCoAAAAqAAAAGwAAAGxpY2Vuc2VzL2dvb2dsZS1nZGstbGljZW5zZQ0KMzNiNmEyYjY0NjA3ZjExYjc1OWYzMjBlZjlkZmY0YWU1YzQ3ZDk3YVBLAwQKAAAAAACiStdSrE3jESoAAAAqAAAAJAAAAGxpY2Vuc2VzL2ludGVsLWFuZHJvaWQtZXh0cmEtbGljZW5zZQ0KZDk3NWY3NTE2OThhNzdiNjYyZjEyNTRkZGJlZWQzOTAxZTk3NmY1YVBLAwQKAAAAAACjStdSkb1vWioAAAAqAAAAJgAAAGxpY2Vuc2VzL21pcHMtYW5kcm9pZC1zeXNpbWFnZS1saWNlbnNlDQplOWFjYWI1YjVmYmI1NjBhNzJjZmFlY2NlODk0Njg5NmZmNmFhYjlkUEsBAj8AFAAAAAAAo0rXUgAAAAAAAAAAAAAAAAkAJAAAAAAAAAAQAAAAAAAAAGxpY2Vuc2VzLwoAIAAAAAAAAQAYACIHOBcRaNcBIgc4FxFo1wHBTVQTEWjXAVBLAQI/AAoAAAAAAJ1K11K7n0IrKgAAACoAAAAhACQAAAAAAAAAIAAAACcAAABsaWNlbnNlcy9hbmRyb2lkLWdvb2dsZXR2LWxpY2Vuc2UKACAAAAAAAAEAGACUEFUTEWjXAZQQVRMRaNcB6XRUExFo1wFQSwECPwAKAAAAAACgStdS80LpiSoAAAAqAAAAJAAkAAAAAAAAACAAAACQAAAAbGljZW5zZXMvYW5kcm9pZC1zZGstYXJtLWRidC1saWNlbnNlCgAgAAAAAAABABgAsEM0FBFo1wGwQzQUEWjXAXb1MxQRaNcBUEsBAj8ACgAAAAAAoUrXUgpI4kUqAAAAKgAAABwAJAAAAAAAAAAgAAAA/AAAAGxpY2Vuc2VzL2FuZHJvaWQtc2RrLWxpY2Vuc2UKACAAAAAAAAEAGAAsMGUVEWjXASwwZRURaNcB5whlFRFo1wFQSwECPwAKAAAAAACiStdSec1a4SoAAAAqAAAAJAAkAAAAAAAAACAAAABgAQAAbGljZW5zZXMvYW5kcm9pZC1zZGstcHJldmlldy1saWNlbnNlCgAgAAAAAAABABgA7s3WFRFo1wHuzdYVEWjXAfGm1hURaNcBUEsBAj8ACgAAAAAAokrXUpOr0CgqAAAAKgAAABsAJAAAAAAAAAAgAAAAzAEAAGxpY2Vuc2VzL2dvb2dsZS1nZGstbGljZW5zZQoAIAAAAAAAAQAYAGRDRxYRaNcBZENHFhFo1wFfHEcWEWjXAVBLAQI/AAoAAAAAAKJK11KsTeMRKgAAACoAAAAkACQAAAAAAAAAIAAAAC8CAABsaWNlbnNlcy9pbnRlbC1hbmRyb2lkLWV4dHJhLWxpY2Vuc2UKACAAAAAAAAEAGADGsq0WEWjXAcayrRYRaNcBxrKtFhFo1wFQSwECPwAKAAAAAACjStdSkb1vWioAAAAqAAAAJgAkAAAAAAAAACAAAACbAgAAbGljZW5zZXMvbWlwcy1hbmRyb2lkLXN5c2ltYWdlLWxpY2Vuc2UKACAAAAAAAAEAGAA4LjgXEWjXATguOBcRaNcBIgc4FxFo1wFQSwUGAAAAAAgACACDAwAACQMAAAAA"
|
||||
$licenseContent = [System.Convert]::FromBase64String($licenseContentBase64)
|
||||
Set-Content -Path "$SDKInstallRoot\android-sdk-licenses.zip" -Value $licenseContent -Encoding Byte
|
||||
Expand-7ZipArchive -Path "$SDKInstallRoot\android-sdk-licenses.zip" -DestinationPath $SDKInstallRoot
|
||||
|
||||
# Install platform-tools
|
||||
$platformToolsPath = Join-Path -Path $SDKInstallRoot -ChildPath "platform-tools"
|
||||
if (Test-Path $platformToolsPath) {
|
||||
Write-Host "Removing previous platform-tools installation from Visual Studio component"
|
||||
Remove-Item $platformToolsPath -Recurse -Force
|
||||
}
|
||||
Install-AndroidSDKPackages "platform-tools"
|
||||
|
||||
# Get Android SDK packages list
|
||||
$androidPackages = Get-AndroidPackages -SDKRootPath $SDKRootPath
|
||||
|
||||
# Install Android platform versions
|
||||
# that are greater than or equal to the minimum version
|
||||
Write-Host "Installing Android SDK packages for platforms..."
|
||||
$platformList = Get-AndroidPlatformPackages `
|
||||
-SDKRootPath $SDKRootPath `
|
||||
-minVersion $androidToolset.platform_min_version
|
||||
Install-AndroidSDKPackages $platformList
|
||||
|
||||
# Install Android build-tools versions
|
||||
# that are greater than or equal to the minimum version
|
||||
Write-Host "Installing Android SDK packages for build tools..."
|
||||
$buildToolsList = Get-AndroidBuildToolPackages `
|
||||
-SDKRootPath $SDKRootPath `
|
||||
-minVersion $androidToolset.build_tools_min_version
|
||||
Install-AndroidSDKPackages $buildToolsList
|
||||
|
||||
# Install Android Emulator
|
||||
Install-AndroidSDKPackages "emulator"
|
||||
|
||||
# Install extras, add-ons and additional tools
|
||||
Write-Host "Installing Android SDK extras, add-ons and additional tools..."
|
||||
Install-AndroidSDKPackages ($androidToolset.extras | ForEach-Object { "extras;$_" })
|
||||
Install-AndroidSDKPackages ($androidToolset.addons | ForEach-Object { "add-ons;$_" })
|
||||
Install-AndroidSDKPackages ($androidToolset.additional_tools)
|
||||
|
||||
# Install NDKs
|
||||
$ndkMajorVersions = $androidToolset.ndk.versions
|
||||
$ndkDefaultMajorVersion = $androidToolset.ndk.default
|
||||
$ndkLatestMajorVersion = $ndkMajorVersions | Select-Object -Last 1
|
||||
|
||||
$androidNDKs = @()
|
||||
foreach ($version in $ndkMajorVersions) {
|
||||
$packageNamePrefix = "ndk;$version"
|
||||
$package = $androidPackages | Where-Object { $_.StartsWith($packageNamePrefix) } | Sort-Object -Unique | Select-Object -Last 1
|
||||
$androidNDKs += $package
|
||||
}
|
||||
|
||||
Write-Host "Installing Android SDK packages for NDKs..."
|
||||
Install-AndroidSDKPackages $androidNDKs
|
||||
|
||||
$ndkLatestVersion = ($androidNDKs | Where-Object { $_ -match "ndk;$ndkLatestMajorVersion" }).Split(';')[1]
|
||||
$ndkDefaultVersion = ($androidNDKs | Where-Object { $_ -match "ndk;$ndkDefaultMajorVersion" }).Split(';')[1]
|
||||
$ndkRoot = "$SDKRootPath\ndk\$ndkDefaultVersion"
|
||||
|
||||
# Create env variables
|
||||
[Environment]::SetEnvironmentVariable("ANDROID_HOME", $SDKRootPath, "Machine")
|
||||
[Environment]::SetEnvironmentVariable("ANDROID_SDK_ROOT", $SDKRootPath, "Machine")
|
||||
# ANDROID_NDK, ANDROID_NDK_HOME, and ANDROID_NDK_ROOT variables should be set as many customer builds depend on them https://github.com/actions/runner-images/issues/5879
|
||||
[Environment]::SetEnvironmentVariable("ANDROID_NDK", $ndkRoot, "Machine")
|
||||
[Environment]::SetEnvironmentVariable("ANDROID_NDK_HOME", $ndkRoot, "Machine")
|
||||
[Environment]::SetEnvironmentVariable("ANDROID_NDK_ROOT", $ndkRoot, "Machine")
|
||||
|
||||
$ndkLatestPath = "$SDKRootPath\ndk\$ndkLatestVersion"
|
||||
if (Test-Path $ndkLatestPath) {
|
||||
[Environment]::SetEnvironmentVariable("ANDROID_NDK_LATEST_HOME", $ndkLatestPath, "Machine")
|
||||
} else {
|
||||
Write-Host "Latest NDK $ndkLatestVersion is not installed at path $ndkLatestPath"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Invoke-PesterTests -TestFile "Android"
|
||||
@@ -0,0 +1,23 @@
|
||||
################################################################################
|
||||
## File: Install-Apache.ps1
|
||||
## Desc: Install Apache HTTP Server
|
||||
################################################################################
|
||||
|
||||
# Stop w3svc service
|
||||
# commented below code w3svc service is not present in 2025
|
||||
Stop-Service -Name w3svc
|
||||
|
||||
# Install latest apache in chocolatey
|
||||
$installDir = "C:\tools"
|
||||
Install-ChocoPackage apache-httpd -ArgumentList "--force", "--params", "/installLocation:$installDir /port:80"
|
||||
|
||||
# Stop and disable Apache service
|
||||
Stop-Service -Name Apache
|
||||
Set-Service -Name Apache -StartupType Disabled
|
||||
|
||||
# Start w3svc service
|
||||
# commented below code w3svc service is not present in 2025
|
||||
Start-Service -Name w3svc
|
||||
|
||||
# Invoke Pester Tests
|
||||
Invoke-PesterTests -TestFile "Apache"
|
||||
@@ -0,0 +1,29 @@
|
||||
################################################################################
|
||||
## File: Install-AzureCli.ps1
|
||||
## Desc: Install and warm-up Azure CLI
|
||||
################################################################################
|
||||
|
||||
Write-Host 'Install the latest Azure CLI release'
|
||||
|
||||
$azureCliConfigPath = 'C:\azureCli'
|
||||
# Store azure-cli cache outside of the provisioning user's profile
|
||||
[Environment]::SetEnvironmentVariable('AZURE_CONFIG_DIR', $azureCliConfigPath, "Machine")
|
||||
|
||||
$azureCliExtensionPath = Join-Path $env:CommonProgramFiles 'AzureCliExtensionDirectory'
|
||||
New-Item -ItemType 'Directory' -Path $azureCliExtensionPath | Out-Null
|
||||
[Environment]::SetEnvironmentVariable('AZURE_EXTENSION_DIR', $azureCliExtensionPath, "Machine")
|
||||
|
||||
Install-Binary -Type MSI `
|
||||
-Url 'https://aka.ms/installazurecliwindowsx64' `
|
||||
-ExpectedSignature '245D262748012A4FE6CE8BA6C951A4C4AFBC3E5D' #'F9A7CF9FBE13BAC767F4781061332DA6E8B4E0EE'
|
||||
|
||||
Update-Environment
|
||||
|
||||
# Warm-up Azure CLI
|
||||
Write-Host "Warmup 'az'"
|
||||
az --help | Out-Null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Command 'az --help' failed"
|
||||
}
|
||||
|
||||
Invoke-PesterTests -TestFile 'CLI.Tools' -TestName 'Azure CLI'
|
||||
@@ -0,0 +1,10 @@
|
||||
####################################################################################
|
||||
## File: Install-AzureCosmosDbEmulator.ps1
|
||||
## Desc: Install Azure CosmosDb Emulator
|
||||
####################################################################################
|
||||
|
||||
Install-Binary -Type MSI `
|
||||
-Url "https://aka.ms/cosmosdb-emulator" `
|
||||
-ExpectedSHA256Sum "DB9D5E496C5FDAE17C12C03385D2BAC973DA61C280023D9FDC9A6020220BEE41"
|
||||
|
||||
Invoke-PesterTests -TestFile "Tools" -TestName "Azure Cosmos DB Emulator"
|
||||
@@ -0,0 +1,35 @@
|
||||
################################################################################
|
||||
## File: Install-AzureDevOpsCli.ps1
|
||||
## Desc: Install Azure DevOps CLI
|
||||
################################################################################
|
||||
|
||||
$azureDevOpsCliConfigPath = 'C:\azureDevOpsCli'
|
||||
# Store azure-devops-cli cache outside of the provisioning user's profile
|
||||
[Environment]::SetEnvironmentVariable('AZ_DEVOPS_GLOBAL_CONFIG_DIR', $azureDevOpsCliConfigPath, "Machine")
|
||||
|
||||
$azureDevOpsCliCachePath = Join-Path $azureDevOpsCliConfigPath 'cache'
|
||||
New-Item -ItemType 'Directory' -Path $azureDevOpsCliCachePath | Out-Null
|
||||
[Environment]::SetEnvironmentVariable('AZURE_DEVOPS_CACHE_DIR', $azureDevOpsCliCachePath, "Machine")
|
||||
|
||||
Update-Environment
|
||||
|
||||
az extension add -n azure-devops
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Command 'az extension add -n azure-devops' failed"
|
||||
}
|
||||
|
||||
# Warm-up Azure DevOps CLI
|
||||
Write-Host "Warmup 'az-devops'"
|
||||
@('devops', 'pipelines', 'boards', 'repos', 'artifacts') | ForEach-Object {
|
||||
az $_ --help
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Command 'az $_ --help' failed"
|
||||
}
|
||||
}
|
||||
|
||||
# calling az devops login to force it to install `keyring`. Login will actually fail, redirecting error to null
|
||||
Write-Output 'fake token' | az devops login | Out-Null
|
||||
# calling az devops logout to be sure no credentials remain.
|
||||
az devops logout | out-null
|
||||
|
||||
Invoke-PesterTests -TestFile 'CLI.Tools' -TestName 'Azure DevOps CLI'
|
||||
@@ -0,0 +1,13 @@
|
||||
################################################################################
|
||||
## File: Install-Bazel.ps1
|
||||
## Desc: Install Bazel and Bazelisk (A user-friendly launcher for Bazel)
|
||||
################################################################################
|
||||
|
||||
Install-ChocoPackage bazel
|
||||
|
||||
npm install -g @bazel/bazelisk
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Command 'npm install -g @bazel/bazelisk' failed"
|
||||
}
|
||||
|
||||
Invoke-PesterTests -TestFile "Tools" -TestName "Bazel"
|
||||
@@ -0,0 +1,28 @@
|
||||
################################################################################
|
||||
## File: Install-BizTalkBuildComponent.ps1
|
||||
## Desc: Install BizTalk Project Build Component
|
||||
################################################################################
|
||||
|
||||
$downloadUrl = "https://aka.ms/BuildComponentSetup.EN"
|
||||
$signatureThumbprint = "8740DF4ACB749640AD318E4BE842F72EC651AD80"
|
||||
|
||||
Write-Host "Downloading BizTalk Project Build Component archive..."
|
||||
$zipFile = Invoke-DownloadWithRetry $downloadUrl
|
||||
|
||||
$setupPath = Join-Path $env:TEMP "BizTalkBuildComponent"
|
||||
if (-not (Test-Path -Path $setupPath)) {
|
||||
New-Item -Path $setupPath -ItemType Directory -Force | Out-Null
|
||||
}
|
||||
Expand-7ZipArchive -Path $zipFile -DestinationPath $setupPath
|
||||
|
||||
Write-Host "Installing BizTalk Project Build Component..."
|
||||
Install-Binary `
|
||||
-LocalPath "$setupPath\Bootstrap.msi" `
|
||||
-ExtraInstallArgs ("/l*v", "$setupPath\bootstrap.log") `
|
||||
-ExpectedSignature $signatureThumbprint
|
||||
Install-Binary `
|
||||
-LocalPath "$setupPath\BuildComponentSetup.msi" `
|
||||
-ExtraInstallArgs ("/l*v", "$setupPath\buildComponentSetup.log") `
|
||||
-ExpectedSignature $signatureThumbprint
|
||||
|
||||
Invoke-PesterTests -TestFile "BizTalk" -TestName "BizTalk Build Component Setup"
|
||||
@@ -0,0 +1,26 @@
|
||||
################################################################################
|
||||
## File: Install-Chocolatey.ps1
|
||||
## Desc: Install Chocolatey package manager
|
||||
################################################################################
|
||||
|
||||
Write-Host "Set TLS1.2"
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor "Tls12"
|
||||
|
||||
Write-Host "Install chocolatey"
|
||||
|
||||
# Add to system PATH
|
||||
Add-MachinePathItem 'C:\ProgramData\Chocolatey\bin'
|
||||
Update-Environment
|
||||
|
||||
# Verify and run choco installer
|
||||
$signatureThumbprint = "B009C875F4E10FFBC62B785BAF4FC4D6BC2D5711"
|
||||
$installScriptPath = Invoke-DownloadWithRetry 'https://chocolatey.org/install.ps1'
|
||||
Test-FileSignature -Path $installScriptPath -ExpectedThumbprint $signatureThumbprint
|
||||
Invoke-Expression $installScriptPath
|
||||
|
||||
# Turn off confirmation
|
||||
choco feature enable -n allowGlobalConfirmation
|
||||
|
||||
# Initialize environmental variable ChocolateyToolsLocation by invoking choco Get-ToolsLocation function
|
||||
Import-Module "$env:ChocolateyInstall\helpers\chocolateyInstaller.psm1" -Force
|
||||
Get-ToolsLocation
|
||||
@@ -0,0 +1,12 @@
|
||||
################################################################################
|
||||
## File: Install-ChocolateyPackages.ps1
|
||||
## Desc: Install common Chocolatey packages
|
||||
################################################################################
|
||||
|
||||
$commonPackages = (Get-ToolsetContent).choco.common_packages
|
||||
|
||||
foreach ($package in $commonPackages) {
|
||||
Install-ChocoPackage $package.name -ArgumentList $package.args
|
||||
}
|
||||
|
||||
Invoke-PesterTests -TestFile "ChocoPackages"
|
||||
@@ -0,0 +1,82 @@
|
||||
################################################################################
|
||||
## File: Install-Chrome.ps1
|
||||
## Desc: Install Google Chrome browser and Chrome WebDriver
|
||||
################################################################################
|
||||
|
||||
# Download and install latest Chrome browser
|
||||
Install-Binary `
|
||||
-Url 'https://dl.google.com/tag/s/dl/chrome/install/googlechromestandaloneenterprise64.msi' `
|
||||
-ExpectedSignature '607A3EDAA64933E94422FC8F0C80388E0590986C'
|
||||
|
||||
# Prepare firewall rules
|
||||
Write-Host "Adding the firewall rule for Google update blocking..."
|
||||
New-NetFirewallRule -DisplayName "BlockGoogleUpdate" -Direction Outbound -Action Block -Program "C:\Program Files (x86)\Google\Update\GoogleUpdate.exe"
|
||||
|
||||
$googleServices = Get-Service -Name "GoogleUpdater*"
|
||||
Stop-Service $googleServices
|
||||
$googleServices.WaitForStatus('Stopped', "00:01:00")
|
||||
$googleServices | Set-Service -StartupType Disabled
|
||||
|
||||
$regGoogleUpdatePath = "HKLM:\SOFTWARE\Policies\Google\Update"
|
||||
$regGoogleUpdateChrome = "HKLM:\SOFTWARE\Policies\Google\Chrome"
|
||||
($regGoogleUpdatePath, $regGoogleUpdateChrome) | ForEach-Object {
|
||||
New-Item -Path $_ -Force
|
||||
}
|
||||
|
||||
$regGoogleParameters = @(
|
||||
@{ Name = "AutoUpdateCheckPeriodMinutes"; Value = 00000000},
|
||||
@{ Name = "UpdateDefault"; Value = 00000000 },
|
||||
@{ Name = "DisableAutoUpdateChecksCheckboxValue"; Value = 00000001 },
|
||||
@{ Name = "Update{8A69D345-D564-463C-AFF1-A69D9E530F96}"; Value = 00000000 },
|
||||
@{ Path = $regGoogleUpdateChrome; Name = "DefaultBrowserSettingEnabled"; Value = 00000000 }
|
||||
)
|
||||
|
||||
$regGoogleParameters | ForEach-Object {
|
||||
$arguments = $_
|
||||
if (-not ($arguments.Path)) {
|
||||
$arguments.Add("Path", $regGoogleUpdatePath)
|
||||
}
|
||||
$arguments.Add("Force", $true)
|
||||
New-ItemProperty @arguments
|
||||
}
|
||||
# Install Chrome WebDriver
|
||||
Write-Host "Install Chrome WebDriver..."
|
||||
$chromeDriverPath = "$($env:SystemDrive)\SeleniumWebDrivers\ChromeDriver"
|
||||
if (-not (Test-Path -Path $chromeDriverPath)) {
|
||||
New-Item -Path $chromeDriverPath -ItemType Directory -Force
|
||||
}
|
||||
|
||||
Write-Host "Get the Chrome WebDriver download URL..."
|
||||
$registryPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths"
|
||||
$chromePath = (Get-ItemProperty "$registryPath\chrome.exe").'(default)'
|
||||
[version] $chromeVersion = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($chromePath).ProductVersion
|
||||
$chromeBuild = "$($chromeVersion.Major).$($chromeVersion.Minor).$($chromeVersion.Build)"
|
||||
$chromeDriverVersionsUrl = "https://googlechromelabs.github.io/chrome-for-testing/latest-patch-versions-per-build-with-downloads.json"
|
||||
|
||||
Write-Host "Chrome version is $chromeVersion"
|
||||
$chromeDriverVersions = Invoke-RestMethod -Uri $chromeDriverVersionsUrl
|
||||
$chromeDriverVersion = $chromeDriverVersions.builds.$chromeBuild
|
||||
|
||||
if (-not ($chromeDriverVersion)) {
|
||||
$availableVersions = $chromeDriverVersions.builds | Get-Member | Select-Object -ExpandProperty Name
|
||||
Write-Host "Available chromedriver builds are $availableVersions"
|
||||
throw "Can't determine chromedriver version that matches chrome build $chromeBuild"
|
||||
}
|
||||
|
||||
$chromeDriverVersion.version | Out-File -FilePath "$chromeDriverPath\versioninfo.txt" -Force;
|
||||
|
||||
Write-Host "Chrome WebDriver version to install is $($chromeDriverVersion.version)"
|
||||
$chromeDriverZipDownloadUrl = ($chromeDriverVersion.downloads.chromedriver | Where-Object platform -eq "win64").url
|
||||
|
||||
Write-Host "Download Chrome WebDriver from $chromeDriverZipDownloadUrl..."
|
||||
$chromeDriverArchPath = Invoke-DownloadWithRetry $chromeDriverZipDownloadUrl
|
||||
|
||||
Write-Host "Expand Chrome WebDriver archive (without using directory names)..."
|
||||
Expand-7ZipArchive -Path $chromeDriverArchPath -DestinationPath $chromeDriverPath -ExtractMethod "e"
|
||||
|
||||
Write-Host "Setting the environment variables..."
|
||||
[Environment]::SetEnvironmentVariable("ChromeWebDriver", $chromeDriverPath, "Machine")
|
||||
Add-MachinePathItem $chromeDriverPath
|
||||
Update-Environment
|
||||
|
||||
Invoke-PesterTests -TestFile "Browsers" -TestName "Chrome"
|
||||
@@ -0,0 +1,26 @@
|
||||
################################################################################
|
||||
## File: Install-CloudFoundryCli.ps1
|
||||
## Desc: Install Cloud Foundry CLI
|
||||
################################################################################
|
||||
|
||||
# Download the latest cf cli exe
|
||||
$cloudFoundryCliUrl = "https://packages.cloudfoundry.org/stable?release=windows64-exe&source=github"
|
||||
|
||||
$cloudFoundryArchPath = Invoke-DownloadWithRetry $cloudFoundryCliUrl
|
||||
|
||||
# Create directory for cf cli
|
||||
$cloudFoundryCliPath = "C:\cf-cli"
|
||||
New-Item -Path $cloudFoundryCliPath -ItemType Directory -Force
|
||||
|
||||
# Extract the zip archive
|
||||
Write-Host "Extracting cf cli..."
|
||||
Expand-7ZipArchive -Path $cloudFoundryArchPath -DestinationPath $cloudFoundryCliPath
|
||||
|
||||
# Add cf to path
|
||||
Add-MachinePathItem $cloudFoundryCliPath
|
||||
|
||||
# Validate cf signature
|
||||
$cloudFoundrySignatureThumbprint = "2C6B2F1562698503A6E4A25F2DF058E12E23A190"
|
||||
Test-FileSignature -Path "$cloudFoundryCliPath\cf.exe" -ExpectedThumbprint $cloudFoundrySignatureThumbprint
|
||||
|
||||
Invoke-PesterTests -TestFile "CLI.Tools" -TestName "CloudFoundry CLI"
|
||||
@@ -0,0 +1,36 @@
|
||||
################################################################################
|
||||
## File: Install-CodeQLBundle.ps1
|
||||
## Desc: Install the CodeQL CLI Bundle to the toolcache.
|
||||
################################################################################
|
||||
|
||||
# Retrieve the CLI version of the latest CodeQL bundle.
|
||||
$defaults = (Invoke-RestMethod "https://raw.githubusercontent.com/github/codeql-action/v2/src/defaults.json")
|
||||
$cliVersion = $defaults.cliVersion
|
||||
$tagName = "codeql-bundle-v" + $cliVersion
|
||||
|
||||
Write-Host "Downloading CodeQL bundle $($cliVersion)..."
|
||||
# Note that this is the all-platforms CodeQL bundle, to support scenarios where customers run
|
||||
# different operating systems within containers.
|
||||
$codeQLBundlePath = Invoke-DownloadWithRetry "https://github.com/github/codeql-action/releases/download/$($tagName)/codeql-bundle.tar.gz"
|
||||
$downloadDirectoryPath = (Get-Item $codeQLBundlePath).Directory.FullName
|
||||
|
||||
$codeQLToolcachePath = Join-Path $env:AGENT_TOOLSDIRECTORY -ChildPath "CodeQL" | Join-Path -ChildPath $cliVersion | Join-Path -ChildPath "x64"
|
||||
New-Item -Path $codeQLToolcachePath -ItemType Directory -Force | Out-Null
|
||||
|
||||
Write-Host "Unpacking the downloaded CodeQL bundle archive..."
|
||||
Expand-7ZipArchive -Path $codeQLBundlePath -DestinationPath $downloadDirectoryPath
|
||||
$unGzipedCodeQLBundlePath = Join-Path $downloadDirectoryPath "codeql-bundle.tar"
|
||||
Expand-7ZipArchive -Path $unGzipedCodeQLBundlePath -DestinationPath $codeQLToolcachePath
|
||||
|
||||
Write-Host "CodeQL bundle at $($codeQLToolcachePath) contains the following directories:"
|
||||
Get-ChildItem -Path $codeQLToolcachePath -Depth 2
|
||||
|
||||
# Touch a file to indicate to the CodeQL Action that this bundle shipped with the toolcache. This is
|
||||
# to support overriding the CodeQL version specified in defaults.json on GitHub Enterprise.
|
||||
New-Item -ItemType file (Join-Path $codeQLToolcachePath -ChildPath "pinned-version")
|
||||
|
||||
# Touch a file to indicate to the toolcache that setting up CodeQL is complete.
|
||||
New-Item -ItemType file "$codeQLToolcachePath.complete"
|
||||
|
||||
# Test that the tools have been extracted successfully.
|
||||
Invoke-PesterTests -TestFile "Tools" -TestName "CodeQL Bundle"
|
||||
@@ -0,0 +1,10 @@
|
||||
####################################################################################
|
||||
## File: Install-DACFx.ps1
|
||||
## Desc: Install SQL Server® Data-Tier Application Framework (DacFx) for Windows
|
||||
####################################################################################
|
||||
|
||||
Install-Binary -Type MSI `
|
||||
-Url 'https://aka.ms/dacfx-msi' `
|
||||
-ExpectedSignature 'C2048FB509F1C37A8C3E9EC6648118458AA01780'
|
||||
|
||||
Invoke-PesterTests -TestFile "Tools" -TestName "DACFx"
|
||||
@@ -0,0 +1,56 @@
|
||||
################################################################################
|
||||
## File: Install-Docker.ps1
|
||||
## Desc: Install Docker.
|
||||
## Must be an independent step because it requires a restart before we
|
||||
## can continue.
|
||||
################################################################################
|
||||
|
||||
Write-Host "Get latest Moby release"
|
||||
$toolsetVersion = (Get-ToolsetContent).docker.components.docker
|
||||
$mobyVersion = (Get-GithubReleasesByVersion -Repo "moby/moby" -Version "${toolsetVersion}").version
|
||||
$dockerceUrl = "https://download.docker.com/win/static/stable/x86_64/"
|
||||
$dockerceBinaries = Invoke-WebRequest -Uri $dockerceUrl -UseBasicParsing
|
||||
|
||||
Write-Host "Check Moby version $mobyVersion"
|
||||
$mobyRelease = $dockerceBinaries.Links.href -match "${mobyVersion}\.zip" | Select-Object -Last 1
|
||||
if (-not $mobyRelease) {
|
||||
Write-Host "Release not found for $mobyLatestRelease version"
|
||||
$versions = [regex]::Matches($dockerceBinaries.Links.href, "docker-(\d+\.\d+\.\d+)\.zip") | Sort-Object { [version] $_.Groups[1].Value }
|
||||
$mobyRelease = $versions | Select-Object -ExpandProperty Value -Last 1
|
||||
Write-Host "Found $mobyRelease"
|
||||
}
|
||||
$mobyReleaseUrl = $dockerceUrl + $mobyRelease
|
||||
|
||||
Write-Host "Install Moby $mobyRelease..."
|
||||
$mobyArchivePath = Invoke-DownloadWithRetry $mobyReleaseUrl
|
||||
Expand-Archive -Path $mobyArchivePath -DestinationPath $env:TEMP
|
||||
$dockerPath = "$env:TEMP\docker\docker.exe"
|
||||
$dockerdPath = "$env:TEMP\docker\dockerd.exe"
|
||||
|
||||
Write-Host "Install Docker CE"
|
||||
$instScriptUrl = "https://raw.githubusercontent.com/microsoft/Windows-Containers/Main/helpful_tools/Install-DockerCE/install-docker-ce.ps1"
|
||||
$instScriptPath = Invoke-DownloadWithRetry $instScriptUrl
|
||||
& $instScriptPath -DockerPath $dockerPath -DockerDPath $dockerdPath
|
||||
if ($LastExitCode -ne 0) {
|
||||
Write-Host "Docker installation failed with exit code $LastExitCode"
|
||||
exit $exitCode
|
||||
}
|
||||
|
||||
# Fix AZ CLI DOCKER_COMMAND_ERROR
|
||||
# cli.azure.cli.command_modules.acr.custom: Could not run 'docker.exe' command.
|
||||
# https://github.com/Azure/azure-cli/issues/18766
|
||||
New-Item -ItemType SymbolicLink -Path "C:\Windows\SysWOW64\docker.exe" -Target "C:\Windows\System32\docker.exe"
|
||||
|
||||
Write-Host "Download docker images"
|
||||
$dockerImages = (Get-ToolsetContent).docker.images
|
||||
foreach ($dockerImage in $dockerImages) {
|
||||
Write-Host "Pulling docker image $dockerImage ..."
|
||||
docker pull $dockerImage
|
||||
|
||||
if (!$?) {
|
||||
throw "Docker pull failed with a non-zero exit code ($LastExitCode)"
|
||||
}
|
||||
}
|
||||
|
||||
Invoke-PesterTests -TestFile "Docker" -TestName "Docker"
|
||||
Invoke-PesterTests -TestFile "Docker" -TestName "DockerImages"
|
||||
@@ -0,0 +1,13 @@
|
||||
################################################################################
|
||||
## File: Install-Docker-Compose.ps1
|
||||
## Desc: Install Docker Compose.
|
||||
################################################################################
|
||||
Write-Host "Install-Package Docker-Compose v2"
|
||||
$toolsetVersion = (Get-ToolsetContent).docker.components.compose
|
||||
$composeVersion = (Get-GithubReleasesByVersion -Repo "docker/compose" -Version "${toolsetVersion}").version
|
||||
$dockerComposev2Url = "https://github.com/docker/compose/releases/download/v${composeVersion}/docker-compose-windows-x86_64.exe"
|
||||
$cliPluginsDir = "C:\ProgramData\docker\cli-plugins"
|
||||
New-Item -Path $cliPluginsDir -ItemType Directory
|
||||
Invoke-DownloadWithRetry -Url $dockerComposev2Url -Path "$cliPluginsDir\docker-compose.exe"
|
||||
|
||||
Invoke-PesterTests -TestFile "Docker" -TestName "DockerCompose"
|
||||
@@ -0,0 +1,22 @@
|
||||
################################################################################
|
||||
## File: Install-Docker-WinCred.ps1
|
||||
## Desc: Install Docker credential helper.
|
||||
## Supply chain security: checksum validation
|
||||
################################################################################
|
||||
|
||||
Write-Host "Install docker-wincred"
|
||||
$downloadUrl = Resolve-GithubReleaseAssetUrl `
|
||||
-Repo "docker/docker-credential-helpers" `
|
||||
-Version "latest" `
|
||||
-UrlMatchPattern "docker-credential-wincred-*amd64.exe"
|
||||
$binaryPath = Invoke-DownloadWithRetry -Url $downloadUrl -Path "C:\Windows\System32\docker-credential-wincred.exe"
|
||||
|
||||
#region Supply chain security
|
||||
$binaryName = Split-Path $downloadUrl -Leaf
|
||||
$externalHash = Get-ChecksumFromUrl -Type "SHA256" `
|
||||
-Url ($downloadUrl -replace $binaryName, "checksums.txt") `
|
||||
-FileName $binaryName
|
||||
Test-FileChecksum -Path $binaryPath -ExpectedSHA256Sum $externalHash
|
||||
#endregion
|
||||
|
||||
Invoke-PesterTests -TestFile "Docker" -TestName "DockerWinCred"
|
||||
@@ -0,0 +1,135 @@
|
||||
################################################################################
|
||||
## File: Install-DotnetSDK.ps1
|
||||
## Desc: Install all released versions of the dotnet sdk and populate package
|
||||
## cache. Should run after VS and Node
|
||||
## Supply chain security: checksum validation
|
||||
################################################################################
|
||||
|
||||
# Set environment variables
|
||||
[Environment]::SetEnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0", "Machine")
|
||||
[Environment]::SetEnvironmentVariable("DOTNET_NOLOGO", "1", "Machine")
|
||||
[Environment]::SetEnvironmentVariable("DOTNET_SKIP_FIRST_TIME_EXPERIENCE", "1", "Machine")
|
||||
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor "Tls12"
|
||||
|
||||
#region "Functions"
|
||||
function Get-SDKVersionsToInstall {
|
||||
param (
|
||||
[Parameter(Mandatory)]
|
||||
[string] $DotnetVersion
|
||||
)
|
||||
$releasesJsonUri = "https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/${DotnetVersion}/releases.json"
|
||||
$releasesData = (Invoke-DownloadWithRetry $releasesJsonUri) | Get-Item | Get-Content | ConvertFrom-Json
|
||||
# filtering out the preview/rc releases
|
||||
$releases = $releasesData.'releases' | Where-Object { !$_.'release-version'.Contains('-') }
|
||||
|
||||
$sdks = @()
|
||||
foreach ($release in $releases) {
|
||||
$sdks += $release.'sdk'
|
||||
$sdks += $release.'sdks'
|
||||
}
|
||||
|
||||
return $sdks.version `
|
||||
| Sort-Object { [Version] $_ } -Unique `
|
||||
| Group-Object { $_.Substring(0, $_.LastIndexOf('.') + 2) } `
|
||||
| ForEach-Object { $_.Group[-1] }
|
||||
}
|
||||
|
||||
function Invoke-DotnetWarmup {
|
||||
param (
|
||||
[Parameter(Mandatory)]
|
||||
[string] $SDKVersion
|
||||
)
|
||||
# warm up dotnet for first time experience
|
||||
$projectTypes = @('console', 'mstest', 'web', 'mvc', 'webapi')
|
||||
foreach ($template in $projectTypes) {
|
||||
$projectPath = Join-Path -Path "C:\temp" -ChildPath $template
|
||||
New-Item -Path $projectPath -Force -ItemType Directory
|
||||
Push-Location -Path $projectPath
|
||||
& "$env:ProgramFiles\dotnet\dotnet.exe" new globaljson --sdk-version "$SDKVersion"
|
||||
if ($LastExitCode -ne 0) {
|
||||
throw "Dotnet new globaljson failed with exit code $LastExitCode"
|
||||
}
|
||||
& "$env:ProgramFiles\dotnet\dotnet.exe" new $template
|
||||
if ($LastExitCode -ne 0) {
|
||||
throw "Dotnet new $template failed with exit code $LastExitCode"
|
||||
}
|
||||
Pop-Location
|
||||
Remove-Item $projectPath -Force -Recurse
|
||||
}
|
||||
}
|
||||
|
||||
function Install-DotnetSDK {
|
||||
param (
|
||||
[Parameter(Mandatory)]
|
||||
[string] $InstallScriptPath,
|
||||
[Parameter(Mandatory)]
|
||||
[Alias('Version')]
|
||||
[string] $SDKVersion,
|
||||
[Parameter(Mandatory)]
|
||||
[string] $DotnetVersion
|
||||
)
|
||||
|
||||
if (Test-Path -Path "C:\Program Files\dotnet\sdk\$SDKVersion") {
|
||||
Write-Host "Sdk version $SDKVersion already installed"
|
||||
return
|
||||
}
|
||||
|
||||
Write-Host "Installing dotnet $SDKVersion"
|
||||
$zipPath = Join-Path ([IO.Path]::GetTempPath()) ([IO.Path]::GetRandomFileName())
|
||||
& $InstallScriptPath -Version $SDKVersion -InstallDir $(Join-Path -Path $env:ProgramFiles -ChildPath 'dotnet') -ZipPath $zipPath -KeepZip
|
||||
# Installer is PowerShell script that doesn't set exit code on failure
|
||||
# If installation failed, tests will fail anyway
|
||||
|
||||
#region Supply chain security
|
||||
$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
|
||||
Test-FileChecksum $zipPath -ExpectedSHA512Sum $distributorFileHash
|
||||
#endregion
|
||||
}
|
||||
#endregion
|
||||
|
||||
$dotnetToolset = (Get-ToolsetContent).dotnet
|
||||
|
||||
# Download installation script.
|
||||
$installScriptPath = Invoke-DownloadWithRetry -Url "https://dot.net/v1/dotnet-install.ps1"
|
||||
|
||||
# Install and warm up dotnet
|
||||
foreach ($dotnetVersion in $dotnetToolset.versions) {
|
||||
$sdkVersionsToInstall = Get-SDKVersionsToInstall -DotnetVersion $dotnetVersion
|
||||
foreach ($sdkVersion in $sdkVersionsToInstall) {
|
||||
Install-DotnetSDK -InstallScriptPath $installScriptPath -SDKVersion $sdkVersion -DotnetVersion $dotnetVersion
|
||||
if ($dotnetToolset.warmup) {
|
||||
Invoke-DotnetWarmup -SDKVersion $sdkVersion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Add dotnet to PATH
|
||||
Add-MachinePathItem "C:\Program Files\dotnet"
|
||||
|
||||
# Remove NuGet Folder
|
||||
$nugetPath = "$env:APPDATA\NuGet"
|
||||
if (Test-Path $nugetPath) {
|
||||
Remove-Item -Path $nugetPath -Force -Recurse
|
||||
}
|
||||
|
||||
# Generate and copy new NuGet.Config config
|
||||
dotnet nuget list source | Out-Null
|
||||
if ($LastExitCode -ne 0) {
|
||||
throw "Dotnet nuget list source failed with exit code $LastExitCode"
|
||||
}
|
||||
Copy-Item -Path $nugetPath -Destination "C:\Users\Default\AppData\Roaming" -Force -Recurse
|
||||
|
||||
# Install dotnet tools
|
||||
Write-Host "Installing dotnet tools"
|
||||
Add-DefaultPathItem "%USERPROFILE%\.dotnet\tools"
|
||||
foreach ($dotnetTool in $dotnetToolset.tools) {
|
||||
dotnet tool install $($dotnetTool.name) --tool-path "C:\Users\Default\.dotnet\tools" --add-source "https://api.nuget.org/v3/index.json" | Out-Null
|
||||
if ($LastExitCode -ne 0) {
|
||||
throw "Dotnet tool install failed with exit code $LastExitCode"
|
||||
}
|
||||
}
|
||||
|
||||
Invoke-PesterTests -TestFile "DotnetSDK"
|
||||
@@ -0,0 +1,39 @@
|
||||
################################################################################
|
||||
## File: Install-EdgeDriver.ps1
|
||||
## Desc: Install Edge WebDriver and configure Microsoft Edge
|
||||
################################################################################
|
||||
|
||||
# Disable Edge auto-updates
|
||||
Rename-Item -Path "C:\Program Files (x86)\Microsoft\EdgeUpdate\MicrosoftEdgeUpdate.exe" -NewName "Disabled_MicrosoftEdgeUpdate.exe" -ErrorAction Stop
|
||||
|
||||
Write-Host "Get the Microsoft Edge WebDriver version..."
|
||||
$edgeBinaryPath = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\msedge.exe").'(default)'
|
||||
[version] $edgeVersion = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($edgeBinaryPath).ProductVersion
|
||||
|
||||
$edgeDriverPath = "$($env:SystemDrive)\SeleniumWebDrivers\EdgeDriver"
|
||||
if (-not (Test-Path -Path $edgeDriverPath)) {
|
||||
New-Item -Path $edgeDriverPath -ItemType Directory -Force
|
||||
}
|
||||
|
||||
$versionInfoUrl = "https://msedgedriver.azureedge.net/LATEST_RELEASE_$($edgeVersion.Major)_WINDOWS"
|
||||
$versionInfoFile = Invoke-DownloadWithRetry -Url $versionInfoUrl -Path "$edgeDriverPath\versioninfo.txt"
|
||||
$latestVersion = Get-Content -Path $versionInfoFile
|
||||
|
||||
Write-Host "Download Microsoft Edge WebDriver..."
|
||||
$downloadUrl = "https://msedgedriver.azureedge.net/$latestVersion/edgedriver_win64.zip"
|
||||
$archivePath = Invoke-DownloadWithRetry $downloadUrl
|
||||
|
||||
Write-Host "Expand Microsoft Edge WebDriver archive..."
|
||||
Expand-7ZipArchive -Path $archivePath -DestinationPath $edgeDriverPath
|
||||
|
||||
#Validate the EdgeDriver signature
|
||||
|
||||
$signatureThumbprint = "CB9C4FBEA1D87D2D468AC5A9CAAB0163F6AD8401","573EF451A68C33FB904346D44551BEF3BB5BBF68", `
|
||||
"7920AC8FB05E0FFFE21E8FF4B4F03093BA6AC16E", "0BD8C56733FDCC06F8CB919FF5A200E39B1ACF71"
|
||||
Test-FileSignature -Path "$edgeDriverPath\msedgedriver.exe" -ExpectedThumbprint $signatureThumbprint
|
||||
|
||||
Write-Host "Setting the environment variables..."
|
||||
[Environment]::SetEnvironmentVariable("EdgeWebDriver", $EdgeDriverPath, "Machine")
|
||||
Add-MachinePathItem "$edgeDriverPath\"
|
||||
|
||||
Invoke-PesterTests -TestFile "Browsers" -TestName "Edge"
|
||||
@@ -0,0 +1,63 @@
|
||||
################################################################################
|
||||
## File: Install-Firefox.ps1
|
||||
## Desc: Install Mozilla Firefox browser and Gecko WebDriver
|
||||
## Supply chain security: Firefox browser - checksum validation
|
||||
################################################################################
|
||||
|
||||
# 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"
|
||||
$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"
|
||||
|
||||
Install-Binary -Type EXE `
|
||||
-Url $installerUrl `
|
||||
-InstallArgs @("/silent", "/install") `
|
||||
-ExpectedSHA256Sum $externalHash
|
||||
|
||||
Write-Host "Disable autoupdate..."
|
||||
$firefoxDirectoryPath = Join-Path $env:ProgramFiles "Mozilla Firefox"
|
||||
New-Item -path $firefoxDirectoryPath -Name 'mozilla.cfg' -Value '//
|
||||
pref("browser.shell.checkDefaultBrowser", false);
|
||||
pref("app.update.enabled", false);' -ItemType file -force
|
||||
|
||||
$firefoxPreferencesFolder = Join-Path $firefoxDirectoryPath "defaults\pref"
|
||||
New-Item -path $firefoxPreferencesFolder -Name 'local-settings.js' -Value 'pref("general.config.obscure_value", 0);
|
||||
pref("general.config.filename", "mozilla.cfg");' -ItemType file -force
|
||||
|
||||
# Download and install Gecko WebDriver
|
||||
Write-Host "Install Gecko WebDriver..."
|
||||
$geckoDriverPath = "$($env:SystemDrive)\SeleniumWebDrivers\GeckoDriver"
|
||||
if (-not (Test-Path -Path $geckoDriverPath)) {
|
||||
New-Item -Path $geckoDriverPath -ItemType Directory -Force
|
||||
}
|
||||
|
||||
Write-Host "Get the Gecko WebDriver version..."
|
||||
$geckoDriverVersion = (Get-GithubReleasesByVersion -Repo "mozilla/geckodriver" -Version "latest").version
|
||||
$geckoDriverVersion | Out-File -FilePath "$geckoDriverPath\versioninfo.txt" -Force
|
||||
|
||||
Write-Host "Download Gecko WebDriver WebDriver..."
|
||||
$geckoDriverDownloadUrl = Resolve-GithubReleaseAssetUrl `
|
||||
-Repo "mozilla/geckodriver" `
|
||||
-Version $geckoDriverVersion `
|
||||
-UrlMatchPattern "geckodriver-*-win64.zip"
|
||||
$geckoDriverArchPath = Invoke-DownloadWithRetry $geckoDriverDownloadUrl
|
||||
|
||||
Write-Host "Expand Gecko WebDriver archive..."
|
||||
Expand-7ZipArchive -Path $geckoDriverArchPath -DestinationPath $geckoDriverPath
|
||||
|
||||
# Validate Gecko WebDriver signature
|
||||
$geckoDriverSignatureThumbprint = "40890F2FE1ACAE18072FA7F3C0AE456AACC8570D"
|
||||
Test-FileSignature -Path "$geckoDriverPath/geckodriver.exe" -ExpectedThumbprint $geckoDriverSignatureThumbprint
|
||||
|
||||
Write-Host "Setting the environment variables..."
|
||||
Add-MachinePathItem -PathItem $geckoDriverPath
|
||||
[Environment]::SetEnvironmentVariable("GeckoWebDriver", $geckoDriverPath, "Machine")
|
||||
|
||||
Invoke-PesterTests -TestFile "Browsers" -TestName "Firefox"
|
||||
@@ -0,0 +1,52 @@
|
||||
################################################################################
|
||||
## File: Install-Git.ps1
|
||||
## Desc: Install Git for Windows
|
||||
## Supply chain security: Git - checksum validation, Hub CLI - managed by package manager
|
||||
################################################################################
|
||||
|
||||
# Install the latest version of Git for Windows
|
||||
|
||||
$downloadUrl = Resolve-GithubReleaseAssetUrl `
|
||||
-Repo "git-for-windows/git" `
|
||||
-Version "latest" `
|
||||
-UrlMatchPattern "Git-*-64-bit.exe"
|
||||
|
||||
$externalHash = Get-ChecksumFromGithubRelease `
|
||||
-Repo "git-for-windows/git" `
|
||||
-Version "latest" `
|
||||
-FileName (Split-Path $downloadUrl -Leaf) `
|
||||
-HashType "SHA256"
|
||||
|
||||
Install-Binary `
|
||||
-Url $downloadUrl `
|
||||
-InstallArgs @(`
|
||||
"/VERYSILENT", `
|
||||
"/NORESTART", `
|
||||
"/NOCANCEL", `
|
||||
"/SP-", `
|
||||
"/CLOSEAPPLICATIONS", `
|
||||
"/RESTARTAPPLICATIONS", `
|
||||
"/o:PathOption=CmdTools", `
|
||||
"/o:BashTerminalOption=ConHost", `
|
||||
"/o:EnableSymlinks=Enabled", `
|
||||
"/COMPONENTS=gitlfs") `
|
||||
-ExpectedSHA256Sum $externalHash
|
||||
|
||||
Update-Environment
|
||||
|
||||
git config --system --add safe.directory "*"
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Error "Failed to configure safe.directory for Git with exit code $LASTEXITCODE"
|
||||
}
|
||||
|
||||
# Disable GCM machine-wide
|
||||
[Environment]::SetEnvironmentVariable("GCM_INTERACTIVE", "Never", "Machine")
|
||||
|
||||
# Add to PATH
|
||||
Add-MachinePathItem "C:\Program Files\Git\bin"
|
||||
|
||||
# Add well-known SSH host keys to ssh_known_hosts
|
||||
ssh-keyscan -t rsa, ecdsa, ed25519 github.com >> "C:\Program Files\Git\etc\ssh\ssh_known_hosts"
|
||||
ssh-keyscan -t rsa ssh.dev.azure.com >> "C:\Program Files\Git\etc\ssh\ssh_known_hosts"
|
||||
|
||||
Invoke-PesterTests -TestFile "Git"
|
||||
@@ -0,0 +1,28 @@
|
||||
################################################################################
|
||||
## File: Install-GitHub-CLI.ps1
|
||||
## Desc: Install GitHub CLI
|
||||
## Supply chain security: GitHub CLI - checksum validation
|
||||
################################################################################
|
||||
|
||||
Write-Host "Get the latest gh version..."
|
||||
|
||||
$downloadUrl = Resolve-GithubReleaseAssetUrl `
|
||||
-Repo "cli/cli" `
|
||||
-Version "latest" `
|
||||
-UrlMatchPattern "gh_*_windows_amd64.msi"
|
||||
|
||||
$checksumsUrl = Resolve-GithubReleaseAssetUrl `
|
||||
-Repo "cli/cli" `
|
||||
-Version "latest" `
|
||||
-UrlMatchPattern "gh_*_checksums.txt"
|
||||
$externalHash = Get-ChecksumFromUrl -Type "SHA256" `
|
||||
-Url $checksumsUrl `
|
||||
-FileName (Split-Path $downloadUrl -Leaf)
|
||||
|
||||
Install-Binary `
|
||||
-Url $downloadUrl `
|
||||
-ExpectedSHA256Sum $externalHash
|
||||
|
||||
Add-MachinePathItem "C:\Program Files (x86)\GitHub CLI"
|
||||
|
||||
Invoke-PesterTests -TestFile "CLI.Tools" -TestName "GitHub CLI"
|
||||
@@ -0,0 +1,12 @@
|
||||
################################################################################
|
||||
## File: Install-GoogleCloudCLI.ps1
|
||||
## Desc: Install Google Cloud CLI
|
||||
################################################################################
|
||||
|
||||
# https://cloud.google.com/sdk/docs/downloads-interactive
|
||||
Install-Binary `
|
||||
-Url 'https://dl.google.com/dl/cloudsdk/channels/rapid/GoogleCloudSDKInstaller.exe' `
|
||||
-InstallArgs @("/S", "/allusers", "/noreporting") `
|
||||
-ExpectedSignature '607A3EDAA64933E94422FC8F0C80388E0590986C'
|
||||
|
||||
Invoke-PesterTests -TestFile "Tools" -TestName "GoogleCloudCLI"
|
||||
@@ -0,0 +1,64 @@
|
||||
################################################################################
|
||||
## File: Install-Haskell.ps1
|
||||
## Desc: Install Haskell for Windows
|
||||
################################################################################
|
||||
|
||||
# install minimal ghcup, utilizing pre-installed msys2 at C:\msys64
|
||||
Write-Host 'Installing ghcup...'
|
||||
$msysPath = "C:\msys64"
|
||||
$ghcupPrefix = "C:\"
|
||||
$cabalDir = "C:\cabal"
|
||||
|
||||
$ghcupDownloadURL = "https://downloads.haskell.org/~ghcup/x86_64-mingw64-ghcup.exe"
|
||||
|
||||
# If you want to install a specific version of ghcup, uncomment the following lines
|
||||
# $ghver = "0.1.19.4"
|
||||
# $ghcupDownloadURL = "https://downloads.haskell.org/~ghcup/${ghver}/x86_64-mingw64-ghcup-${ghver}.exe"
|
||||
|
||||
# Other option is to download ghcup from GitHub releases:
|
||||
# https://github.com/haskell/ghcup-hs/releases/latest
|
||||
|
||||
New-Item -Path "$ghcupPrefix\ghcup" -ItemType 'directory' -ErrorAction SilentlyContinue | Out-Null
|
||||
New-Item -Path "$ghcupPrefix\ghcup\bin" -ItemType 'directory' -ErrorAction SilentlyContinue | Out-Null
|
||||
Invoke-DownloadWithRetry -Url $ghcupDownloadURL -Path "$ghcupPrefix\ghcup\bin\ghcup.exe"
|
||||
|
||||
[Environment]::SetEnvironmentVariable("GHCUP_INSTALL_BASE_PREFIX", $ghcupPrefix, "Machine")
|
||||
[Environment]::SetEnvironmentVariable("GHCUP_MSYS2", $msysPath, "Machine")
|
||||
[Environment]::SetEnvironmentVariable("CABAL_DIR", $cabalDir, "Machine")
|
||||
Add-MachinePathItem "$ghcupPrefix\ghcup\bin"
|
||||
Add-MachinePathItem "$cabalDir\bin"
|
||||
Update-Environment
|
||||
|
||||
# Get 3 latest versions of GHC
|
||||
$versions = ghcup list -t ghc -r | Where-Object { $_ -notlike "prerelease" }
|
||||
$versionsOutput = [version[]]($versions | ForEach-Object { $_.Split(' ')[1]; })
|
||||
$latestMajorMinor = $versionsOutput | Group-Object { $_.ToString(2) } | Sort-Object { [Version] $_.Name } | Select-Object -last 3
|
||||
$versionsList = $latestMajorMinor | ForEach-Object { $_.Group | Select-Object -Last 1 } | Sort-Object
|
||||
|
||||
# The latest version will be installed as a default
|
||||
foreach ($version in $versionsList) {
|
||||
Write-Host "Installing ghc $version..."
|
||||
ghcup install ghc $version
|
||||
if ($LastExitCode -ne 0) {
|
||||
throw "GHC installation failed with exit code $LastExitCode"
|
||||
}
|
||||
ghcup set ghc $version
|
||||
if ($LastExitCode -ne 0) {
|
||||
throw "Setting GHC version failed with exit code $LastExitCode"
|
||||
}
|
||||
}
|
||||
|
||||
# Add default version of GHC to path
|
||||
$defaultGhcVersion = $versionsList | Select-Object -Last 1
|
||||
ghcup set ghc $defaultGhcVersion
|
||||
if ($LastExitCode -ne 0) {
|
||||
throw "Setting default GHC version failed with exit code $LastExitCode"
|
||||
}
|
||||
|
||||
Write-Host 'Installing cabal...'
|
||||
ghcup install cabal latest
|
||||
if ($LastExitCode -ne 0) {
|
||||
throw "Cabal installation failed with exit code $LastExitCode"
|
||||
}
|
||||
|
||||
Invoke-PesterTests -TestFile 'Haskell'
|
||||
@@ -0,0 +1,30 @@
|
||||
################################################################################
|
||||
## File: Install-IEWebDriver.ps1
|
||||
## Desc: Install IE Web Driver
|
||||
################################################################################
|
||||
|
||||
$seleniumMajorVersion = (Get-ToolsetContent).selenium.version
|
||||
$ieDriverUrl = Resolve-GithubReleaseAssetUrl `
|
||||
-Repo "SeleniumHQ/selenium" `
|
||||
-Version "$seleniumMajorVersion.*" `
|
||||
-Asset "IEDriverServer_x64_*.zip"
|
||||
|
||||
# Download IE selenium driver
|
||||
Write-Host "Selenium IEDriverServer download and install..."
|
||||
$driverZipFile = Invoke-DownloadWithRetry $ieDriverUrl
|
||||
|
||||
$ieDriverPath = "C:\SeleniumWebDrivers\IEDriver"
|
||||
if (-not (Test-Path -Path $ieDriverPath)) {
|
||||
New-Item -Path $ieDriverPath -ItemType Directory -Force | Out-Null
|
||||
}
|
||||
|
||||
Expand-7ZipArchive -Path $driverZipFile -DestinationPath $ieDriverPath
|
||||
Remove-Item $driverZipFile
|
||||
|
||||
Write-Host "Get the IEDriver version..."
|
||||
(Get-Item "$ieDriverPath\IEDriverServer.exe").VersionInfo.FileVersion | Out-File -FilePath "$ieDriverPath\versioninfo.txt"
|
||||
|
||||
Write-Host "Setting the IEWebDriver environment variables"
|
||||
[Environment]::SetEnvironmentVariable("IEWebDriver", $ieDriverPath, "Machine")
|
||||
|
||||
Invoke-PesterTests -TestFile "Browsers" -TestName "Internet Explorer"
|
||||
@@ -0,0 +1,141 @@
|
||||
################################################################################
|
||||
## File: Install-JavaTools.ps1
|
||||
## Desc: Install various JDKs and java tools
|
||||
## Supply chain security: JDK - checksum validation
|
||||
################################################################################
|
||||
|
||||
function Set-JavaPath {
|
||||
param (
|
||||
[string] $Version,
|
||||
[string] $Architecture = "x64",
|
||||
[switch] $Default
|
||||
)
|
||||
|
||||
$javaPathPattern = Join-Path -Path $env:AGENT_TOOLSDIRECTORY -ChildPath "Java_Temurin-Hotspot_jdk/${Version}*/${Architecture}"
|
||||
$javaPath = (Get-Item -Path $javaPathPattern).FullName
|
||||
|
||||
if ([string]::IsNullOrEmpty($javaPath)) {
|
||||
Write-Host "Not found path to Java '${Version}'"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "Set 'JAVA_HOME_${Version}_X64' environmental variable as $javaPath"
|
||||
[Environment]::SetEnvironmentVariable("JAVA_HOME_${Version}_X64", $javaPath, "Machine")
|
||||
|
||||
if ($Default) {
|
||||
# Clean up any other Java folders from PATH to make sure that they won't conflict with each other
|
||||
$currentPath = [System.Environment]::GetEnvironmentVariable("PATH", "Machine")
|
||||
|
||||
$pathSegments = $currentPath.Split(';')
|
||||
$newPathSegments = @()
|
||||
|
||||
foreach ($pathSegment in $pathSegments) {
|
||||
if ($pathSegment -notlike '*java*') {
|
||||
$newPathSegments += $pathSegment
|
||||
}
|
||||
}
|
||||
|
||||
$newPath = [string]::Join(';', $newPathSegments)
|
||||
$newPath = $javaPath + '\bin;' + $newPath
|
||||
|
||||
Write-Host "Add $javaPath\bin to PATH"
|
||||
[Environment]::SetEnvironmentVariable("PATH", $newPath, "Machine")
|
||||
|
||||
Write-Host "Set JAVA_HOME environmental variable as $javaPath"
|
||||
[Environment]::SetEnvironmentVariable("JAVA_HOME", $javaPath, "Machine")
|
||||
}
|
||||
}
|
||||
|
||||
function Install-JavaJDK {
|
||||
param(
|
||||
[string] $JDKVersion,
|
||||
[string] $Architecture = "x64"
|
||||
)
|
||||
|
||||
# Get Java version from api
|
||||
$assetUrl = Invoke-RestMethod -Uri "https://api.adoptium.net/v3/assets/latest/${JDKVersion}/hotspot"
|
||||
|
||||
$asset = $assetUrl | Where-Object {
|
||||
$_.binary.os -eq "windows" `
|
||||
-and $_.binary.architecture -eq $Architecture `
|
||||
-and $_.binary.image_type -eq "jdk"
|
||||
}
|
||||
|
||||
# Download and extract java binaries to temporary folder
|
||||
$downloadUrl = $asset.binary.package.link
|
||||
$archivePath = Invoke-DownloadWithRetry $downloadUrl
|
||||
Test-FileChecksum $archivePath -ExpectedSHA256Sum $asset.binary.package.checksum
|
||||
|
||||
# We have to replace '+' sign in the version to '-' due to the issue with incorrect path in Android builds https://github.com/actions/runner-images/issues/3014
|
||||
$fullJavaVersion = $asset.version.semver -replace '\+', '-'
|
||||
# Remove 'LTS' suffix from the version if present
|
||||
$fullJavaVersion = $fullJavaVersion -replace '\.LTS$', ''
|
||||
# Create directories in toolcache path
|
||||
$javaToolcachePath = Join-Path -Path $env:AGENT_TOOLSDIRECTORY -ChildPath "Java_Temurin-Hotspot_jdk"
|
||||
$javaVersionPath = Join-Path -Path $javaToolcachePath -ChildPath $fullJavaVersion
|
||||
$javaArchPath = Join-Path -Path $javaVersionPath -ChildPath $Architecture
|
||||
|
||||
if (-not (Test-Path $javaToolcachePath)) {
|
||||
Write-Host "Creating Temurin-Hotspot toolcache folder"
|
||||
New-Item -ItemType Directory -Path $javaToolcachePath | Out-Null
|
||||
}
|
||||
|
||||
Write-Host "Creating Java '${fullJavaVersion}' folder in '${javaVersionPath}'"
|
||||
New-Item -ItemType Directory -Path $javaVersionPath -Force | Out-Null
|
||||
|
||||
# Complete the installation by extracting Java binaries to toolcache and creating the complete file
|
||||
Expand-7ZipArchive -Path $archivePath -DestinationPath $javaVersionPath
|
||||
Invoke-ScriptBlockWithRetry -Command {
|
||||
Get-ChildItem -Path $javaVersionPath | Rename-Item -NewName $javaArchPath -ErrorAction Stop
|
||||
}
|
||||
New-Item -ItemType File -Path $javaVersionPath -Name "$Architecture.complete" | Out-Null
|
||||
}
|
||||
|
||||
$toolsetJava = (Get-ToolsetContent).java
|
||||
$defaultVersion = $toolsetJava.default
|
||||
$jdkVersionsToInstall = $toolsetJava.versions
|
||||
|
||||
foreach ($jdkVersionToInstall in $jdkVersionsToInstall) {
|
||||
$isDefaultVersion = $jdkVersionToInstall -eq $defaultVersion
|
||||
|
||||
Install-JavaJDK -JDKVersion $jdkVersionToInstall
|
||||
|
||||
if ($isDefaultVersion) {
|
||||
Set-JavaPath -Version $jdkVersionToInstall -Default
|
||||
} else {
|
||||
Set-JavaPath -Version $jdkVersionToInstall
|
||||
}
|
||||
}
|
||||
|
||||
# Install Java tools
|
||||
# Force chocolatey to ignore dependencies on Ant and Maven or else they will download the Oracle JDK
|
||||
Install-ChocoPackage ant -ArgumentList "--ignore-dependencies"
|
||||
# Maven 3.9.x has multiple compatibilities problems
|
||||
$toolsetMavenVersion = (Get-ToolsetContent).maven.version
|
||||
$versionToInstall = Resolve-ChocoPackageVersion -PackageName "maven" -TargetVersion $toolsetMavenVersion
|
||||
|
||||
Install-ChocoPackage maven -ArgumentList "--version=$versionToInstall"
|
||||
Install-ChocoPackage gradle
|
||||
|
||||
# Add maven env variables to Machine
|
||||
[string] $m2Path = ([Environment]::GetEnvironmentVariable("PATH", "Machine")).Split(";") -match "maven"
|
||||
|
||||
$m2RepoPath = 'C:\ProgramData\m2'
|
||||
New-Item -Path $m2RepoPath -ItemType Directory -Force | Out-Null
|
||||
|
||||
[Environment]::SetEnvironmentVariable("M2", $m2Path, "Machine")
|
||||
[Environment]::SetEnvironmentVariable("M2_REPO", $m2RepoPath, "Machine")
|
||||
[Environment]::SetEnvironmentVariable("MAVEN_OPTS", "-Xms256m", "Machine")
|
||||
|
||||
# Download cobertura jars
|
||||
$uri = 'https://repo1.maven.org/maven2/net/sourceforge/cobertura/cobertura/2.1.1/cobertura-2.1.1-bin.zip'
|
||||
$sha256sum = '79479DDE416B082F38ECD1F2F7C6DEBD4D0C2249AF80FD046D1CE05D628F2EC6'
|
||||
$coberturaPath = "C:\cobertura-2.1.1"
|
||||
|
||||
$archivePath = Invoke-DownloadWithRetry $uri
|
||||
Test-FileChecksum $archivePath -ExpectedSHA256Sum $sha256sum
|
||||
Expand-7ZipArchive -Path $archivePath -DestinationPath "C:\"
|
||||
|
||||
[Environment]::SetEnvironmentVariable("COBERTURA_HOME", $coberturaPath, "Machine")
|
||||
|
||||
Invoke-PesterTests -TestFile "Java"
|
||||
@@ -0,0 +1,28 @@
|
||||
################################################################################
|
||||
## File: Install-Kotlin.ps1
|
||||
## Desc: Install Kotlin
|
||||
## Supply chain security: Kotlin - checksum validation
|
||||
################################################################################
|
||||
|
||||
# Install Kotlin
|
||||
$kotlinVersion = (Get-ToolsetContent).kotlin.version
|
||||
|
||||
$kotlinDownloadUrl = Resolve-GithubReleaseAssetUrl `
|
||||
-Repo "JetBrains/kotlin" `
|
||||
-Version "$kotlinVersion" `
|
||||
-Asset "kotlin-compiler-*.zip"
|
||||
$kotlinArchivePath = Invoke-DownloadWithRetry $kotlinDownloadUrl
|
||||
|
||||
#region Supply chain security
|
||||
$externalHash = Get-Content $(Invoke-DownloadWithRetry "$kotlinDownloadUrl.sha256")
|
||||
Test-FileChecksum $kotlinArchivePath -ExpectedSHA256Sum $externalHash
|
||||
#endregion
|
||||
|
||||
Write-Host "Expand Kotlin archive"
|
||||
$kotlinPath = "C:\tools"
|
||||
Expand-7ZipArchive -Path $kotlinArchivePath -DestinationPath $kotlinPath
|
||||
|
||||
# Add to PATH
|
||||
Add-MachinePathItem "$kotlinPath\kotlinc\bin"
|
||||
|
||||
Invoke-PesterTests -TestFile "Tools" -TestName "Kotlin"
|
||||
@@ -0,0 +1,37 @@
|
||||
################################################################################
|
||||
## File: Install-KubernetesTools.ps1
|
||||
## Desc: Install tools for K8s.
|
||||
## Supply chain security: GitHub Kind - checksum validation, Kubectl, Helm, Minikube - by package manager
|
||||
################################################################################
|
||||
|
||||
Write-Host "Install Kind"
|
||||
# Choco installation can't be used because it depends on docker-desktop
|
||||
|
||||
$targetDir = "C:\ProgramData\kind"
|
||||
New-Item -Path $targetDir -ItemType Directory -Force | Out-Null
|
||||
|
||||
$downloadUrl = Resolve-GithubReleaseAssetUrl `
|
||||
-Repo "kubernetes-sigs/kind" `
|
||||
-Version "latest" `
|
||||
-UrlMatchPattern "kind-windows-amd64"
|
||||
$packagePath = Invoke-DownloadWithRetry -Url $downloadUrl -Path "$targetDir\kind.exe"
|
||||
|
||||
#region Supply chain security - Kind
|
||||
$externalHash = Get-ChecksumFromUrl -Type "SHA256" `
|
||||
-Url "$downloadUrl.sha256sum" `
|
||||
-FileName (Split-Path $downloadUrl -Leaf)
|
||||
Test-FileChecksum $packagePath -ExpectedSHA256Sum $externalHash
|
||||
#endregion
|
||||
|
||||
Add-MachinePathItem $targetDir
|
||||
|
||||
Write-Host "Install Kubectl"
|
||||
Install-ChocoPackage kubernetes-cli
|
||||
|
||||
Write-Host "Install Helm"
|
||||
Install-ChocoPackage kubernetes-helm
|
||||
|
||||
Write-Host "Install Minikube"
|
||||
Install-ChocoPackage minikube
|
||||
|
||||
Invoke-PesterTests -TestFile "Tools" -TestName "KubernetesTools"
|
||||
@@ -0,0 +1,10 @@
|
||||
################################################################################
|
||||
## File: Install-LLVM.ps1
|
||||
## Desc: Install the latest 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
|
||||
|
||||
Invoke-PesterTests -TestFile "LLVM"
|
||||
@@ -0,0 +1,11 @@
|
||||
################################################################################
|
||||
## File: Install-Mercurial.ps1
|
||||
## Desc: Install Mercurial
|
||||
################################################################################
|
||||
|
||||
Install-ChocoPackage hg -ArgumentList "--version", "5.0.0"
|
||||
|
||||
Add-MachinePathItem "${env:ProgramFiles}\Mercurial\"
|
||||
Update-Environment
|
||||
|
||||
Invoke-PesterTests -TestFile "Tools" -TestName "Mercurial"
|
||||
@@ -0,0 +1,70 @@
|
||||
################################################################################
|
||||
## File: Install-Mingw64.ps1
|
||||
## Desc: Install GNU tools for Windows
|
||||
################################################################################
|
||||
|
||||
if (Test-IsWin25 -or Test-IsWin19) {
|
||||
# If Windows 2019, install version 8.1.0 form sourceforge
|
||||
$baseUrl = "https://download.qt.io/development_releases/prebuilt"
|
||||
|
||||
$("mingw32", "mingw64") | ForEach-Object {
|
||||
if ($_ -eq "mingw32") {
|
||||
$url = "$baseUrl/mingw_32/i686-8.1.0-release-posix-dwarf-rt_v6-rev0.7z"
|
||||
$sha256sum = 'adb84b70094c0225dd30187ff995e311d19424b1eb8f60934c60e4903297f946'
|
||||
} elseif ($_ -eq "mingw64") {
|
||||
$url = "$baseUrl/mingw_64/x86_64-8.1.0-release-posix-seh-rt_v6-rev0.7z"
|
||||
$sha256sum = '853970527b5de4a55ec8ca4d3fd732c00ae1c69974cc930c82604396d43e79f8'
|
||||
} else {
|
||||
throw "Unknown architecture $_"
|
||||
}
|
||||
|
||||
$packagePath = Invoke-DownloadWithRetry $url
|
||||
Test-FileChecksum -Path $packagePath -ExpectedSHA256Sum $sha256sum
|
||||
Expand-7ZipArchive -Path $packagePath -DestinationPath "C:\"
|
||||
|
||||
# Make a copy of mingw-make.exe to make.exe, which is a more discoverable name
|
||||
# and so the same command line can be used on Windows as on macOS and Linux
|
||||
$path = "C:\$_\bin\mingw32-make.exe" | Get-Item
|
||||
Copy-Item -Path $path -Destination (Join-Path $path.Directory 'make.exe')
|
||||
}
|
||||
|
||||
Add-MachinePathItem "C:\mingw64\bin"
|
||||
|
||||
}
|
||||
|
||||
if (Test-IsWin22 -or Test-IsWin25) {
|
||||
# If Windows 2022, install version specified in the toolset
|
||||
$version = (Get-ToolsetContent).mingw.version
|
||||
$runtime = (Get-ToolsetContent).mingw.runtime
|
||||
|
||||
$("mingw32", "mingw64") | ForEach-Object {
|
||||
if ($_ -eq "mingw32") {
|
||||
$arch = "i686"
|
||||
$threads = "posix"
|
||||
$exceptions = "dwarf"
|
||||
} elseif ($_ -eq "mingw64") {
|
||||
$arch = "x86_64"
|
||||
$threads = "posix"
|
||||
$exceptions = "seh"
|
||||
} else {
|
||||
throw "Unknown architecture $_"
|
||||
}
|
||||
|
||||
$url = Resolve-GithubReleaseAssetUrl `
|
||||
-Repo "niXman/mingw-builds-binaries" `
|
||||
-Version "$version" `
|
||||
-Asset "$arch-*-release-$threads-$exceptions-$runtime-*.7z"
|
||||
|
||||
$packagePath = Invoke-DownloadWithRetry $url
|
||||
Expand-7ZipArchive -Path $packagePath -DestinationPath "C:\"
|
||||
|
||||
# Make a copy of mingw-make.exe to make.exe, which is a more discoverable name
|
||||
# and so the same command line can be used on Windows as on macOS and Linux
|
||||
$path = "C:\$_\bin\mingw32-make.exe" | Get-Item
|
||||
Copy-Item -Path $path -Destination (Join-Path $path.Directory 'make.exe')
|
||||
}
|
||||
|
||||
Add-MachinePathItem "C:\mingw64\bin"
|
||||
}
|
||||
|
||||
Invoke-PesterTests -TestFile "Tools" -TestName "Mingw64"
|
||||
@@ -0,0 +1,32 @@
|
||||
################################################################################
|
||||
## File: Install-Miniconda.ps1
|
||||
## Desc: Install the latest version of Miniconda and set $env:CONDA
|
||||
## Supply chain security: checksum validation
|
||||
################################################################################
|
||||
|
||||
$condaDestination = "C:\Miniconda"
|
||||
$installerName = "Miniconda3-latest-Windows-x86_64.exe"
|
||||
|
||||
#region Supply chain security
|
||||
$distributorFileHash = $null
|
||||
$checksums = (ConvertFrom-HTML -Uri 'https://repo.anaconda.com/miniconda/').SelectNodes('//html/body/table/tr')
|
||||
|
||||
foreach ($node in $checksums) {
|
||||
if ($node.ChildNodes[1].InnerText -eq $installerName) {
|
||||
$distributorFileHash = $node.ChildNodes[7].InnerText
|
||||
}
|
||||
}
|
||||
|
||||
if ($null -eq $distributorFileHash) {
|
||||
throw "Unable to find checksum for $installerName in https://repo.anaconda.com/miniconda/"
|
||||
}
|
||||
#endregion
|
||||
|
||||
Install-Binary `
|
||||
-Url "https://repo.anaconda.com/miniconda/${installerName}" `
|
||||
-InstallArgs @("/S", "/AddToPath=0", "/RegisterPython=0", "/D=$condaDestination") `
|
||||
-ExpectedSHA256Sum $distributorFileHash
|
||||
|
||||
[Environment]::SetEnvironmentVariable("CONDA", $condaDestination, "Machine")
|
||||
|
||||
Invoke-PesterTests -TestFile "Miniconda"
|
||||
@@ -0,0 +1,56 @@
|
||||
####################################################################################
|
||||
## File: Install-MongoDB.ps1
|
||||
## Desc: Install MongoDB
|
||||
####################################################################################
|
||||
|
||||
# Install mongodb package
|
||||
$toolsetContent = Get-ToolsetContent
|
||||
$toolsetVersion = $toolsetContent.mongodb.version
|
||||
|
||||
$getMongoReleases = Invoke-WebRequest -Uri "mongodb.com/docs/manual/release-notes/$toolsetVersion/" -UseBasicParsing
|
||||
$targetReleases = $getMongoReleases.Links.href | Where-Object { $_ -like "#$toolsetVersion*---*" }
|
||||
|
||||
$minorVersions = @()
|
||||
foreach ($release in $targetReleases) {
|
||||
if ($release -notlike "*upcoming*") {
|
||||
$pattern = '\d+\.\d+\.\d+'
|
||||
$version = $release | Select-String -Pattern $pattern -AllMatches | ForEach-Object { $_.Matches } | ForEach-Object { $_.Value }
|
||||
$minorVersions += $version
|
||||
}
|
||||
}
|
||||
|
||||
$latestVersion = $minorVersions[0]
|
||||
|
||||
Install-Binary `
|
||||
-Url "https://fastdl.mongodb.org/windows/mongodb-windows-x86_64-$latestVersion-signed.msi" `
|
||||
-ExtraInstallArgs @('TARGETDIR=C:\PROGRA~1\MongoDB ADDLOCAL=ALL') `
|
||||
-ExpectedSignature $toolsetContent.mongodb.signature
|
||||
|
||||
# Add mongodb to the PATH
|
||||
$mongoPath = (Get-CimInstance Win32_Service -Filter "Name LIKE 'mongodb'").PathName
|
||||
$mongoBin = Split-Path -Path $mongoPath.split('"')[1]
|
||||
Add-MachinePathItem "$mongoBin"
|
||||
|
||||
# Wait for mongodb service running
|
||||
$mongodbService = Get-Service "mongodb"
|
||||
$mongodbService.WaitForStatus('Running', '00:01:00')
|
||||
|
||||
# Stop and disable mongodb service
|
||||
Stop-Service $mongodbService
|
||||
$mongodbService | Set-Service -StartupType Disabled
|
||||
|
||||
# Install mongodb shell for mongodb > 5
|
||||
if (Test-IsWin25) {
|
||||
$mongoshVersion = (Get-GithubReleasesByVersion -Repo "mongodb-js/mongosh" -Version "latest").version
|
||||
|
||||
$mongoshDownloadUrl = Resolve-GithubReleaseAssetUrl `
|
||||
-Repo "mongodb-js/mongosh" `
|
||||
-Version $mongoshVersion `
|
||||
-UrlMatchPattern "mongosh-*-x64.msi"
|
||||
|
||||
Install-Binary -Type MSI `
|
||||
-Url $mongoshDownloadUrl `
|
||||
-ExpectedSignature 'F2D7C28591847BB2CB2B1C2A0C59459FDC728A38'
|
||||
}
|
||||
|
||||
Invoke-PesterTests -TestFile "Databases" -TestName "MongoDB"
|
||||
@@ -0,0 +1,136 @@
|
||||
################################################################################
|
||||
## File: Install-Msys2.ps1
|
||||
## Desc: Install Msys2 and 64 & 32 bit gcc, cmake, & llvm
|
||||
################################################################################
|
||||
|
||||
# References
|
||||
# https://github.com/msys2/MINGW-packages/blob/master/azure-pipelines.yml
|
||||
# https://packages.msys2.org/group/
|
||||
|
||||
$logPrefix = "`n" + ("-" * 40) + "`n---"
|
||||
$origPath = $env:PATH
|
||||
|
||||
function Install-Msys2 {
|
||||
# We can't use Resolve-GithubReleaseAssetUrl function here
|
||||
# because msys2-installer releases don't have a consistent versioning scheme
|
||||
|
||||
$assets = (Invoke-RestMethod -Uri "https://api.github.com/repos/msys2/msys2-installer/releases/latest").assets
|
||||
$downloadUri = ($assets | Where-Object { $_.name -match "^msys2-x86_64" -and $_.name.EndsWith(".exe") }).browser_download_url
|
||||
$installerName = Split-Path $downloadUri -Leaf
|
||||
|
||||
# Download the latest msys2 x86_64, filename includes release date
|
||||
Write-Host "Download msys2 installer $installerName"
|
||||
$installerPath = Invoke-DownloadWithRetry $downloadUri
|
||||
|
||||
#region Supply chain security - MSYS2
|
||||
$externalHash = Get-ChecksumFromUrl -Type "SHA256" `
|
||||
-Url ($downloadUri -replace $installerName, "msys2-checksums.txt") `
|
||||
-FileName $installerName
|
||||
Test-FileChecksum $installerPath -ExpectedSHA256Sum $externalHash
|
||||
#endregion
|
||||
|
||||
Write-Host "Starting msys2 installation"
|
||||
& $installerPath in --confirm-command --accept-messages --root C:/msys64
|
||||
if ($LastExitCode -ne 0) {
|
||||
throw "MSYS2 installation failed with exit code $LastExitCode"
|
||||
}
|
||||
Remove-Item $installerPath
|
||||
}
|
||||
|
||||
function Install-Msys2Packages {
|
||||
param (
|
||||
[Parameter(Mandatory = $true)]
|
||||
[AllowEmptyCollection()]
|
||||
[string[]]$Packages
|
||||
)
|
||||
|
||||
if (-not $Packages) {
|
||||
return
|
||||
}
|
||||
|
||||
Write-Host "$logPrefix Install msys2 packages"
|
||||
pacman.exe -S --noconfirm --needed --noprogressbar $Packages
|
||||
if ($LastExitCode -ne 0) {
|
||||
throw "MSYS2 packages installation failed with exit code $LastExitCode"
|
||||
}
|
||||
taskkill /f /fi "MODULES eq msys-2.0.dll"
|
||||
|
||||
Write-Host "$logPrefix Remove p7zip/7z package due to conflicts"
|
||||
pacman.exe -R --noconfirm --noprogressbar p7zip
|
||||
if ($LastExitCode -ne 0) {
|
||||
throw "Removal of p7zip/7z package failed with exit code $LastExitCode"
|
||||
}
|
||||
}
|
||||
|
||||
function Install-MingwPackages {
|
||||
param (
|
||||
[Parameter(Mandatory = $true)]
|
||||
[AllowEmptyCollection()]
|
||||
[object[]] $Packages
|
||||
)
|
||||
|
||||
if (-not $Packages) {
|
||||
return
|
||||
}
|
||||
|
||||
Write-Host "$logPrefix Install mingw packages"
|
||||
$archs = $Packages.arch
|
||||
|
||||
foreach ($arch in $archs) {
|
||||
Write-Host "Installing $arch packages"
|
||||
$archPackages = $toolsetContent.mingw | Where-Object { $_.arch -eq $arch }
|
||||
$runtimePackages = $archPackages.runtime_packages.name | ForEach-Object { "${arch}-$_" }
|
||||
$additionalPackages = $archPackages.additional_packages | ForEach-Object { "${arch}-$_" }
|
||||
$packagesToInstall = $runtimePackages + $additionalPackages
|
||||
Write-Host "The following packages will be installed: $packagesToInstall"
|
||||
pacman.exe -S --noconfirm --needed --noprogressbar $packagesToInstall
|
||||
if ($LastExitCode -ne 0) {
|
||||
throw "Installation of $arch packages failed with exit code $LastExitCode"
|
||||
}
|
||||
}
|
||||
|
||||
# clean all packages to decrease image size
|
||||
Write-Host "$logPrefix Clean packages"
|
||||
pacman.exe -Scc --noconfirm
|
||||
if ($LastExitCode -ne 0) {
|
||||
throw "Cleaning of packages failed with exit code $LastExitCode"
|
||||
}
|
||||
|
||||
$pkgs = pacman.exe -Q
|
||||
if ($LastExitCode -ne 0) {
|
||||
throw "Listing of packages failed with exit code $LastExitCode"
|
||||
}
|
||||
|
||||
foreach ($arch in $archs) {
|
||||
Write-Host "$logPrefix Installed $arch packages"
|
||||
$pkgs | Select-String -Pattern "^${arch}-"
|
||||
}
|
||||
}
|
||||
|
||||
Install-Msys2
|
||||
|
||||
# Add msys2 bin tools folders to PATH temporary
|
||||
$env:PATH = "C:\msys64\mingw64\bin;C:\msys64\usr\bin;$origPath"
|
||||
|
||||
Write-Host "$logPrefix pacman --noconfirm -Syyuu"
|
||||
pacman.exe -Syyuu --noconfirm
|
||||
if ($LastExitCode -ne 0) {
|
||||
throw "Updating of packages failed with exit code $LastExitCode"
|
||||
}
|
||||
taskkill /f /fi "MODULES eq msys-2.0.dll"
|
||||
|
||||
Write-Host "$logPrefix pacman --noconfirm -Syuu (2nd pass)"
|
||||
pacman.exe -Syuu --noconfirm
|
||||
if ($LastExitCode -ne 0) {
|
||||
throw "Second pass updating of packages failed with exit code $LastExitCode"
|
||||
}
|
||||
taskkill /f /fi "MODULES eq msys-2.0.dll"
|
||||
|
||||
$toolsetContent = (Get-ToolsetContent).MsysPackages
|
||||
Install-Msys2Packages -Packages $toolsetContent.msys2
|
||||
Install-MingwPackages -Packages $toolsetContent.mingw
|
||||
|
||||
$env:PATH = $origPath
|
||||
Write-Host "`nMSYS2 installation completed"
|
||||
|
||||
Invoke-PesterTests -TestFile "MSYS2"
|
||||
@@ -0,0 +1,40 @@
|
||||
################################################################################
|
||||
## File: Install-MysqlCli.ps1
|
||||
## Desc: Install Mysql CLI
|
||||
## Supply chain security: checksum validation (visual c++ redistributable package)
|
||||
################################################################################
|
||||
|
||||
# Installing visual c++ redistributable package.
|
||||
Install-Binary `
|
||||
-Url 'https://download.microsoft.com/download/0/5/6/056dcda9-d667-4e27-8001-8a0c6971d6b1/vcredist_x64.exe' `
|
||||
-InstallArgs @("/install", "/quiet", "/norestart") `
|
||||
-ExpectedSHA256Sum '20E2645B7CD5873B1FA3462B99A665AC8D6E14AAE83DED9D875FEA35FFDD7D7E'
|
||||
|
||||
# Downloading mysql
|
||||
[version] $mysqlVersion = (Get-ToolsetContent).mysql.version
|
||||
$mysqlVersionMajorMinor = $mysqlVersion.ToString(2)
|
||||
|
||||
if ($mysqlVersion.Build -lt 0) {
|
||||
if ($mysqlVersionMajorMinor -eq "5.7") {
|
||||
$downloadsPageUrl = "https://downloads.mysql.com/archives/community/"
|
||||
} else {
|
||||
$downloadsPageUrl = "https://dev.mysql.com/downloads/mysql/${mysqlVersionMajorMinor}.html"
|
||||
}
|
||||
$mysqlVersion = Invoke-RestMethod -Uri $downloadsPageUrl -Headers @{ 'User-Agent' = 'curl/8.4.0' } `
|
||||
| Select-String -Pattern "${mysqlVersionMajorMinor}\.\d+" `
|
||||
| ForEach-Object { $_.Matches.Value }
|
||||
}
|
||||
|
||||
$mysqlVersionFull = $mysqlVersion.ToString()
|
||||
$mysqlVersionUrl = "https://cdn.mysql.com/Downloads/MySQL-${mysqlVersionMajorMinor}/mysql-${mysqlVersionFull}-winx64.msi"
|
||||
|
||||
Install-Binary `
|
||||
-Url $mysqlVersionUrl `
|
||||
-ExpectedSignature (Get-ToolsetContent).mysql.signature
|
||||
|
||||
# Adding mysql in system environment path
|
||||
$mysqlPath = $(Get-ChildItem -Path "C:\PROGRA~1\MySQL" -Directory)[0].FullName
|
||||
|
||||
Add-MachinePathItem "${mysqlPath}\bin"
|
||||
|
||||
Invoke-PesterTests -TestFile "Databases" -TestName "MySQL"
|
||||
@@ -0,0 +1,13 @@
|
||||
################################################################################
|
||||
## File: Install-NET48-devpack.ps1
|
||||
## Desc: Install .NET 4.8 devpack
|
||||
## Supply chain security: checksum validation
|
||||
################################################################################
|
||||
|
||||
# .NET 4.8 Dev pack
|
||||
Install-Binary `
|
||||
-Url 'https://download.visualstudio.microsoft.com/download/pr/014120d7-d689-4305-befd-3cb711108212/0307177e14752e359fde5423ab583e43/ndp48-devpack-enu.exe' `
|
||||
-InstallArgs @("Setup", "/passive", "/norestart") `
|
||||
-ExpectedSHA256Sum '0A7AC4A9B44CED6BB7A0EBF3AD9BA29F60BD4D3BEB2047E19F4D8749DE61F5AC'
|
||||
|
||||
Invoke-PesterTests -TestFile "Tools" -TestName "NET48"
|
||||
@@ -0,0 +1,11 @@
|
||||
################################################################################
|
||||
## File: Install-NET48.ps1
|
||||
## Desc: Install .NET 4.8
|
||||
## Supply chain security: checksum validation
|
||||
################################################################################
|
||||
|
||||
# .NET 4.8 Dev pack
|
||||
Install-Binary `
|
||||
-Url 'https://download.visualstudio.microsoft.com/download/pr/2d6bb6b2-226a-4baa-bdec-798822606ff1/8494001c276a4b96804cde7829c04d7f/ndp48-x86-x64-allos-enu.exe' `
|
||||
-InstallArgs @("Setup", "/passive", "/norestart") `
|
||||
-ExpectedSHA256Sum '68C9986A8DCC0214D909AA1F31BEE9FB5461BB839EDCA996A75B08DDFFC1483F'
|
||||
@@ -0,0 +1,14 @@
|
||||
################################################################################
|
||||
## File: Install-NSIS.ps1
|
||||
## Desc: Install NSIS
|
||||
## Supply chain security: NSIS - managed by package manager
|
||||
################################################################################
|
||||
|
||||
$nsisVersion = (Get-ToolsetContent).nsis.version
|
||||
|
||||
Install-ChocoPackage nsis -ArgumentList "--version", "$nsisVersion"
|
||||
|
||||
Add-MachinePathItem "${env:ProgramFiles(x86)}\NSIS\"
|
||||
Update-Environment
|
||||
|
||||
Invoke-PesterTests -TestFile "Tools" -TestName "NSIS"
|
||||
@@ -0,0 +1,22 @@
|
||||
################################################################################
|
||||
## File: Install-NativeImages.ps1
|
||||
## Desc: Generate and install native images for .NET assemblies
|
||||
################################################################################
|
||||
|
||||
Write-Host "NGen: install Microsoft.PowerShell.Utility.Activities..."
|
||||
& $env:SystemRoot\Microsoft.NET\Framework64\v4.0.30319\ngen.exe install "Microsoft.PowerShell.Utility.Activities, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" | Out-Null
|
||||
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"
|
||||
}
|
||||
|
||||
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"
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
################################################################################
|
||||
## File: Install-Nginx.ps1
|
||||
## Desc: Install Nginx
|
||||
################################################################################
|
||||
|
||||
# Stop w3svc service
|
||||
|
||||
Stop-Service -Name w3svc
|
||||
|
||||
# Install latest nginx in chocolatey
|
||||
$installDir = "C:\tools"
|
||||
Install-ChocoPackage nginx -ArgumentList "--force", "--params", "/installLocation:$installDir /port:80"
|
||||
|
||||
# Stop and disable Nginx service
|
||||
Stop-Service -Name nginx
|
||||
Set-Service -Name nginx -StartupType Disabled
|
||||
|
||||
# Start w3svc service
|
||||
Start-Service -Name w3svc
|
||||
|
||||
# Invoke Pester Tests
|
||||
Invoke-PesterTests -TestFile "Nginx"
|
||||
@@ -0,0 +1,32 @@
|
||||
################################################################################
|
||||
## File: Install-NodeJS.ps1
|
||||
## Desc: Install nodejs-lts and other common node tools.
|
||||
## Must run after python is configured
|
||||
################################################################################
|
||||
|
||||
$prefixPath = 'C:\npm\prefix'
|
||||
$cachePath = 'C:\npm\cache'
|
||||
|
||||
New-Item -Path $prefixPath -Force -ItemType Directory
|
||||
New-Item -Path $cachePath -Force -ItemType Directory
|
||||
|
||||
$defaultVersion = (Get-ToolsetContent).node.default
|
||||
$versionToInstall = Resolve-ChocoPackageVersion -PackageName "nodejs" -TargetVersion $defaultVersion
|
||||
|
||||
Install-ChocoPackage "nodejs" -ArgumentList "--version=$versionToInstall"
|
||||
|
||||
Add-MachinePathItem $prefixPath
|
||||
Update-Environment
|
||||
|
||||
[Environment]::SetEnvironmentVariable("npm_config_prefix", $prefixPath, "Machine")
|
||||
$env:npm_config_prefix = $prefixPath
|
||||
|
||||
npm config set cache $cachePath --global
|
||||
npm config set registry https://registry.npmjs.org/
|
||||
|
||||
$globalNpmPackages = (Get-ToolsetContent).npm.global_packages
|
||||
$globalNpmPackages | ForEach-Object {
|
||||
npm install -g $_.name
|
||||
}
|
||||
|
||||
Invoke-PesterTests -TestFile "Node"
|
||||
@@ -0,0 +1,44 @@
|
||||
################################################################################
|
||||
## File: Install-OpenSSL.ps1
|
||||
## Desc: Install win64-openssl.
|
||||
## Supply chain security: checksum validation
|
||||
################################################################################
|
||||
|
||||
$arch = 'INTEL'
|
||||
$bits = '64'
|
||||
$light = $false
|
||||
$installerType = "exe"
|
||||
$version = (Get-ToolsetContent).openssl.version
|
||||
$installDir = "$env:ProgramFiles\OpenSSL"
|
||||
|
||||
# Fetch available installers list
|
||||
$jsonUrl = 'https://raw.githubusercontent.com/slproweb/opensslhashes/master/win32_openssl_hashes.json'
|
||||
|
||||
$installersAvailable = (Invoke-RestMethod $jsonUrl).files
|
||||
$installerNames = $installersAvailable | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty Name
|
||||
|
||||
$installerUrl = $null
|
||||
$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 -eq $version)) {
|
||||
$installerUrl = $installer.url
|
||||
$installerHash = $installer.sha512
|
||||
}
|
||||
}
|
||||
|
||||
if ($null -eq $installerUrl) {
|
||||
throw "Installer not found for version $version"
|
||||
}
|
||||
|
||||
Install-Binary `
|
||||
-Url $installerUrl `
|
||||
-InstallArgs @('/silent', '/sp-', '/suppressmsgboxes', "/DIR=`"$installDir`"") `
|
||||
-ExpectedSHA512Sum $installerHash
|
||||
|
||||
# Update PATH
|
||||
Add-MachinePathItem "$installDir\bin"
|
||||
Update-Environment
|
||||
|
||||
Invoke-PesterTests -TestFile "Tools" -TestName "OpenSSL"
|
||||
@@ -0,0 +1,22 @@
|
||||
################################################################################
|
||||
## File: Install-PHP.ps1
|
||||
## Desc: Install PHP
|
||||
################################################################################
|
||||
|
||||
# Install latest PHP in chocolatey
|
||||
$installDir = "c:\tools\php"
|
||||
$phpMajorMinor = (Get-ToolsetContent).php.version
|
||||
$phpVersionToInstall = Resolve-ChocoPackageVersion -PackageName "php" -TargetVersion $phpMajorMinor
|
||||
Install-ChocoPackage php -ArgumentList "--params", "/InstallDir:$installDir", "--version=$phpVersionToInstall"
|
||||
|
||||
# Install latest Composer in chocolatey
|
||||
Install-ChocoPackage composer -ArgumentList "--install-args", "/DEV=$installDir /PHP=$installDir"
|
||||
|
||||
# update path to extensions and enable curl and mbstring extensions, and enable php openssl extensions.
|
||||
((Get-Content -path $installDir\php.ini -Raw) -replace ';extension=curl','extension=curl' -replace ';extension=mbstring','extension=mbstring' -replace ';extension_dir = "ext"','extension_dir = "ext"' -replace ';extension=openssl','extension=openssl') | Set-Content -Path $installDir\php.ini
|
||||
|
||||
# Set the PHPROOT environment variable.
|
||||
[Environment]::SetEnvironmentVariable("PHPROOT", $installDir, "Machine")
|
||||
|
||||
# Invoke Pester Tests
|
||||
Invoke-PesterTests -TestFile "PHP"
|
||||
@@ -0,0 +1,39 @@
|
||||
################################################################################
|
||||
## File: Install-Pipx.ps1
|
||||
## Desc: Install pipx and pipx packages
|
||||
################################################################################
|
||||
|
||||
Write-Host "Installing pipx..."
|
||||
$env:PIPX_BIN_DIR = "${env:ProgramFiles(x86)}\pipx_bin"
|
||||
$env:PIPX_HOME = "${env:ProgramFiles(x86)}\pipx"
|
||||
|
||||
pip install pipx
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "pipx installation failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
|
||||
Add-MachinePathItem "${env:PIPX_BIN_DIR}"
|
||||
[Environment]::SetEnvironmentVariable("PIPX_BIN_DIR", $env:PIPX_BIN_DIR, "Machine")
|
||||
[Environment]::SetEnvironmentVariable("PIPX_HOME", $env:PIPX_HOME, "Machine")
|
||||
|
||||
Invoke-PesterTests -TestFile "Tools" -TestName "Pipx"
|
||||
|
||||
Write-Host "Installing pipx packages..."
|
||||
|
||||
$pipxToolset = (Get-ToolsetContent).pipx
|
||||
foreach ($tool in $pipxToolset) {
|
||||
if ($tool.python) {
|
||||
$pythonPath = (Get-Item -Path "${env:AGENT_TOOLSDIRECTORY}\Python\${tool.python}.*\x64\python-${tool.python}*").FullName
|
||||
Write-Host "Install ${tool.package} into python ${tool.python}"
|
||||
pipx install $tool.package --python $pythonPath
|
||||
} else {
|
||||
Write-Host "Install ${tool.package} into default python"
|
||||
pipx install $tool.package
|
||||
}
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Package ${tool.package} installation failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
}
|
||||
|
||||
Invoke-PesterTests -TestFile "PipxPackages"
|
||||
@@ -0,0 +1,97 @@
|
||||
################################################################################
|
||||
## File: Install-PostgreSQL.ps1
|
||||
## Desc: Install PostgreSQL
|
||||
################################################################################
|
||||
|
||||
# Define user and password for PostgreSQL database
|
||||
$pgUser = "postgres"
|
||||
$pgPwd = "root"
|
||||
|
||||
# Prepare environment variable for validation
|
||||
[Environment]::SetEnvironmentVariable("PGUSER", $pgUser, "Machine")
|
||||
[Environment]::SetEnvironmentVariable("PGPASSWORD", $pgPwd, "Machine")
|
||||
|
||||
$toolsetVersion = (Get-ToolsetContent).postgresql.version
|
||||
if ($null -ne ($toolsetVersion | Select-String -Pattern '\d+\.\d+\.\d+')) {
|
||||
$majorVersion = ([version]$toolsetVersion).Major
|
||||
$minorVersion = ([version]$toolsetVersion).Minor
|
||||
$patchVersion = ([version]$toolsetVersion).Build
|
||||
$installerUrl = "https://get.enterprisedb.com/postgresql/postgresql-$majorVersion.$minorVersion-$patchVersion-windows-x64.exe"
|
||||
} else {
|
||||
# Define latest available version to install based on version specified in the toolset
|
||||
$getPostgreReleases = Invoke-WebRequest -Uri "https://git.postgresql.org/gitweb/?p=postgresql.git;a=tags" -UseBasicParsing
|
||||
# Getting all links matched to the pattern (e.g.a=log;h=refs/tags/REL_14)
|
||||
$targetReleases = $getPostgreReleases.Links.href | Where-Object { $_ -match "a=log;h=refs/tags/REL_$toolsetVersion" }
|
||||
[Int32] $outNumber = $null
|
||||
$minorVersions = @()
|
||||
foreach ($release in $targetReleases) {
|
||||
$version = $release.split('/')[-1]
|
||||
# Checking if the latest symbol of the release version is actually a number. If yes, add to $minorVersions array
|
||||
if ([Int32]::TryParse($($version.Split('_')[-1]), [ref] $outNumber)) {
|
||||
$minorVersions += $outNumber
|
||||
}
|
||||
}
|
||||
# Sorting and getting the last one
|
||||
$targetMinorVersions = ($minorVersions | Sort-Object)[-1]
|
||||
|
||||
# In order to get rid of error messages (we know we will have them), force ErrorAction to SilentlyContinue
|
||||
$errorActionOldValue = $ErrorActionPreference
|
||||
$ErrorActionPreference = 'SilentlyContinue'
|
||||
|
||||
# Install latest PostgreSQL
|
||||
# Starting from number 9 and going down, check if the installer is available. If yes, break the loop.
|
||||
# If an installer with $targetMinorVersions is not to be found, the $targetMinorVersions will be decreased by 1
|
||||
$increment = 9
|
||||
do {
|
||||
$url = "https://get.enterprisedb.com/postgresql/postgresql-$toolsetVersion.$targetMinorVersions-$increment-windows-x64.exe"
|
||||
$checkAccess = [System.Net.WebRequest]::Create($url)
|
||||
$response = $null
|
||||
$response = $checkAccess.GetResponse()
|
||||
if ($response) {
|
||||
$installerUrl = $response.ResponseUri.OriginalString
|
||||
} elseif (!$response -and ($increment -eq 0)) {
|
||||
$increment = 9
|
||||
$targetMinorVersions--
|
||||
} else {
|
||||
$increment--
|
||||
}
|
||||
} while (!$response)
|
||||
}
|
||||
|
||||
# Return the previous value of ErrorAction and invoke Install-Binary function
|
||||
$ErrorActionPreference = $errorActionOldValue
|
||||
$installerArgs = @("--install_runtimes 0", "--superpassword root", "--enable_acledit 1", "--unattendedmodeui none", "--mode unattended")
|
||||
Install-Binary `
|
||||
-Url $installerUrl `
|
||||
-InstallArgs $installerArgs `
|
||||
-ExpectedSignature (Get-ToolsetContent).postgresql.signature
|
||||
|
||||
# Get Path to pg_ctl.exe
|
||||
$pgPath = (Get-CimInstance Win32_Service -Filter "Name LIKE 'postgresql-%'").PathName
|
||||
|
||||
# Parse output of command above to obtain pure path
|
||||
$pgBin = Split-Path -Path $pgPath.split('"')[1]
|
||||
$pgRoot = Split-Path -Path $pgPath.split('"')[5]
|
||||
$pgData = Join-Path $pgRoot "data"
|
||||
|
||||
# Validate PostgreSQL installation
|
||||
$pgReadyPath = Join-Path $pgBin "pg_isready.exe"
|
||||
$pgReady = Start-Process -FilePath $pgReadyPath -Wait -PassThru
|
||||
$exitCode = $pgReady.ExitCode
|
||||
|
||||
if ($exitCode -ne 0) {
|
||||
Write-Host -Object "PostgreSQL is not ready. Exitcode: $exitCode"
|
||||
exit $exitCode
|
||||
}
|
||||
|
||||
# Added PostgreSQL environment variable
|
||||
[Environment]::SetEnvironmentVariable("PGBIN", $pgBin, "Machine")
|
||||
[Environment]::SetEnvironmentVariable("PGROOT", $pgRoot, "Machine")
|
||||
[Environment]::SetEnvironmentVariable("PGDATA", $pgData, "Machine")
|
||||
|
||||
# Stop and disable PostgreSQL service
|
||||
$pgService = Get-Service -Name postgresql*
|
||||
Stop-Service $pgService
|
||||
$pgService | Set-Service -StartupType Disabled
|
||||
|
||||
Invoke-PesterTests -TestFile "Databases" -TestName "PostgreSQL"
|
||||
@@ -0,0 +1,27 @@
|
||||
################################################################################
|
||||
## File: Install-PowershellModules.ps1
|
||||
## Desc: Install common PowerShell modules
|
||||
################################################################################
|
||||
|
||||
# Set TLS1.2
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor "Tls12"
|
||||
|
||||
# Install PowerShell modules
|
||||
$modules = (Get-ToolsetContent).powershellModules
|
||||
|
||||
foreach ($module in $modules) {
|
||||
$moduleName = $module.name
|
||||
Write-Host "Installing ${moduleName} module"
|
||||
|
||||
if ($module.versions) {
|
||||
foreach ($version in $module.versions) {
|
||||
Write-Host " - $version"
|
||||
Install-Module -Name $moduleName -RequiredVersion $version -Scope AllUsers -SkipPublisherCheck -Force
|
||||
}
|
||||
} else {
|
||||
Install-Module -Name $moduleName -Scope AllUsers -SkipPublisherCheck -Force
|
||||
}
|
||||
}
|
||||
|
||||
Import-Module Pester
|
||||
Invoke-PesterTests -TestFile "PowerShellModules" -TestName "PowerShellModules"
|
||||
@@ -0,0 +1,48 @@
|
||||
################################################################################
|
||||
## File: Install-PowershellAzModules.ps1
|
||||
## Desc: Install PowerShell modules used by AzureFileCopy@4, AzureFileCopy@5, AzurePowerShell@4, AzurePowerShell@5 tasks
|
||||
## Supply chain security: package manager
|
||||
################################################################################
|
||||
|
||||
# The correct Modules need to be saved in C:\Modules
|
||||
$installPSModulePath = "C:\\Modules"
|
||||
if (-not (Test-Path -LiteralPath $installPSModulePath)) {
|
||||
Write-Host "Creating ${installPSModulePath} folder to store PowerShell Azure modules..."
|
||||
New-Item -Path $installPSModulePath -ItemType Directory | Out-Null
|
||||
}
|
||||
|
||||
# Get modules content from toolset
|
||||
$modules = (Get-ToolsetContent).azureModules
|
||||
|
||||
$psModuleMachinePath = ""
|
||||
|
||||
foreach ($module in $modules) {
|
||||
$moduleName = $module.name
|
||||
|
||||
Write-Host "Installing ${moduleName} to the ${installPSModulePath} path..."
|
||||
foreach ($version in $module.versions) {
|
||||
$modulePath = Join-Path -Path $installPSModulePath -ChildPath "${moduleName}_${version}"
|
||||
Write-Host " - $version [$modulePath]"
|
||||
Save-Module -Path $modulePath -Name $moduleName -RequiredVersion $version -Force -ErrorAction Stop
|
||||
}
|
||||
|
||||
foreach ($version in $module.zip_versions) {
|
||||
$modulePath = Join-Path -Path $installPSModulePath -ChildPath "${moduleName}_${version}"
|
||||
Save-Module -Path $modulePath -Name $moduleName -RequiredVersion $version -Force -ErrorAction Stop
|
||||
Compress-Archive -Path $modulePath -DestinationPath "${modulePath}.zip"
|
||||
Remove-Item $modulePath -Recurse -Force
|
||||
}
|
||||
# Append default tool version to machine path
|
||||
if ($null -ne $module.default) {
|
||||
$defaultVersion = $module.default
|
||||
|
||||
Write-Host "Use ${moduleName} ${defaultVersion} as default version..."
|
||||
$psModuleMachinePath += "${installPSModulePath}\${moduleName}_${defaultVersion};"
|
||||
}
|
||||
}
|
||||
|
||||
# Add modules to the PSModulePath
|
||||
$psModuleMachinePath += $env:PSModulePath
|
||||
[Environment]::SetEnvironmentVariable("PSModulePath", $psModuleMachinePath, "Machine")
|
||||
|
||||
Invoke-PesterTests -TestFile "PowerShellAzModules" -TestName "AzureModules"
|
||||
@@ -0,0 +1,43 @@
|
||||
################################################################################
|
||||
## File: Install-PowershellCore.ps1
|
||||
## Desc: Install PowerShell Core
|
||||
## Supply chain security: checksum validation
|
||||
################################################################################
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$tempDir = Join-Path ([System.IO.Path]::GetTempPath()) ([System.IO.Path]::GetRandomFileName())
|
||||
New-Item -ItemType Directory -Path $tempDir -Force -ErrorAction SilentlyContinue | Out-Null
|
||||
try {
|
||||
$originalValue = [Net.ServicePointManager]::SecurityProtocol
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
|
||||
|
||||
$metadata = Invoke-RestMethod https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/metadata.json
|
||||
$pwshMajorMinor = (Get-ToolsetContent).pwsh.version
|
||||
|
||||
$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"
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
$installerName = Split-Path $downloadUrl -Leaf
|
||||
$externalHash = Get-ChecksumFromUrl -Type "SHA256" `
|
||||
-Url ($downloadUrl -replace $installerName, "hashes.sha256") `
|
||||
-FileName $installerName
|
||||
Install-Binary -Url $downloadUrl -ExpectedSHA256Sum $externalHash
|
||||
} finally {
|
||||
# Restore original value
|
||||
[Net.ServicePointManager]::SecurityProtocol = $originalValue
|
||||
Remove-Item -Path $tempDir -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
# about_update_notifications
|
||||
# While the update check happens during the first session in a given 24-hour period, for performance reasons,
|
||||
# the notification will only be shown on the start of subsequent sessions.
|
||||
# Also for performance reasons, the check will not start until at least 3 seconds after the session begins.
|
||||
[Environment]::SetEnvironmentVariable("POWERSHELL_UPDATECHECK", "Off", "Machine")
|
||||
|
||||
Invoke-PesterTests -TestFile "Tools" -TestName "PowerShell Core"
|
||||
@@ -0,0 +1,108 @@
|
||||
################################################################################
|
||||
## File: Install-PyPy.ps1
|
||||
## Desc: Install PyPy
|
||||
## Supply chain security: checksum validation
|
||||
################################################################################
|
||||
|
||||
function Install-PyPy {
|
||||
param(
|
||||
[String] $PackagePath,
|
||||
[String] $Architecture
|
||||
)
|
||||
|
||||
# Create PyPy toolcache folder
|
||||
$pypyToolcachePath = Join-Path -Path $env:AGENT_TOOLSDIRECTORY -ChildPath "PyPy"
|
||||
if (-not (Test-Path $pypyToolcachePath)) {
|
||||
Write-Host "Create PyPy toolcache folder"
|
||||
New-Item -ItemType Directory -Path $pypyToolcachePath | Out-Null
|
||||
}
|
||||
|
||||
# Expand archive with binaries
|
||||
$packageName = [IO.Path]::GetFileNameWithoutExtension((Split-Path -Path $packagePath -Leaf))
|
||||
$tempFolder = Join-Path -Path $pypyToolcachePath -ChildPath $packageName
|
||||
Expand-7ZipArchive -Path $packagePath -DestinationPath $pypyToolcachePath
|
||||
|
||||
# Get Python version from binaries
|
||||
$pypyApp = Get-ChildItem -Path "$tempFolder\pypy*.exe" | Where-Object Name -match "pypy(\d+)?.exe" | Select-Object -First 1
|
||||
$pythonVersion = & $pypyApp -c "import sys;print('{}.{}.{}'.format(sys.version_info[0],sys.version_info[1],sys.version_info[2]))"
|
||||
|
||||
$pypyFullVersion = & $pypyApp -c "import sys;print('{}.{}.{}'.format(*sys.pypy_version_info[0:3]))"
|
||||
Write-Host "Put '$pypyFullVersion' to PYPY_VERSION file"
|
||||
New-Item -Path "$tempFolder\PYPY_VERSION" -Value $pypyFullVersion | Out-Null
|
||||
|
||||
if ($pythonVersion) {
|
||||
Write-Host "Installing PyPy $pythonVersion"
|
||||
$pypyVersionPath = Join-Path -Path $pypyToolcachePath -ChildPath $pythonVersion
|
||||
$pypyArchPath = Join-Path -Path $pypyVersionPath -ChildPath $architecture
|
||||
|
||||
Write-Host "Create PyPy '${pythonVersion}' folder in '${pypyVersionPath}'"
|
||||
New-Item -ItemType Directory -Path $pypyVersionPath -Force | Out-Null
|
||||
|
||||
Write-Host "Move PyPy '${pythonVersion}' files to '${pypyArchPath}'"
|
||||
Invoke-ScriptBlockWithRetry -Command {
|
||||
Move-Item -Path $tempFolder -Destination $pypyArchPath -ErrorAction Stop | Out-Null
|
||||
}
|
||||
|
||||
Write-Host "Install PyPy '${pythonVersion}' in '${pypyArchPath}'"
|
||||
if (Test-Path "$pypyArchPath\python.exe") {
|
||||
cmd.exe /c "cd /d $pypyArchPath && python.exe -m ensurepip && python.exe -m pip install --upgrade pip"
|
||||
} else {
|
||||
$pypyName = $pypyApp.Name
|
||||
cmd.exe /c "cd /d $pypyArchPath && mklink python.exe $pypyName && python.exe -m ensurepip && python.exe -m pip install --upgrade pip"
|
||||
}
|
||||
|
||||
# Create pip.exe if missing
|
||||
$pipPath = Join-Path -Path $pypyArchPath -ChildPath "Scripts/pip.exe"
|
||||
if (-not (Test-Path $pipPath)) {
|
||||
$pip3Path = Join-Path -Path $pypyArchPath -ChildPath "Scripts/pip3.exe"
|
||||
Copy-Item -Path $pip3Path -Destination $pipPath
|
||||
}
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "PyPy installation failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
|
||||
Write-Host "Create complete file"
|
||||
New-Item -ItemType File -Path $pypyVersionPath -Name "$architecture.complete" | Out-Null
|
||||
} else {
|
||||
throw "PyPy application is not found. Failed to expand '$packagePath' archive"
|
||||
}
|
||||
}
|
||||
|
||||
# Get PyPy content from toolset
|
||||
$toolsetVersions = Get-ToolsetContent | Select-Object -ExpandProperty toolcache | Where-Object Name -eq "PyPy"
|
||||
|
||||
# Get PyPy releases
|
||||
$pypyVersions = Invoke-RestMethod https://downloads.python.org/pypy/versions.json
|
||||
|
||||
# required for html parsing
|
||||
$checksums = (Invoke-RestMethod -Uri 'https://www.pypy.org/checksums.html' | ConvertFrom-HTML).SelectNodes('//*[@id="content"]/article/div/pre')
|
||||
|
||||
Write-Host "Start PyPy installation"
|
||||
foreach ($toolsetVersion in $toolsetVersions.versions) {
|
||||
# Query latest PyPy version
|
||||
$latestMajorPyPyVersion = $pypyVersions |
|
||||
Where-Object { $_.python_version.StartsWith("$toolsetVersion") -and $_.stable -eq $true } |
|
||||
Select-Object -ExpandProperty files -First 1 |
|
||||
Where-Object platform -like "win*"
|
||||
|
||||
if (-not $latestMajorPyPyVersion) {
|
||||
throw "Failed to query PyPy version '$toolsetVersion'"
|
||||
}
|
||||
|
||||
$filename = $latestMajorPyPyVersion.filename
|
||||
Write-Host "Found PyPy '$filename' package"
|
||||
$tempPyPyPackagePath = Invoke-DownloadWithRetry $latestMajorPyPyVersion.download_url
|
||||
|
||||
#region Supply chain security
|
||||
$distributorFileHash = $null
|
||||
foreach ($node in $checksums) {
|
||||
if ($node.InnerText -ilike "*${filename}*") {
|
||||
$distributorFileHash = $node.InnerText.ToString().Split("`n").Where({ $_ -ilike "*${filename}*" }).Split(' ')[0]
|
||||
}
|
||||
}
|
||||
Test-FileChecksum $tempPyPyPackagePath -ExpectedSHA256Sum $distributorFileHash
|
||||
#endregion
|
||||
|
||||
Install-PyPy -PackagePath $tempPyPyPackagePath -Architecture $toolsetVersions.arch
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
################################################################################
|
||||
## File: Install-R.ps1
|
||||
## Desc: Install R for Windows
|
||||
################################################################################
|
||||
|
||||
Install-ChocoPackage R.Project
|
||||
Install-ChocoPackage rtools
|
||||
|
||||
$rscriptPath = Resolve-Path "C:\Program Files\R\*\bin\x64"
|
||||
Add-MachinePathItem $rscriptPath
|
||||
Invoke-PesterTests -TestFile "Tools" -TestName "R"
|
||||
@@ -0,0 +1,136 @@
|
||||
################################################################################
|
||||
## File: Install-RootCA.ps1
|
||||
## Desc: Install Root CA certificates
|
||||
################################################################################
|
||||
|
||||
# https://www.sysadmins.lv/blog-en/how-to-retrieve-certificate-purposes-property-with-cryptoapi-and-powershell.aspx
|
||||
# https://www.sysadmins.lv/blog-en/dump-authroot-and-disallowed-certificates-with-powershell.aspx
|
||||
# https://www.sysadmins.lv/blog-en/constraining-extended-key-usages-in-microsoft-windows.aspx
|
||||
|
||||
function Add-ExtendedCertType {
|
||||
$signature = @"
|
||||
[DllImport("Crypt32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
public static extern bool CertGetCertificateContextProperty(
|
||||
IntPtr pCertContext,
|
||||
uint dwPropId,
|
||||
Byte[] pvData,
|
||||
ref uint pcbData
|
||||
);
|
||||
|
||||
[DllImport("Crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern bool CertSetCertificateContextProperty(
|
||||
IntPtr pCertContext,
|
||||
int dwPropId,
|
||||
uint dwFlags,
|
||||
IntPtr pvData
|
||||
);
|
||||
"@
|
||||
|
||||
Add-Type -MemberDefinition $signature -Namespace PKI -Name Cert
|
||||
}
|
||||
|
||||
function Get-CertificatesWithoutPropId {
|
||||
# List installed certificates
|
||||
$certs = Get-ChildItem -Path "Cert:\LocalMachine\Root"
|
||||
|
||||
Write-Host "Certificates without CERT_NOT_BEFORE_FILETIME_PROP_ID property"
|
||||
$certsWithoutPropId = @{}
|
||||
$certs | ForEach-Object -Process {
|
||||
$certHandle = $_.Handle
|
||||
$isPropertySet = [PKI.Cert]::CertGetCertificateContextProperty(
|
||||
$certHandle, $CERT_NOT_BEFORE_FILETIME_PROP_ID, $null, [ref] $null
|
||||
)
|
||||
if (-not $isPropertySet) {
|
||||
Write-Host "Subject: $($_.Subject)"
|
||||
$certsWithoutPropId[$_.Thumbprint] = $null
|
||||
}
|
||||
}
|
||||
$certsWithoutPropId
|
||||
}
|
||||
|
||||
function Import-SSTFromWU {
|
||||
# Serialized Certificate Store File
|
||||
$sstFile = "$env:TEMP\roots.sst"
|
||||
# Generate SST from Windows Update
|
||||
$result = Invoke-ScriptBlockWithRetry -RetryCount 5 -RetryIntervalSeconds 10 -Command {
|
||||
$r = certutil.exe -generateSSTFromWU $sstFile
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "failed to generate $sstFile sst file`n$o"
|
||||
}
|
||||
return $r
|
||||
}
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "[Error]: failed to generate $sstFile sst file`n$result"
|
||||
exit $LASTEXITCODE
|
||||
}
|
||||
|
||||
$result = certutil.exe -dump $sstFile
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "[Error]: failed to dump $sstFile sst file`n$result"
|
||||
exit $LASTEXITCODE
|
||||
}
|
||||
|
||||
Import-Certificate -FilePath $sstFile -CertStoreLocation Cert:\LocalMachine\Root
|
||||
}
|
||||
|
||||
function Clear-CertificatesPropId {
|
||||
param(
|
||||
[hashtable] $CertsWithoutPropId
|
||||
)
|
||||
|
||||
# List installed certificates
|
||||
$certs = Get-ChildItem -Path Cert:\LocalMachine\Root
|
||||
|
||||
# Clear property CERT_NOT_BEFORE_FILETIME_PROP_ID
|
||||
$certs | ForEach-Object -Process {
|
||||
$thumbprint = $_.Thumbprint
|
||||
if ($certsWithoutPropId.ContainsKey($thumbprint)) {
|
||||
$subject = $_.Subject
|
||||
$certHandle = $_.Handle
|
||||
$result = [PKI.Cert]::CertSetCertificateContextProperty(
|
||||
$certHandle, $CERT_NOT_BEFORE_FILETIME_PROP_ID, 0, [System.IntPtr]::Zero
|
||||
)
|
||||
if ($result) {
|
||||
Write-Host "[Success] Clear CERT_NOT_BEFORE_FILETIME_PROP_ID property $subject"
|
||||
} else {
|
||||
Write-Host "[Fail] Clear CERT_NOT_BEFORE_FILETIME_PROP_ID property $subject"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Disable-RootAutoUpdate {
|
||||
Write-Host "Disable auto root update mechanism"
|
||||
$regPath = "HKLM:\Software\Policies\Microsoft\SystemCertificates\AuthRoot"
|
||||
$regKey = "DisableRootAutoUpdate"
|
||||
|
||||
# Create the registry key if it doesn't exist
|
||||
if (-not (Test-Path $regPath)) {
|
||||
Write-Verbose "Creating $regPath"
|
||||
New-Item $regPath | Out-Null
|
||||
}
|
||||
|
||||
Set-ItemProperty $regPath -Name $regKey -Type DWord -Value 1
|
||||
}
|
||||
|
||||
# Property to remove
|
||||
$CERT_NOT_BEFORE_FILETIME_PROP_ID = 126
|
||||
|
||||
# Add extended cert type
|
||||
Add-ExtendedCertType
|
||||
|
||||
# Get certificates without property CERT_NOT_BEFORE_FILETIME_PROP_ID
|
||||
$certsWithoutPropId = Get-CertificatesWithoutPropId
|
||||
|
||||
# Download and install the latest version of root ca list
|
||||
Import-SSTFromWU
|
||||
|
||||
# Clear property CERT_NOT_BEFORE_FILETIME_PROP_ID
|
||||
if ($certsWithoutPropId.Count -gt 0) {
|
||||
Clear-CertificatesPropId -CertsWithoutPropId $certsWithoutPropId
|
||||
} else {
|
||||
Write-Host "Nothing to clear"
|
||||
}
|
||||
|
||||
# Disable auto root update mechanism
|
||||
Disable-RootAutoUpdate
|
||||
@@ -0,0 +1,81 @@
|
||||
################################################################################
|
||||
## File: Install-Ruby.ps1
|
||||
## Desc: Install Ruby using the RubyInstaller2 package and set the default Ruby version
|
||||
################################################################################
|
||||
|
||||
# Most of this logic is from
|
||||
# https://github.com/ruby/setup-ruby/blob/master/windows.js
|
||||
function Install-Ruby {
|
||||
param(
|
||||
[String] $PackagePath,
|
||||
[String] $Architecture = "x64"
|
||||
)
|
||||
|
||||
# Create Ruby toolcache folder
|
||||
$rubyToolcachePath = Join-Path -Path $env:AGENT_TOOLSDIRECTORY -ChildPath "Ruby"
|
||||
if (-not (Test-Path $rubyToolcachePath)) {
|
||||
Write-Host "Creating Ruby toolcache folder"
|
||||
New-Item -ItemType Directory -Path $rubyToolcachePath | Out-Null
|
||||
}
|
||||
|
||||
$packageName = [IO.Path]::GetFileNameWithoutExtension((Split-Path -Path $PackagePath -Leaf))
|
||||
Write-Host "Expanding Ruby archive $packageName"
|
||||
$tempFolder = Join-Path -Path $rubyToolcachePath -ChildPath $packageName
|
||||
Expand-7ZipArchive -Path $PackagePath -DestinationPath $rubyToolcachePath
|
||||
|
||||
# Get Ruby version from binaries
|
||||
$rubyVersion = & "$tempFolder\bin\ruby.exe" -e "print RUBY_VERSION"
|
||||
if (($LASTEXITCODE -ne 0) -or (-not $rubyVersion)) {
|
||||
throw "Unable to determine Ruby version. Exit code: $LASTEXITCODE, output: '$rubyVersion'"
|
||||
}
|
||||
Write-Host "Ruby version is $rubyVersion"
|
||||
|
||||
$rubyVersionPath = Join-Path -Path $rubyToolcachePath -ChildPath $rubyVersion
|
||||
$rubyArchPath = Join-Path -Path $rubyVersionPath -ChildPath $Architecture
|
||||
|
||||
Write-Host "Creating Ruby '${rubyVersion}' folder in '${rubyVersionPath}'"
|
||||
New-Item -ItemType Directory -Path $rubyVersionPath -Force | Out-Null
|
||||
|
||||
Write-Host "Moving Ruby '${rubyVersion}' files to '${rubyArchPath}'"
|
||||
Invoke-ScriptBlockWithRetry -Command {
|
||||
Move-Item -Path $tempFolder -Destination $rubyArchPath -ErrorAction Stop | Out-Null
|
||||
}
|
||||
|
||||
Write-Host "Removing Ruby '${rubyVersion}' documentation '${rubyArchPath}\share\doc' folder"
|
||||
Remove-Item -Path "${rubyArchPath}\share\doc" -Force -Recurse -ErrorAction Ignore
|
||||
|
||||
Write-Host "Creating complete file for Ruby $rubyVersion $Architecture"
|
||||
New-Item -ItemType File -Path $rubyVersionPath -Name "$Architecture.complete" | Out-Null
|
||||
}
|
||||
|
||||
function Set-DefaultRubyVersion {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[version] $Version,
|
||||
[Alias("Arch")]
|
||||
[string] $Architecture = "x64"
|
||||
)
|
||||
|
||||
$rubyPath = Join-Path $env:AGENT_TOOLSDIRECTORY "/Ruby/${Version}*/${Architecture}/bin"
|
||||
$rubyDir = (Get-Item -Path $rubyPath).FullName
|
||||
|
||||
Write-Host "Use Ruby ${Version} as a system Ruby"
|
||||
Add-MachinePathItem -PathItem $rubyDir | Out-Null
|
||||
}
|
||||
|
||||
# Install Ruby
|
||||
$rubyTools = (Get-ToolsetContent).toolcache | Where-Object { $_.name -eq "Ruby" }
|
||||
$rubyToolVersions = $rubyTools.versions
|
||||
|
||||
Write-Host "Starting installation Ruby..."
|
||||
foreach ($rubyVersion in $rubyToolVersions) {
|
||||
Write-Host "Starting Ruby $rubyVersion installation"
|
||||
$downloadUrl = Resolve-GithubReleaseAssetUrl `
|
||||
-Repo "oneclick/rubyinstaller2" `
|
||||
-Version "$rubyVersion*" `
|
||||
-UrlMatchPattern "*-x64.7z"
|
||||
$packagePath = Invoke-DownloadWithRetry $downloadUrl
|
||||
Install-Ruby -PackagePath $packagePath
|
||||
}
|
||||
|
||||
Set-DefaultRubyVersion -Version $rubyTools.default -Arch $rubyTools.arch
|
||||
@@ -0,0 +1,16 @@
|
||||
################################################################################
|
||||
## File: Install-Runner.ps1
|
||||
## Desc: Install Runner for GitHub Actions
|
||||
## Supply chain security: none
|
||||
################################################################################
|
||||
|
||||
Write-Host "Download latest Runner for GitHub Actions"
|
||||
$downloadUrl = Resolve-GithubReleaseAssetUrl `
|
||||
-Repo "actions/runner" `
|
||||
-Version "latest" `
|
||||
-UrlMatchPattern "actions-runner-win-x64-*[0-9.].zip"
|
||||
$fileName = Split-Path $downloadUrl -Leaf
|
||||
New-Item -Path "C:\ProgramData\runner" -ItemType Directory
|
||||
Invoke-DownloadWithRetry -Url $downloadUrl -Path "C:\ProgramData\runner\$fileName"
|
||||
|
||||
Invoke-PesterTests -TestFile "RunnerCache"
|
||||
@@ -0,0 +1,51 @@
|
||||
################################################################################
|
||||
## File: Install-Rust.ps1
|
||||
## Desc: Install Rust for Windows
|
||||
## Supply chain security: checksum validation for bootstrap, managed by rustup for workloads
|
||||
################################################################################
|
||||
|
||||
# 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
|
||||
# See https://rustup.rs/#
|
||||
$rustupPath = Invoke-DownloadWithRetry "https://static.rust-lang.org/rustup/dist/x86_64-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()
|
||||
Test-FileChecksum $rustupPath -ExpectedSHA256Sum $distributorFileHash
|
||||
#endregion
|
||||
|
||||
# Install Rust by running rustup-init.exe (disabling the confirmation prompt with -y)
|
||||
& $rustupPath -y --default-toolchain=stable --profile=minimal
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Rust installation failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
|
||||
# Add %USERPROFILE%\.cargo\bin to USER PATH
|
||||
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
|
||||
|
||||
# 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"
|
||||
}
|
||||
# bindgen-cli commenting it
|
||||
cargo install cbindgen cargo-audit cargo-outdated
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Rust tools installation failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
|
||||
# Cleanup Cargo crates cache
|
||||
Remove-Item "${env:CARGO_HOME}\registry\*" -Recurse -Force
|
||||
|
||||
Invoke-PesterTests -TestFile "Rust"
|
||||
@@ -0,0 +1,9 @@
|
||||
################################################################################
|
||||
## File: Install-SQLOLEDBDriver.ps1
|
||||
## Desc: Install OLE DB Driver for SQL Server
|
||||
################################################################################
|
||||
|
||||
Install-Binary -Type MSI `
|
||||
-Url "https://go.microsoft.com/fwlink/?linkid=2242656" `
|
||||
-ExtraInstallArgs @("ADDLOCAL=ALL", "IACCEPTMSOLEDBSQLLICENSETERMS=YES") `
|
||||
-ExpectedSignature '6E78B3DCE2998F6C2457C3E54DA90A01034916AE'
|
||||
@@ -0,0 +1,20 @@
|
||||
################################################################################
|
||||
## File: Install-SQLPowerShellTools.ps1
|
||||
## Desc: Install SQL PowerShell tool
|
||||
################################################################################
|
||||
|
||||
$baseUrl = "https://download.microsoft.com/download/B/1/7/B1783FE9-717B-4F78-A39A-A2E27E3D679D/ENU/x64"
|
||||
$signatureThumbrint = "9ACA9419E53D3C9E56396DD2335FF683A8B0B8F3"
|
||||
|
||||
# install required MSIs
|
||||
Install-Binary `
|
||||
-Url "${baseUrl}/SQLSysClrTypes.msi" `
|
||||
-ExpectedSignature $signatureThumbrint
|
||||
|
||||
Install-Binary `
|
||||
-Url "${baseUrl}/SharedManagementObjects.msi" `
|
||||
-ExpectedSignature $signatureThumbrint
|
||||
|
||||
Install-Binary `
|
||||
-Url "${baseUrl}/PowerShellTools.msi" `
|
||||
-ExpectedSignature $signatureThumbrint
|
||||
@@ -0,0 +1,15 @@
|
||||
################################################################################
|
||||
## File: Install-Sbt.ps1
|
||||
## Desc: Install sbt for Windows
|
||||
################################################################################
|
||||
|
||||
# Install the latest version of sbt.
|
||||
# See https://chocolatey.org/packages/sbt
|
||||
Install-ChocoPackage sbt
|
||||
|
||||
$env:SBT_HOME="${env:ProgramFiles(x86)}\sbt"
|
||||
|
||||
# Add sbt binaries to the path
|
||||
Add-MachinePathItem "$env:SBT_HOME\bin"
|
||||
|
||||
Invoke-PesterTests -TestFile "Tools" -TestName "Sbt"
|
||||
@@ -0,0 +1,29 @@
|
||||
################################################################################
|
||||
## File: Install-Selenium.ps1
|
||||
## Desc: Install Selenium Server standalone
|
||||
################################################################################
|
||||
|
||||
# Create Selenium directory
|
||||
$seleniumDirectory = "C:\selenium\"
|
||||
New-Item -ItemType directory -Path $seleniumDirectory
|
||||
|
||||
# Download Selenium
|
||||
$seleniumMajorVersion = (Get-ToolsetContent).selenium.version
|
||||
|
||||
$seleniumDownloadUrl = Resolve-GithubReleaseAssetUrl `
|
||||
-Repo "SeleniumHQ/selenium" `
|
||||
-Version "$seleniumMajorVersion.*" `
|
||||
-Asset "selenium-server-*.jar" `
|
||||
-AllowMultipleMatches
|
||||
|
||||
$seleniumBinPath = Join-Path $seleniumDirectory "selenium-server.jar"
|
||||
Invoke-DownloadWithRetry -Url $seleniumDownloadUrl -Path $seleniumBinPath
|
||||
|
||||
# Create an empty file to retrieve Selenium version
|
||||
$seleniumFullVersion = $seleniumDownloadUrl.Split("-")[1].Split("/")[0]
|
||||
New-Item -Path $seleniumDirectory -Name "selenium-server-$seleniumFullVersion"
|
||||
|
||||
# Add SELENIUM_JAR_PATH environment variable
|
||||
[Environment]::SetEnvironmentVariable("SELENIUM_JAR_PATH", $seleniumBinPath, "Machine")
|
||||
|
||||
Invoke-PesterTests -TestFile "Browsers" -TestName "Selenium"
|
||||
@@ -0,0 +1,29 @@
|
||||
################################################################################
|
||||
## File: Install-ServiceFabricSDK.ps1
|
||||
## Desc: Install webpicmd and then the service fabric sdk
|
||||
## must be install after Visual Studio
|
||||
## Supply chain security: checksum validation
|
||||
################################################################################
|
||||
|
||||
# Creating 'Installer' cache folder if it doesn't exist
|
||||
New-Item -Path 'C:\Windows\Installer' -ItemType Directory -Force
|
||||
|
||||
# Get Service Fabric components versions
|
||||
$runtimeVersion = (Get-ToolsetContent).serviceFabric.runtime.version
|
||||
$sdkVersion = (Get-ToolsetContent).serviceFabric.sdk.version
|
||||
|
||||
$urlBase = "https://download.microsoft.com/download/b/8/a/b8a2fb98-0ec1-41e5-be98-9d8b5abf7856"
|
||||
|
||||
# Install Service Fabric Runtime for Windows
|
||||
Install-Binary `
|
||||
-Url "${urlBase}/MicrosoftServiceFabric.${runtimeVersion}.exe" `
|
||||
-InstallArgs @("/accepteula ", "/quiet", "/force") `
|
||||
-ExpectedSHA256Sum (Get-ToolsetContent).serviceFabric.runtime.checksum
|
||||
|
||||
|
||||
# Install Service Fabric SDK
|
||||
Install-Binary `
|
||||
-Url "${urlBase}/MicrosoftServiceFabricSDK.${sdkVersion}.msi" `
|
||||
-ExpectedSHA256Sum (Get-ToolsetContent).serviceFabric.sdk.checksum
|
||||
|
||||
Invoke-PesterTests -TestFile "Tools" -TestName "ServiceFabricSDK"
|
||||
@@ -0,0 +1,35 @@
|
||||
################################################################################
|
||||
## File: Install-Stack.ps1
|
||||
## Desc: Install Stack for Windows
|
||||
## Supply chain security: Stack - checksum validation
|
||||
################################################################################
|
||||
|
||||
Write-Host "Get the latest Stack version..."
|
||||
|
||||
$version = (Get-GithubReleasesByVersion -Repo "commercialhaskell/stack" -Version "latest" -WithAssetsOnly).version
|
||||
|
||||
$downloadUrl = Resolve-GithubReleaseAssetUrl `
|
||||
-Repo "commercialhaskell/stack" `
|
||||
-Version $version `
|
||||
-UrlMatchPattern "stack-*-windows-x86_64.zip"
|
||||
|
||||
Write-Host "Download stack archive"
|
||||
$stackToolcachePath = Join-Path $env:AGENT_TOOLSDIRECTORY "stack\$version"
|
||||
$destinationPath = Join-Path $stackToolcachePath "x64"
|
||||
$stackArchivePath = Invoke-DownloadWithRetry $downloadUrl
|
||||
|
||||
#region Supply chain security - Stack
|
||||
$externalHash = Get-ChecksumFromUrl -Type "SHA256" `
|
||||
-Url "$downloadUrl.sha256" `
|
||||
-FileName (Split-Path $downloadUrl -Leaf)
|
||||
Test-FileChecksum $stackArchivePath -ExpectedSHA256Sum $externalHash
|
||||
#endregion
|
||||
|
||||
Write-Host "Expand stack archive"
|
||||
Expand-7ZipArchive -Path $stackArchivePath -DestinationPath $destinationPath
|
||||
|
||||
New-Item -Name "x64.complete" -Path $stackToolcachePath
|
||||
|
||||
Add-MachinePathItem -PathItem $destinationPath
|
||||
|
||||
Invoke-PesterTests -TestFile "Tools" -TestName "Stack"
|
||||
@@ -0,0 +1,60 @@
|
||||
################################################################################
|
||||
## File: Install-Toolset.ps1
|
||||
## Team: CI-Build
|
||||
## Desc: Install toolset
|
||||
################################################################################
|
||||
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls13
|
||||
|
||||
Function Install-Asset {
|
||||
param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[object] $ReleaseAsset
|
||||
)
|
||||
|
||||
$releaseAssetName = [System.IO.Path]::GetFileNameWithoutExtension($ReleaseAsset.filename)
|
||||
$assetFolderPath = Join-Path $env:TEMP $releaseAssetName
|
||||
$assetArchivePath = Invoke-DownloadWithRetry $ReleaseAsset.download_url
|
||||
|
||||
Write-Host "Extract $($ReleaseAsset.filename) content..."
|
||||
if ($assetArchivePath.EndsWith(".tar.gz")) {
|
||||
$assetTarPath = $assetArchivePath.TrimEnd(".tar.gz")
|
||||
Expand-7ZipArchive -Path $assetArchivePath -DestinationPath $assetTarPath
|
||||
Expand-7ZipArchive -Path $assetTarPath -DestinationPath $assetFolderPath
|
||||
} else {
|
||||
Expand-7ZipArchive -Path $assetArchivePath -DestinationPath $assetFolderPath
|
||||
}
|
||||
|
||||
Write-Host "Invoke installation script..."
|
||||
Push-Location -Path $assetFolderPath
|
||||
Invoke-Expression .\setup.ps1
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
# Get toolcache content from toolset
|
||||
$toolsToInstall = @("Python", "Node", "Go")
|
||||
$tools = Get-ToolsetContent | Select-Object -ExpandProperty toolcache | Where-Object { $toolsToInstall -contains $_.Name }
|
||||
|
||||
foreach ($tool in $tools) {
|
||||
# Get versions manifest for current tool
|
||||
# Invoke-RestMethod doesn't support retry in PowerShell 5.1
|
||||
$assets = Invoke-ScriptBlockWithRetry -Command {
|
||||
Invoke-RestMethod $tool.url
|
||||
}
|
||||
|
||||
# Get github release asset for each version
|
||||
foreach ($toolVersion in $tool.versions) {
|
||||
$asset = $assets `
|
||||
| Where-Object version -like $toolVersion `
|
||||
| Select-Object -ExpandProperty files `
|
||||
| Where-Object { ($_.platform -eq $tool.platform) -and ($_.arch -eq $tool.arch) -and ($_.toolset -eq $tool.toolset) } `
|
||||
| Select-Object -First 1
|
||||
|
||||
if (-not $asset) {
|
||||
throw "Asset for $($tool.name) $toolVersion $($tool.arch) not found in versions manifest"
|
||||
}
|
||||
|
||||
Write-Host "Installing $($tool.name) $toolVersion $($tool.arch)..."
|
||||
Install-Asset -ReleaseAsset $asset
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
################################################################################
|
||||
## File: Install-TortoiseSvn.ps1
|
||||
## Desc: Install TortoiseSvn
|
||||
################################################################################
|
||||
|
||||
Install-ChocoPackage tortoisesvn
|
||||
@@ -0,0 +1,20 @@
|
||||
################################################################################
|
||||
## File: Install-VCRedist.ps1
|
||||
## Desc: Install Visual C++ Redistributable
|
||||
## Supply chain security: checksum validation
|
||||
################################################################################
|
||||
|
||||
$baseUrl = "https://download.microsoft.com/download/1/6/5/165255E7-1014-4D0A-B094-B6A430A6BFFC"
|
||||
$argumentList = ("/install", "/quiet", "/norestart")
|
||||
|
||||
Install-Binary `
|
||||
-Url "${baseUrl}/vcredist_x86.exe" `
|
||||
-InstallArgs $argumentList `
|
||||
-ExpectedSHA256Sum '99DCE3C841CC6028560830F7866C9CE2928C98CF3256892EF8E6CF755147B0D8'
|
||||
|
||||
Install-Binary `
|
||||
-Url "${baseUrl}/vcredist_x64.exe" `
|
||||
-InstallArgs $argumentList `
|
||||
-ExpectedSHA256Sum 'F3B7A76D84D23F91957AA18456A14B4E90609E4CE8194C5653384ED38DADA6F3'
|
||||
|
||||
Invoke-PesterTests -TestFile "Tools" -TestName "VCRedist"
|
||||
@@ -0,0 +1,27 @@
|
||||
###################################################################################
|
||||
## File: Install-VSExtensions.ps1
|
||||
## Desc: Install the Visual Studio Extensions from toolset.json
|
||||
###################################################################################
|
||||
|
||||
$toolset = Get-ToolsetContent
|
||||
$vsixPackagesList = $toolset.visualStudio.vsix
|
||||
if (-not $vsixPackagesList) {
|
||||
Write-Host "No extensions to install"
|
||||
exit 0
|
||||
}
|
||||
|
||||
$vsixPackagesList | ForEach-Object {
|
||||
# Retrieve cdn endpoint to avoid HTTP error 429
|
||||
# https://github.com/actions/runner-images/issues/3074
|
||||
$vsixPackage = Get-VsixInfoFromMarketplace $_
|
||||
Write-Host "Installing $vsixPackage"
|
||||
if ($vsixPackage.FileName.EndsWith(".vsix")) {
|
||||
Install-VSIXFromUrl $vsixPackage.DownloadUri
|
||||
} else {
|
||||
Install-Binary `
|
||||
-Url $vsixPackage.DownloadUri `
|
||||
-InstallArgs @('/install', '/quiet', '/norestart')
|
||||
}
|
||||
}
|
||||
|
||||
Invoke-PesterTests -TestFile "Vsix"
|
||||
@@ -0,0 +1,27 @@
|
||||
################################################################################
|
||||
## File: Install-Vcpkg.ps1
|
||||
## Desc: Install vcpkg
|
||||
################################################################################
|
||||
|
||||
$Uri = 'https://github.com/Microsoft/vcpkg.git'
|
||||
$InstallDir = 'C:\vcpkg'
|
||||
$VcpkgExecPath = 'vcpkg.exe'
|
||||
|
||||
git clone $Uri $InstallDir -q
|
||||
|
||||
# Build and integrate vcpkg
|
||||
Invoke-Expression "$InstallDir\bootstrap-vcpkg.bat"
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "vcpkg bootstrap failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
Invoke-Expression "$InstallDir\$VcpkgExecPath integrate install"
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "vcpkg integration failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
|
||||
# Add vcpkg to system environment
|
||||
Add-MachinePathItem $InstallDir
|
||||
[Environment]::SetEnvironmentVariable("VCPKG_INSTALLATION_ROOT", $InstallDir, "Machine")
|
||||
Update-Environment
|
||||
|
||||
Invoke-PesterTests -TestFile "Tools" -TestName "Vcpkg"
|
||||
@@ -0,0 +1,57 @@
|
||||
################################################################################
|
||||
## File: Install-VisualStudio.ps1
|
||||
## Desc: Install Visual Studio
|
||||
################################################################################
|
||||
|
||||
$vsToolset = (Get-ToolsetContent).visualStudio
|
||||
|
||||
# Install VS
|
||||
Install-VisualStudio `
|
||||
-Version $vsToolset.subversion `
|
||||
-Edition $vsToolset.edition `
|
||||
-Channel $vsToolset.channel `
|
||||
-RequiredComponents $vsToolset.workloads `
|
||||
-ExtraArgs "--allWorkloads --includeRecommended --remove Component.CPython3.x64" `
|
||||
-SignatureThumbprint $vsToolset.signature
|
||||
|
||||
# Find the version of VS installed for this instance
|
||||
# Only supports a single instance
|
||||
$vsProgramData = Get-Item -Path "C:\ProgramData\Microsoft\VisualStudio\Packages\_Instances"
|
||||
$instanceFolders = Get-ChildItem -Path $vsProgramData.FullName
|
||||
|
||||
if ($instanceFolders -is [array]) {
|
||||
throw "More than one instance installed"
|
||||
}
|
||||
|
||||
# Updating content of MachineState.json file to disable autoupdate of VSIX extensions
|
||||
$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-IsWin19) {
|
||||
# Install Windows 10 SDK version 10.0.14393.795
|
||||
Install-Binary -Type EXE `
|
||||
-Url 'https://go.microsoft.com/fwlink/p/?LinkId=838916' `
|
||||
-InstallArgs @("/q", "/norestart", "/ceip off", "/features OptionId.WindowsSoftwareDevelopmentKit") `
|
||||
-ExpectedSignature 'C91545B333C52C4465DE8B90A3FAF4E1D9C58DFA'
|
||||
|
||||
# Install Windows 11 SDK version 10.0.22621.0
|
||||
Install-Binary -Type EXE `
|
||||
-Url 'https://go.microsoft.com/fwlink/p/?linkid=2196241' `
|
||||
-InstallArgs @("/q", "/norestart", "/ceip off", "/features OptionId.UWPManaged OptionId.UWPCPP OptionId.UWPLocalized OptionId.DesktopCPPx86 OptionId.DesktopCPPx64 OptionId.DesktopCPParm64") `
|
||||
-ExpectedSignature 'E4C5C5FCDB68B930EE4E19BC25D431EF6D864C51'
|
||||
}
|
||||
|
||||
if (Test-IsWin22) {
|
||||
# Install Windows 10 SDK version 10.0.17763
|
||||
Install-Binary -Type EXE `
|
||||
-Url 'https://go.microsoft.com/fwlink/p/?LinkID=2033908' `
|
||||
-InstallArgs @("/q", "/norestart", "/ceip off", "/features OptionId.UWPManaged OptionId.UWPCPP OptionId.UWPLocalized OptionId.DesktopCPPx86 OptionId.DesktopCPPx64 OptionId.DesktopCPParm64") `
|
||||
-ExpectedSignature '7535269B94C1FEA4A5EF6D808E371DA242F27936'
|
||||
}
|
||||
if (Test-IsWin25){
|
||||
Write-Host "It is for windows-25 testing"
|
||||
}
|
||||
|
||||
# Disable pester tests for now
|
||||
# Invoke-PesterTests -TestFile "VisualStudio"
|
||||
@@ -0,0 +1,40 @@
|
||||
################################################################################
|
||||
## File: Install-WDK.ps1
|
||||
## Desc: Install the Windows Driver Kit
|
||||
################################################################################
|
||||
|
||||
# Requires Windows SDK with the same version number as the WDK
|
||||
if (Test-IsWin19) {
|
||||
# Install all features without showing the GUI using winsdksetup.exe
|
||||
Install-Binary -Type EXE `
|
||||
-Url 'https://go.microsoft.com/fwlink/?linkid=2173743' `
|
||||
-InstallArgs @("/features", "+", "/quiet") `
|
||||
-ExpectedSignature '44796EB5BD439B4BFB078E1DC2F8345AE313CBB1'
|
||||
|
||||
$wdkUrl = "https://go.microsoft.com/fwlink/?linkid=2166289"
|
||||
$wdkSignatureThumbprint = "914A09C2E02C696AF394048BCB8D95449BCD5B9E"
|
||||
$wdkExtensionPath = "C:\Program Files (x86)\Windows Kits\10\Vsix\VS2019\WDK.vsix"
|
||||
} elseif (Test-IsWin22) {
|
||||
# SDK is available through Visual Studio
|
||||
$wdkUrl = "https://go.microsoft.com/fwlink/?linkid=2249371"
|
||||
$wdkSignatureThumbprint = "7C94971221A799907BB45665663BBFD587BAC9F8"
|
||||
$wdkExtensionPath = "C:\Program Files (x86)\Windows Kits\10\Vsix\VS2022\*\WDK.vsix"
|
||||
} elseif (Test-IsWin25) {
|
||||
# SDK is available through Visual Studio
|
||||
$wdkUrl = "https://go.microsoft.com/fwlink/?linkid=2249371"
|
||||
$wdkSignatureThumbprint = "7C94971221A799907BB45665663BBFD587BAC9F8"
|
||||
$wdkExtensionPath = "C:\Program Files (x86)\Windows Kits\10\Vsix\VS2022\*\WDK.vsix"
|
||||
}else {
|
||||
throw "Invalid version of Visual Studio is found. Either 2019 or 2022 are required"
|
||||
}
|
||||
|
||||
# Install all features without showing the GUI using wdksetup.exe
|
||||
Install-Binary -Type EXE `
|
||||
-Url $wdkUrl `
|
||||
-InstallArgs @("/features", "+", "/quiet") `
|
||||
-ExpectedSignature $wdkSignatureThumbprint
|
||||
|
||||
# Need to install the VSIX to get the build targets when running VSBuild
|
||||
Install-VSIXFromFile (Resolve-Path -Path $wdkExtensionPath)
|
||||
|
||||
Invoke-PesterTests -TestFile "WDK"
|
||||
@@ -0,0 +1,10 @@
|
||||
################################################################################
|
||||
## File: Install-WebPI.ps1
|
||||
## Desc: Install WebPlatformInstaller
|
||||
################################################################################
|
||||
|
||||
Install-Binary -Type MSI `
|
||||
-Url 'http://go.microsoft.com/fwlink/?LinkId=287166' `
|
||||
-ExpectedSignature 'C3A3D43788E7ABCD287CB4F5B6583043774F99D2'
|
||||
|
||||
Invoke-PesterTests -TestFile "Tools" -TestName "WebPlatformInstaller"
|
||||
@@ -0,0 +1,16 @@
|
||||
####################################################################################
|
||||
## File: Install-WinAppDriver.ps1
|
||||
## Desc: Install Windows Application Driver (WinAppDriver)
|
||||
####################################################################################
|
||||
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
$downloadUrl = Resolve-GithubReleaseAssetUrl `
|
||||
-Repo "microsoft/WinAppDriver" `
|
||||
-Version "latest" `
|
||||
-UrlMatchPattern "WindowsApplicationDriver_*.msi"
|
||||
|
||||
Install-Binary `
|
||||
-Url $downloadUrl `
|
||||
-ExpectedSignature '2485A7AFA98E178CB8F30C9838346B514AEA4769'
|
||||
|
||||
Invoke-PesterTests -TestFile "WinAppDriver" -TestName "WinAppDriver"
|
||||
@@ -0,0 +1,47 @@
|
||||
####################################################################################
|
||||
## File: Install-WindowsFeatures.ps1
|
||||
## Desc: Install Windows Features
|
||||
####################################################################################
|
||||
|
||||
$windowsFeatures = (Get-ToolsetContent).windowsFeatures
|
||||
|
||||
foreach ($feature in $windowsFeatures) {
|
||||
if ($feature.optionalFeature) {
|
||||
Write-Host "Activating Windows Optional Feature '$($feature.name)'..."
|
||||
Enable-WindowsOptionalFeature -Online -FeatureName $feature.name -NoRestart
|
||||
|
||||
$resultSuccess = $?
|
||||
} else {
|
||||
Write-Host "Activating Windows Feature '$($feature.name)'..."
|
||||
$arguments = @{
|
||||
Name = $feature.name
|
||||
IncludeAllSubFeature = [System.Convert]::ToBoolean($feature.includeAllSubFeatures)
|
||||
IncludeManagementTools = [System.Convert]::ToBoolean($feature.includeManagementTools)
|
||||
}
|
||||
|
||||
if ($feature.name -eq "NET-Framework-Features") {
|
||||
$arguments += @{ LogPath = $(Join-Path $env:IMAGE_FOLDER "NET-Framework-Features.log") }
|
||||
}
|
||||
$result = Install-WindowsFeature @arguments
|
||||
$resultSuccess = $result.Success
|
||||
}
|
||||
|
||||
if ($feature.name -eq "NET-Framework-Features") {
|
||||
$dotNetFeatureLog = Get-Content -Path $(Join-Path $env:IMAGE_FOLDER "NET-Framework-Features.log")
|
||||
Write-Host "The log of NET-Framework-Features"
|
||||
Write-Host $dotNetFeatureLog
|
||||
}
|
||||
|
||||
if ($resultSuccess) {
|
||||
Write-Host "Windows Feature '$($feature.name)' was activated successfully"
|
||||
} else {
|
||||
throw "Failed to activate Windows Feature '$($feature.name)'"
|
||||
}
|
||||
}
|
||||
|
||||
# it improves Android emulator launch on Windows Server
|
||||
# https://learn.microsoft.com/en-us/windows-server/virtualization/hyper-v/manage/manage-hyper-v-scheduler-types
|
||||
bcdedit /set hypervisorschedulertype root
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Failed to set hypervisorschedulertype to root"
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
################################################################################
|
||||
## File: Install-WindowsUpdates.ps1
|
||||
## Desc: Install Windows Updates.
|
||||
## Should be run at end, just before SoftwareReport and Finalize-VM.ps1.
|
||||
################################################################################
|
||||
|
||||
function Install-WindowsUpdates {
|
||||
Write-Host "Starting wuauserv"
|
||||
Start-Service -Name wuauserv -PassThru | Out-Host
|
||||
|
||||
# Temporarily exclude Windows update KB5034439 since it throws an error.
|
||||
# The known issue (https://support.microsoft.com/en-au/topic/kb5034439-windows-recovery-environment-update-for-azure-stack-hci-version-22h2-and-windows-server-2022-january-9-2024-6f9d26e6-784c-4503-a3c6-0beedda443ca)
|
||||
Write-Host "Getting list of available windows updates"
|
||||
|
||||
# Added KB5044030 to the excluded list since it is failing for 2025
|
||||
$excludedKBs = @()
|
||||
if (Test-IsWin25) {
|
||||
$excludedKBs = @("KB5034439", "KB5044030", "KB5044284")
|
||||
}
|
||||
else {
|
||||
$excludedKBs = @("KB5034439")
|
||||
}
|
||||
|
||||
|
||||
Get-WindowsUpdate -MicrosoftUpdate -NotKBArticleID $excludedKBs -OutVariable updates | Out-Host
|
||||
|
||||
if ( -not $updates ) {
|
||||
Write-Host "There are no windows updates to install"
|
||||
return
|
||||
}
|
||||
|
||||
Write-Host "Installing windows updates"
|
||||
|
||||
Get-WindowsUpdate -MicrosoftUpdate -NotKBArticleID $excludedKBs -AcceptAll -Install -IgnoreUserInput -IgnoreReboot | Out-Host
|
||||
|
||||
Write-Host "Validating windows updates installation"
|
||||
# Get-WUHistory doesn't support Windows Server 2022
|
||||
$notFailedUpdateNames = Get-WindowsUpdateStates | Where-Object { $_.State -in ("Installed", "Running") } | Select-Object -ExpandProperty Title
|
||||
# We ignore Microsoft Defender Antivirus updates; Azure service updates AV automatically
|
||||
$failedUpdates = $updates[0] | Where-Object Title -notmatch "Microsoft Defender Antivirus" | Where-Object { -not ($notFailedUpdateNames -match $_.KB) }
|
||||
|
||||
if ( $failedUpdates ) {
|
||||
throw "Windows updates failed to install: $($failedUpdates.KB)"
|
||||
}
|
||||
}
|
||||
|
||||
Install-WindowsUpdates
|
||||
|
||||
# Create complete windows update file
|
||||
New-Item -Path $env:windir -Name WindowsUpdateDone.txt -ItemType File | Out-Null
|
||||
@@ -0,0 +1,12 @@
|
||||
################################################################################
|
||||
## File: Install-WindowsUpdatesAfterReboot.ps1
|
||||
## Desc: Waits for Windows Updates to finish installing after reboot
|
||||
################################################################################
|
||||
|
||||
Invoke-ScriptBlockWithRetry -RetryCount 10 -RetryIntervalSeconds 120 -Command {
|
||||
$inProgress = Get-WindowsUpdateStates | Where-Object State -eq "Running" | Where-Object Title -notmatch "Microsoft Defender Antivirus"
|
||||
if ( $inProgress ) {
|
||||
$title = $inProgress.Title -join "`n"
|
||||
throw "Windows updates are still installing: $title"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
################################################################################
|
||||
## File: Install-Wix.ps1
|
||||
## Desc: Install WIX.
|
||||
################################################################################
|
||||
|
||||
Install-ChocoPackage wixtoolset -ArgumentList "--force"
|
||||
|
||||
Update-Environment
|
||||
$currentPath = [System.Environment]::GetEnvironmentVariable("PATH", "Machine")
|
||||
$newPath = $currentPath + ";$(Join-Path -Path $env:WIX -ChildPath "bin")"
|
||||
[Environment]::SetEnvironmentVariable("PATH", $newPath, "Machine")
|
||||
Update-Environment
|
||||
|
||||
Invoke-PesterTests -TestFile "Wix"
|
||||
@@ -0,0 +1,29 @@
|
||||
################################################################################
|
||||
## File: Install-Zstd.ps1
|
||||
## Desc: Install zstd
|
||||
################################################################################
|
||||
|
||||
$downloadUrl = Resolve-GithubReleaseAssetUrl `
|
||||
-Repo "facebook/zstd" `
|
||||
-Version "latest" `
|
||||
-UrlMatchPattern "zstd-*-win64.zip"
|
||||
$zstdArchivePath = Invoke-DownloadWithRetry $downloadUrl
|
||||
$zstdName = [IO.Path]::GetFileNameWithoutExtension($zstdArchivePath)
|
||||
|
||||
$toolPath = "C:\tools"
|
||||
$zstdPath = Join-Path $toolPath zstd
|
||||
$filesInArchive = 7z l $zstdArchivePath | Out-String
|
||||
|
||||
if ($filesInArchive.Contains($zstdName)) {
|
||||
Expand-7ZipArchive -Path $zstdArchivePath -DestinationPath $toolPath
|
||||
Invoke-ScriptBlockWithRetry -Command {
|
||||
Move-Item -Path "${zstdPath}*" -Destination $zstdPath -ErrorAction Stop
|
||||
}
|
||||
} else {
|
||||
Expand-7ZipArchive -Path $zstdArchivePath -DestinationPath $zstdPath
|
||||
}
|
||||
|
||||
# Add zstd-win64 to PATH
|
||||
Add-MachinePathItem $zstdPath
|
||||
|
||||
Invoke-PesterTests -TestFile "Tools" -TestName "Zstd"
|
||||
@@ -0,0 +1,253 @@
|
||||
using module ./software-report-base/SoftwareReport.psm1
|
||||
using module ./software-report-base/SoftwareReport.Nodes.psm1
|
||||
|
||||
$global:ErrorActionPreference = "Stop"
|
||||
$global:ProgressPreference = "SilentlyContinue"
|
||||
$ErrorView = "NormalView"
|
||||
Set-StrictMode -Version Latest
|
||||
|
||||
Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Android.psm1") -DisableNameChecking
|
||||
Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Browsers.psm1") -DisableNameChecking
|
||||
Import-Module (Join-Path $PSScriptRoot "SoftwareReport.CachedTools.psm1") -DisableNameChecking
|
||||
Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Common.psm1") -DisableNameChecking
|
||||
Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Databases.psm1") -DisableNameChecking
|
||||
Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Helpers.psm1") -DisableNameChecking
|
||||
Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Tools.psm1") -DisableNameChecking
|
||||
Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Java.psm1") -DisableNameChecking
|
||||
Import-Module (Join-Path $PSScriptRoot "SoftwareReport.WebServers.psm1") -DisableNameChecking
|
||||
Import-Module (Join-Path $PSScriptRoot "SoftwareReport.VisualStudio.psm1") -DisableNameChecking
|
||||
|
||||
# Software report
|
||||
$softwareReport = [SoftwareReport]::new($(Build-OSInfoSection))
|
||||
$optionalFeatures = $softwareReport.Root.AddHeader("Windows features")
|
||||
$optionalFeatures.AddToolVersion("Windows Subsystem for Linux (WSLv1):", "Enabled")
|
||||
$installedSoftware = $softwareReport.Root.AddHeader("Installed Software")
|
||||
|
||||
# Language and Runtime
|
||||
$languageAndRuntime = $installedSoftware.AddHeader("Language and Runtime")
|
||||
$languageAndRuntime.AddToolVersion("Bash", $(Get-BashVersion))
|
||||
$languageAndRuntime.AddToolVersion("Go", $(Get-GoVersion))
|
||||
$languageAndRuntime.AddToolVersion("Julia", $(Get-JuliaVersion))
|
||||
$languageAndRuntime.AddToolVersion("Kotlin", $(Get-KotlinVersion))
|
||||
$languageAndRuntime.AddToolVersion("LLVM", $(Get-LLVMVersion))
|
||||
$languageAndRuntime.AddToolVersion("Node", $(Get-NodeVersion))
|
||||
$languageAndRuntime.AddToolVersion("Perl", $(Get-PerlVersion))
|
||||
$languageAndRuntime.AddToolVersion("PHP", $(Get-PHPVersion))
|
||||
$languageAndRuntime.AddToolVersion("Python", $(Get-PythonVersion))
|
||||
$languageAndRuntime.AddToolVersion("Ruby", $(Get-RubyVersion))
|
||||
|
||||
# Package Management
|
||||
$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))
|
||||
$packageManagement.AddToolVersion("NPM", $(Get-NPMVersion))
|
||||
$packageManagement.AddToolVersion("NuGet", $(Get-NugetVersion))
|
||||
$packageManagement.AddToolVersion("pip", $(Get-PipVersion))
|
||||
$packageManagement.AddToolVersion("Pipx", $(Get-PipxVersion))
|
||||
$packageManagement.AddToolVersion("RubyGems", $(Get-RubyGemsVersion))
|
||||
$packageManagement.AddToolVersion("Vcpkg", $(Get-VcpkgVersion))
|
||||
$packageManagement.AddToolVersion("Yarn", $(Get-YarnVersion))
|
||||
|
||||
$packageManagement.AddHeader("Environment variables").AddTable($(Build-PackageManagementEnvironmentTable))
|
||||
|
||||
# Project Management
|
||||
$projectManagement = $installedSoftware.AddHeader("Project Management")
|
||||
$projectManagement.AddToolVersion("Ant", $(Get-AntVersion))
|
||||
$projectManagement.AddToolVersion("Gradle", $(Get-GradleVersion))
|
||||
$projectManagement.AddToolVersion("Maven", $(Get-MavenVersion))
|
||||
$projectManagement.AddToolVersion("sbt", $(Get-SbtVersion))
|
||||
|
||||
# Tools
|
||||
$tools = $installedSoftware.AddHeader("Tools")
|
||||
$tools.AddToolVersion("7zip", $(Get-7zipVersion))
|
||||
$tools.AddToolVersion("aria2", $(Get-Aria2Version))
|
||||
$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))
|
||||
$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))
|
||||
$tools.AddToolVersion("Git", $(Get-GitVersion))
|
||||
$tools.AddToolVersion("Git LFS", $(Get-GitLFSVersion))
|
||||
if (Test-IsWin19) {
|
||||
$tools.AddToolVersion("Google Cloud CLI", $(Get-GoogleCloudCLIVersion))
|
||||
}
|
||||
$tools.AddToolVersion("ImageMagick", $(Get-ImageMagickVersion))
|
||||
if (-not (Test-IsWin25)) {
|
||||
$tools.AddToolVersion("InnoSetup", $(Get-InnoSetupVersion))
|
||||
}
|
||||
$tools.AddToolVersion("jq", $(Get-JQVersion))
|
||||
$tools.AddToolVersion("Kind", $(Get-KindVersion))
|
||||
$tools.AddToolVersion("Kubectl", $(Get-KubectlVersion))
|
||||
if (-not (Test-IsWin25)) {
|
||||
$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)) {
|
||||
$tools.AddToolVersion("NSIS", $(Get-NSISVersion))
|
||||
}
|
||||
$tools.AddToolVersion("OpenSSL", $(Get-OpenSSLVersion))
|
||||
$tools.AddToolVersion("Packer", $(Get-PackerVersion))
|
||||
if (Test-IsWin19) {
|
||||
$tools.AddToolVersion("Parcel", $(Get-ParcelVersion))
|
||||
}
|
||||
$tools.AddToolVersion("Pulumi", $(Get-PulumiVersion))
|
||||
$tools.AddToolVersion("R", $(Get-RVersion))
|
||||
$tools.AddToolVersion("Service Fabric SDK", $(Get-ServiceFabricSDKVersion))
|
||||
$tools.AddToolVersion("Stack", $(Get-StackVersion))
|
||||
#$tools.AddToolVersion("Swift", $(Get-SwiftVersion))
|
||||
if (-not (Test-IsWin25)) {
|
||||
$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))
|
||||
$tools.AddToolVersion("yamllint", $(Get-YAMLLintVersion))
|
||||
$tools.AddToolVersion("zstd", $(Get-ZstdVersion))
|
||||
|
||||
# CLI Tools
|
||||
$cliTools = $installedSoftware.AddHeader("CLI Tools")
|
||||
if (-not (Test-IsWin25)) {
|
||||
$cliTools.AddToolVersion("Alibaba Cloud CLI", $(Get-AlibabaCLIVersion))
|
||||
}
|
||||
$cliTools.AddToolVersion("AWS CLI", $(Get-AWSCLIVersion))
|
||||
$cliTools.AddToolVersion("AWS SAM CLI", $(Get-AWSSAMVersion))
|
||||
$cliTools.AddToolVersion("AWS Session Manager CLI", $(Get-AWSSessionManagerVersion))
|
||||
$cliTools.AddToolVersion("Azure CLI", $(Get-AzureCLIVersion))
|
||||
$cliTools.AddToolVersion("Azure DevOps CLI extension", $(Get-AzureDevopsExtVersion))
|
||||
if (Test-IsWin19) {
|
||||
$cliTools.AddToolVersion("Cloud Foundry CLI", $(Get-CloudFoundryVersion))
|
||||
}
|
||||
$cliTools.AddToolVersion("GitHub CLI", $(Get-GHVersion))
|
||||
|
||||
# Rust Tools
|
||||
Initialize-RustEnvironment
|
||||
$rustTools = $installedSoftware.AddHeader("Rust Tools")
|
||||
$rustTools.AddToolVersion("Cargo", $(Get-RustCargoVersion))
|
||||
$rustTools.AddToolVersion("Rust", $(Get-RustVersion))
|
||||
$rustTools.AddToolVersion("Rustdoc", $(Get-RustdocVersion))
|
||||
$rustTools.AddToolVersion("Rustup", $(Get-RustupVersion))
|
||||
|
||||
$rustToolsPackages = $rustTools.AddHeader("Packages")
|
||||
if (-not (Test-IsWin25)) {
|
||||
$rustToolsPackages.AddToolVersion("bindgen", $(Get-BindgenVersion))
|
||||
}
|
||||
$rustToolsPackages.AddToolVersion("cargo-audit", $(Get-CargoAuditVersion))
|
||||
$rustToolsPackages.AddToolVersion("cargo-outdated", $(Get-CargoOutdatedVersion))
|
||||
$rustToolsPackages.AddToolVersion("cbindgen", $(Get-CbindgenVersion))
|
||||
$rustToolsPackages.AddToolVersion("Clippy", $(Get-RustClippyVersion))
|
||||
$rustToolsPackages.AddToolVersion("Rustfmt", $(Get-RustfmtVersion))
|
||||
|
||||
# Browsers and Drivers
|
||||
$browsersAndWebdrivers = $installedSoftware.AddHeader("Browsers and Drivers")
|
||||
$browsersAndWebdrivers.AddNodes($(Build-BrowserSection))
|
||||
$browsersAndWebdrivers.AddHeader("Environment variables").AddTable($(Build-BrowserWebdriversEnvironmentTable))
|
||||
|
||||
# Java
|
||||
$installedSoftware.AddHeader("Java").AddTable($(Get-JavaVersions))
|
||||
|
||||
# Shells
|
||||
$installedSoftware.AddHeader("Shells").AddTable($(Get-ShellTarget))
|
||||
|
||||
# MSYS2
|
||||
$msys2 = $installedSoftware.AddHeader("MSYS2")
|
||||
$msys2.AddToolVersion("Pacman", $(Get-PacmanVersion))
|
||||
|
||||
$notes = @'
|
||||
Location: C:\msys64
|
||||
|
||||
Note: MSYS2 is pre-installed on image but not added to PATH.
|
||||
'@
|
||||
$msys2.AddHeader("Notes").AddNote($notes)
|
||||
|
||||
# BizTalk Server
|
||||
if (Test-IsWin19)
|
||||
{
|
||||
$installedSoftware.AddHeader("BizTalk Server").AddNode($(Get-BizTalkVersion))
|
||||
}
|
||||
|
||||
# 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))
|
||||
|
||||
# Database tools
|
||||
$databaseTools = $installedSoftware.AddHeader("Database tools")
|
||||
$databaseTools.AddToolVersion("Azure CosmosDb Emulator", $(Get-AzCosmosDBEmulatorVersion))
|
||||
$databaseTools.AddToolVersion("DacFx", $(Get-DacFxVersion))
|
||||
$databaseTools.AddToolVersion("MySQL", $(Get-MySQLVersion))
|
||||
$databaseTools.AddToolVersion("SQL OLEDB Driver", $(Get-SQLOLEDBDriverVersion))
|
||||
$databaseTools.AddToolVersion("SQLPS", $(Get-SQLPSVersion))
|
||||
if (Test-IsWin25) {
|
||||
$databaseTools.AddToolVersion("MongoDB Shell (mongosh)", $(Get-MongoshVersion))
|
||||
}
|
||||
# Web Servers
|
||||
$installedSoftware.AddHeader("Web Servers").AddTable($(Build-WebServersSection))
|
||||
|
||||
# Visual Studio
|
||||
$vsTable = Get-VisualStudioVersion
|
||||
$visualStudio = $installedSoftware.AddHeader($vsTable.Name)
|
||||
$visualStudio.AddTable($vsTable)
|
||||
|
||||
$workloads = $visualStudio.AddHeader("Workloads, components and extensions")
|
||||
$workloads.AddTable((Get-VisualStudioComponents) + (Get-VisualStudioExtensions))
|
||||
|
||||
$msVisualCpp = $visualStudio.AddHeader("Microsoft Visual C++")
|
||||
$msVisualCpp.AddTable($(Get-VisualCPPComponents))
|
||||
|
||||
$visualStudio.AddToolVersionsList("Installed Windows SDKs", $(Get-WindowsSDKs).Versions, '^.+')
|
||||
|
||||
# .NET Core Tools
|
||||
$netCoreTools = $installedSoftware.AddHeader(".NET Core Tools")
|
||||
if (Test-IsWin19) {
|
||||
# Visual Studio 2019 brings own version of .NET Core which is different from latest official version
|
||||
$netCoreTools.AddToolVersionsListInline(".NET Core SDK", $(Get-DotnetSdks).Versions, '^\d+\.\d+\.\d{2}')
|
||||
} else {
|
||||
$netCoreTools.AddToolVersionsListInline(".NET Core SDK", $(Get-DotnetSdks).Versions, '^\d+\.\d+\.\d')
|
||||
}
|
||||
$netCoreTools.AddToolVersionsListInline(".NET Framework", $(Get-DotnetFrameworkVersions), '^.+')
|
||||
Get-DotnetRuntimes | ForEach-Object {
|
||||
$netCoreTools.AddToolVersionsListInline($_.Runtime, $_.Versions, '^.+')
|
||||
}
|
||||
$netCoreTools.AddNodes($(Get-DotnetTools))
|
||||
|
||||
# PowerShell Tools
|
||||
$psTools = $installedSoftware.AddHeader("PowerShell Tools")
|
||||
$psTools.AddToolVersion("PowerShell", $(Get-PowershellCoreVersion))
|
||||
|
||||
$psModules = $psTools.AddHeader("Powershell Modules")
|
||||
$psModules.AddNodes($(Get-PowerShellModules))
|
||||
|
||||
$azPsNotes = @'
|
||||
Azure PowerShell module 2.1.0 and AzureRM PowerShell module 2.1.0 are installed
|
||||
and are available via 'Get-Module -ListAvailable'.
|
||||
All other versions are saved but not installed.
|
||||
'@
|
||||
$psModules.AddNote($azPsNotes)
|
||||
|
||||
# Android
|
||||
$android = $installedSoftware.AddHeader("Android")
|
||||
$android.AddTable($(Build-AndroidTable))
|
||||
|
||||
$android.AddHeader("Environment variables").AddTable($(Build-AndroidEnvironmentTable))
|
||||
|
||||
# Cached Docker images
|
||||
$installedSoftware.AddHeader("Cached Docker images").AddTable($(Get-CachedDockerImagesTableData))
|
||||
|
||||
# Generate reports
|
||||
$softwareReport.ToJson() | Out-File -FilePath "C:\software-report.json" -Encoding UTF8NoBOM
|
||||
$softwareReport.ToMarkdown() | Out-File -FilePath "C:\software-report.md" -Encoding UTF8NoBOM
|
||||
@@ -0,0 +1,174 @@
|
||||
Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Helpers.psm1") -DisableNameChecking
|
||||
|
||||
function Split-TableRowByColumns {
|
||||
param(
|
||||
[string] $Row
|
||||
)
|
||||
return $Row.Split("|") | ForEach-Object { $_.trim() }
|
||||
}
|
||||
|
||||
function Get-AndroidSDKRoot {
|
||||
param(
|
||||
[string] $ComponentName
|
||||
)
|
||||
$path = Join-Path $env:ANDROID_HOME $ComponentName
|
||||
return "Location $path"
|
||||
}
|
||||
|
||||
function Build-AndroidTable {
|
||||
$packageInfo = Get-AndroidInstalledPackages
|
||||
return @(
|
||||
@{
|
||||
"Package" = "Android Command Line Tools"
|
||||
"Version" = Get-AndroidCommandLineToolsVersion
|
||||
},
|
||||
@{
|
||||
"Package" = "Android Emulator"
|
||||
"Version" = Get-AndroidPackageVersions -PackageInfo $packageInfo -MatchedString "Android Emulator"
|
||||
},
|
||||
@{
|
||||
"Package" = "Android SDK Build-tools"
|
||||
"Version" = Get-AndroidBuildToolVersions -PackageInfo $packageInfo
|
||||
},
|
||||
@{
|
||||
"Package" = "Android SDK Platforms"
|
||||
"Version" = Get-AndroidPlatformVersions -PackageInfo $packageInfo
|
||||
},
|
||||
@{
|
||||
"Package" = "Android SDK Platform-Tools"
|
||||
"Version" = Get-AndroidPackageVersions -PackageInfo $packageInfo -MatchedString "Android SDK Platform-Tools"
|
||||
},
|
||||
@{
|
||||
"Package" = "Android Support Repository"
|
||||
"Version" = Get-AndroidPackageVersions -PackageInfo $packageInfo -MatchedString "Android Support Repository"
|
||||
},
|
||||
@{
|
||||
"Package" = "CMake"
|
||||
"Version" = Get-AndroidPackageVersions -PackageInfo $packageInfo -MatchedString "cmake"
|
||||
},
|
||||
@{
|
||||
"Package" = "Google APIs"
|
||||
"Version" = Get-AndroidGoogleAPIsVersions -PackageInfo $packageInfo
|
||||
},
|
||||
@{
|
||||
"Package" = "Google Play services"
|
||||
"Version" = Get-AndroidPackageVersions -PackageInfo $packageInfo -MatchedString "Google Play services"
|
||||
},
|
||||
@{
|
||||
"Package" = "Google Repository"
|
||||
"Version" = Get-AndroidPackageVersions -PackageInfo $packageInfo -MatchedString "Google Repository"
|
||||
},
|
||||
@{
|
||||
"Package" = "NDK"
|
||||
"Version" = Get-AndroidNdkVersions -PackageInfo $packageInfo
|
||||
},
|
||||
@{
|
||||
"Package" = "SDK Patch Applier v4"
|
||||
"Version" = Get-AndroidPackageVersions -PackageInfo $packageInfo -MatchedString "SDK Patch Applier v4"
|
||||
}
|
||||
) | Where-Object { $_.Version } | ForEach-Object {
|
||||
[PSCustomObject] @{
|
||||
"Package Name" = $_.Package
|
||||
"Version" = $_.Version
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Get-AndroidPackageVersions {
|
||||
param (
|
||||
[Parameter(Mandatory)]
|
||||
[object] $PackageInfo,
|
||||
[Parameter(Mandatory)]
|
||||
[object] $MatchedString
|
||||
)
|
||||
|
||||
$versions = $packageInfo | Where-Object { $_ -Match $MatchedString } | ForEach-Object {
|
||||
$packageInfoParts = Split-TableRowByColumns $_
|
||||
return $packageInfoParts[1]
|
||||
}
|
||||
return ($versions -Join "<br>")
|
||||
}
|
||||
|
||||
function Get-AndroidPlatformVersions {
|
||||
param (
|
||||
[Parameter(Mandatory)]
|
||||
[object] $PackageInfo
|
||||
)
|
||||
|
||||
$versions = $packageInfo | Where-Object { $_ -Match "Android SDK Platform " } | ForEach-Object {
|
||||
$packageInfoParts = Split-TableRowByColumns $_
|
||||
$revision = $packageInfoParts[1]
|
||||
$version = $packageInfoParts[0].split(";")[1]
|
||||
return "$version (rev $revision)"
|
||||
}
|
||||
[array]::Reverse($versions)
|
||||
return ($versions -Join "<br>")
|
||||
}
|
||||
|
||||
function Get-AndroidCommandLineToolsVersion {
|
||||
$commandLineTools = (Join-Path $env:ANDROID_HOME "cmdline-tools\latest\bin\sdkmanager.bat")
|
||||
(cmd /c "$commandLineTools --version 2>NUL" | Out-String).Trim() -match "(?<version>^(\d+\.){1,}\d+$)" | Out-Null
|
||||
$commandLineToolsVersion = $Matches.Version
|
||||
return $commandLineToolsVersion
|
||||
}
|
||||
|
||||
function Get-AndroidBuildToolVersions {
|
||||
param (
|
||||
[Parameter(Mandatory)]
|
||||
[object] $PackageInfo
|
||||
)
|
||||
|
||||
$versions = $packageInfo | Where-Object { $_ -Match "Android SDK Build-Tools" } | ForEach-Object {
|
||||
$packageInfoParts = Split-TableRowByColumns $_
|
||||
return $packageInfoParts[1]
|
||||
}
|
||||
$groupVersions = @()
|
||||
$versions | ForEach-Object {
|
||||
$majorVersion = $_.Split(".")[0]
|
||||
$groupVersions += $versions | Where-Object { $_.StartsWith($majorVersion) } | Join-String -Separator " "
|
||||
}
|
||||
return ($groupVersions | Sort-Object -Descending -Unique | Join-String -Separator "<br>")
|
||||
}
|
||||
|
||||
function Get-AndroidGoogleAPIsVersions {
|
||||
param (
|
||||
[Parameter(Mandatory)]
|
||||
[object] $PackageInfo
|
||||
)
|
||||
|
||||
$versions = $packageInfo | Where-Object { $_ -Match "addon-google_apis" } | ForEach-Object {
|
||||
$packageInfoParts = Split-TableRowByColumns $_
|
||||
return $packageInfoParts[0].split(";")[1]
|
||||
}
|
||||
return ($versions -Join "<br>")
|
||||
}
|
||||
|
||||
function Get-AndroidNdkVersions {
|
||||
param (
|
||||
[Parameter(Mandatory)]
|
||||
[object] $PackageInfo
|
||||
)
|
||||
|
||||
$ndkDefaultFullVersion = Get-ChildItem $env:ANDROID_NDK_HOME -Name
|
||||
|
||||
$versions = $packageInfo | Where-Object { $_ -Match "ndk;" } | ForEach-Object {
|
||||
$version = (Split-TableRowByColumns $_)[1]
|
||||
if ($version -eq $ndkDefaultFullVersion) {
|
||||
$version += " (default)"
|
||||
}
|
||||
$version
|
||||
}
|
||||
return ($versions -Join "<br>")
|
||||
}
|
||||
|
||||
function Build-AndroidEnvironmentTable {
|
||||
$androidVersions = Get-Item env:ANDROID_*
|
||||
|
||||
$shoulddResolveLink = 'ANDROID_NDK', 'ANDROID_NDK_HOME', 'ANDROID_NDK_ROOT', 'ANDROID_NDK_LATEST_HOME'
|
||||
return $androidVersions | Sort-Object -Property Name | ForEach-Object {
|
||||
[PSCustomObject] @{
|
||||
"Name" = $_.Name
|
||||
"Value" = if ($shoulddResolveLink.Contains($_.Name )) { Get-PathWithLink($_.Value) } else {$_.Value}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
$browsers = @{
|
||||
chrome = @{
|
||||
Name="Google Chrome";
|
||||
File="chrome.exe"
|
||||
};
|
||||
edge = @{
|
||||
Name="Microsoft Edge";
|
||||
File="msedge.exe"
|
||||
};
|
||||
firefox = @{
|
||||
Name="Mozilla Firefox";
|
||||
File="firefox.exe"
|
||||
}
|
||||
}
|
||||
|
||||
$webDrivers = @{
|
||||
chrome = @{
|
||||
Name="Chrome Driver";
|
||||
Path="C:\SeleniumWebDrivers\ChromeDriver"
|
||||
};
|
||||
edge = @{
|
||||
Name="Microsoft Edge Driver";
|
||||
Path="C:\SeleniumWebDrivers\EdgeDriver"
|
||||
};
|
||||
firefox = @{
|
||||
Name="Gecko Driver";
|
||||
Path="C:\SeleniumWebDrivers\GeckoDriver"
|
||||
};
|
||||
iexplorer = @{
|
||||
Name="IE Driver";
|
||||
Path="C:\SeleniumWebDrivers\IEDriver"
|
||||
}
|
||||
}
|
||||
|
||||
function Build-BrowserSection {
|
||||
return @(
|
||||
$(Get-BrowserVersion -Browser "chrome"),
|
||||
$(Get-SeleniumWebDriverVersion -Driver "chrome"),
|
||||
$(Get-BrowserVersion -Browser "edge"),
|
||||
$(Get-SeleniumWebDriverVersion -Driver "edge"),
|
||||
$(Get-BrowserVersion -Browser "firefox"),
|
||||
$(Get-SeleniumWebDriverVersion -Driver "firefox"),
|
||||
$(Get-SeleniumWebDriverVersion -Driver "iexplorer"),
|
||||
$(Get-SeleniumVersion)
|
||||
)
|
||||
}
|
||||
|
||||
function Get-BrowserVersion {
|
||||
param(
|
||||
[string] $Browser
|
||||
)
|
||||
$browserName = $browsers.$Browser.Name
|
||||
$browserFile = $browsers.$Browser.File
|
||||
$registryKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\$browserFile"
|
||||
$browserVersion = (Get-Item (Get-ItemProperty $registryKey)."(Default)").VersionInfo.FileVersion
|
||||
return [ToolVersionNode]::new($browserName, $browserVersion)
|
||||
}
|
||||
|
||||
function Get-SeleniumWebDriverVersion {
|
||||
param(
|
||||
[string] $Driver
|
||||
)
|
||||
$driverName = $webDrivers.$Driver.Name
|
||||
$driverPath = $webDrivers.$Driver.Path
|
||||
$versionFileName = "versioninfo.txt";
|
||||
$webDriverVersion = Get-Content -Path "$driverPath\$versionFileName"
|
||||
return [ToolVersionNode]::new($driverName, $webDriverVersion)
|
||||
}
|
||||
|
||||
function Get-SeleniumVersion {
|
||||
$seleniumBinaryName = "selenium-server"
|
||||
$fullSeleniumVersion = (Get-ChildItem "C:\selenium\${seleniumBinaryName}-*").Name -replace "${seleniumBinaryName}-"
|
||||
return [ToolVersionNode]::new("Selenium server", $fullSeleniumVersion)
|
||||
}
|
||||
|
||||
function Build-BrowserWebdriversEnvironmentTable {
|
||||
return @(
|
||||
@{
|
||||
"Name" = "CHROMEWEBDRIVER"
|
||||
"Value" = $env:CHROMEWEBDRIVER
|
||||
},
|
||||
@{
|
||||
"Name" = "EDGEWEBDRIVER"
|
||||
"Value" = $env:EDGEWEBDRIVER
|
||||
},
|
||||
@{
|
||||
"Name" = "GECKOWEBDRIVER"
|
||||
"Value" = $env:GECKOWEBDRIVER
|
||||
},
|
||||
@{
|
||||
"Name" = "SELENIUM_JAR_PATH"
|
||||
"Value" = $env:SELENIUM_JAR_PATH
|
||||
}
|
||||
) | ForEach-Object {
|
||||
[PSCustomObject] @{
|
||||
"Name" = $_.Name
|
||||
"Value" = $_.Value
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
function Get-ToolcacheGoVersions {
|
||||
$toolcachePath = Join-Path $env:AGENT_TOOLSDIRECTORY "Go"
|
||||
return Get-ChildItem $toolcachePath -Name | Sort-Object { [Version] $_ }
|
||||
}
|
||||
|
||||
function Get-ToolcacheNodeVersions {
|
||||
$toolcachePath = Join-Path $env:AGENT_TOOLSDIRECTORY "Node"
|
||||
return Get-ChildItem $toolcachePath -Name | Sort-Object { [Version] $_ }
|
||||
}
|
||||
|
||||
function Get-ToolcachePythonVersions {
|
||||
$toolcachePath = Join-Path $env:AGENT_TOOLSDIRECTORY "Python"
|
||||
return Get-ChildItem $toolcachePath -Name | Sort-Object { [Version] $_ }
|
||||
}
|
||||
|
||||
function Get-ToolcacheRubyVersions {
|
||||
$toolcachePath = Join-Path $env:AGENT_TOOLSDIRECTORY "Ruby"
|
||||
return Get-ChildItem $toolcachePath -Name | Sort-Object { [Version] $_ }
|
||||
}
|
||||
|
||||
function Get-ToolcachePyPyVersions {
|
||||
$toolcachePath = Join-Path $env:AGENT_TOOLSDIRECTORY "PyPy"
|
||||
Get-ChildItem -Path $toolcachePath -Name | Sort-Object { [Version] $_ } | ForEach-Object {
|
||||
$pypyRootPath = Join-Path $toolcachePath $_ "x86"
|
||||
[string] $pypyVersionOutput = & "$pypyRootPath\python.exe" -c "import sys;print(sys.version)"
|
||||
$pypyVersionOutput -match "^([\d\.]+) \(.+\) \[PyPy ([\d\.]+\S*) .+]$" | Out-Null
|
||||
return "{0} [PyPy {1}]" -f $Matches[1], $Matches[2]
|
||||
}
|
||||
}
|
||||
|
||||
function Build-CachedToolsSection
|
||||
{
|
||||
return @(
|
||||
[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'),
|
||||
[ToolVersionsListNode]::new("Ruby", $(Get-ToolcacheRubyVersions), '^\d+\.\d+', 'List')
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,329 @@
|
||||
function Initialize-RustEnvironment {
|
||||
$env:RUSTUP_HOME = "C:\Users\Default\.rustup"
|
||||
$env:CARGO_HOME = "C:\Users\Default\.cargo"
|
||||
$env:Path += ";$env:CARGO_HOME\bin"
|
||||
}
|
||||
|
||||
function Get-OSName {
|
||||
return (Get-CimInstance -ClassName Win32_OperatingSystem).Caption | Get-StringPart -Part 1,2,3
|
||||
}
|
||||
|
||||
function Get-OSVersion {
|
||||
$OSVersion = (Get-CimInstance -ClassName Win32_OperatingSystem).Version
|
||||
$OSBuild = (Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion' UBR).UBR
|
||||
return "$OSVersion Build $OSBuild"
|
||||
}
|
||||
|
||||
function Build-OSInfoSection {
|
||||
$osInfoNode = [HeaderNode]::new($(Get-OSName))
|
||||
$osInfoNode.AddToolVersion("OS Version:", $(Get-OSVersion))
|
||||
$osInfoNode.AddToolVersion("Image Version:", $env:IMAGE_VERSION)
|
||||
return $osInfoNode
|
||||
}
|
||||
|
||||
function Get-BashVersion {
|
||||
bash --% -c 'echo ${BASH_VERSION}'
|
||||
}
|
||||
|
||||
function Get-RustVersion {
|
||||
rustc --version | Get-StringPart -Part 1
|
||||
}
|
||||
|
||||
function Get-RustupVersion {
|
||||
cmd /c "rustup --version 2>NUL" | Get-StringPart -Part 1
|
||||
}
|
||||
|
||||
function Get-RustCargoVersion {
|
||||
cargo --version | Get-StringPart -Part 1
|
||||
}
|
||||
|
||||
function Get-RustdocVersion {
|
||||
rustdoc --version | Get-StringPart -Part 1
|
||||
}
|
||||
|
||||
function Get-RustfmtVersion {
|
||||
rustfmt --version | Get-StringPart -Part 1 | Get-StringPart -Part 0 -Delimiter ('-')
|
||||
}
|
||||
|
||||
function Get-RustClippyVersion {
|
||||
cargo clippy --version | Get-StringPart -Part 1
|
||||
}
|
||||
|
||||
function Get-BindgenVersion {
|
||||
bindgen --version | Get-StringPart -Part 1
|
||||
}
|
||||
|
||||
function Get-CbindgenVersion {
|
||||
cbindgen --version | Get-StringPart -Part 1
|
||||
}
|
||||
|
||||
function Get-CargoAuditVersion {
|
||||
cargo-audit --version | Get-StringPart -Part 1
|
||||
}
|
||||
|
||||
function Get-CargoOutdatedVersion {
|
||||
cargo outdated --version | Get-StringPart -Part 1
|
||||
}
|
||||
|
||||
function Get-PythonVersion {
|
||||
python --version | Get-StringPart -Part 1
|
||||
}
|
||||
|
||||
function Get-PowershellCoreVersion {
|
||||
pwsh --version | Get-StringPart -Part 1
|
||||
}
|
||||
|
||||
function Get-RubyVersion {
|
||||
ruby --version | Get-StringPart -Part 1
|
||||
}
|
||||
|
||||
function Get-GoVersion {
|
||||
go version | Get-StringPart -Part 2 | Get-StringPart -Part 1 -Delimiter ('o')
|
||||
}
|
||||
|
||||
function Get-KotlinVersion {
|
||||
cmd /c "kotlinc -version 2>&1" | Get-StringPart -Part 2
|
||||
}
|
||||
|
||||
function Get-PHPVersion {
|
||||
php --version | Out-String | Get-StringPart -Part 1
|
||||
}
|
||||
|
||||
function Get-JuliaVersion {
|
||||
julia --version | Get-StringPart -Part 2
|
||||
}
|
||||
|
||||
function Get-LLVMVersion {
|
||||
(clang --version) -match "clang" | Get-StringPart -Part 2
|
||||
}
|
||||
|
||||
function Get-PerlVersion {
|
||||
($(perl --version) | Out-String) -match "\(v(?<version>\d+\.\d+\.\d+)\)" | Out-Null
|
||||
$perlVersion = $Matches.Version
|
||||
return $perlVersion
|
||||
}
|
||||
|
||||
function Get-NodeVersion {
|
||||
node --version | Get-StringPart -Part 0 -Delimiter ('v')
|
||||
}
|
||||
|
||||
function Get-ChocoVersion {
|
||||
choco --version
|
||||
}
|
||||
|
||||
function Get-VcpkgVersion {
|
||||
$commitId = git -C "C:\vcpkg" rev-parse --short HEAD
|
||||
return "(build from commit $commitId)"
|
||||
}
|
||||
|
||||
function Get-NPMVersion {
|
||||
npm -version
|
||||
}
|
||||
|
||||
function Get-YarnVersion {
|
||||
yarn -version
|
||||
}
|
||||
|
||||
function Get-RubyGemsVersion {
|
||||
gem --version
|
||||
}
|
||||
|
||||
function Get-HelmVersion {
|
||||
($(helm version --short) | Out-String) -match "v(?<version>\d+\.\d+\.\d+)" | Out-Null
|
||||
$helmVersion = $Matches.Version
|
||||
return $helmVersion
|
||||
}
|
||||
|
||||
function Get-PipVersion {
|
||||
(pip --version) -match "pip" | Get-StringPart -Part 1, 4, 5
|
||||
}
|
||||
|
||||
function Get-CondaVersion {
|
||||
$condaVersion = ((& "$env:CONDA\Scripts\conda.exe" --version) -replace "^conda").Trim()
|
||||
return "$condaVersion (pre-installed on the image but not added to PATH)"
|
||||
}
|
||||
|
||||
function Get-ComposerVersion {
|
||||
composer --version | Get-StringPart -Part 2
|
||||
}
|
||||
|
||||
function Get-NugetVersion {
|
||||
(nuget help) -match "Nuget Version" | Get-StringPart -Part 2
|
||||
}
|
||||
|
||||
function Get-AntVersion {
|
||||
ant -version | Get-StringPart -Part 3
|
||||
}
|
||||
|
||||
function Get-MavenVersion {
|
||||
(mvn -version) -match "Apache Maven" | Get-StringPart -Part 2
|
||||
}
|
||||
|
||||
function Get-GradleVersion {
|
||||
($(gradle -version) | Out-String) -match "Gradle (?<version>\d+\.\d+)" | Out-Null
|
||||
$gradleVersion = $Matches.Version
|
||||
return $gradleVersion
|
||||
}
|
||||
|
||||
function Get-SbtVersion {
|
||||
(sbt -version) -match "sbt script" | Get-StringPart -Part 3
|
||||
}
|
||||
|
||||
function Get-DotnetSdks {
|
||||
$sdksRawList = dotnet --list-sdks
|
||||
$sdkVersions = $sdksRawList | Foreach-Object { $_.Split()[0] }
|
||||
$sdkPath = $sdksRawList[0].Split(' ', 2)[1] -replace '\[|]'
|
||||
[PSCustomObject]@{
|
||||
Versions = $sdkVersions
|
||||
Path = $sdkPath
|
||||
}
|
||||
}
|
||||
|
||||
function Get-DotnetTools {
|
||||
$env:Path += ";C:\Users\Default\.dotnet\tools"
|
||||
$dotnetTools = (Get-ToolsetContent).dotnet.tools
|
||||
|
||||
$toolsList = @()
|
||||
|
||||
foreach ($dotnetTool in $dotnetTools) {
|
||||
$version = Invoke-Expression $dotnetTool.getversion
|
||||
$toolsList += [ToolVersionNode]::new($dotnetTool.name, $version)
|
||||
}
|
||||
return $toolsList
|
||||
}
|
||||
|
||||
function Get-DotnetRuntimes {
|
||||
$runtimesRawList = dotnet --list-runtimes
|
||||
$runtimesRawList | Group-Object { $_.Split()[0] } | ForEach-Object {
|
||||
$runtimeName = $_.Name
|
||||
$runtimeVersions = $_.Group | Foreach-Object { $_.split()[1] }
|
||||
$runtimePath = $_.Group[0].Split(' ', 3)[2] -replace '\[|]'
|
||||
[PSCustomObject]@{
|
||||
"Runtime" = $runtimeName
|
||||
"Versions" = $runtimeVersions
|
||||
"Path" = $runtimePath
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Get-DotnetFrameworkVersions {
|
||||
$path = "${env:ProgramFiles(x86)}\Microsoft SDKs\Windows\*\*\NETFX * Tools"
|
||||
return Get-ChildItem -Path $path -Directory | ForEach-Object { $_.Name | Get-StringPart -Part 1 }
|
||||
}
|
||||
|
||||
function Get-PowerShellAzureModules {
|
||||
[Array] $result = @()
|
||||
$defaultAzureModuleVersion = "2.1.0"
|
||||
|
||||
[Array] $azInstalledModules = Get-ChildItem -Path "C:\Modules\az_*" -Directory | ForEach-Object { $_.Name.Split("_")[1] }
|
||||
if ($azInstalledModules.Count -gt 0) {
|
||||
$result += [ToolVersionsListNode]::new("Az", $($azInstalledModules), '^\d+\.\d+', "Inline")
|
||||
}
|
||||
|
||||
[Array] $azureInstalledModules = Get-ChildItem -Path "C:\Modules\azure_*" -Directory | ForEach-Object { $_.Name.Split("_")[1] } | ForEach-Object { if ($_ -eq $defaultAzureModuleVersion) { "$($_) (Default)" } else { $_ } }
|
||||
if ($azureInstalledModules.Count -gt 0) {
|
||||
$result += [ToolVersionsListNode]::new("Azure", $($azureInstalledModules), '^\d+\.\d+', "Inline")
|
||||
}
|
||||
|
||||
[Array] $azurermInstalledModules = Get-ChildItem -Path "C:\Modules\azurerm_*" -Directory | ForEach-Object { $_.Name.Split("_")[1] } | ForEach-Object { if ($_ -eq $defaultAzureModuleVersion) { "$($_) (Default)" } else { $_ } }
|
||||
if ($azurermInstalledModules.Count -gt 0) {
|
||||
$result += [ToolVersionsListNode]::new("AzureRM", $($azurermInstalledModules), '^\d+\.\d+', "Inline")
|
||||
}
|
||||
|
||||
[Array] $azCachedModules = Get-ChildItem -Path "C:\Modules\az_*.zip" -File | ForEach-Object { $_.Name.Split("_")[1] }
|
||||
if ($azCachedModules.Count -gt 0) {
|
||||
$result += [ToolVersionsListNode]::new("Az (Cached)", $($azCachedModules), '^\d+\.\d+', "Inline")
|
||||
}
|
||||
|
||||
[Array] $azureCachedModules = Get-ChildItem -Path "C:\Modules\azure_*.zip" -File | ForEach-Object { $_.Name.Split("_")[1] }
|
||||
if ($azureCachedModules.Count -gt 0) {
|
||||
$result += [ToolVersionsListNode]::new("Azure (Cached)", $($azureCachedModules), '^\d+\.\d+', "Inline")
|
||||
}
|
||||
|
||||
[Array] $azurermCachedModules = Get-ChildItem -Path "C:\Modules\azurerm_*.zip" -File | ForEach-Object { $_.Name.Split("_")[1] }
|
||||
if ($azurermCachedModules.Count -gt 0) {
|
||||
$result += [ToolVersionsListNode]::new("AzureRM (Cached)", $($azurermCachedModules), '^\d+\.\d+', "Inline")
|
||||
}
|
||||
|
||||
return $result
|
||||
}
|
||||
|
||||
function Get-PowerShellModules {
|
||||
[Array] $result = @()
|
||||
|
||||
$result += Get-PowerShellAzureModules
|
||||
|
||||
$result += (Get-ToolsetContent).powershellModules.name | Sort-Object | ForEach-Object {
|
||||
$moduleName = $_
|
||||
$moduleVersions = Get-Module -Name $moduleName -ListAvailable | Select-Object -ExpandProperty Version | Sort-Object -Unique
|
||||
return [ToolVersionsListNode]::new($moduleName, $moduleVersions, '^\d+', "Inline")
|
||||
}
|
||||
|
||||
return $result
|
||||
}
|
||||
|
||||
function Get-CachedDockerImages {
|
||||
return (docker images --digests --format "* {{.Repository}}:{{.Tag}}").Split("*") | Where-Object { $_ }
|
||||
}
|
||||
|
||||
function Get-CachedDockerImagesTableData {
|
||||
$allImages = docker images --digests --format "*{{.Repository}}:{{.Tag}}|{{.Digest}} |{{.CreatedAt}}"
|
||||
if (-not $allImages) {
|
||||
return $null
|
||||
}
|
||||
|
||||
$allImages.Split("*") | Where-Object { $_ } | ForEach-Object {
|
||||
$parts = $_.Split("|")
|
||||
[PSCustomObject] @{
|
||||
"Repository:Tag" = $parts[0]
|
||||
"Digest" = $parts[1]
|
||||
"Created" = $parts[2].split(' ')[0]
|
||||
}
|
||||
} | Sort-Object -Property "Repository:Tag"
|
||||
}
|
||||
|
||||
function Get-ShellTarget {
|
||||
return Get-ChildItem C:\shells -File | Select-Object Name, @{n = "Target"; e = {
|
||||
if ($_.Name -eq "msys2bash.cmd") {
|
||||
"C:\msys64\usr\bin\bash.exe"
|
||||
} else {
|
||||
@($_.Target)[0]
|
||||
}
|
||||
}
|
||||
} | Sort-Object Name
|
||||
}
|
||||
|
||||
function Get-PacmanVersion {
|
||||
$msys2BinDir = "C:\msys64\usr\bin"
|
||||
$pacmanPath = Join-Path $msys2BinDir "pacman.exe"
|
||||
$rawVersion = & $pacmanPath --version
|
||||
$rawVersion.Split([System.Environment]::NewLine)[1] -match "\d+\.\d+(\.\d+)?" | Out-Null
|
||||
$pacmanVersion = $matches[0]
|
||||
return $pacmanVersion
|
||||
}
|
||||
|
||||
function Get-YAMLLintVersion {
|
||||
yamllint --version | Get-StringPart -Part 1
|
||||
}
|
||||
|
||||
function Get-BizTalkVersion {
|
||||
$bizTalkReg = Get-ItemProperty "HKLM:\SOFTWARE\WOW6432Node\Microsoft\BizTalk Server\3.0"
|
||||
return [ToolVersionNode]::new($bizTalkReg.ProductName, $bizTalkReg.ProductVersion)
|
||||
}
|
||||
|
||||
function Get-PipxVersion {
|
||||
pipx --version
|
||||
}
|
||||
|
||||
function Build-PackageManagementEnvironmentTable {
|
||||
return @(
|
||||
[PSCustomObject] @{
|
||||
"Name" = "VCPKG_INSTALLATION_ROOT"
|
||||
"Value" = $env:VCPKG_INSTALLATION_ROOT
|
||||
},
|
||||
[PSCustomObject] @{
|
||||
"Name" = "CONDA"
|
||||
"Value" = $env:CONDA
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
function Get-PostgreSQLTable
|
||||
{
|
||||
$pgService = Get-CimInstance Win32_Service -Filter "Name LIKE 'postgresql-%'"
|
||||
$pgPath = $pgService.PathName
|
||||
$pgRoot = $pgPath.split('"')[1].replace("\bin\pg_ctl.exe", "")
|
||||
$env:Path += ";${env:PGBIN}"
|
||||
$pgVersion = (postgres --version).split()[2].Trim()
|
||||
|
||||
return @(
|
||||
[PSCustomObject]@{ Property = "ServiceName"; Value = $pgService.Name },
|
||||
[PSCustomObject]@{ Property = "Version"; Value = $pgVersion },
|
||||
[PSCustomObject]@{ Property = "ServiceStatus"; Value = $pgService.State },
|
||||
[PSCustomObject]@{ Property = "ServiceStartType"; Value = $pgService.StartMode },
|
||||
[PSCustomObject]@{ Property = "EnvironmentVariables"; Value = "`PGBIN=$env:PGBIN` <br> `PGDATA=$env:PGDATA` <br> `PGROOT=$env:PGROOT` " },
|
||||
[PSCustomObject]@{ Property = "Path"; Value = $pgRoot },
|
||||
[PSCustomObject]@{ Property = "UserName"; Value = $env:PGUSER },
|
||||
[PSCustomObject]@{ Property = "Password"; Value = $env:PGPASSWORD }
|
||||
)
|
||||
}
|
||||
|
||||
function Get-MongoDBTable
|
||||
{
|
||||
$name = "MongoDB"
|
||||
if (Test-IsWin25) {
|
||||
$command = "mongod"
|
||||
} else {
|
||||
$command = "mongo"
|
||||
}
|
||||
$mongoService = Get-Service -Name $name
|
||||
$mongoVersion = (Get-Command -Name $command).Version.ToString()
|
||||
return [PSCustomObject]@{
|
||||
Version = $mongoVersion
|
||||
ServiceName = $name
|
||||
ServiceStatus = $mongoService.Status
|
||||
ServiceStartType = $mongoService.StartType
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
function Get-LinkTarget {
|
||||
param (
|
||||
[string] $inputPath
|
||||
)
|
||||
$link = Get-Item $inputPath | Select-Object -ExpandProperty Target
|
||||
if ($link) {
|
||||
return " -> $link"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
function Get-PathWithLink {
|
||||
param (
|
||||
[string] $inputPath
|
||||
)
|
||||
$link = Get-LinkTarget($inputPath)
|
||||
return "${inputPath}${link}"
|
||||
}
|
||||
|
||||
function Get-StringPart {
|
||||
param (
|
||||
[Parameter(ValueFromPipeline)]
|
||||
[string] $toolOutput,
|
||||
[string] $Delimiter = " ",
|
||||
[int[]] $Part
|
||||
)
|
||||
$parts = $toolOutput.Split($Delimiter, [System.StringSplitOptions]::RemoveEmptyEntries)
|
||||
$selectedParts = $parts[$Part]
|
||||
return [string]::Join($Delimiter, $selectedParts)
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
function Get-JavaVersions {
|
||||
$defaultJavaPath = $env:JAVA_HOME
|
||||
$javaVersions = Get-Item env:JAVA_HOME_*_X64
|
||||
$sortRules = @{
|
||||
Expression = { [Int32] $_.Name.Split("_")[2] }
|
||||
Descending = $false
|
||||
}
|
||||
|
||||
return $javaVersions | Sort-Object $sortRules | ForEach-Object {
|
||||
$javaPath = $_.Value
|
||||
# Take semver from the java path
|
||||
# The path contains '-' sign in the version number instead of '+' due to the following issue, need to substitute it back https://github.com/actions/runner-images/issues/3014
|
||||
$versionInPath = (Split-Path $javaPath) -replace "\w:\\.*\\"
|
||||
$version = $versionInPath -replace '-', '+'
|
||||
$defaultPostfix = ($javaPath -eq $defaultJavaPath) ? " (default)" : ""
|
||||
|
||||
[PSCustomObject] @{
|
||||
"Version" = $version + $defaultPostfix
|
||||
"Environment Variable" = $_.Name
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,320 @@
|
||||
function Get-Aria2Version {
|
||||
(aria2c -v | Out-String) -match "(?<version>(\d+\.){1,}\d+)" | Out-Null
|
||||
$aria2Version = $Matches.Version
|
||||
return $aria2Version
|
||||
}
|
||||
|
||||
function Get-AzCosmosDBEmulatorVersion {
|
||||
$regKey = gci HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\* | gp | ? { $_.DisplayName -eq 'Azure Cosmos DB Emulator' }
|
||||
$installDir = $regKey.InstallLocation
|
||||
$exeFilePath = Join-Path $installDir 'CosmosDB.Emulator.exe'
|
||||
$version = (Get-Item $exeFilePath).VersionInfo.FileVersion
|
||||
return $version
|
||||
}
|
||||
|
||||
function Get-BazelVersion {
|
||||
((cmd /c "bazel --version 2>&1") | Out-String) -match "bazel (?<version>\d+\.\d+\.\d+)" | Out-Null
|
||||
$bazelVersion = $Matches.Version
|
||||
return $bazelVersion
|
||||
}
|
||||
|
||||
function Get-BazeliskVersion {
|
||||
((cmd /c "bazelisk version 2>&1") | Out-String) -match "Bazelisk version: v(?<version>\d+\.\d+\.\d+)" | Out-Null
|
||||
$bazeliskVersion = $Matches.Version
|
||||
return $bazeliskVersion
|
||||
}
|
||||
|
||||
function Get-BicepVersion {
|
||||
(bicep --version | Out-String) -match "bicep cli version (?<version>\d+\.\d+\.\d+)" | Out-Null
|
||||
$bicepVersion = $Matches.Version
|
||||
return $bicepVersion
|
||||
}
|
||||
|
||||
function Get-RVersion {
|
||||
($(cmd /c "Rscript --version 2>&1") | Out-String) -match "Rscript .* version (?<version>\d+\.\d+\.\d+)" | Out-Null
|
||||
$rVersion = $Matches.Version
|
||||
return $rVersion
|
||||
}
|
||||
|
||||
function Get-CMakeVersion {
|
||||
($(cmake -version) | Out-String) -match "cmake version (?<version>\d+\.\d+\.\d+)" | Out-Null
|
||||
$cmakeVersion = $Matches.Version
|
||||
return $cmakeVersion
|
||||
}
|
||||
|
||||
function Get-CodeQLBundleVersion {
|
||||
$CodeQLVersionsWildcard = Join-Path $env:AGENT_TOOLSDIRECTORY -ChildPath "CodeQL" | Join-Path -ChildPath "*"
|
||||
$CodeQLVersionPath = Get-ChildItem $CodeQLVersionsWildcard | Select-Object -First 1 -Expand FullName
|
||||
$CodeQLPath = Join-Path $CodeQLVersionPath -ChildPath "x64" | Join-Path -ChildPath "codeql" | Join-Path -ChildPath "codeql.exe"
|
||||
$CodeQLVersion = & $CodeQLPath version --quiet
|
||||
return $CodeQLVersion
|
||||
}
|
||||
|
||||
function Get-DockerVersion {
|
||||
$dockerVersion = $(docker version --format "{{.Server.Version}}")
|
||||
return $dockerVersion
|
||||
}
|
||||
|
||||
function Get-DockerComposeVersionV2 {
|
||||
$dockerComposeVersion = docker compose version --short
|
||||
return $dockerComposeVersion
|
||||
}
|
||||
|
||||
function Get-DockerWincredVersion {
|
||||
$dockerCredVersion = docker-credential-wincred version | Get-StringPart -Part 2 | Get-StringPart -Part 0 -Delimiter "v"
|
||||
return $dockerCredVersion
|
||||
}
|
||||
|
||||
function Get-GitVersion {
|
||||
$gitVersion = git --version | Get-StringPart -Part -1
|
||||
return $gitVersion
|
||||
}
|
||||
|
||||
function Get-GitLFSVersion {
|
||||
$(git-lfs version) -match "git-lfs\/(?<version>\d+\.\d+\.\d+)" | Out-Null
|
||||
$gitLfsVersion = $Matches.Version
|
||||
return $gitLfsVersion
|
||||
}
|
||||
|
||||
function Get-InnoSetupVersion {
|
||||
$innoSetupVersion = $(choco list innosetup) | Select-String -Pattern "InnoSetup"
|
||||
return ($innoSetupVersion -replace "^InnoSetup").Trim()
|
||||
}
|
||||
|
||||
function Get-JQVersion {
|
||||
$jqVersion = ($(jq --version) -Split "jq-")[1]
|
||||
return $jqVersion
|
||||
}
|
||||
|
||||
function Get-KubectlVersion {
|
||||
$kubectlVersion = (kubectl version --client --output=json | ConvertFrom-Json).clientVersion.gitVersion.Replace('v', '')
|
||||
return $kubectlVersion
|
||||
}
|
||||
|
||||
function Get-KindVersion {
|
||||
$(kind version) -match "kind v(?<version>\d+\.\d+\.\d+)" | Out-Null
|
||||
$kindVersion = $Matches.Version
|
||||
return $kindVersion
|
||||
}
|
||||
|
||||
function Get-GCCVersion {
|
||||
(gcc --version | Select-String -Pattern "gcc.exe") -match "(?<version>\d+\.\d+\.\d+)" | Out-Null
|
||||
$mingwVersion = $Matches.Version
|
||||
return $mingwVersion
|
||||
}
|
||||
|
||||
function Get-GDBVersion {
|
||||
(gdb --version | Select-String -Pattern "GNU gdb") -match "(?<version>\d+\.\d+)" | Out-Null
|
||||
$mingwVersion = $Matches.Version
|
||||
return $mingwVersion
|
||||
}
|
||||
|
||||
function Get-GNUBinutilsVersion {
|
||||
(ld --version | Select-String -Pattern "GNU Binutils") -match "(?<version>\d+\.\d+)" | Out-Null
|
||||
$mingwVersion = $Matches.Version
|
||||
return $mingwVersion
|
||||
}
|
||||
|
||||
function Get-MySQLVersion {
|
||||
$mysqlCommand = Get-Command -Name "mysql"
|
||||
$mysqlVersion = $mysqlCommand.Version.ToString()
|
||||
return $mysqlVersion
|
||||
}
|
||||
|
||||
function Get-SQLOLEDBDriverVersion {
|
||||
$SQLOLEDBDriverVersion = (Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSOLEDBSQL' InstalledVersion).InstalledVersion
|
||||
return $SQLOLEDBDriverVersion
|
||||
}
|
||||
|
||||
function Get-MercurialVersion {
|
||||
($(hg --version) | Out-String) -match "version (?<version>\d+\.\d+\.?\d*)" | Out-Null
|
||||
$mercurialVersion = $Matches.Version
|
||||
return $mercurialVersion
|
||||
}
|
||||
|
||||
function Get-NSISVersion {
|
||||
$nsisVersion = & "c:\Program Files (x86)\NSIS\makensis.exe" "/Version"
|
||||
return $nsisVersion.TrimStart("v")
|
||||
}
|
||||
|
||||
function Get-OpenSSLVersion {
|
||||
$(openssl version) -match "OpenSSL (?<version>\d+\.\d+\.\d+\w?) " | Out-Null
|
||||
$opensslVersion = $Matches.Version
|
||||
return $opensslVersion
|
||||
}
|
||||
|
||||
function Get-PackerVersion {
|
||||
$packerVersion = (packer --version | Select-String "^Packer").Line.Replace('v','') | Get-StringPart -Part 1
|
||||
return $packerVersion
|
||||
}
|
||||
|
||||
function Get-ParcelVersion {
|
||||
$parcelVersion = parcel --version
|
||||
return "$parcelVersion"
|
||||
}
|
||||
|
||||
function Get-PulumiVersion {
|
||||
return (pulumi version).TrimStart("v")
|
||||
}
|
||||
|
||||
function Get-SQLPSVersion {
|
||||
$module = Get-Module -Name SQLPS -ListAvailable
|
||||
$version = $module.Version
|
||||
return $version
|
||||
}
|
||||
|
||||
function Get-SVNVersion {
|
||||
$svnVersion = $(svn --version --quiet)
|
||||
return $svnVersion
|
||||
}
|
||||
|
||||
function Get-VSWhereVersion {
|
||||
($(Get-Command -Name vswhere).FileVersionInfo.ProductVersion) -match "(?<version>\d+\.\d+\.\d+)" | Out-Null
|
||||
$vswhereVersion = $Matches.Version
|
||||
return $vswhereVersion
|
||||
}
|
||||
|
||||
function Get-WinAppDriver {
|
||||
$winAppDriverVersion = [System.Diagnostics.FileVersionInfo]::GetVersionInfo("C:\Program Files (x86)\Windows Application Driver\WinAppDriver.exe").FileVersion
|
||||
return $winAppDriverVersion
|
||||
}
|
||||
|
||||
function Get-WixVersion {
|
||||
$regKey = "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
|
||||
$installedApplications = Get-ItemProperty -Path $regKey
|
||||
$wixToolsetVersion = ($installedApplications | Where-Object { $_.BundleCachePath -imatch ".*\\WiX\d*\.exe$" } | Select-Object -First 1).DisplayName
|
||||
return ($wixToolsetVersion -replace "^WiX Toolset v").Trim()
|
||||
}
|
||||
|
||||
function Get-ZstdVersion {
|
||||
$(zstd --version) -match "v(?<version>\d+\.\d+\.\d+)" | Out-Null
|
||||
$zstdVersion = $Matches.Version
|
||||
return $zstdVersion
|
||||
}
|
||||
|
||||
function Get-AzureCLIVersion {
|
||||
$azureCLIVersion = $(az version) | ConvertFrom-Json | Foreach{ $_."azure-cli" }
|
||||
return $azureCLIVersion
|
||||
}
|
||||
|
||||
function Get-AzCopyVersion {
|
||||
return ($(azcopy --version) -replace "^azcopy version").Trim()
|
||||
}
|
||||
|
||||
function Get-AzureDevopsExtVersion {
|
||||
$azureDevExtVersion = (az version | ConvertFrom-Json | ForEach-Object { $_."extensions" })."azure-devops"
|
||||
return $azureDevExtVersion
|
||||
}
|
||||
|
||||
function Get-AWSCLIVersion {
|
||||
$(aws --version) -match "aws-cli\/(?<version>\d+\.\d+\.\d+)" | Out-Null
|
||||
$awscliVersion = $Matches.Version
|
||||
return $awscliVersion
|
||||
}
|
||||
|
||||
function Get-AWSSAMVersion {
|
||||
$(sam --version) -match "version (?<version>\d+\.\d+\.\d+)" | Out-Null
|
||||
$awssamVersion = $Matches.Version
|
||||
return $awssamVersion
|
||||
}
|
||||
|
||||
function Get-AWSSessionManagerVersion {
|
||||
$awsSessionManagerVersion = $(session-manager-plugin --version)
|
||||
return $awsSessionManagerVersion
|
||||
}
|
||||
|
||||
function Get-AlibabaCLIVersion {
|
||||
$alicliVersion = $(aliyun version)
|
||||
return $alicliVersion
|
||||
}
|
||||
|
||||
function Get-CloudFoundryVersion {
|
||||
$(cf version) -match "(?<version>\d+\.\d+\.\d+)" | Out-Null
|
||||
$cfVersion = $Matches.Version
|
||||
return $cfVersion
|
||||
}
|
||||
|
||||
function Get-7zipVersion {
|
||||
(7z | Out-String) -match "7-Zip (?<version>\d+\.\d+\.?\d*)" | Out-Null
|
||||
$version = $Matches.Version
|
||||
return $version
|
||||
}
|
||||
|
||||
function Get-GHCVersion {
|
||||
((ghc --version) | Out-String) -match "version (?<version>\d+\.\d+\.\d+)" | Out-Null
|
||||
$ghcVersion = $Matches.Version
|
||||
return $ghcVersion
|
||||
}
|
||||
|
||||
function Get-CabalVersion {
|
||||
((cabal --version) | Out-String) -match "version (?<version>\d+\.\d+\.\d+\.\d+)" | Out-Null
|
||||
$cabalVersion = $Matches.Version
|
||||
return $cabalVersion
|
||||
}
|
||||
|
||||
function Get-StackVersion {
|
||||
((stack --version --quiet) | Out-String) -match "Version (?<version>\d+\.\d+\.\d+)," | Out-Null
|
||||
$stackVersion = $Matches.Version
|
||||
return $stackVersion
|
||||
}
|
||||
|
||||
function Get-GoogleCloudCLIVersion {
|
||||
return (((cmd /c "gcloud --version") -match "Google Cloud SDK") -replace "Google Cloud SDK").Trim()
|
||||
}
|
||||
|
||||
function Get-ServiceFabricSDKVersion {
|
||||
$serviceFabricSDKVersion = Get-ItemPropertyValue 'HKLM:\SOFTWARE\Microsoft\Service Fabric\' -Name FabricVersion
|
||||
return $serviceFabricSDKVersion
|
||||
}
|
||||
|
||||
function Get-NewmanVersion {
|
||||
return $(newman --version)
|
||||
}
|
||||
|
||||
function Get-GHVersion {
|
||||
($(gh --version) | Select-String -Pattern "gh version") -match "gh version (?<version>\d+\.\d+\.\d+)" | Out-Null
|
||||
$ghVersion = $Matches.Version
|
||||
return $ghVersion
|
||||
}
|
||||
|
||||
function Get-VisualCPPComponents {
|
||||
$regKeys = @(
|
||||
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*"
|
||||
"HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
|
||||
)
|
||||
$vcpp = Get-ItemProperty -Path $regKeys | Where-Object DisplayName -like "Microsoft Visual C++*"
|
||||
$vcpp | Sort-Object DisplayName, DisplayVersion | ForEach-Object {
|
||||
$isMatch = $_.DisplayName -match "^(?<Name>Microsoft Visual C\+\+ \d{4})\s+(?<Arch>\w{3})\s+(?<Ext>.+)\s+-"
|
||||
if ($isMatch) {
|
||||
$name = '{0} {1}' -f $matches["Name"], $matches["Ext"]
|
||||
$arch = $matches["Arch"].ToLower()
|
||||
$version = $_.DisplayVersion
|
||||
[PSCustomObject]@{
|
||||
Name = $name
|
||||
Architecture = $arch
|
||||
Version = $version
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Get-DacFxVersion {
|
||||
$dacfxversion = & "$env:ProgramFiles\Microsoft SQL Server\160\DAC\bin\sqlpackage.exe" /version
|
||||
return $dacfxversion
|
||||
}
|
||||
|
||||
function Get-SwigVersion {
|
||||
(swig -version | Out-String) -match "version (?<version>\d+\.\d+\.\d+)" | Out-Null
|
||||
$swigVersion = $Matches.Version
|
||||
return $swigVersion
|
||||
}
|
||||
|
||||
function Get-ImageMagickVersion {
|
||||
(magick -version | Select-String -Pattern "Version") -match "(?<version>\d+\.\d+\.\d+-\d+)" | Out-Null
|
||||
$magickVersion = $Matches.Version
|
||||
return $magickVersion
|
||||
}
|
||||
|
||||
function Get-MongoshVersion {
|
||||
return $(mongosh --version)
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
function Get-VisualStudioVersion {
|
||||
$vsInstance = Get-VisualStudioInstance
|
||||
[PSCustomObject]@{
|
||||
Name = $vsInstance.DisplayName
|
||||
Version = $vsInstance.InstallationVersion
|
||||
Path = $vsInstance.InstallationPath
|
||||
}
|
||||
}
|
||||
|
||||
function Get-SDKVersion {
|
||||
$regKey = "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
|
||||
$installedApplications = Get-ItemProperty -Path $regKey
|
||||
($installedApplications | Where-Object { $_.DisplayName -eq 'Windows SDK' } | Select-Object -First 1).DisplayVersion
|
||||
}
|
||||
|
||||
function Get-WDKVersion {
|
||||
$regKey = "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
|
||||
$installedApplications = Get-ItemProperty -Path $regKey
|
||||
($installedApplications | Where-Object { $_.DisplayName -eq 'Windows Driver Kit' } | Select-Object -First 1).DisplayVersion
|
||||
}
|
||||
|
||||
function Get-VisualStudioExtensions {
|
||||
$vsPackages = (Get-VisualStudioInstance).Packages
|
||||
|
||||
# Additional vsixs
|
||||
$toolset = Get-ToolsetContent
|
||||
$vsixPackagesList = $toolset.visualStudio.vsix
|
||||
if ($vsixPackagesList) {
|
||||
$vsixs = $vsixPackagesList | ForEach-Object {
|
||||
$vsixPackage = Get-VsixInfoFromMarketplace $_
|
||||
$vsixVersion = ($vsPackages | Where-Object { $_.Id -match $vsixPackage.VsixId -and $_.type -eq 'vsix' }).Version
|
||||
@{
|
||||
Package = $vsixPackage.ExtensionName
|
||||
Version = $vsixVersion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# SDK
|
||||
$sdkVersion = Get-SDKVersion
|
||||
$sdkPackages = @(
|
||||
@{Package = 'Windows Software Development Kit'; Version = $sdkVersion }
|
||||
)
|
||||
|
||||
# WDK
|
||||
$wdkVersion = Get-WDKVersion
|
||||
$wdkExtensionVersion = Get-VSExtensionVersion -packageName 'Microsoft.Windows.DriverKit'
|
||||
$wdkPackages = @(
|
||||
@{Package = 'Windows Driver Kit'; Version = $wdkVersion }
|
||||
@{Package = 'Windows Driver Kit Visual Studio Extension'; Version = $wdkExtensionVersion }
|
||||
)
|
||||
|
||||
$extensions = @(
|
||||
$vsixs
|
||||
$ssdtPackages
|
||||
$sdkPackages
|
||||
$wdkPackages
|
||||
)
|
||||
|
||||
$extensions | Foreach-Object {
|
||||
[PSCustomObject] $_
|
||||
} | Select-Object Package, Version | Sort-Object Package
|
||||
}
|
||||
|
||||
function Get-WindowsSDKs {
|
||||
$path = "${env:ProgramFiles(x86)}\Windows Kits\10\Extension SDKs\WindowsDesktop"
|
||||
return [PSCustomObject]@{
|
||||
Path = $path
|
||||
Versions = $(Get-ChildItem $path).Name
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user