early-access version 2853

This commit is contained in:
pineappleEA
2022-07-23 03:01:36 +02:00
parent 1f2b5081b5
commit 1f111bb69c
8955 changed files with 418777 additions and 999 deletions

View File

@@ -0,0 +1,20 @@
[CmdletBinding(PositionalBinding=$False)]
Param(
[Parameter(Mandatory=$True)]
[String]$DiffFile
)
Start-Process -FilePath 'git' -ArgumentList 'diff' `
-NoNewWindow -Wait `
-RedirectStandardOutput $DiffFile
if (0 -ne (Get-Item -LiteralPath $DiffFile).Length)
{
$msg = @(
'The formatting of the files in the repo were not what we expected,',
'or the documentation was not regenerated.',
'Please access the diff from format.diff in the build artifacts,'
'and apply the patch with `git apply`'
)
Write-Error ($msg -join "`n")
throw
}

View File

@@ -0,0 +1,73 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: MIT
#
variables:
windows-pool: 'PrWin-2022-05-19'
linux-pool: 'PrLin-2022-05-19'
osx-pool: 'PrOsx-2022-02-04'
parameters:
- name: vcpkgToolSha
displayName: 'Custom SHA of vcpkg-tool to use rather than bootstrap'
type: string
default: 'use default'
jobs:
- template: windows/azure-pipelines.yml
parameters:
triplet: x86-windows
jobName: x86_windows
poolName: $(windows-pool)
vcpkgToolSha: ${{ parameters.vcpkgToolSha }}
- template: windows/azure-pipelines.yml
parameters:
triplet: x64-windows
jobName: x64_windows
poolName: $(windows-pool)
vcpkgToolSha: ${{ parameters.vcpkgToolSha }}
- template: windows/azure-pipelines.yml
parameters:
triplet: x64-windows-static
jobName: x64_windows_static
poolName: $(windows-pool)
vcpkgToolSha: ${{ parameters.vcpkgToolSha }}
- template: windows/azure-pipelines.yml
parameters:
triplet: x64-windows-static-md
jobName: x64_windows_static_md
poolName: $(windows-pool)
vcpkgToolSha: ${{ parameters.vcpkgToolSha }}
- template: windows/azure-pipelines.yml
parameters:
triplet: x64-uwp
jobName: x64_uwp
poolName: $(windows-pool)
vcpkgToolSha: ${{ parameters.vcpkgToolSha }}
- template: windows/azure-pipelines.yml
parameters:
triplet: arm64-windows
jobName: arm64_windows
poolName: $(windows-pool)
vcpkgToolSha: ${{ parameters.vcpkgToolSha }}
- template: windows/azure-pipelines.yml
parameters:
triplet: arm-uwp
jobName: arm_uwp
poolName: $(windows-pool)
vcpkgToolSha: ${{ parameters.vcpkgToolSha }}
- template: osx/azure-pipelines.yml
parameters:
poolName: $(osx-pool)
vcpkgToolSha: ${{ parameters.vcpkgToolSha }}
- template: linux/azure-pipelines.yml
parameters:
poolName: $(linux-pool)
vcpkgToolSha: ${{ parameters.vcpkgToolSha }}

View File

@@ -0,0 +1,9 @@
#!/bin/sh
set -e
git clone https://github.com/microsoft/vcpkg-tool vcpkg-tool
git -C vcpkg-tool switch -d $1
rm -rf build.x64.release
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF -DVCPKG_DEVELOPMENT_WARNINGS=OFF -DVCPKG_WARNINGS_AS_ERRORS=OFF -DVCPKG_BUILD_FUZZING=OFF -DVCPKG_BUILD_TLS12_DOWNLOADER=OFF -B build.x64.release -S vcpkg-tool
ninja -C build.x64.release
mv build.x64.release/vcpkg vcpkg

View File

@@ -0,0 +1,352 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: MIT
<#
.SYNOPSIS
Returns whether there's a name collision in the resource group.
.DESCRIPTION
Find-ResourceGroupNameCollision takes a list of resources, and checks if $Test
collides names with any of the resources.
.PARAMETER Test
The name to test.
.PARAMETER Resources
The list of resources.
#>
function Find-ResourceGroupNameCollision {
[CmdletBinding()]
Param([string]$Test, $Resources)
foreach ($resource in $Resources) {
if ($resource.ResourceGroupName -eq $Test) {
return $true
}
}
return $false
}
<#
.SYNOPSIS
Attempts to find a name that does not collide with any resources in the resource group.
.DESCRIPTION
Find-ResourceGroupName takes a set of resources from Get-AzResourceGroup, and finds the
first name in {$Prefix, $Prefix-1, $Prefix-2, ...} such that the name doesn't collide with
any of the resources in the resource group.
.PARAMETER Prefix
The prefix of the final name; the returned name will be of the form "$Prefix(-[1-9][0-9]*)?"
#>
function Find-ResourceGroupName {
[CmdletBinding()]
Param([string] $Prefix)
$resources = Get-AzResourceGroup
$result = $Prefix
$suffix = 0
while (Find-ResourceGroupNameCollision -Test $result -Resources $resources) {
$suffix++
$result = "$Prefix-$suffix"
}
return $result
}
<#
.SYNOPSIS
Returns whether there's a name collision for an image in the resource group.
.DESCRIPTION
Find-ImageNameCollision takes a list of images, and checks if $Test
collides names with any of the image names.
.PARAMETER Test
The name to test.
.PARAMETER Images
The list of images.
#>
function Find-ImageNameCollision {
[CmdletBinding()]
Param([string]$Test, $Images)
foreach ($resource in $Images) {
if ($resource.Name -eq $Test) {
return $true
}
}
return $false
}
<#
.SYNOPSIS
Attempts to find a name that does not collide with any images in the resource group.
.DESCRIPTION
Find-ResourceGroupName takes a set of resources from Get-AzResourceGroup, and finds the
first name in {$Prefix, $Prefix-1, $Prefix-2, ...} such that the name doesn't collide with
any of the resources in the resource group.
.PARAMETER Prefix
The prefix of the final name; the returned name will be of the form "$Prefix(-[1-9][0-9]*)?"
#>
function Find-ImageName {
[CmdLetBinding()]
Param([string]$ResourceGroupName, [string]$Prefix)
$images = Get-AzImage -ResourceGroupName $ResourceGroupName
$result = $Prefix
$suffix = 0
while (Find-ImageNameCollision -Test $result -Images $images) {
$suffix++
$result = "$Prefix-$suffix"
}
return $result
}
<#
.SYNOPSIS
Generates a random password.
.DESCRIPTION
New-Password generates a password, randomly, of length $Length, containing
only alphanumeric characters, underscore, and dash.
.PARAMETER Length
The length of the returned password.
#>
function New-Password {
Param ([int] $Length = 32)
# This 64-character alphabet generates 6 bits of entropy per character.
# The power-of-2 alphabet size allows us to select a character by masking a random Byte with bitwise-AND.
$alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-"
$mask = 63
if ($alphabet.Length -ne 64) {
throw 'Bad alphabet length'
}
[Byte[]]$randomData = [Byte[]]::new($Length)
$rng = $null
try {
$rng = [System.Security.Cryptography.RandomNumberGenerator]::Create()
$rng.GetBytes($randomData)
}
finally {
if ($null -ne $rng) {
$rng.Dispose()
}
}
$result = ''
for ($idx = 0; $idx -lt $Length; $idx++) {
$result += $alphabet[$randomData[$idx] -band $mask]
}
return $result
}
<#
.SYNOPSIS
Waits for the shutdown of the specified resource.
.DESCRIPTION
Wait-Shutdown takes a VM, and checks if there's a 'PowerState/stopped'
code; if there is, it returns. If there isn't, it waits ten seconds and
tries again.
.PARAMETER ResourceGroupName
The name of the resource group to look up the VM in.
.PARAMETER Name
The name of the virtual machine to wait on.
#>
function Wait-Shutdown {
[CmdletBinding()]
Param([string]$ResourceGroupName, [string]$Name)
Write-Host "Waiting for $Name to stop..."
while ($true) {
$Vm = Get-AzVM -ResourceGroupName $ResourceGroupName -Name $Name -Status
$highestStatus = $Vm.Statuses.Count
for ($idx = 0; $idx -lt $highestStatus; $idx++) {
if ($Vm.Statuses[$idx].Code -eq 'PowerState/stopped') {
return
}
}
Write-Host "... not stopped yet, sleeping for 10 seconds"
Start-Sleep -Seconds 10
}
}
<#
.SYNOPSIS
Sanitizes a name to be used in a storage account.
.DESCRIPTION
Sanitize-Name takes a string, and removes all of the '-'s and
lowercases the string, since storage account names must have no
'-'s and must be completely lowercase alphanumeric. It then makes
certain that the length of the string is not greater than 24,
since that is invalid.
.PARAMETER RawName
The name to sanitize.
#>
function Sanitize-Name {
[CmdletBinding()]
Param(
[string]$RawName
)
$result = $RawName.Replace('-', '').ToLowerInvariant()
if ($result.Length -gt 24) {
Write-Error 'Sanitized name for storage account $result was too long.'
throw
}
return $result
}
<#
.SYNOPSIS
Creates a new Azure virtual network with locked down firewall rules.
.PARAMETER ResourceGroupName
The name of the resource group in which the virtual network should be created.
.PARAMETER Location
The location (region) where the network is to be created.
#>
function Create-LockedDownNetwork {
[CmdletBinding()]
Param(
[parameter(Mandatory=$true)]
[string]$ResourceGroupName,
[parameter(Mandatory=$true)]
[string]$Location
)
$allFirewallRules = @()
$allFirewallRules += New-AzNetworkSecurityRuleConfig `
-Name AllowHTTP `
-Description 'Allow HTTP(S)' `
-Access Allow `
-Protocol Tcp `
-Direction Outbound `
-Priority 1008 `
-SourceAddressPrefix * `
-SourcePortRange * `
-DestinationAddressPrefix * `
-DestinationPortRange @(80, 443)
$allFirewallRules += New-AzNetworkSecurityRuleConfig `
-Name AllowSFTP `
-Description 'Allow (S)FTP' `
-Access Allow `
-Protocol Tcp `
-Direction Outbound `
-Priority 1009 `
-SourceAddressPrefix * `
-SourcePortRange * `
-DestinationAddressPrefix * `
-DestinationPortRange @(21, 22)
$allFirewallRules += New-AzNetworkSecurityRuleConfig `
-Name AllowDNS `
-Description 'Allow DNS' `
-Access Allow `
-Protocol * `
-Direction Outbound `
-Priority 1010 `
-SourceAddressPrefix * `
-SourcePortRange * `
-DestinationAddressPrefix * `
-DestinationPortRange 53
$allFirewallRules += New-AzNetworkSecurityRuleConfig `
-Name AllowGit `
-Description 'Allow git' `
-Access Allow `
-Protocol Tcp `
-Direction Outbound `
-Priority 1011 `
-SourceAddressPrefix * `
-SourcePortRange * `
-DestinationAddressPrefix * `
-DestinationPortRange 9418
$allFirewallRules += New-AzNetworkSecurityRuleConfig `
-Name DenyElse `
-Description 'Deny everything else' `
-Access Deny `
-Protocol * `
-Direction Outbound `
-Priority 1013 `
-SourceAddressPrefix * `
-SourcePortRange * `
-DestinationAddressPrefix * `
-DestinationPortRange *
$NetworkSecurityGroupName = $ResourceGroupName + 'NetworkSecurity'
$NetworkSecurityGroup = New-AzNetworkSecurityGroup `
-Name $NetworkSecurityGroupName `
-ResourceGroupName $ResourceGroupName `
-Location $Location `
-SecurityRules $allFirewallRules
$SubnetName = $ResourceGroupName + 'Subnet'
$Subnet = New-AzVirtualNetworkSubnetConfig `
-Name $SubnetName `
-AddressPrefix "10.0.0.0/16" `
-NetworkSecurityGroup $NetworkSecurityGroup `
-ServiceEndpoint "Microsoft.Storage"
$VirtualNetworkName = $ResourceGroupName + 'Network'
$VirtualNetwork = New-AzVirtualNetwork `
-Name $VirtualNetworkName `
-ResourceGroupName $ResourceGroupName `
-Location $Location `
-AddressPrefix "10.0.0.0/16" `
-Subnet $Subnet
return $VirtualNetwork
}
function Invoke-AzVMRunCommandWithRetries {
$result = $null
$success = $false
$attempt = 0
while ($success -eq $false) {
try {
++$attempt
Write-Host "Command attempt $attempt..."
$result = Invoke-AzVMRunCommand @args
$success = $true
} catch {
Write-Host "Running command failed. $_ Retrying after 10 seconds..."
Start-Sleep -Seconds 10
if ($attempt -eq 5) {
Write-Error "Running command failed too many times. Giving up!"
throw $_
}
}
}
return $result
}
Export-ModuleMember -Function Find-ResourceGroupName
Export-ModuleMember -Function Find-ImageName
Export-ModuleMember -Function New-Password
Export-ModuleMember -Function Wait-Shutdown
Export-ModuleMember -Function Sanitize-Name
Export-ModuleMember -Function Create-LockedDownNetwork
Export-ModuleMember -Function Invoke-AzVMRunCommandWithRetries

View File

@@ -0,0 +1,78 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: MIT
#
parameters:
- name: vcpkgToolSha
displayName: 'Custom SHA of vcpkg-tool to use rather than bootstrap'
type: string
default: 'use default'
- name: poolName
type: string
jobs:
- job: x64_linux
pool:
name: ${{ parameters.poolName }}
workspace:
clean: resources
timeoutInMinutes: 1440 # 1 day
variables:
- name: WORKING_ROOT
value: /mnt/vcpkg-ci
- name: VCPKG_DOWNLOADS
value: /mnt/vcpkg-ci/downloads
- group: vcpkg-asset-caching-credentials
- name: X_VCPKG_ASSET_SOURCES
value: "x-azurl,$(root-url-ea),$(sas-ea),readwrite"
- group: vcpkg-binary-caching-credentials
- name: X_VCPKG_BINARY_SOURCE_STUB
value: "x-azblob,$(root-bin-url-ea),$(sas-bin-ea)"
steps:
# Note: /mnt is the Azure machines' temporary disk.
- bash: |
sudo mkdir /home/agent -m=777
sudo chown `id -u` /home/agent
sudo mkdir ${{ variables.WORKING_ROOT }} -m=777
sudo mkdir ${{ variables.VCPKG_DOWNLOADS }} -m=777
exit 0
displayName: 'Create working directories'
- bash: ./bootstrap-vcpkg.sh
displayName: 'Bootstrap vcpkg'
condition: eq('use default', '${{ parameters.vcpkgToolSha }}')
- bash: ./scripts/azure-pipelines/bootstrap-from-source.sh ${{ parameters.vcpkgToolSha }}
displayName: "Build vcpkg with CMake"
condition: ne('use default', '${{ parameters.vcpkgToolSha }}')
- task: PowerShell@2
displayName: '*** Test Modified Ports'
inputs:
failOnStderr: true
filePath: 'scripts/azure-pipelines/test-modified-ports.ps1'
arguments: '-Triplet x64-linux -BuildReason $(Build.Reason) -BinarySourceStub "$(X_VCPKG_BINARY_SOURCE_STUB)" -WorkingRoot ${{ variables.WORKING_ROOT }} -ArtifactStagingDirectory $(Build.ArtifactStagingDirectory)'
pwsh: true
- task: PublishBuildArtifacts@1
displayName: 'Publish Artifact: failure logs for x64-linux'
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)/failure-logs'
ArtifactName: 'failure logs for x64-linux'
condition: ne(variables['FAILURE_LOGS_EMPTY'], 'True')
- bash: |
python3 scripts/file_script.py /mnt/vcpkg-ci/installed/vcpkg/info/
displayName: 'Build a file list for all packages'
condition: always()
- task: PublishBuildArtifacts@1
displayName: 'Publish Artifact: file lists for x64-linux'
condition: always()
inputs:
PathtoPublish: scripts/list_files
ArtifactName: 'file lists for x64-linux'
- task: PublishTestResults@2
displayName: 'Publish Test Results'
condition: ne(variables['XML_RESULTS_FILE'], '')
inputs:
testRunTitle: x64-linux
testResultsFormat: xUnit
testResultsFiles: $(XML_RESULTS_FILE)
platform: x64-linux
configuration: static

View File

@@ -0,0 +1,177 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: MIT
#
<#
.SYNOPSIS
Creates a Linux virtual machine image, set up for vcpkg's CI.
.DESCRIPTION
create-image.ps1 creates an Azure Linux VM image, set up for vcpkg's CI system.
This script assumes you have installed Azure tools into PowerShell by following the instructions
at https://docs.microsoft.com/en-us/powershell/azure/install-az-ps?view=azps-3.6.1
or are running from Azure Cloud Shell.
This script assumes you have installed the OpenSSH Client optional Windows component.
#>
$Location = 'eastasia'
$Prefix = 'Lin-'
$Prefix += (Get-Date -Format 'yyyy-MM-dd')
$VMSize = 'Standard_D8a_v4'
$ProtoVMName = 'PROTOTYPE'
$ErrorActionPreference = 'Stop'
$ProgressActivity = 'Creating Linux Image'
$TotalProgress = 11
$CurrentProgress = 1
Import-Module "$PSScriptRoot/../create-vmss-helpers.psm1" -DisableNameChecking
####################################################################################################
Write-Progress `
-Activity $ProgressActivity `
-Status 'Creating SSH key' `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
$sshDir = [System.IO.Path]::GetTempPath() + [System.IO.Path]::GetRandomFileName()
mkdir $sshDir
try {
ssh-keygen.exe -q -b 2048 -t rsa -f "$sshDir/key" -P [string]::Empty
$sshPublicKey = Get-Content "$sshDir/key.pub"
} finally {
Remove-Item $sshDir -Recurse -Force
}
####################################################################################################
Write-Progress `
-Activity $ProgressActivity `
-Status 'Creating resource group' `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
$ResourceGroupName = Find-ResourceGroupName $Prefix
$AdminPW = New-Password
New-AzResourceGroup -Name $ResourceGroupName -Location $Location
$AdminPWSecure = ConvertTo-SecureString $AdminPW -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential ("AdminUser", $AdminPWSecure)
####################################################################################################
Write-Progress `
-Activity $ProgressActivity `
-Status 'Creating virtual network' `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
$VirtualNetwork = Create-LockedDownNetwork -ResourceGroupName $ResourceGroupName -Location $Location
####################################################################################################
Write-Progress `
-Activity $ProgressActivity `
-Status 'Creating prototype VM' `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
$NicName = $ResourceGroupName + 'NIC'
$Nic = New-AzNetworkInterface `
-Name $NicName `
-ResourceGroupName $ResourceGroupName `
-Location $Location `
-Subnet $VirtualNetwork.Subnets[0]
$VM = New-AzVMConfig -Name $ProtoVMName -VMSize $VMSize -Priority 'Spot' -MaxPrice -1
$VM = Set-AzVMOperatingSystem `
-VM $VM `
-Linux `
-ComputerName $ProtoVMName `
-Credential $Credential `
-DisablePasswordAuthentication
$VM = Add-AzVMNetworkInterface -VM $VM -Id $Nic.Id
$VM = Set-AzVMSourceImage `
-VM $VM `
-PublisherName 'Canonical' `
-Offer '0001-com-ubuntu-server-focal' `
-Skus '20_04-lts' `
-Version latest
$VM = Set-AzVMBootDiagnostic -VM $VM -Disable
$VM = Add-AzVMSshPublicKey `
-VM $VM `
-KeyData $sshPublicKey `
-Path "/home/AdminUser/.ssh/authorized_keys"
New-AzVm `
-ResourceGroupName $ResourceGroupName `
-Location $Location `
-VM $VM
####################################################################################################
Write-Progress `
-Activity $ProgressActivity `
-Status 'Waiting 1 minute to let Azure VM customizations be applied' `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
Start-Sleep -Seconds 60
####################################################################################################
Write-Progress `
-Activity $ProgressActivity `
-Status 'Restarting VM' `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
Restart-AzVm -ResourceGroupName $ResourceGroupName -Name $ProtoVMName
####################################################################################################
Write-Progress `
-Activity $ProgressActivity `
-Status 'Running provisioning script provision-image.sh in VM' `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
$ProvisionImageResult = Invoke-AzVMRunCommandWithRetries `
-ResourceGroupName $ResourceGroupName `
-VMName $ProtoVMName `
-CommandId 'RunShellScript' `
-ScriptPath "$PSScriptRoot\provision-image.sh"
Write-Host "provision-image.sh output: $($ProvisionImageResult.value.Message)"
####################################################################################################
Write-Progress `
-Activity $ProgressActivity `
-Status 'Restarting VM' `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
Restart-AzVM -ResourceGroupName $ResourceGroupName -Name $ProtoVMName
####################################################################################################
Write-Progress `
-Activity $ProgressActivity `
-Status 'Converting VM to Image' `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
Stop-AzVM `
-ResourceGroupName $ResourceGroupName `
-Name $ProtoVMName `
-Force
Set-AzVM `
-ResourceGroupName $ResourceGroupName `
-Name $ProtoVMName `
-Generalized
$VM = Get-AzVM -ResourceGroupName $ResourceGroupName -Name $ProtoVMName
$ImageConfig = New-AzImageConfig -Location $Location -SourceVirtualMachineId $VM.ID
$ImageName = Find-ImageName -ResourceGroupName 'vcpkg-image-minting' -Prefix $Prefix
New-AzImage -Image $ImageConfig -ImageName $ImageName -ResourceGroupName 'vcpkg-image-minting'
####################################################################################################
Write-Progress `
-Activity $ProgressActivity `
-Status 'Deleting unused temporary resources' `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
Remove-AzResourceGroup $ResourceGroupName -Force
####################################################################################################
Write-Progress -Activity $ProgressActivity -Completed
Write-Host "Generated Image: $ImageName"
Write-Host 'Finished!'

View File

@@ -0,0 +1,108 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: MIT
#
<#
.SYNOPSIS
Creates a Linux virtual machine scale set, set up for vcpkg's CI.
.DESCRIPTION
create-vmss.ps1 creates an Azure Linux VM scale set, set up for vcpkg's CI
system. See https://docs.microsoft.com/en-us/azure/virtual-machine-scale-sets/overview
for more information.
This script assumes you have installed Azure tools into PowerShell by following the instructions
at https://docs.microsoft.com/en-us/powershell/azure/install-az-ps?view=azps-3.6.1
or are running from Azure Cloud Shell.
This script assumes you have installed the OpenSSH Client optional Windows component.
.PARAMETER ImageName
The name of the image to deploy into the scale set.
#>
[CmdLetBinding()]
Param(
[parameter(Mandatory=$true)]
[string]$ImageName
)
$Location = 'eastasia'
$Prefix = 'PrLin-'
$Prefix += (Get-Date -Format 'yyyy-MM-dd')
$VMSize = 'Standard_D32a_v4'
$LiveVMPrefix = 'BUILD'
$ErrorActionPreference = 'Stop'
Import-Module "$PSScriptRoot/../create-vmss-helpers.psm1" -DisableNameChecking
$sshDir = [System.IO.Path]::GetTempPath() + [System.IO.Path]::GetRandomFileName()
mkdir $sshDir
try {
ssh-keygen.exe -q -b 2048 -t rsa -f "$sshDir/key" -P [string]::Empty
$sshPublicKey = Get-Content "$sshDir/key.pub"
} finally {
Remove-Item $sshDir -Recurse -Force
}
$ResourceGroupName = Find-ResourceGroupName $Prefix
$AdminPW = New-Password
$Image = Get-AzImage -ResourceGroupName 'vcpkg-image-minting' -ImageName $ImageName
New-AzResourceGroup -Name $ResourceGroupName -Location $Location
$VirtualNetwork = Create-LockedDownNetwork -ResourceGroupName $ResourceGroupName -Location $Location
$VmssIpConfigName = $ResourceGroupName + 'VmssIpConfig'
$VmssIpConfig = New-AzVmssIpConfig -SubnetId $VirtualNetwork.Subnets[0].Id -Primary -Name $VmssIpConfigName
$VmssName = $ResourceGroupName + 'Vmss'
$Vmss = New-AzVmssConfig `
-Location $Location `
-SkuCapacity 0 `
-SkuName $VMSize `
-SkuTier 'Standard' `
-Overprovision $false `
-UpgradePolicyMode Manual `
-EvictionPolicy Delete `
-Priority Spot `
-MaxPrice -1
$NicName = $ResourceGroupName + 'NIC'
New-AzNetworkInterface `
-Name $NicName `
-ResourceGroupName $ResourceGroupName `
-Location $Location `
-Subnet $VirtualNetwork.Subnets[0]
$Vmss = Add-AzVmssNetworkInterfaceConfiguration `
-VirtualMachineScaleSet $Vmss `
-Primary $true `
-IpConfiguration $VmssIpConfig `
-NetworkSecurityGroupId $VirtualNetwork.Subnets[0].NetworkSecurityGroup.Id `
-Name $NicName
$VmssPublicKey = New-Object -TypeName 'Microsoft.Azure.Management.Compute.Models.SshPublicKey' `
-ArgumentList @('/home/AdminUser/.ssh/authorized_keys', $sshPublicKey)
$Vmss = Set-AzVmssOsProfile `
-VirtualMachineScaleSet $Vmss `
-ComputerNamePrefix $LiveVMPrefix `
-AdminUsername AdminUser `
-AdminPassword $AdminPW `
-LinuxConfigurationDisablePasswordAuthentication $true `
-PublicKey @($VmssPublicKey)
$Vmss = Set-AzVmssStorageProfile `
-VirtualMachineScaleSet $Vmss `
-OsDiskCreateOption 'FromImage' `
-OsDiskCaching ReadOnly `
-DiffDiskSetting Local `
-ImageReferenceId $Image.Id
New-AzVmss `
-ResourceGroupName $ResourceGroupName `
-Name $VmssName `
-VirtualMachineScaleSet $Vmss
Write-Host "Location: $Location"
Write-Host "Resource group name: $ResourceGroupName"
Write-Host 'Finished!'

View File

@@ -0,0 +1,78 @@
#!/bin/bash
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: MIT
#
export DEBIAN_FRONTEND=noninteractive
apt-get -y update
apt-get -y dist-upgrade
# Install common build dependencies
APT_PACKAGES="at curl unzip tar libxt-dev gperf libxaw7-dev cifs-utils \
build-essential g++ gfortran zip libx11-dev libxkbcommon-x11-dev libxi-dev \
libgl1-mesa-dev libglu1-mesa-dev mesa-common-dev libxinerama-dev libxxf86vm-dev \
libxcursor-dev yasm libnuma1 libnuma-dev python-six python3-six python-yaml \
flex libbison-dev autoconf libudev-dev libncurses5-dev libtool libxrandr-dev \
xutils-dev dh-autoreconf autoconf-archive libgles2-mesa-dev ruby-full \
pkg-config meson nasm cmake ninja-build"
# Additionally required by qt5-base
APT_PACKAGES="$APT_PACKAGES libxext-dev libxfixes-dev libxrender-dev \
libxcb1-dev libx11-xcb-dev libxcb-glx0-dev libxcb-util0-dev"
# Additionally required by qt5-base for qt5-x11extras
APT_PACKAGES="$APT_PACKAGES libxkbcommon-dev libxcb-keysyms1-dev \
libxcb-image0-dev libxcb-shm0-dev libxcb-icccm4-dev libxcb-sync0-dev \
libxcb-xfixes0-dev libxcb-shape0-dev libxcb-randr0-dev \
libxcb-render-util0-dev libxcb-xinerama0-dev libxcb-xkb-dev libxcb-xinput-dev"
# Additionally required by libhdfs3
APT_PACKAGES="$APT_PACKAGES libkrb5-dev"
# Additionally required by kf5windowsystem
APT_PACKAGES="$APT_PACKAGES libxcb-res0-dev"
# Additionally required by mesa
APT_PACKAGES="$APT_PACKAGES python3-setuptools python3-mako"
# Additionally required by some packages to install additional python packages
APT_PACKAGES="$APT_PACKAGES python3-pip python3-venv"
# Additionally required by qtwebengine
APT_PACKAGES="$APT_PACKAGES nodejs"
# Additionally required by qtwayland
APT_PACKAGES="$APT_PACKAGES libwayland-dev"
# Additionally required by all GN projects
APT_PACKAGES="$APT_PACKAGES python2 python-is-python3"
# Additionally required by libctl
APT_PACKAGES="$APT_PACKAGES guile-2.2-dev"
# Additionally required by gtk
APT_PACKAGES="$APT_PACKAGES libxdamage-dev"
# Additionally required/installed by Azure DevOps Scale Set Agents
APT_PACKAGES="$APT_PACKAGES liblttng-ust0 libkrb5-3 zlib1g libicu66"
apt-get -y install $APT_PACKAGES
# Install the latest Haskell stack for bond
curl -sSL https://get.haskellstack.org/ | sh
# Install CUDA
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pin
mv cuda-ubuntu2004.pin /etc/apt/preferences.d/cuda-repository-pin-600
apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/3bf863cc.pub
add-apt-repository "deb https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/ /"
apt-get -y update
apt-get install -y --no-install-recommends cuda-compiler-11-6 cuda-libraries-dev-11-6 cuda-driver-dev-11-6 \
cuda-cudart-dev-11-6 libcublas-11-6 libcurand-dev-11-6 cuda-nvml-dev-11-6 libcudnn8-dev libnccl2 libnccl-dev
# Install PowerShell
wget -q https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb
dpkg -i packages-microsoft-prod.deb
apt-get update
add-apt-repository universe
apt-get install -y powershell

View File

@@ -0,0 +1,128 @@
#!pwsh
#Requires -Version 6.0
<#
.SYNOPSIS
Installs the set of prerequisites for the macOS CI hosts.
.DESCRIPTION
Install-Prerequisites.ps1 installs all of the necessary prerequisites
to run the vcpkg macOS CI in a vagrant virtual machine,
skipping all prerequisites that are already installed and of the right version.
.INPUTS
None
.OUTPUTS
None
#>
[CmdletBinding()]
Param()
Set-StrictMode -Version 2
if (-not $IsMacOS) {
Write-Error 'This script should only be run on a macOS host'
throw
}
Import-Module "$PSScriptRoot/Utilities.psm1"
$Installables = Get-Content "$PSScriptRoot/configuration/installables.json" | ConvertFrom-Json
$Installables.Applications | ForEach-Object {
$VersionCommand = $_.VersionCommand
$InstalledVersion = (& $VersionCommand[0] $VersionCommand[1..$VersionCommand.Length])
if (-not $?) {
Write-Host "$($_.Name) not installed; installing now"
} else {
$InstalledVersion = $InstalledVersion -join "`n"
if ($InstalledVersion -match $_.VersionRegex) {
if ($Matches.Count -ne 2) {
Write-Error "$($_.Name) has a malformed version regex ($($_.VersionRegex)); it should have a single capture group
(it has $($Matches.Count - 1))"
throw
}
if ($Matches[1] -eq $_.Version) {
Write-Host "$($_.Name) already installed and at the correct version ($($Matches[1]))"
return
} else {
Write-Host "$($_.Name) already installed but with the incorrect version
installed version: '$($Matches[1])'
required version : '$($_.Version)'
upgrading now."
}
} else {
Write-Warning "$($_.Name)'s version command ($($VersionCommand -join ' ')) returned a value we did not expect:
$InstalledVersion
expected a version matching the regex: $($_.VersionRegex)
Installing anyways."
}
}
if ($null -ne (Get-Member -InputObject $_ -Name 'DmgUrl')) {
$pathToDmg = "~/Downloads/$($_.Name).dmg"
Get-RemoteFile -OutFile $pathToDmg -Uri $_.DmgUrl -Sha256 $_.Sha256
hdiutil attach $pathToDmg -mountpoint /Volumes/setup-installer
if ($null -ne (Get-Member -InputObject $_ -Name 'InstallationCommands')) {
$_.InstallationCommands | % {
Write-Host "> $($_ -join ' ')"
& $_[0] $_[1..$_.Length] | Write-Host
}
} elseif ($null -ne (Get-Member -InputObject $_ -Name 'InstallerPath')) {
sudo installer -pkg "/Volumes/setup-installer/$($_.InstallerPath)" -target /
hdiutil detach /Volumes/setup-installer
} else {
Write-Error "$($_.Name) installer object has a DmgUrl, but neither an InstallerPath nor an InstallationCommands"
throw
}
} elseif ($null -ne (Get-Member -InputObject $_ -Name 'PkgUrl')) {
$pathToPkg = "~/Downloads/$($_.Name).pkg"
Get-RemoteFile -OutFile $pathToPkg -Uri $_.PkgUrl -Sha256 $_.Sha256
sudo installer -pkg $pathToPkg -target /
} else {
Write-Error "$($_.Name) does not have an installer in the configuration file."
throw
}
}
$installedVagrantPlugins = @{}
vagrant plugin list --machine-readable | ForEach-Object {
$timestamp, $target, $type, $data = $_ -split ','
switch ($type) {
# these are not important
'ui' { }
'plugin-version-constraint' { }
'plugin-name' {
$installedVagrantPlugins[$data] = $Null
}
'plugin-version' {
$version = $data -replace '%!\(VAGRANT_COMMA\)',','
if ($version -notmatch '^(.*), global') {
Write-Error "Invalid version string for plugin ${target}: $version"
throw
}
$installedVagrantPlugins[$target] = $Matches[1]
}
default {
Write-Warning "Unknown plugin list member type $type for plugin $target"
}
}
}
$Installables.VagrantPlugins | ForEach-Object {
if (-not $installedVagrantPlugins.Contains($_.Name)) {
Write-Host "$($_.Name) not installed; installing now"
} elseif ($installedVagrantPlugins[$_.Name] -ne $_.Version) {
Write-Host "$($_.Name) already installed but with the incorrect version
installed version: '$($installedVagrantPlugins[$_.Name])'
required version: '$($_.Version)'"
} else {
Write-Host "$($_.Name) already installed and at the correct version ($($_.Version))"
return
}
vagrant plugin install $_.Name --plugin-version $_.Version
}

View File

@@ -0,0 +1,258 @@
# `vcpkg-eg-mac` VMs
## Table of Contents
- [`vcpkg-eg-mac` VMs](#vcpkg-eg-mac-vms)
- [Table of Contents](#table-of-contents)
- [Basic Usage](#basic-usage)
- [Creating a new Vagrant box](#creating-a-new-vagrant-box)
- [VM Software Versions](#vm-software-versions)
- [Creating a New Azure Agent Pool](#creating-a-new-azure-agent-pool)
- [Running the VM](#running-the-vm)
- [Getting an Azure Pipelines PAT](#getting-an-azure-pipelines-pat)
- [Setting up a new macOS machine](#setting-up-a-new-macos-machine)
- [Troubleshooting](#troubleshooting)
- [(Internal) Accessing the macOS fileshare](#internal-accessing-the-macos-fileshare)
## Basic Usage
The most common operation here is to set up a new VM for Azure
pipelines; we try to make that operation as easy as possible.
It should take all of three steps, assuming the machine is
already set up (or read [these instructions] for how to set up a machine):
1. [Create a new vagrant box](#creating-a-new-vagrant-box)
2. [Create a new agent pool](#creating-a-new-azure-agent-pool)
3. [Setup and run the vagrant VM](#running-the-vm)
4. Update `azure-pipelines.yml` and `azure-pipelines-osx.yml` to point to the new macOS pool.
[these instructions]: #setting-up-a-new-macos-machine
### Creating a new Vagrant box
Whenever we want to install updated versions of the command line tools,
or of macOS, we need to create a new vagrant box.
This is pretty easy, but the results of the creation are not public,
since we're concerned about licensing.
However, if you're sure you're following Apple's licensing,
you can set up your own vagrant boxes that are the same as ours by doing the following:
You'll need some prerequisites:
- An Xcode installer - you can get this from Apple's developer website,
although you'll need to sign in first: <https://developer.apple.com/downloads>
- The software installed by `Install-Prerequisites.ps1`
If you're updating the CI pool, make sure you update macOS.
First, you'll need to create a base VM;
this is where you determine what version of macOS is installed.
Follow the Parallels process for creating a macOS VM; this involves
updating to whatever version, and then scrolling right until you find
"Install macOS from recovery partition".
Once you've done this, you can run through the installation of macOS onto a new VM.
You should set the username to `vagrant`.
Once it's finished installing, make sure to turn on the SSH server.
Open System Preferences, then go to Sharing > Remote Login,
and turn it on.
You'll then want to add the vagrant SSH keys to the VM's vagrant user.
Open the terminal application and run the following:
```sh
$ # basic stuff
$ date | sudo tee '/etc/vagrant_box_build_time'
$ printf 'vagrant\tALL=(ALL)\tNOPASSWD:\tALL\n' | sudo tee -a '/etc/sudoers.d/vagrant'
$ sudo chmod 0440 '/etc/sudoers.d/vagrant'
$ # then install vagrant keys
$ mkdir -p ~/.ssh
$ curl -fsSL 'https://raw.github.com/mitchellh/vagrant/master/keys/vagrant.pub' >~/.ssh/authorized_keys
$ chmod 0600 ~/.ssh/authorized_keys
```
Finally, you'll need to install the Parallel Tools.
From your host, in the top bar,
go to Actions > Install Parallels Tools...,
and then follow the instructions.
Now, let's package the VM into a base box.
(The following instructions are adapted from
[these official instructions][base-box-instructions]).
Run the following commands:
```sh
$ cd ~/Parallels
$ echo '{ "provider": "parallels" }' >metadata.json
$ tar zcvf <macos version>.box ./metadata.json ./<name of VM>.pvm
```
This will create a box file which contains all the necessary data.
You can delete the `metadata.json` file after.
Once you've done that, you can upload it to the fileshare,
under `share/boxes/macos-base`, add it to `share/boxes/macos-base.json`,
and finally add it to vagrant:
```sh
$ vagrant box add ~/vagrant/share/boxes/macos-base.json
```
Then, we'll create the final box,
which contains all the necessary programs for doing CI work.
Copy `configuration/Vagrantfile-box.rb` as `Vagrantfile`, and
`configuration/vagrant-box-configuration.json`
into a new directory; into that same directory,
download the Xcode command line tools dmg, and name it `clt.dmg`.
Then, run the following in that directory:
```sh
$ vagrant up
$ vagrant package
```
This will create a `package.box`, which is the box file for the base VM.
Once you've created this box, if you're making it the new box for the CI,
upload it to the fileshare, under `share/boxes/macos-ci`.
Then, add the metadata about the box (the name and version) to
`share/boxes/macos-ci.json`.
Once you've done that, add the software versions under [VM Software Versions](#vm-software-versions).
[base-box-instructions]: https://parallels.github.io/vagrant-parallels/docs/boxes/base.html
#### VM Software Versions
* 2022-02-04 (minor update to 2022-01-03)
* macOS: 12.1
* Xcode CLTs: 13.2
* 2022-01-03:
* macOS: 12.1
* Xcode CLTs: 13.2
* 2021-07-27:
* macOS: 11.5.1
* Xcode CLTs: 12.5.1
* 2021-04-16:
* macOS: 11.2.3
* Xcode CLTs: 12.4
* 2020-09-28:
* macOS: 10.15.6
* Xcode CLTs: 12
### Creating a New Azure Agent Pool
When updating the macOS machines to a new version, you'll need to create
a new agent pool for the machines to join. The standard for this is to
name it `PrOsx-YYYY-MM-DD`, with `YYYY-MM-DD` the day that the process
is started.
In order to create a new agent pool, go to the `vcpkg/public` project;
go to `Project settings`, then go to `Agent pools` under `Pipelines`.
Add a new self-hosted pool, name it as above, and make certain to check
the box for "Grant access permission to all pipelines".
Once you've done this, you are done; you can start adding new machines
to the pool!
### Running the VM
First, make sure that your software is up to date:
```sh
$ cd ~/vcpkg
$ git fetch
$ git switch -d origin/master
$ ./scripts/azure-pipelines/osx/Install-Prerequisites.ps1
```
as well as checking to make sure macOS is up to date.
Then, follow the instructions for [accessing ~/vagrant/share][access-fileshare].
And finally, [grab a PAT], update the vagrant box, set up the VM, and run it:
```sh
$ vagrant box remove -f vcpkg/macos-ci # This won't do anything if the machine never had a box before
$ vagrant box add ~/vagrant/share/boxes/macos-ci.json
$ ~/vcpkg/scripts/azure-pipelines/osx/Setup-VagrantMachines.ps1 -Date <box version YYYY-MM-DD> -DevopsPat <PAT>
$ cd ~/vagrant/vcpkg-eg-mac
$ vagrant up # if this fails, reboot through the kvm and/or log in interactively, then come back here
```
[grab a PAT]: #getting-an-azure-pipelines-pat
## Getting an Azure Pipelines PAT
Personal Access Tokens are an important part of this process,
and they are fairly easy to generate.
On ADO, under the correct project (in vcpkg's case, "vcpkg"),
click on the "User Settings" icon, then go to "Personal access tokens".
It is the icon to the left of your user icon, in the top right corner.
Then, create a new token, give it a name, make sure it expires quickly,
and give it a custom defined scope that includes the
"Agent pools: Read & manage" permission (you'll need to "Show all scopes"
to access this).
You can now copy this token and use it to allow machines to join.
## Setting up a new macOS machine
Before anything else, one must download `brew` and `powershell`.
```sh
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
$ brew cask install powershell
```
Then, we need to download the `vcpkg` repository:
```sh
$ git clone https://github.com/microsoft/vcpkg
```
Then, we need to mint an SSH key:
```sh
$ ssh-keygen
$ cat .ssh/id_rsa.pub
```
Add that SSH key to `authorized_keys` on the file share machine with the base box.
Next, install prerequisites:
```sh
$ cd vcpkg/scripts/azure-pipelines/osx
$ ./Install-Prerequisites.ps1 -Force
```
And finally, make sure you can [access ~/vagrant/share][access-fileshare].
## Troubleshooting
The following are issues that we've run into:
- (with a Parallels box) `vagrant up` doesn't work, and vagrant gives the error that the VM is `'stopped'`.
- Try logging into the GUI with the KVM, and retrying `vagrant up`.
- (when running a powershell script) The error `Failed to initialize CoreCLR, HRESULT: 0x8007001F` is printed.
- Reboot the machine; run
```sh
$ sudo shutdown -r now
```
and wait for the machine to start back up. Then, start again from where the error was emitted.
## (Internal) Accessing the macOS fileshare
The fileshare is located on `vcpkgmm-01`, under the `fileshare` user, in the `share` directory.
In order to get `sshfs` working on the physical machine,
You can run `Install-Prerequisites.ps1` to grab the right software, then either:
```sh
$ mkdir -p ~/vagrant/share
$ sshfs fileshare@vcpkgmm-01:share ~/vagrant/share
```
If you get an error, that means that gatekeeper has prevented the kernel extension from loading,
so you'll need to access the GUI of the machine, go to System Preferences,
Security & Privacy, General, unlock the settings,
and allow system extensions from the osxfuse developer to run.
Then, you'll be able to add ~/vagrant/share as an sshfs.
[access-fileshare]: #internal-accessing-the-macos-fileshare

View File

@@ -0,0 +1,126 @@
#!pwsh
#Requires -Version 6.0
<#
.SYNOPSIS
Sets up the configuration for the vagrant virtual machines.
.DESCRIPTION
Setup-VagrantMachines.ps1 sets up the virtual machines for
vcpkg's macOS CI. It puts the VagrantFile and necessary
configuration JSON file into ~/vagrant/vcpkg-eg-mac.
.PARAMETER MachineId
The number to give the machine; should match [0-9]{2}.
Defaults to the numbers at the end of the machine name,
assuming that that machine name matches `VCPKGMM-[0-9]{2}`.
.PARAMETER DevopsPat
The personal access token which has Read & Manage permissions on the ADO pool.
.PARAMETER Date
The date on which this pool is being created. Sets the default values for BoxVersion and AgentPool.
.PARAMETER BoxVersion
The version of the box to use. If -Date is passed, uses that as the version.
.PARAMETER AgentPool
The agent pool to add the machine to. If -Date is passed, uses "PrOsx-$Date" as the pool.
.PARAMETER DevopsUrl
The URL of the ADO instance; defaults to vcpkg's, which is https://dev.azure.com/vcpkg.
.PARAMETER BaseName
The base name for the vagrant VM; the machine name is $BaseName-$MachineId.
Defaults to 'vcpkg-eg-mac'.
.PARAMETER BoxName
The name of the box to use. Defaults to 'vcpkg/macos-ci',
which is only available internally.
.INPUTS
None
.OUTPUTS
None
#>
[CmdletBinding(PositionalBinding=$False, DefaultParameterSetName='DefineDate')]
Param(
[Parameter(Mandatory=$False)]
[String]$MachineId,
[Parameter(Mandatory=$True)]
[String]$DevopsPat,
[Parameter(Mandatory=$True, ParameterSetName='DefineDate')]
[String]$Date,
[Parameter(Mandatory=$True, ParameterSetName='DefineVersionAndAgentPool')]
[String]$BoxVersion,
[Parameter(Mandatory=$True, ParameterSetName='DefineVersionAndAgentPool')]
[String]$AgentPool,
[Parameter(Mandatory=$False)]
[String]$DevopsUrl = 'https://dev.azure.com/vcpkg',
[Parameter()]
[String]$BaseName = 'vcpkg-eg-mac',
[Parameter()]
[String]$BoxName = 'vcpkg/macos-ci'
)
Set-StrictMode -Version 2
if (-not $IsMacOS) {
throw 'This script should only be run on a macOS host'
}
if (-not [String]::IsNullOrEmpty($Date)) {
$BoxVersion = $Date
$AgentPool = "PrOsx-$Date"
}
if ([String]::IsNullOrEmpty($MachineId)) {
$hostname = hostname -s
if ($hostname -match '^VCPKGMM-([0-9]{2})$') {
$MachineId = $matches[1]
} else {
Write-Error "Hostname ($hostname) does not match the expected format (VCPKGMM-NN). Please pass -MachineId in order to give the VM a number."
}
}
if (Test-Path '~/vagrant/vcpkg-eg-mac') {
Write-Host 'Deleting existing directories'
Push-Location '~/vagrant/vcpkg-eg-mac'
vagrant destroy -f
if (-not $?) {
throw "Failed to destroy vagrant VM."
}
Pop-Location
Remove-Item -Recurse -Force -LiteralPath '~/vagrant/vcpkg-eg-mac' | Out-Null
}
Write-Host 'Creating new directories'
if (-not (Test-Path -Path '~/vagrant')) {
New-Item -ItemType 'Directory' -Path '~/vagrant' | Out-Null
}
New-Item -ItemType 'Directory' -Path '~/vagrant/vcpkg-eg-mac' | Out-Null
Copy-Item `
-Path "$PSScriptRoot/configuration/Vagrantfile-vm.rb" `
-Destination '~/vagrant/vcpkg-eg-mac/Vagrantfile'
$configuration = @{
pat = $DevopsPat
agent_pool = $AgentPool
devops_url = $DevopsUrl
machine_name = "${BaseName}-${MachineId}"
box_name = $BoxName
box_version = $BoxVersion
}
ConvertTo-Json -InputObject $configuration -Depth 5 `
| Set-Content -Path '~/vagrant/vcpkg-eg-mac/vagrant-configuration.json'

View File

@@ -0,0 +1,90 @@
#Requires -Version 6.0
Set-StrictMode -Version 2
<#
.SYNOPSIS
Returns whether the specified command exists in the current environment.
.DESCRIPTION
Get-CommandExists takes a string as a parameter,
and returns whether it exists in the current environment;
either a function, alias, or an executable in the path.
It's somewhat equivalent to `which`.
.PARAMETER Name
Specifies the name of the command which may or may not exist.
.INPUTS
System.String
The name of the command.
.OUTPUTS
System.Boolean
Whether the command exists.
#>
function Get-CommandExists
{
[CmdletBinding()]
[OutputType([Boolean])]
Param(
[Parameter(ValueFromPipeline)]
[String]$Name
)
$null -ne (Get-Command -Name $Name -ErrorAction SilentlyContinue)
}
<#
.SYNOPSIS
Downloads a file and checks its hash.
.DESCRIPTION
Get-RemoteFile takes a URI and a hash,
downloads the file at that URI to OutFile,
and checks that the hash of the downloaded file.
It then returns a FileInfo object corresponding to the downloaded file.
.PARAMETER OutFile
Specifies the file path to download to.
.PARAMETER Uri
The URI to download from.
.PARAMETER Sha256
The expected SHA256 of the downloaded file.
.INPUTS
None
.OUTPUTS
System.IO.FileInfo
The FileInfo for the downloaded file.
#>
function Get-RemoteFile
{
[CmdletBinding(PositionalBinding=$False)]
[OutputType([System.IO.FileInfo])]
Param(
[Parameter(Mandatory=$True)]
[String]$OutFile,
[Parameter(Mandatory=$True)]
[String]$Uri,
[Parameter(Mandatory=$True)]
[String]$Sha256
)
Invoke-WebRequest -OutFile $OutFile -Uri $Uri
$actualHash = Get-FileHash -Algorithm SHA256 -Path $OutFile
if ($actualHash.Hash -ne $Sha256) {
throw @"
Invalid hash for file $OutFile;
expected: $Sha256
found: $($actualHash.Hash)
Please make sure that the hash in the powershell file is correct.
"@
}
Get-Item $OutFile
}

View File

@@ -0,0 +1,81 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: MIT
#
parameters:
- name: vcpkgToolSha
displayName: 'Custom SHA of vcpkg-tool to use rather than bootstrap'
type: string
default: 'use default'
- name: poolName
type: string
jobs:
- job: x64_osx
pool:
name: ${{ parameters.poolName }}
workspace:
clean: resources
timeoutInMinutes: 2880 # 2 days
variables:
- name: WORKING_ROOT
value: /Users/vagrant/Data
- name: VCPKG_DOWNLOADS
value: /Users/vagrant/Data/downloads
- group: vcpkg-binary-caching-credentials
- name: X_VCPKG_BINARY_SOURCE_STUB
value: "x-azblob,$(root-bin-url),$(sas-bin)" # not in eastasia due to physical location
- group: vcpkg-asset-caching-credentials
- name: X_VCPKG_ASSET_SOURCES
value: "x-azurl,$(root-url-ea),$(sas-ea),readwrite"
steps:
- bash: |
sudo mkdir ${{ variables.VCPKG_DOWNLOADS }} || 0
sudo chmod 777 ${{ variables.VCPKG_DOWNLOADS }} || 0
exit 0
displayName: 'Create ${{ variables.VCPKG_DOWNLOADS }}'
- bash: ./bootstrap-vcpkg.sh
displayName: 'Bootstrap vcpkg'
condition: eq('use default', '${{ parameters.vcpkgToolSha }}')
- bash: |
brew install cmake
./scripts/azure-pipelines/bootstrap-from-source.sh ${{ parameters.vcpkgToolSha }}
displayName: "Build vcpkg with CMake"
condition: ne('use default', '${{ parameters.vcpkgToolSha }}')
- task: PowerShell@2
displayName: '*** Test Modified Ports'
inputs:
failOnStderr: true
filePath: 'scripts/azure-pipelines/test-modified-ports.ps1'
arguments: >
-Triplet "x64-osx"
-BuildReason "$(Build.Reason)"
-BinarySourceStub "${{ variables.X_VCPKG_BINARY_SOURCE_STUB }}"
-WorkingRoot "${{ variables.WORKING_ROOT }}"
-ArtifactStagingDirectory "$(Build.ArtifactStagingDirectory)"
pwsh: true
- task: PublishBuildArtifacts@1
displayName: 'Publish Artifact: failure logs for x64-osx'
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)/failure-logs'
ArtifactName: 'failure logs for x64-osx${{ variables.Postfix }}'
condition: ne(variables['FAILURE_LOGS_EMPTY'], 'True')
- bash: python3 scripts/file_script.py /Users/vagrant/Data/installed/vcpkg/info/
displayName: 'Build a file list for all packages'
condition: always()
- task: PublishBuildArtifacts@1
displayName: 'Publish Artifact: file lists for x64-osx${{ variables.Postfix }}'
condition: always()
inputs:
PathtoPublish: scripts/list_files
ArtifactName: 'file lists for x64-osx${{ variables.Postfix }}'
- task: PublishTestResults@2
displayName: 'Publish Test Results'
condition: ne(variables['XML_RESULTS_FILE'], '')
inputs:
testRunTitle: x64-osx
testResultsFormat: xUnit
testResultsFiles: $(XML_RESULTS_FILE)
platform: x64-osx
configuration: static

View File

@@ -0,0 +1,35 @@
require 'json'
configuration = JSON.parse(File.read("#{__dir__}/vagrant-box-configuration.json"))
Vagrant.configure('2') do |config|
config.vm.box = 'vcpkg/macos-base'
config.vm.synced_folder '.', '/Users/vagrant/shared'
config.vm.provision 'shell',
run: 'once',
name: 'Install Xcode Command Line Tools: attach dmg file',
inline: 'hdiutil attach shared/clt.dmg -mountpoint /Volumes/setup-installer',
privileged: false
config.vm.provision 'shell',
run: 'once',
name: 'Install Xcode Command Line Tools: run installer',
inline: 'installer -pkg "/Volumes/setup-installer/Command Line Tools.pkg" -target /',
privileged: true
config.vm.provision 'shell',
run: 'once',
name: 'Install XCode Command Line Tools: detach dmg file',
inline: 'hdiutil detach /Volumes/setup-installer',
privileged: false
config.vm.provision 'shell',
run: 'once',
name: 'Install brew',
inline: '/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"',
privileged: false
config.vm.provision 'shell',
run: 'once',
name: 'Install brew applications',
inline: "brew install #{configuration['brew'].join(' ')} && brew install --cask #{configuration['brew-cask'].join(' ')}",
privileged: false
end

View File

@@ -0,0 +1,67 @@
require 'json'
configuration = JSON.parse(File.read("#{__dir__}/vagrant-configuration.json"))
server = {
:machine_name => configuration['machine_name'],
:box => configuration['box_name'],
:box_version => configuration['box_version'],
:ram => 24000,
:cpu => 11
}
azure_agent_url = 'https://vstsagentpackage.azureedge.net/agent/2.198.3/vsts-agent-osx-x64-2.198.3.tar.gz'
devops_url = configuration['devops_url']
agent_pool = configuration['agent_pool']
pat = configuration['pat']
Vagrant.configure('2') do |config|
config.vm.box = server[:box]
config.vm.box_version = server[:box_version]
config.vm.synced_folder '.', '/vagrant', disabled: true
config.vm.provider 'parallels' do |prl|
prl.memory = server[:ram]
prl.cpus = server[:cpu]
end
config.vm.provision 'shell',
run: 'once',
name: 'Create the data directory',
inline: "mkdir ~/Data",
privileged: false
config.vm.provision 'shell',
run: 'once',
name: 'Download azure agent',
inline: "curl -s -o ~/Downloads/azure-agent.tar.gz #{azure_agent_url}",
privileged: false
config.vm.provision 'shell',
run: 'once',
name: 'Unpack azure agent',
inline: 'mkdir myagent; cd myagent; tar xf ~/Downloads/azure-agent.tar.gz',
privileged: false
config.vm.provision 'shell',
run: 'once',
name: 'Add VM to azure agent pool',
inline: "cd ~/myagent;\
./config.sh --unattended \
--url #{devops_url} \
--work ~/Data/work \
--auth pat --token #{pat} \
--pool #{agent_pool} \
--agent #{server[:machine_name]} \
--replace \
--acceptTeeEula",
privileged: false
# Start listening for jobs
config.vm.provision 'shell',
run: 'always',
name: 'Start running azure pipelines',
inline: 'cd /Users/vagrant/myagent;\
nohup ./run.sh&',
privileged: false
end

View File

@@ -0,0 +1,53 @@
{
"$schema": "./installables.schema.json",
"Applications": [
{
"Name": "vagrant",
"VersionCommand": [ "vagrant", "-v" ],
"VersionRegex": "Vagrant (.*)",
"Version": "2.2.19",
"DmgUrl": "https://releases.hashicorp.com/vagrant/2.2.19/vagrant_2.2.19_x86_64.dmg",
"Sha256": "6307BE217813A11C9E106448BF232803031E434A08C8B2DF8C62FDC9E8543845",
"InstallerPath": "vagrant.pkg"
},
{
"Name": "Parallels",
"VersionCommand": [ "cat", "/Applications/Parallels Desktop.app/Contents/Info.plist" ],
"VersionRegex": "<key>CFBundleShortVersionString</key>[\\n\\t ]*<string>([0-9.]+)</string>",
"Version": "17.1.1",
"DmgUrl": "https://download.parallels.com/desktop/v17/17.1.1-51537/ParallelsDesktop-17.1.1-51537.dmg",
"Sha256": "BD7BE2DF4D1B3508C127CF1D9C1EF93CDDA63384BCF3893A77FBC9F1169765A9",
"InstallationCommands": [
[ "bash", "-c", "ps x | grep 'Parallels Desktop' | grep -v 'grep' | sed -E 's/^ *([0-9]+).*(\\/Applications.*)$/\\1: \\2/'" ],
[ "bash", "-c", "ps x | grep 'Parallels Desktop' | grep -v 'grep' | sed -E 's/^ *([0-9]+).*$/\\1/' | xargs -p kill" ],
[ "sudo", "rm", "-rf", "/Applications/Parallels Desktop.app" ],
[ "sudo", "cp", "-r", "/Volumes/setup-installer/Parallels Desktop.app", "/Applications" ],
[ "sudo", "/Applications/Parallels Desktop.app/Contents/MacOS/inittool2", "init", "-b", "/Applications/Parallels Desktop.app" ]
]
},
{
"Name": "osxfuse",
"VersionCommand": [ "cat", "/Library/Filesystems/macfuse.fs/Contents/version.plist" ],
"VersionRegex": "<key>CFBundleVersion</key>[\\n\\t ]*<string>([0-9.]+)</string>",
"Version": "4.2.4",
"DmgUrl": "https://github.com/osxfuse/osxfuse/releases/download/macfuse-4.2.4/macfuse-4.2.4.dmg",
"Sha256": "82A2C30B3A7BF56AA2755C0C192FB50D9EECC3FE42505AB4E8679B50306188BD",
"InstallerPath": "Install macFUSE.pkg"
},
{
"Name": "sshfs",
"VersionCommand": [ "sshfs", "--version" ],
"VersionRegex": "SSHFS version [0-9.]* \\(OSXFUSE SSHFS (.*)\\)",
"Version": "2.5.0",
"PkgUrl": "https://github.com/osxfuse/sshfs/releases/download/osxfuse-sshfs-2.5.0/sshfs-2.5.0.pkg",
"Sha256": "F8F4F71814273EA42DBE6CD92199F7CFF418571FFD1B10C0608878D3472D2162"
}
],
"VagrantPlugins": [
{
"Name": "vagrant-parallels",
"Version": "2.2.4"
}
]
}

View File

@@ -0,0 +1,66 @@
{
"$schema": "https://json-schema.org/draft-07/schema",
"type": "object",
"definitions": {
"sha256": {
"type": "string",
"pattern": "[A-Z0-9]{64}"
}
},
"required": [
"Applications",
"VagrantPlugins"
],
"properties": {
"Applications": {
"type": "array",
"items": {
"type": "object",
"properties": {
"Name": {
"type": "string"
},
"VersionCommand": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1
},
"VersionRegex": {
"type": "string",
"format": "regex"
},
"Version": {
"type": "string"
},
"DmgUrl": {
"type": "string",
"format": "uri"
},
"Sha256": {
"$ref": "#/definitions/sha256"
},
"InstallerPath": {
"type": "string"
}
}
}
},
"VagrantPlugins": {
"type": "array",
"items": {
"type": "object",
"required": [ "Name", "Version" ],
"properties": {
"Name": {
"type": "string"
},
"Version": {
"type": "string"
}
}
}
}
}
}

View File

@@ -0,0 +1,25 @@
{
"$schema": "./vagrant-box-configuration.schema.json",
"brew": [
"autoconf-archive",
"autoconf",
"automake",
"bison",
"cmake",
"gettext",
"gfortran",
"gperf",
"gtk-doc",
"libtool",
"meson",
"mono",
"nasm",
"ninja",
"pkg-config",
"texinfo",
"yasm"
],
"brew-cask": [
"powershell"
]
}

View File

@@ -0,0 +1,18 @@
{
"$schema": "https://json-schema.org/draft-07/schema",
"type": "object",
"required": [
"brew",
"brew-cask"
],
"properties": {
"brew": {
"type": "array",
"items": { "type": "string" }
},
"brew-cask": {
"type": "array",
"items": { "type": "string" }
}
}
}

View File

@@ -0,0 +1,35 @@
{
"$schema": "https://json-schema.org/draft/2019-09/schema",
"type": "object",
"required": [
"pat",
"agent_pool",
"devops_url",
"machine_name",
"box_name",
"box_version"
],
"properties": {
"pat": {
"type": "string"
},
"agent_pool": {
"type": "string"
},
"devops_url": {
"type": "string"
},
"machine_name": {
"type": "string"
},
"box_name": {
"type": "string"
},
"box_version": {
"type": "string"
}
}
}

View File

@@ -0,0 +1,176 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: MIT
#
<#
.SYNOPSIS
Runs the 'Test Modified Ports' part of the vcpkg CI system for all platforms.
.PARAMETER Triplet
The triplet to test.
.PARAMETER WorkingRoot
The location used as scratch space for 'installed', 'packages', and 'buildtrees' vcpkg directories.
.PARAMETER ArtifactStagingDirectory
The Azure Pipelines artifacts directory. If not supplied, defaults to the current directory.
.PARAMETER ArchivesRoot
Equivalent to '-BinarySourceStub "files,$ArchivesRoot"'
.PARAMETER BinarySourceStub
The type and parameters of the binary source. Shared across runs of this script. If
this parameter is not set, binary caching will not be used. Example: "files,W:\"
.PARAMETER BuildReason
The reason Azure Pipelines is running this script. For invocations caused by `PullRequest`,
modified ports are identified by changed hashes with regard to git HEAD~1 (subject to NoParentHashes),
and ports marked as failing in the CI baseline (or which depend on such ports) are skipped.
If BinarySourceStub is set and this parameter is set to a non-empty value other than `PullRequest`,
binary caching will be in write-only mode.
.PARAMETER NoParentHashes
Indicates to not use parent hashes even for pull requests.
.PARAMETER PassingIsPassing
Indicates that 'Passing, remove from fail list' results should not be emitted as failures. (For example, this is used
when using vcpkg to test a prerelease MSVC++ compiler)
#>
[CmdletBinding(DefaultParameterSetName="ArchivesRoot")]
Param(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string]$Triplet,
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
$WorkingRoot,
[ValidateNotNullOrEmpty()]
$ArtifactStagingDirectory = '.',
[Parameter(ParameterSetName='ArchivesRoot')]
$ArchivesRoot = $null,
[Parameter(ParameterSetName='BinarySourceStub')]
$BinarySourceStub = $null,
[String]$BuildReason = $null,
[switch]$NoParentHashes = $false,
[switch]$PassingIsPassing = $false
)
if (-Not ((Test-Path "triplets/$Triplet.cmake") -or (Test-Path "triplets/community/$Triplet.cmake"))) {
Write-Error "Incorrect triplet '$Triplet', please supply a valid triplet."
throw
}
if ((-Not [string]::IsNullOrWhiteSpace($ArchivesRoot))) {
if ((-Not [string]::IsNullOrWhiteSpace($BinarySourceStub))) {
Write-Error "Only one binary caching setting may be used."
throw
}
$BinarySourceStub = "files,$ArchivesRoot"
}
$env:VCPKG_DOWNLOADS = Join-Path $WorkingRoot 'downloads'
$buildtreesRoot = Join-Path $WorkingRoot 'buildtrees'
$installRoot = Join-Path $WorkingRoot 'installed'
$packagesRoot = Join-Path $WorkingRoot 'packages'
$commonArgs = @(
"--x-buildtrees-root=$buildtreesRoot",
"--x-install-root=$installRoot",
"--x-packages-root=$packagesRoot",
"--overlay-ports=scripts/test_ports"
)
$cachingArgs = @()
$skipFailuresArg = @()
if ([string]::IsNullOrWhiteSpace($BinarySourceStub)) {
$cachingArgs = @('--no-binarycaching')
} else {
$cachingArgs = @('--binarycaching')
$binaryCachingMode = 'readwrite'
if ([string]::IsNullOrWhiteSpace($BuildReason)) {
Write-Host 'Build reason not specified, defaulting to using binary caching in read write mode.'
}
elseif ($BuildReason -eq 'PullRequest') {
Write-Host 'Build reason was Pull Request, using binary caching in read write mode, skipping failures.'
$skipFailuresArg = @('--skip-failures')
}
else {
Write-Host "Build reason was $BuildReason, using binary caching in write only mode."
$binaryCachingMode = 'write'
}
$cachingArgs += @("--binarysource=clear;$BinarySourceStub,$binaryCachingMode")
}
if ($Triplet -eq 'x64-linux') {
$env:HOME = '/home/agent'
$executableExtension = [string]::Empty
}
elseif ($Triplet -eq 'x64-osx') {
$executableExtension = [string]::Empty
}
else {
$executableExtension = '.exe'
}
$failureLogs = Join-Path $ArtifactStagingDirectory 'failure-logs'
$xunitFile = Join-Path $ArtifactStagingDirectory "$Triplet-results.xml"
if ($IsWindows)
{
mkdir empty
cmd /c "robocopy.exe empty `"$buildtreesRoot`" /MIR /NFL /NDL /NC /NP > nul"
cmd /c "robocopy.exe empty `"$packagesRoot`" /MIR /NFL /NDL /NC /NP > nul"
cmd /c "robocopy.exe empty `"$installRoot`" /MIR /NFL /NDL /NC /NP > nul"
rmdir empty
}
& "./vcpkg$executableExtension" x-ci-clean @commonArgs
if ($LASTEXITCODE -ne 0)
{
throw "vcpkg clean failed"
}
$parentHashes = @()
if (($BuildReason -eq 'PullRequest') -and -not $NoParentHashes)
{
# Prefetch tools for better output
foreach ($tool in @('cmake', 'ninja', 'git')) {
& "./vcpkg$executableExtension" fetch $tool
if ($LASTEXITCODE -ne 0)
{
throw "Failed to fetch $tool"
}
}
Write-Host "Determining parent hashes using HEAD~1"
$parentHashesFile = Join-Path $ArtifactStagingDirectory 'parent-hashes.json'
$parentHashes = @("--parent-hashes=$parentHashesFile")
& git revert -n -m 1 HEAD | Out-Null
# The vcpkg.cmake toolchain file is not part of ABI hashing,
# but changes must trigger at least some testing.
Copy-Item "scripts/buildsystems/vcpkg.cmake" -Destination "scripts/test_ports/cmake"
Copy-Item "scripts/buildsystems/vcpkg.cmake" -Destination "scripts/test_ports/cmake-user"
& "./vcpkg$executableExtension" ci "--triplet=$Triplet" --dry-run "--ci-baseline=$PSScriptRoot/../ci.baseline.txt" @commonArgs --no-binarycaching "--output-hashes=$parentHashesFile"
Write-Host "Running CI using parent hashes"
& git reset --hard HEAD
}
# The vcpkg.cmake toolchain file is not part of ABI hashing,
# but changes must trigger at least some testing.
Copy-Item "scripts/buildsystems/vcpkg.cmake" -Destination "scripts/test_ports/cmake"
Copy-Item "scripts/buildsystems/vcpkg.cmake" -Destination "scripts/test_ports/cmake-user"
& "./vcpkg$executableExtension" ci "--triplet=$Triplet" --failure-logs=$failureLogs --x-xunit=$xunitFile "--ci-baseline=$PSScriptRoot/../ci.baseline.txt" @commonArgs @cachingArgs @parentHashes @skipFailuresArg
$failureLogsEmpty = (-Not (Test-Path $failureLogs) -Or ((Get-ChildItem $failureLogs).count -eq 0))
Write-Host "##vso[task.setvariable variable=FAILURE_LOGS_EMPTY]$failureLogsEmpty"
if ($LASTEXITCODE -ne 0)
{
throw "vcpkg ci failed"
}
Write-Host "##vso[task.setvariable variable=XML_RESULTS_FILE]$xunitFile"

View File

@@ -0,0 +1,4 @@
The "unstable" build is used internally by Microsoft to test prerelease versions
of our C++ compiler; not seeing results from these build definitions in the
GitHub portal is normal as these builds depend on acquisition of private
compiler bits that aren't yet shipping.

View File

@@ -0,0 +1,11 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: MIT
#
variables:
unstable-pool: 'VcpkgUnstable1ES'
jobs:
- template: job.yml
parameters:
triplet: x64-windows
jobName: x64_windows

View File

@@ -0,0 +1,76 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: MIT
#
jobs:
- job: ${{ parameters.jobName }}
pool:
name: $(unstable-pool)
workspace:
clean: resources
timeoutInMinutes: 2880 # 2 days
variables:
- name: WORKING_ROOT
value: D:\
- name: VCPKG_DOWNLOADS
value: D:\downloads
- group: vcpkg-asset-caching-credentials
- name: X_VCPKG_ASSET_SOURCES
value: "x-azurl,$(root-url),$(sas),readwrite"
steps:
- task: DownloadBuildArtifacts@0
displayName: 'Download DropBuildNumber if not specified'
inputs:
buildType: specific
project: '0bdbc590-a062-4c3f-b0f6-9383f67865ee'
pipeline: 16549
buildVersionToDownload: latestFromBranch
branchName: 'refs/heads/$(MSVCBranchName)'
artifactName: BuildNumber
downloadPath: 'D:\msvc-drops'
condition: eq(variables['DropBuildNumber'], '')
- task: PowerShell@2
displayName: 'Set DropBuildNumber if not specified'
inputs:
targetType: inline
script: |
$DropBuildNumber = Get-Content -Path D:\msvc-drops\BuildNumber\Build.BuildNumber.txt
Write-Host "##vso[task.setvariable variable=DropBuildNumber]$DropBuildNumber"
Write-Host "Build Number set to: $DropBuildNumber"
pwsh: true
condition: eq(variables['DropBuildNumber'], '')
- task: ms-vscs-artifact.build-tasks.artifactDropDownloadTask-1.artifactDropDownloadTask@0
displayName: 'Download msvc x86 ret'
inputs:
dropServiceURI: 'https://devdiv.artifacts.visualstudio.com/DefaultCollection'
buildNumber: 'msvc/builds/$(DropBuildNumber)/x86ret'
destinationPath: 'D:\msvc-drops\$(DropBuildNumber)\binaries.x86ret'
- task: ms-vscs-artifact.build-tasks.artifactDropDownloadTask-1.artifactDropDownloadTask@0
displayName: 'Download msvc amd64 ret'
inputs:
dropServiceURI: 'https://devdiv.artifacts.visualstudio.com/DefaultCollection'
buildNumber: 'msvc/builds/$(DropBuildNumber)/amd64ret'
destinationPath: 'D:\msvc-drops\$(DropBuildNumber)\binaries.amd64ret'
- task: PowerShell@2
displayName: 'Rearrange MSVC Drop Layout'
inputs:
targetType: filePath
filePath: 'scripts/azure-pipelines/windows-unstable/rearrange-msvc-drop-layout.ps1'
arguments: '-DropRoot "D:\msvc-drops\$(DropBuildNumber)" -BuildType ret'
pwsh: true
- script: .\bootstrap-vcpkg.bat
displayName: 'Bootstrap vcpkg'
- task: PowerShell@2
displayName: '*** Test Modified Ports'
inputs:
failOnStderr: true
filePath: 'scripts/azure-pipelines/test-modified-ports.ps1'
arguments: '-Triplet ${{ parameters.triplet }} -BuildReason $(Build.Reason) -WorkingRoot ${{ variables.WORKING_ROOT }} -ArtifactStagingDirectory $(Build.ArtifactStagingDirectory) -PassingIsPassing'
pwsh: true
- task: PublishBuildArtifacts@1
displayName: 'Publish Artifact: failure logs for ${{ parameters.triplet }}'
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)\failure-logs'
ArtifactName: 'failure logs for ${{ parameters.triplet }}'
condition: ne(variables['FAILURE_LOGS_EMPTY'], 'True')

View File

@@ -0,0 +1,75 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: MIT
#
<#
.SYNOPSIS
Moves files from an MSVC compiler drop to the locations where they are installed in a Visual Studio installation.
.PARAMETER DropRoot
The location where the MSVC compiler drop has been downloaded.
.PARAMETER BuildType
The MSVC drop build type set with /p:_BuildType when MSVC was built. Defaults to 'ret'.
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)][string]$DropRoot,
[Parameter(Mandatory = $false)][ValidateSet('ret', 'chk')][string]$BuildType = 'ret'
)
Set-StrictMode -Version Latest
$MSVCRoot = "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC"
$ErrorActionPreference = "Stop"
$tempRoot = "$DropRoot\readytodeploy"
New-Item -ItemType Directory -Path $tempRoot | Out-Null
Write-Host "Rearranging x86$BuildType"
New-Item -ItemType Directory -Path "$tempRoot\bin\HostX86" | Out-Null
Move-Item "$DropRoot\binaries.x86$BuildType\bin\i386" "$tempRoot\bin\HostX86\x86"
Move-Item "$DropRoot\binaries.x86$BuildType\bin\x86_amd64" "$tempRoot\bin\HostX86\x64"
Move-Item "$DropRoot\binaries.x86$BuildType\bin\x86_arm" "$tempRoot\bin\HostX86\arm"
Write-Host "Rearranging amd64$BuildType"
New-Item -ItemType Directory -Path "$tempRoot\bin\HostX64" | Out-Null
Move-Item "$DropRoot\binaries.amd64$BuildType\bin\amd64" "$tempRoot\bin\HostX64\x64"
Move-Item "$DropRoot\binaries.amd64$BuildType\bin\amd64_x86" "$tempRoot\bin\HostX64\x86"
Move-Item "$DropRoot\binaries.amd64$BuildType\bin\amd64_arm" "$tempRoot\bin\HostX64\arm"
# Only copy files and directories that already exist in the VS installation.
Write-Host "Rearranging inc, lib"
New-Item -ItemType Directory -Path "$tempRoot\lib" | Out-Null
Move-Item "$DropRoot\binaries.x86$BuildType\inc" "$tempRoot\include"
Move-Item "$DropRoot\binaries.x86$BuildType\lib\i386" "$tempRoot\lib\x86"
Move-Item "$DropRoot\binaries.amd64$BuildType\lib\amd64" "$tempRoot\lib\x64"
Write-Host "Rearranging atlmfc"
New-Item -ItemType Directory -Path "$tempRoot\atlmfc" | Out-Null
New-Item -ItemType Directory -Path "$tempRoot\atlmfc\lib" | Out-Null
Move-Item "$DropRoot\binaries.x86$BuildType\atlmfc\include" "$tempRoot\atlmfc\include"
Move-Item "$DropRoot\binaries.x86$BuildType\atlmfc\lib\i386" "$tempRoot\atlmfc\lib\x86"
Move-Item "$DropRoot\binaries.amd64$BuildType\atlmfc\lib\amd64" "$tempRoot\atlmfc\lib\x64"
[string[]]$toolsets = Get-ChildItem -Path $MSVCRoot -Directory | Sort-Object -Descending
if ($toolsets.Length -eq 0) {
throw "Could not find Visual Studio toolset!"
}
Write-Host "Found toolsets:`n$($toolsets -join `"`n`")`n"
$selectedToolset = $toolsets[0]
Write-Host "Using toolset: $selectedToolset"
for ($idx = 1; $idx -lt $toolsets.Length; $idx++) {
$badToolset = $toolsets[$idx]
Write-Host "Deleting toolset: $badToolset"
Remove-Item $badToolset -Recurse -Force
}
Write-Host "Deploying $tempRoot => $selectedToolset"
Copy-Item "$tempRoot\*" $selectedToolset -Recurse -Force
Write-Host "Deleting $DropRoot..."
Remove-Item $DropRoot -Recurse -Force
Write-Host "Done!"

View File

@@ -0,0 +1,107 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: MIT
#
parameters:
- name: vcpkgToolSha
displayName: 'Custom SHA of vcpkg-tool to use rather than bootstrap'
type: string
default: 'use default'
- name: triplet
type: string
default: 'x86-windows'
- name: jobName
type: string
default: 'x86_windows'
- name: poolName
type: string
jobs:
- job: ${{ parameters.jobName }}
pool:
name: ${{ parameters.poolName }}
workspace:
clean: resources
timeoutInMinutes: 2880 # 2 days
variables:
- name: WORKING_ROOT
value: D:\
- name: VCPKG_DOWNLOADS
value: D:\downloads
- name: DiffFile
value: $(Build.ArtifactStagingDirectory)\format.diff
- name: ExtraChecksTriplet
value: x86-windows
- group: vcpkg-asset-caching-credentials
- name: X_VCPKG_ASSET_SOURCES
value: "x-azurl,$(root-url-ea),$(sas-ea),readwrite"
- group: vcpkg-binary-caching-credentials
- name: X_VCPKG_BINARY_SOURCE_STUB
value: "x-azblob,$(root-bin-url-ea),$(sas-bin-ea)"
steps:
- script: .\bootstrap-vcpkg.bat
displayName: 'Bootstrap vcpkg'
condition: eq('use default', '${{ parameters.vcpkgToolSha }}')
- script: .\scripts\azure-pipelines\windows\bootstrap-from-source.cmd ${{ parameters.vcpkgToolSha }}
displayName: "Build vcpkg with CMake"
condition: ne('use default', '${{ parameters.vcpkgToolSha }}')
- script: '.\vcpkg.exe format-manifest --all'
displayName: 'Format Manifests'
condition: eq('${{ parameters.triplet }}', '${{ variables.ExtraChecksTriplet }}')
- task: Powershell@2
displayName: 'Create Diff'
condition: eq('${{ parameters.triplet }}', '${{ variables.ExtraChecksTriplet }}')
inputs:
filePath: scripts/azure-pipelines/Create-PRDiff.ps1
arguments: "-DiffFile '$(DiffFile)'"
pwsh: true
- task: PublishBuildArtifacts@1
displayName: 'Publish Format and Documentation Diff'
condition: and(eq('${{ parameters.triplet }}', '${{ variables.ExtraChecksTriplet }}'), failed())
inputs:
PathtoPublish: '$(DiffFile)'
ArtifactName: 'format.diff'
- task: PowerShell@2
displayName: '*** Test Modified Ports'
inputs:
failOnStderr: true
filePath: 'scripts/azure-pipelines/test-modified-ports.ps1'
arguments: '-Triplet ${{ parameters.triplet }} -BuildReason $(Build.Reason) -BinarySourceStub "$(X_VCPKG_BINARY_SOURCE_STUB)" -WorkingRoot ${{ variables.WORKING_ROOT }} -ArtifactStagingDirectory $(Build.ArtifactStagingDirectory)'
pwsh: true
- task: PowerShell@2
displayName: 'Validate version files'
condition: eq('${{ parameters.triplet }}', '${{ variables.ExtraChecksTriplet }}')
inputs:
filePath: 'scripts/azure-pipelines/windows/validate-version-files.ps1'
pwsh: true
- task: PublishBuildArtifacts@1
displayName: 'Publish Artifact: failure logs for ${{ parameters.triplet }}'
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)\failure-logs'
ArtifactName: 'failure logs for ${{ parameters.triplet }}'
condition: ne(variables['FAILURE_LOGS_EMPTY'], 'True')
- task: PowerShell@2
displayName: 'Build a file list for all packages'
condition: always()
inputs:
targetType: inline
script: |
./vcpkg.exe fetch python3
& $(.\vcpkg fetch python3) .\scripts\file_script.py D:\installed\vcpkg\info\
pwsh: true
- task: PublishBuildArtifacts@1
displayName: 'Publish Artifact: file lists for ${{ parameters.triplet }}'
condition: always()
inputs:
PathtoPublish: scripts/list_files
ArtifactName: 'file lists for ${{ parameters.triplet }}'
- task: PublishTestResults@2
displayName: 'Publish Test Results'
condition: ne(variables['XML_RESULTS_FILE'], '')
inputs:
testRunTitle: ${{ parameters.triplet }}
testResultsFormat: xUnit
testResultsFiles: $(XML_RESULTS_FILE)
platform: ${{ parameters.triplet }}

View File

@@ -0,0 +1,7 @@
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=x86 -host_arch=x86
git clone https://github.com/microsoft/vcpkg-tool vcpkg-tool
git -C vcpkg-tool switch -d %1
rmdir /s /q build.x86.release > nul 2> nul
cmake.exe -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF -DVCPKG_DEVELOPMENT_WARNINGS=OFF -DVCPKG_WARNINGS_AS_ERRORS=OFF -DVCPKG_BUILD_FUZZING=OFF -DVCPKG_BUILD_TLS12_DOWNLOADER=OFF -B build.x86.release -S vcpkg-tool
ninja.exe -C build.x86.release
move build.x86.release\vcpkg.exe vcpkg.exe

View File

@@ -0,0 +1,271 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: MIT
#
<#
.SYNOPSIS
Creates a Windows virtual machine image, set up for vcpkg's CI.
.DESCRIPTION
create-image.ps1 creates an Azure Windows VM image, set up for vcpkg's CI system.
This script assumes you have installed Azure tools into PowerShell by following the instructions
at https://docs.microsoft.com/en-us/powershell/azure/install-az-ps?view=azps-3.6.1
or are running from Azure Cloud Shell.
#>
$Location = 'eastasia'
$Prefix = 'Win-'
$Prefix += (Get-Date -Format 'yyyy-MM-dd')
$VMSize = 'Standard_D8a_v4'
$ProtoVMName = 'PROTOTYPE'
$WindowsServerSku = '2022-datacenter'
$ErrorActionPreference = 'Stop'
$CudnnBaseUrl = 'https://vcpkgimageminting.blob.core.windows.net/assets/cudnn-windows-x86_64-8.3.2.44_cuda11.5-archive.zip'
$ProgressActivity = 'Creating Windows Image'
$TotalProgress = 18
$CurrentProgress = 1
Import-Module "$PSScriptRoot/../create-vmss-helpers.psm1" -DisableNameChecking
####################################################################################################
Write-Progress `
-Activity $ProgressActivity `
-Status 'Creating resource group' `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
$ResourceGroupName = Find-ResourceGroupName $Prefix
$AdminPW = New-Password
New-AzResourceGroup -Name $ResourceGroupName -Location $Location
$AdminPWSecure = ConvertTo-SecureString $AdminPW -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential ("AdminUser", $AdminPWSecure)
####################################################################################################
Write-Progress `
-Activity $ProgressActivity `
-Status 'Creating virtual network' `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
$VirtualNetwork = Create-LockedDownNetwork -ResourceGroupName $ResourceGroupName -Location $Location
####################################################################################################
Write-Progress `
-Activity $ProgressActivity `
-Status 'Creating prototype VM' `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
$NicName = $ResourceGroupName + 'NIC'
$Nic = New-AzNetworkInterface `
-Name $NicName `
-ResourceGroupName $ResourceGroupName `
-Location $Location `
-Subnet $VirtualNetwork.Subnets[0]
$VM = New-AzVMConfig -Name $ProtoVMName -VMSize $VMSize -Priority 'Spot' -MaxPrice -1
$VM = Set-AzVMOperatingSystem `
-VM $VM `
-Windows `
-ComputerName $ProtoVMName `
-Credential $Credential `
-ProvisionVMAgent
$VM = Add-AzVMNetworkInterface -VM $VM -Id $Nic.Id
$VM = Set-AzVMSourceImage `
-VM $VM `
-PublisherName 'MicrosoftWindowsServer' `
-Offer 'WindowsServer' `
-Skus $WindowsServerSku `
-Version latest
$VM = Set-AzVMBootDiagnostic -VM $VM -Disable
New-AzVm `
-ResourceGroupName $ResourceGroupName `
-Location $Location `
-VM $VM
####################################################################################################
Write-Progress `
-Activity $ProgressActivity `
-Status 'Running provisioning script deploy-tlssettings.ps1 in VM' `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
$ProvisionImageResult = Invoke-AzVMRunCommandWithRetries `
-ResourceGroupName $ResourceGroupName `
-VMName $ProtoVMName `
-CommandId 'RunPowerShellScript' `
-ScriptPath "$PSScriptRoot\deploy-tlssettings.ps1"
Write-Host "deploy-tlssettings.ps1 output: $($ProvisionImageResult.value.Message)"
Write-Host 'Waiting 1 minute for VM to reboot...'
Start-Sleep -Seconds 60
####################################################################################################
Write-Progress `
-Activity $ProgressActivity `
-Status 'Running provisioning script deploy-psexec.ps1 in VM' `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
$DeployPsExecResult = Invoke-AzVMRunCommandWithRetries `
-ResourceGroupName $ResourceGroupName `
-VMName $ProtoVMName `
-CommandId 'RunPowerShellScript' `
-ScriptPath "$PSScriptRoot\deploy-psexec.ps1"
Write-Host "deploy-psexec.ps1 output: $($DeployPsExecResult.value.Message)"
####################################################################################################
function Invoke-ScriptWithPrefix {
param(
[string]$ScriptName,
[switch]$AddAdminPw,
[string]$CudnnUrl
)
Write-Progress `
-Activity $ProgressActivity `
-Status "Running provisioning script $ScriptName in VM" `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
$DropToAdminUserPrefix = Get-Content "$PSScriptRoot\drop-to-admin-user-prefix.ps1" -Encoding utf8NoBOM -Raw
$UtilityPrefixContent = Get-Content "$PSScriptRoot\utility-prefix.ps1" -Encoding utf8NoBOM -Raw
$tempScriptFilename = [System.IO.Path]::GetTempPath() + [System.IO.Path]::GetRandomFileName() + ".txt"
try {
$script = Get-Content "$PSScriptRoot\$ScriptName" -Encoding utf8NoBOM -Raw
if ($AddAdminPw) {
$script = $script.Replace('# REPLACE WITH DROP-TO-ADMIN-USER-PREFIX.ps1', $DropToAdminUserPrefix)
}
if (-Not ([string]::IsNullOrWhiteSpace($CudnnUrl))) {
$script = $script.Replace('# REPLACE WITH $CudnnUrl', "`$CudnnUrl = '$CudnnUrl'")
}
$script = $script.Replace('# REPLACE WITH UTILITY-PREFIX.ps1', $UtilityPrefixContent);
Set-Content -Path $tempScriptFilename -Value $script -Encoding utf8NoBOM
$parameter = $null
if ($AddAdminPw) {
$parameter = @{AdminUserPassword = $AdminPW;}
}
$InvokeResult = Invoke-AzVMRunCommandWithRetries `
-ResourceGroupName $ResourceGroupName `
-VMName $ProtoVMName `
-CommandId 'RunPowerShellScript' `
-ScriptPath $tempScriptFilename `
-Parameter $parameter
Write-Host "$ScriptName output: $($InvokeResult.value.Message)"
} finally {
Remove-Item $tempScriptFilename -Force
}
}
Invoke-ScriptWithPrefix -ScriptName 'deploy-windows-sdks.ps1' -AddAdminPw
####################################################################################################
Invoke-ScriptWithPrefix -ScriptName 'deploy-visual-studio.ps1' -AddAdminPw
####################################################################################################
Invoke-ScriptWithPrefix -ScriptName 'deploy-mpi.ps1' -AddAdminPw
####################################################################################################
$StorageAccountKeys = Get-AzStorageAccountKey `
-ResourceGroupName 'vcpkg-image-minting' `
-Name 'vcpkgimageminting'
$StorageContext = New-AzStorageContext `
-StorageAccountName 'vcpkgimageminting' `
-StorageAccountKey $StorageAccountKeys[0].Value
$StartTime = [DateTime]::Now
$ExpiryTime = $StartTime.AddDays(1)
$SetupSasToken = New-AzStorageAccountSASToken `
-Service Blob `
-Permission "r" `
-Context $StorageContext `
-StartTime $StartTime `
-ExpiryTime $ExpiryTime `
-ResourceType Object `
-Protocol HttpsOnly
Invoke-ScriptWithPrefix -ScriptName 'deploy-cuda.ps1' -AddAdminPw -CudnnUrl ($CudnnBaseUrl + $SetupSasToken)
####################################################################################################
Invoke-ScriptWithPrefix -ScriptName 'deploy-inteloneapi.ps1' -AddAdminPw
####################################################################################################
Invoke-ScriptWithPrefix -ScriptName 'deploy-pwsh.ps1' -AddAdminPw
####################################################################################################
Write-Progress `
-Activity $ProgressActivity `
-Status 'Running provisioning script deploy-settings.txt (as a .ps1) in VM' `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
$ProvisionImageResult = Invoke-AzVMRunCommandWithRetries `
-ResourceGroupName $ResourceGroupName `
-VMName $ProtoVMName `
-CommandId 'RunPowerShellScript' `
-ScriptPath "$PSScriptRoot\deploy-settings.txt"
Write-Host "deploy-settings.txt output: $($ProvisionImageResult.value.Message)"
Restart-AzVM -ResourceGroupName $ResourceGroupName -Name $ProtoVMName
####################################################################################################
Write-Progress `
-Activity $ProgressActivity `
-Status 'Running provisioning script sysprep.ps1 in VM' `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
$SysprepResult = Invoke-AzVMRunCommandWithRetries `
-ResourceGroupName $ResourceGroupName `
-VMName $ProtoVMName `
-CommandId 'RunPowerShellScript' `
-ScriptPath "$PSScriptRoot\sysprep.ps1"
Write-Host "sysprep.ps1 output: $($SysprepResult.value.Message)"
####################################################################################################
Write-Progress `
-Activity $ProgressActivity `
-Status 'Waiting for VM to shut down' `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
Wait-Shutdown -ResourceGroupName $ResourceGroupName -Name $ProtoVMName
####################################################################################################
Write-Progress `
-Activity $ProgressActivity `
-Status 'Converting VM to Image' `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
Stop-AzVM `
-ResourceGroupName $ResourceGroupName `
-Name $ProtoVMName `
-Force
Set-AzVM `
-ResourceGroupName $ResourceGroupName `
-Name $ProtoVMName `
-Generalized
$VM = Get-AzVM -ResourceGroupName $ResourceGroupName -Name $ProtoVMName
$ImageConfig = New-AzImageConfig -Location $Location -SourceVirtualMachineId $VM.ID
$ImageName = Find-ImageName -ResourceGroupName 'vcpkg-image-minting' -Prefix $Prefix
New-AzImage -Image $ImageConfig -ImageName $ImageName -ResourceGroupName 'vcpkg-image-minting'
####################################################################################################
Write-Progress `
-Activity $ProgressActivity `
-Status 'Deleting unused temporary resources' `
-PercentComplete (100 / $TotalProgress * $CurrentProgress++)
Remove-AzResourceGroup $ResourceGroupName -Force
####################################################################################################
Write-Progress -Activity $ProgressActivity -Completed
Write-Host "Generated Image: $ImageName"
Write-Host 'Finished!'

View File

@@ -0,0 +1,94 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: MIT
#
<#
.SYNOPSIS
Creates a Windows virtual machine scale set, set up for vcpkg's CI.
.DESCRIPTION
create-vmss.ps1 creates an Azure Windows VM scale set, set up for vcpkg's CI
system. See https://docs.microsoft.com/en-us/azure/virtual-machine-scale-sets/overview
for more information.
This script assumes you have installed Azure tools into PowerShell by following the instructions
at https://docs.microsoft.com/en-us/powershell/azure/install-az-ps?view=azps-3.6.1
or are running from Azure Cloud Shell.
.PARAMETER ImageName
The name of the image to deploy into the scale set.
#>
[CmdLetBinding()]
Param(
[parameter(Mandatory=$true)]
[string]$ImageName
)
$Location = 'eastasia'
$Prefix = 'PrWin-'
$Prefix += (Get-Date -Format 'yyyy-MM-dd')
$VMSize = 'Standard_D32a_v4'
$LiveVMPrefix = 'BUILD'
$ErrorActionPreference = 'Stop'
Import-Module "$PSScriptRoot/../create-vmss-helpers.psm1" -DisableNameChecking
$ResourceGroupName = Find-ResourceGroupName $Prefix
$AdminPW = New-Password
$Image = Get-AzImage -ResourceGroupName 'vcpkg-image-minting' -ImageName $ImageName
New-AzResourceGroup -Name $ResourceGroupName -Location $Location
$VirtualNetwork = Create-LockedDownNetwork -ResourceGroupName $ResourceGroupName -Location $Location
$VmssIpConfigName = $ResourceGroupName + 'VmssIpConfig'
$VmssIpConfig = New-AzVmssIpConfig -SubnetId $VirtualNetwork.Subnets[0].Id -Primary -Name $VmssIpConfigName
$VmssName = $ResourceGroupName + 'Vmss'
$Vmss = New-AzVmssConfig `
-Location $Location `
-SkuCapacity 0 `
-SkuName $VMSize `
-SkuTier 'Standard' `
-Overprovision $false `
-UpgradePolicyMode Manual `
-EvictionPolicy Delete `
-Priority Spot `
-MaxPrice -1
$NicName = $ResourceGroupName + 'NIC'
New-AzNetworkInterface `
-Name $NicName `
-ResourceGroupName $ResourceGroupName `
-Location $Location `
-Subnet $VirtualNetwork.Subnets[0]
$Vmss = Add-AzVmssNetworkInterfaceConfiguration `
-VirtualMachineScaleSet $Vmss `
-Primary $true `
-IpConfiguration $VmssIpConfig `
-NetworkSecurityGroupId $VirtualNetwork.Subnets[0].NetworkSecurityGroup.Id `
-Name $NicName
$Vmss = Set-AzVmssOsProfile `
-VirtualMachineScaleSet $Vmss `
-ComputerNamePrefix $LiveVMPrefix `
-AdminUsername 'AdminUser' `
-AdminPassword $AdminPW `
-WindowsConfigurationProvisionVMAgent $true `
-WindowsConfigurationEnableAutomaticUpdate $false
$Vmss = Set-AzVmssStorageProfile `
-VirtualMachineScaleSet $Vmss `
-OsDiskCreateOption 'FromImage' `
-OsDiskCaching ReadOnly `
-DiffDiskSetting Local `
-ImageReferenceId $Image.Id
New-AzVmss `
-ResourceGroupName $ResourceGroupName `
-Name $VmssName `
-VirtualMachineScaleSet $Vmss
Write-Host "Location: $Location"
Write-Host "Resource group name: $ResourceGroupName"
Write-Host 'Finished!'

View File

@@ -0,0 +1,62 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: MIT
# REPLACE WITH DROP-TO-ADMIN-USER-PREFIX.ps1
# REPLACE WITH UTILITY-PREFIX.ps1
# REPLACE WITH $CudnnUrl
$CudnnLocalZipPath = "$PSScriptRoot\cudnn-windows-x86_64-8.3.2.44_cuda11.5-archive.zip"
$CudaUrl = 'https://developer.download.nvidia.com/compute/cuda/11.6.0/network_installers/cuda_11.6.0_windows_network.exe'
$CudaFeatures = 'nvcc_11.6 cuobjdump_11.6 nvprune_11.6 cupti_11.6 memcheck_11.6 nvdisasm_11.6 nvprof_11.6 ' + `
'visual_studio_integration_11.6 visual_profiler_11.6 visual_profiler_11.6 cublas_11.6 cublas_dev_11.6 ' + `
'cudart_11.6 cufft_11.6 cufft_dev_11.6 curand_11.6 curand_dev_11.6 cusolver_11.6 cusolver_dev_11.6 ' + `
'cusparse_11.6 cusparse_dev_11.6 npp_11.6 npp_dev_11.6 nvrtc_11.6 nvrtc_dev_11.6 nvml_dev_11.6 ' + `
'occupancy_calculator_11.6 thrust_11.6 '
$destination = "$env:ProgramFiles\NVIDIA GPU Computing Toolkit\CUDA\v11.6"
try {
Write-Host 'Downloading CUDA...'
[string]$installerPath = Get-TempFilePath -Extension 'exe'
curl.exe -L -o $installerPath -s -S $CudaUrl
Write-Host 'Installing CUDA...'
$proc = Start-Process -FilePath $installerPath -ArgumentList @('-s ' + $CudaFeatures) -Wait -PassThru
$exitCode = $proc.ExitCode
if ($exitCode -eq 0) {
Write-Host 'Installation successful!'
}
else {
Write-Error "Installation failed! Exited with $exitCode."
throw
}
}
catch {
Write-Error "Failed to install CUDA! $($_.Exception.Message)"
throw
}
try {
if ([string]::IsNullOrWhiteSpace($CudnnUrl)) {
if (-Not (Test-Path $CudnnLocalZipPath)) {
throw "CUDNN zip ($CudnnLocalZipPath) was missing, please download from NVidia and place next to this script."
}
$cudnnZipPath = $CudnnLocalZipPath
} else {
Write-Host 'Downloading CUDNN...'
$cudnnZipPath = Get-TempFilePath -Extension 'zip'
curl.exe -L -o $cudnnZipPath -s -S $CudnnUrl
}
Write-Host "Installing CUDNN to $destination..."
tar.exe -xvf "$cudnnZipPath" --strip 1 --directory "$destination"
Write-Host 'Installation successful!'
}
catch {
Write-Error "Failed to install CUDNN! $($_.Exception.Message)"
throw
}

View File

@@ -0,0 +1,60 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: MIT
# REPLACE WITH UTILITY-PREFIX.ps1
<#
.SYNOPSIS
Partitions a new physical disk.
.DESCRIPTION
Takes the disk $DiskNumber, turns it on, then partitions it for use with label
$Label and drive letter $Letter.
.PARAMETER DiskNumber
The number of the disk to set up.
.PARAMETER Letter
The drive letter at which to mount the disk.
.PARAMETER Label
The label to give the disk.
#>
Function New-PhysicalDisk {
Param(
[int]$DiskNumber,
[string]$Letter,
[string]$Label
)
if ($Letter.Length -ne 1) {
throw "Bad drive letter $Letter, expected only one letter. (Did you accidentially add a : ?)"
}
try {
Write-Host "Attempting to online physical disk $DiskNumber"
[string]$diskpartScriptPath = Get-TempFilePath -Extension 'txt'
[string]$diskpartScriptContent =
"SELECT DISK $DiskNumber`r`n" +
"ONLINE DISK`r`n"
Write-Host "Writing diskpart script to $diskpartScriptPath with content:"
Write-Host $diskpartScriptContent
Set-Content -Path $diskpartScriptPath -Value $diskpartScriptContent
Write-Host 'Invoking DISKPART...'
& diskpart.exe /s $diskpartScriptPath
Write-Host "Provisioning physical disk $DiskNumber as drive $Letter"
[string]$diskpartScriptContent =
"SELECT DISK $DiskNumber`r`n" +
"ATTRIBUTES DISK CLEAR READONLY`r`n" +
"CREATE PARTITION PRIMARY`r`n" +
"FORMAT FS=NTFS LABEL=`"$Label`" QUICK`r`n" +
"ASSIGN LETTER=$Letter`r`n"
Write-Host "Writing diskpart script to $diskpartScriptPath with content:"
Write-Host $diskpartScriptContent
Set-Content -Path $diskpartScriptPath -Value $diskpartScriptContent
Write-Host 'Invoking DISKPART...'
& diskpart.exe /s $diskpartScriptPath
}
catch {
Write-Error "Failed to provision physical disk $DiskNumber as drive $Letter! $($_.Exception.Message)"
}
}
New-PhysicalDisk -DiskNumber 1 -Letter 'E' -Label 'install disk'

View File

@@ -0,0 +1,74 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: MIT
# REPLACE WITH DROP-TO-ADMIN-USER-PREFIX.ps1
# REPLACE WITH UTILITY-PREFIX.ps1
# Seems like only the HPC kit is really needed?
#$oneAPIBaseUrl = 'https://registrationcenter-download.intel.com/akdlm/irc_nas/17768/w_BaseKit_p_2021.2.0.2871_offline.exe'
$oneAPIHPCUrl = 'https://registrationcenter-download.intel.com/akdlm/irc_nas/18578/w_HPCKit_p_2022.1.3.145_offline.exe'
# Possible oneAPI Base components:
#intel.oneapi.win.vtune 2021.1.1-68 true Intel® VTune(TM) Profiler
#intel.oneapi.win.tbb.devel 2021.1.1-133 true Intel® oneAPI Threading Building Blocks
#intel.oneapi.win.dnnl 2021.1.1-44 true Intel® oneAPI Deep Neural Network Library
#intel.oneapi.win.mkl.devel 2021.1.1-52 true Intel® oneAPI Math Kernel Library
#intel.oneapi.win.vpl 2021.1.1-76 true Intel® oneAPI Video Processing Library
#intel.oneapi.win.dpcpp_debugger 10.0.0-2213 true Intel® Distribution for GDB*
#intel.oneapi.win.ipp.devel 2021.1.1-47 true Intel® Integrated Performance Primitives
#intel.oneapi.win.ippcp 2021.1.1-53 true Intel® Integrated Performance Primitives Cryptography
#intel.oneapi.win.dpcpp-compiler 2021.1.1-191 true Intel® oneAPI DPC++/C++ Compiler
#intel.oneapi.win.dpcpp-library 2021.1.1-191 true Intel® oneAPI DPC++ Library
#intel.oneapi.win.dpcpp_ct.common 2021.1.1-54 true Intel® DPC++ Compatibility Tool
#intel.oneapi.win.dal.devel 2021.1.1-71 true Intel® oneAPI Data Analytics Library
#intel.oneapi.win.python3 2021.1.1-46 true Intel® Distribution for Python*
#intel.oneapi.win.advisor 2021.1.1-53 true Intel® Advisor
#$oneAPIBaseComponents = 'intel.oneapi.win.dpcpp-compiler:intel.oneapi.win.dpcpp-library:intel.oneapi.win.mkl.devel:intel.oneapi.win.ipp.devel:intel.oneapi.win.ippcp:intel.oneapi.win.dal.devel:intel.oneapi.win.dnnl:intel.oneapi.win.vpl:intel.oneapi.win.tbb.devel'
$oneAPIHPCComponents = 'intel.oneapi.win.cpp-compiler:intel.oneapi.win.ifort-compiler'
<#
.SYNOPSIS
Installs Intel oneAPI compilers and toolsets. Examples for CI can be found here: https://github.com/oneapi-src/oneapi-ci
.DESCRIPTION
InstallInteloneAPI installs the Intel oneAPI Compiler & Toolkit with the components specified as a
:-separated list of strings in $Components.
.PARAMETER Url
The URL of the Intel Toolkit installer.
.PARAMETER Components
A :-separated list of components to install.
#>
Function InstallInteloneAPI {
Param(
[String]$Url,
[String]$Components
)
try {
[string]$installerPath = Get-TempFilePath -Extension 'exe'
[string]$extractionPath = [System.IO.Path]::GetTempPath() + [System.IO.Path]::GetRandomFileName()
Write-Host 'Downloading Intel oneAPI...to: ' $installerPath
curl.exe -L -o $installerPath -s -S $Url
Write-Host 'Extracting Intel oneAPI...to folder: ' $extractionPath
$proc = Start-Process -FilePath $installerPath -ArgumentList @('-s ', '-x ', '-f ' + $extractionPath , '--log extract.log') -Wait -PassThru
Write-Host 'Install Intel oneAPI...from folder: ' $extractionPath
$proc = Start-Process -FilePath $extractionPath/bootstrapper.exe -ArgumentList @('-s ', '--action install', "--components=$Components" , '--eula=accept', '-p=NEED_VS2017_INTEGRATION=0', '-p=NEED_VS2019_INTEGRATION=0', '-p=NEED_VS2022_INTEGRATION=0', '--log-dir=.') -Wait -PassThru
$exitCode = $proc.ExitCode
if ($exitCode -eq 0) {
Write-Host 'Installation successful!'
}
else {
Write-Error "Installation failed! Exited with $exitCode."
throw
}
}
catch {
Write-Error "Failed to install Intel oneAPI! $($_.Exception.Message)"
throw
}
}
InstallInteloneAPI -Url $oneAPIHPCUrl -Components $oneAPIHPCComponents

View File

@@ -0,0 +1,47 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: MIT
# REPLACE WITH DROP-TO-ADMIN-USER-PREFIX.ps1
# REPLACE WITH UTILITY-PREFIX.ps1
$MpiUrl = 'https://download.microsoft.com/download/a/5/2/a5207ca5-1203-491a-8fb8-906fd68ae623/msmpisetup.exe'
<#
.SYNOPSIS
Installs MPI
.DESCRIPTION
Downloads the MPI installer located at $Url, and installs it with the
correct flags.
.PARAMETER Url
The URL of the installer.
#>
Function InstallMpi {
Param(
[String]$Url
)
try {
Write-Host 'Downloading MPI...'
[string]$installerPath = Get-TempFilePath -Extension 'exe'
curl.exe -L -o $installerPath -s -S $Url
Write-Host 'Installing MPI...'
$proc = Start-Process -FilePath $installerPath -ArgumentList @('-force', '-unattend') -Wait -PassThru
$exitCode = $proc.ExitCode
if ($exitCode -eq 0) {
Write-Host 'Installation successful!'
}
else {
Write-Error "Installation failed! Exited with $exitCode."
throw
}
}
catch {
Write-Error "Failed to install MPI! $($_.Exception.Message)"
throw
}
}
InstallMpi -Url $MpiUrl

View File

@@ -0,0 +1,8 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: MIT
$ErrorActionPreference = 'Stop'
$ProgressPreference = 'SilentlyContinue'
$PsExecPath = 'C:\PsExec64.exe'
Write-Host "Downloading psexec to: $PsExecPath"
& curl.exe -L -o $PsExecPath -s -S https://live.sysinternals.com/PsExec64.exe

View File

@@ -0,0 +1,9 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: MIT
# REPLACE WITH DROP-TO-ADMIN-USER-PREFIX.ps1
# REPLACE WITH UTILITY-PREFIX.ps1
$PwshUrl = 'https://github.com/PowerShell/PowerShell/releases/download/v7.2.3/PowerShell-7.2.3-win-x64.msi'
InstallMSI -Url $PwshUrl -Name 'PowerShell Core'

View File

@@ -0,0 +1,21 @@
$ErrorActionPreference = 'Stop'
$ProgressPreference = 'SilentlyContinue'
Write-Host 'Disabling pagefile...'
wmic computersystem set AutomaticManagedPagefile=False
wmic pagefileset delete
$av = Get-Command Add-MPPreference -ErrorAction SilentlyContinue
if ($null -eq $av) {
Write-Host 'AntiVirus not installed, skipping exclusions.'
} else {
Write-Host 'Configuring AntiVirus exclusions...'
Add-MpPreference -ExclusionPath C:\agent
Add-MPPreference -ExclusionPath D:\
Add-MPPreference -ExclusionPath E:\
Add-MPPreference -ExclusionProcess ninja.exe
Add-MPPreference -ExclusionProcess clang-cl.exe
Add-MPPreference -ExclusionProcess cl.exe
Add-MPPreference -ExclusionProcess link.exe
Add-MPPreference -ExclusionProcess python.exe
}

View File

@@ -0,0 +1,738 @@
#***************************************************************************************************************
# This script supports the TLS 1.2 everywhere project
# It does the following:
# * By default it disables TLS 1.O, TLS 1.1, SSLv2, SSLv3 and Enables TLS1.2
# * The CipherSuite order is set to the SDL approved version.
# * The FIPS MinEncryptionLevel is set to 3.
# * RC4 is disabled
# * A log with a transcript of all actions taken is generated
#***************************************************************************************************************
#************************************************ SCRIPT USAGE ************************************************
# .\TLSSettings.ps1
# -SetCipherOrder : Excellence/Min-Bar, default(Excellence), use B to set Min-Bar. (Min-Bar ordering prefers ciphers with smaller key sizes to improve performance over security)
# -RebootIfRequired : $true/$false, default($true), use $false to disable auto-reboot (Settings won't take effect until a reboot is completed)
# -EnableOlderTlsVersions : $true/$false, default($false), use $true to explicitly Enable TLS1.0, TLS1.1
#***************************************************************************************************************
#***************************TEAM CAN DETERMINE WHAT CIPHER SUITE ORDER IS CHOSEN ******************************
# Option B provides the min-bar configuration (small trade-off: performance over security)
# Syntax: .\TLSSettings.ps1 -SetCipherOrder B
# if no option is supplied, you will get the opportunity for excellence cipher order (small trade-off: security over performance)
# Syntax: .\TLSSettings.ps1
#***************************************************************************************************************
param (
[string]$SetCipherOrder = " ",
[bool]$RebootIfRequired = $true,
[bool]$EnableOlderTlsVersions = $false
)
#******************* FUNCTION THAT ACTUALLY UPDATES KEYS; WILL RETURN REBOOT FLAG IF CHANGES ***********************
Function Set-CryptoSetting {
param (
$regKeyName,
$value,
$valuedata,
$valuetype
)
$restart = $false
# Check for existence of registry key, and create if it does not exist
If (!(Test-Path -Path $regKeyName)) {
New-Item $regKeyName | Out-Null
}
# Get data of registry value, or null if it does not exist
$val = (Get-ItemProperty -Path $regKeyName -Name $value -ErrorAction SilentlyContinue).$value
If ($val -eq $null) {
# Value does not exist - create and set to desired value
New-ItemProperty -Path $regKeyName -Name $value -Value $valuedata -PropertyType $valuetype | Out-Null
$restart = $true
}
Else {
# Value does exist - if not equal to desired value, change it
If ($val -ne $valuedata) {
Set-ItemProperty -Path $regKeyName -Name $value -Value $valuedata
$restart = $true
}
}
$restart
}
#***************************************************************************************************************
#******************* FUNCTION THAT DISABLES RC4 ***********************
Function DisableRC4 {
$restart = $false
$subkeys = Get-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL"
$ciphers = $subkeys.OpenSubKey("Ciphers", $true)
Write-Log -Message "----- Checking the status of RC4 -----" -Logfile $logLocation -Severity Information
$RC4 = $false
if ($ciphers.SubKeyCount -eq 0) {
$k1 = $ciphers.CreateSubKey("RC4 128/128")
$k1.SetValue("Enabled", 0, [Microsoft.Win32.RegistryValueKind]::DWord)
$restart = $true
$k2 = $ciphers.CreateSubKey("RC4 64/128")
$k2.SetValue("Enabled", 0, [Microsoft.Win32.RegistryValueKind]::DWord)
$k3 = $ciphers.CreateSubKey("RC4 56/128")
$k3.SetValue("Enabled", 0, [Microsoft.Win32.RegistryValueKind]::DWord)
$k4 = $ciphers.CreateSubKey("RC4 40/128")
$k4.SetValue("Enabled", 0, [Microsoft.Win32.RegistryValueKind]::DWord)
Write-Log -Message "RC4 was disabled " -Logfile $logLocation -Severity Information
$RC4 = $true
}
If ($RC4 -ne $true) {
Write-Log -Message "There was no change for RC4 " -Logfile $logLocation -Severity Information
}
$restart
}
#***************************************************************************************************************
#******************* FUNCTION CHECKS FOR PROBLEMATIC FIPS SETTING AND FIXES IT ***********************
Function Test-RegistryValueForFipsSettings {
$restart = $false
$fipsPath = @(
"HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp",
"HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services",
"HKLM:\System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration"
)
$fipsValue = "MinEncryptionLevel"
foreach ($path in $fipsPath) {
Write-Log -Message "Checking to see if $($path)\$fipsValue exists" -Logfile $logLocation -Severity Information
$ErrorActionPreference = "stop"
Try {
$result = Get-ItemProperty -Path $path | Select-Object -ExpandProperty $fipsValue
if ($result -eq 4) {
set-itemproperty -Path $path -Name $fipsValue -value 3
Write-Log -Message "Regkey $($path)\$fipsValue was changed from value $result to a value of 3" -Logfile $logLocation -Severity Information
$restart = $true
}
else {
Write-Log -Message "Regkey $($path)\$fipsValue left at value $result" -Logfile $logLocation -Severity Information
}
}
Catch [System.Management.Automation.ItemNotFoundException] {
Write-Log -Message "Reg path $path was not found" -Logfile $logLocation -Severity Information
}
Catch [System.Management.Automation.PSArgumentException] {
Write-Log -Message "Regkey $($path)\$fipsValue was not found" -Logfile $logLocation -Severity Information
}
Catch {
Write-Log -Message "Error of type $($Error[0].Exception.GetType().FullName) trying to get $($path)\$fipsValue" -Logfile $logLocation -Severity Information
}
Finally {$ErrorActionPreference = "Continue"
}
}
$restart
}
#***************************************************************************************************************
#********************************** FUNCTION THAT CREATE LOG DIRECTORY IF IT DOES NOT EXIST *******************************
function CreateLogDirectory {
$TARGETDIR = "$env:HOMEDRIVE\Logs"
if ( -Not (Test-Path -Path $TARGETDIR ) ) {
New-Item -ItemType directory -Path $TARGETDIR | Out-Null
}
$TARGETDIR = $TARGETDIR + "\" + "TLSSettingsLogFile.csv"
return $TARGETDIR
}
#***************************************************************************************************************
#********************************** FUNCTION THAT LOGS WHAT THE SCRIPT IS DOING *******************************
function Write-Log {
[CmdletBinding()]
param(
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$Message,
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$LogFile,
[Parameter()]
[ValidateNotNullOrEmpty()]
[ValidateSet('Information', 'Warning', 'Error')]
[string]$Severity = 'Information'
)
[pscustomobject]@{
Time = (Get-Date -f g)
Message = $Message
Severity = $Severity
} | ConvertTo-Csv -NoTypeInformation | Select-Object -Skip 1 | Out-File -Append -FilePath $LogFile
}
#********************************TLS CipherSuite Settings *******************************************
# CipherSuites for windows OS < 10
function Get-BaseCipherSuitesOlderWindows()
{
param
(
[Parameter(Mandatory=$true, Position=0)][bool] $isExcellenceOrder
)
$cipherorder = @()
if ($isExcellenceOrder -eq $true)
{
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384_P384"
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256_P256"
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384_P384"
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256_P256"
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384"
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256"
}
else
{
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256_P256"
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384_P384"
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256_P256"
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384_P384"
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256"
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384"
}
# Add additional ciphers when EnableOlderTlsVersions flag is set to true
if ($EnableOlderTlsVersions)
{
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA_P256"
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA_P256"
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P256"
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_P256"
$cipherorder += "TLS_RSA_WITH_AES_256_GCM_SHA384"
$cipherorder += "TLS_RSA_WITH_AES_128_GCM_SHA256"
$cipherorder += "TLS_RSA_WITH_AES_256_CBC_SHA256"
$cipherorder += "TLS_RSA_WITH_AES_128_CBC_SHA256"
$cipherorder += "TLS_RSA_WITH_AES_256_CBC_SHA"
$cipherorder += "TLS_RSA_WITH_AES_128_CBC_SHA"
}
return $cipherorder
}
# Ciphersuites needed for backwards compatibility with Firefox, Chrome
# Server 2012 R2 doesn't support TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
# Both firefox and chrome negotiate ECDHE_RSA_AES_256_CBC_SHA1, Edge negotiates ECDHE_RSA_AES_256_CBC_SHA384
function Get-BrowserCompatCipherSuitesOlderWindows()
{
param
(
[Parameter(Mandatory=$true, Position=0)][bool] $isExcellenceOrder
)
$cipherorder = @()
if ($isExcellenceOrder -eq $true)
{
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384" # (uses SHA-1)
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_P256" # (uses SHA-1)
}
else
{
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_P256" # (uses SHA-1)
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384" # (uses SHA-1)
}
return $cipherorder
}
# Ciphersuites for OS versions windows 10 and above
function Get-BaseCipherSuitesWin10Above()
{
param
(
[Parameter(Mandatory=$true, Position=0)][bool] $isExcellenceOrder
)
$cipherorder = @()
if ($isExcellenceOrder -eq $true)
{
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"
}
else
{
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"
}
# Add additional ciphers when EnableOlderTlsVersions flag is set to true
if ($EnableOlderTlsVersions)
{
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA_P256"
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA_P256"
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P256"
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_P256"
$cipherorder += "TLS_RSA_WITH_AES_256_GCM_SHA384"
$cipherorder += "TLS_RSA_WITH_AES_128_GCM_SHA256"
$cipherorder += "TLS_RSA_WITH_AES_256_CBC_SHA256"
$cipherorder += "TLS_RSA_WITH_AES_128_CBC_SHA256"
$cipherorder += "TLS_RSA_WITH_AES_256_CBC_SHA"
$cipherorder += "TLS_RSA_WITH_AES_128_CBC_SHA"
}
return $cipherorder
}
#******************************* TLS Version Settings ****************************************************
function Get-RegKeyPathForTls12()
{
$regKeyPath = @(
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2",
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client",
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server"
)
return $regKeyPath
}
function Get-RegKeyPathForTls11()
{
$regKeyPath = @(
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1",
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client",
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server"
)
return $regKeyPath
}
function Get-RegKeypathForTls10()
{
$regKeyPath = @(
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0",
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client",
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server"
)
return $regKeyPath
}
function Get-RegKeyPathForSsl30()
{
$regKeyPath = @(
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0",
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Client",
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server"
)
return $regKeyPath
}
function Get-RegKeyPathForSsl20()
{
$regKeyPath = @(
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0",
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client",
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server"
)
return $regKeyPath
}
#Initialize reboot value to false
$reboot = $false
#*****************************Create the logfile if not does not exist***************************************
$logLocation = CreateLogDirectory
#Start writing to the logs
Write-Log -Message "========== Start of logging for a script execution ==========" -Logfile $logLocation -Severity Information
$registryPathGoodGuys = @()
$registryPathBadGuys = @()
# we enable TLS 1.2 and disable SSL 2.0, 3.0 in any case
$registryPathGoodGuys += Get-RegKeyPathForTls12
$registryPathBadGuys += Get-RegKeyPathForSsl20
$registryPathBadGuys += Get-RegKeyPathForSsl30
# add TLS 1.0/1.1 to good/bad depending on user's preference
# default is adding TLS 1.0/1.1 to bad
if ($EnableOlderTlsVersions)
{
$registryPathGoodGuys += Get-RegKeypathForTls10
$registryPathGoodGuys += Get-RegKeyPathForTls11
Write-Log -Message "Enabling TLS1.2, TLS1.1, TLS1.0. Disabling SSL3.0, SSL2.0" -Logfile $logLocation -Severity Information
}
else
{
$registryPathBadGuys += Get-RegKeypathForTls10
$registryPathBadGuys += Get-RegKeyPathForTls11
Write-Log -Message "Enabling TLS1.2. Disabling TLS1.1, TLS1.0, SSL3.0, SSL2.0" -Logfile $logLocation -Severity Information
}
Write-Log -Message "Check which registry keys exist already and which registry keys need to be created." -Logfile $logLocation -Severity Information
#******************* CREATE THE REGISTRY KEYS IF THEY DON'T EXIST********************************
# Check for existence of GoodGuy registry keys, and create if they do not exist
For ($i = 0; $i -lt $registryPathGoodGuys.Length; $i = $i + 1) {
Write-Log -Message "Checking for existing of key: $($registryPathGoodGuys[$i]) " -Logfile $logLocation -Severity Information
If (!(Test-Path -Path $registryPathGoodGuys[$i])) {
New-Item $registryPathGoodGuys[$i] | Out-Null
Write-Log -Message "Creating key: $($registryPathGoodGuys[$i]) " -Logfile $logLocation -Severity Information
}
}
# Check for existence of BadGuy registry keys, and create if they do not exist
For ($i = 0; $i -lt $registryPathBadGuys.Length; $i = $i + 1) {
Write-Log -Message "Checking for existing of key: $($registryPathBadGuys[$i]) " -Logfile $logLocation -Severity Information
If (!(Test-Path -Path $registryPathBadGuys[$i])) {
Write-Log -Message "Creating key: $($registryPathBadGuys[$i]) " -Logfile $logLocation -Severity Information
New-Item $registryPathBadGuys[$i] | Out-Null
}
}
#******************* EXPLICITLY DISABLE SSLV2, SSLV3, TLS10 AND TLS11 ********************************
For ($i = 0; $i -lt $registryPathBadGuys.Length; $i = $i + 1) {
if ($registryPathBadGuys[$i].Contains("Client") -Or $registryPathBadGuys[$i].Contains("Server")) {
Write-Log -Message "Disabling this key: $($registryPathBadGuys[$i]) " -Logfile $logLocation -Severity Information
$result = Set-CryptoSetting $registryPathBadGuys[$i].ToString() Enabled 0 DWord
$result = Set-CryptoSetting $registryPathBadGuys[$i].ToString() DisabledByDefault 1 DWord
$reboot = $reboot -or $result
}
}
#********************************* EXPLICITLY Enable TLS12 ****************************************
For ($i = 0; $i -lt $registryPathGoodGuys.Length; $i = $i + 1) {
if ($registryPathGoodGuys[$i].Contains("Client") -Or $registryPathGoodGuys[$i].Contains("Server")) {
Write-Log -Message "Enabling this key: $($registryPathGoodGuys[$i]) " -Logfile $logLocation -Severity Information
$result = Set-CryptoSetting $registryPathGoodGuys[$i].ToString() Enabled 1 DWord
$result = Set-CryptoSetting $registryPathGoodGuys[$i].ToString() DisabledByDefault 0 DWord
$reboot = $reboot -or $result
}
}
#************************************** Disable RC4 ************************************************
$result = DisableRC4
$reboot = $reboot -or $result
#************************************** Set Cipher Suite Order **************************************
Write-Log -Message "----- starting ciphersuite order calculation -----" -Logfile $logLocation -Severity Information
$configureExcellenceOrder = $true
if ($SetCipherOrder.ToUpper() -eq "B")
{
$configureExcellenceOrder = $false
Write-Host "The min bar cipher suite order was chosen."
Write-Log -Message "The min bar cipher suite order was chosen." -Logfile $logLocation -Severity Information
}
else
{
Write-Host "The opportunity for excellence cipher suite order was chosen."
Write-Log -Message "The opportunity for excellence cipher suite order was chosen." -Logfile $logLocation -Severity Information
}
$cipherlist = @()
if ([Environment]::OSVersion.Version.Major -lt 10)
{
$cipherlist += Get-BaseCipherSuitesOlderWindows -isExcellenceOrder $configureExcellenceOrder
$cipherlist += Get-BrowserCompatCipherSuitesOlderWindows -isExcellenceOrder $configureExcellenceOrder
}
else
{
$cipherlist += Get-BaseCipherSuitesWin10Above -isExcellenceOrder $configureExcellenceOrder
}
$cipherorder = [System.String]::Join(",", $cipherlist)
Write-Host "Appropriate ciphersuite order : $cipherorder"
Write-Log -Message "Appropriate ciphersuite order : $cipherorder" -Logfile $logLocation -Severity Information
$CipherSuiteRegKey = "HKLM:\SOFTWARE\Policies\Microsoft\Cryptography\Configuration\SSL\00010002"
if (!(Test-Path -Path $CipherSuiteRegKey))
{
New-Item $CipherSuiteRegKey | Out-Null
$reboot = $True
Write-Log -Message "Creating key: $($CipherSuiteRegKey) " -Logfile $logLocation -Severity Information
}
$val = (Get-Item -Path $CipherSuiteRegKey -ErrorAction SilentlyContinue).GetValue("Functions", $null)
Write-Log -Message "Previous cipher suite value: $val " -Logfile $logLocation -Severity Information
Write-Log -Message "New cipher suite value : $cipherorder " -Logfile $logLocation -Severity Information
if ($val -ne $cipherorder)
{
Write-Log -Message "Cipher suite order needs to be updated. " -Logfile $logLocation -Severity Information
Write-Host "The original cipher suite order needs to be updated", `n, $val
Set-ItemProperty -Path $CipherSuiteRegKey -Name Functions -Value $cipherorder
Write-Log -Message "Cipher suite value was updated. " -Logfile $logLocation -Severity Information
$reboot = $True
}
else
{
Write-Log -Message "Cipher suite order does not need to be updated. " -Logfile $logLocation -Severity Information
Write-Log -Message "Cipher suite value was not updated as there was no change. " -Logfile $logLocation -Severity Information
}
#****************************** CHECK THE FIPS SETTING WHICH IMPACTS RDP'S ALLOWED CIPHERS **************************
#Check for FipsSettings
Write-Log -Message "Checking to see if reg keys exist and if MinEncryptionLevel is set to 4" -Logfile $logLocation -Severity Information
$result = Test-RegistryValueForFipsSettings
$reboot = $reboot -or $result
#************************************** REBOOT **************************************
if ($RebootIfRequired)
{
Write-Log -Message "You set the RebootIfRequired flag to true. If changes are made, the system will reboot " -Logfile $logLocation -Severity Information
# If any settings were changed, reboot
If ($reboot)
{
Write-Log -Message "Rebooting now... " -Logfile $logLocation -Severity Information
Write-Log -Message "Using this command: shutdown.exe /r /t 5 /c ""Crypto settings changed"" /f /d p:2:4 " -Logfile $logLocation -Severity Information
Write-Host "Rebooting now..."
shutdown.exe /r /t 5 /c "Crypto settings changed" /f /d p:2:4
}
Else
{
Write-Host "Nothing get updated."
Write-Log -Message "Nothing get updated. " -Logfile $logLocation -Severity Information
}
}
else
{
Write-Log -Message "You set the RebootIfRequired flag to false. If changes are made, the system will NOT reboot " -Logfile $logLocation -Severity Information
Write-Log -Message "No changes will take effect until a reboot has been completed. " -Logfile $logLocation -Severity Information
Write-Log -Message "Script does not include a reboot by design" -Logfile $logLocation -Severity Information
}
Write-Log -Message "========== End of logging for a script execution ==========" -Logfile $logLocation -Severity Information
# SIG # Begin signature block
# MIIjhgYJKoZIhvcNAQcCoIIjdzCCI3MCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAHtlEJwNffjnOP
# Sr2t1yq5EfE0ll4GozyZt3UXO9BXKKCCDYEwggX/MIID56ADAgECAhMzAAABh3IX
# chVZQMcJAAAAAAGHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
# bmcgUENBIDIwMTEwHhcNMjAwMzA0MTgzOTQ3WhcNMjEwMzAzMTgzOTQ3WjB0MQsw
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
# AQDOt8kLc7P3T7MKIhouYHewMFmnq8Ayu7FOhZCQabVwBp2VS4WyB2Qe4TQBT8aB
# znANDEPjHKNdPT8Xz5cNali6XHefS8i/WXtF0vSsP8NEv6mBHuA2p1fw2wB/F0dH
# sJ3GfZ5c0sPJjklsiYqPw59xJ54kM91IOgiO2OUzjNAljPibjCWfH7UzQ1TPHc4d
# weils8GEIrbBRb7IWwiObL12jWT4Yh71NQgvJ9Fn6+UhD9x2uk3dLj84vwt1NuFQ
# itKJxIV0fVsRNR3abQVOLqpDugbr0SzNL6o8xzOHL5OXiGGwg6ekiXA1/2XXY7yV
# Fc39tledDtZjSjNbex1zzwSXAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUhov4ZyO96axkJdMjpzu2zVXOJcsw
# UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1
# ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDU4Mzg1MB8GA1UdIwQYMBaAFEhu
# ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu
# bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w
# Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3
# Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx
# MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAixmy
# S6E6vprWD9KFNIB9G5zyMuIjZAOuUJ1EK/Vlg6Fb3ZHXjjUwATKIcXbFuFC6Wr4K
# NrU4DY/sBVqmab5AC/je3bpUpjtxpEyqUqtPc30wEg/rO9vmKmqKoLPT37svc2NV
# BmGNl+85qO4fV/w7Cx7J0Bbqk19KcRNdjt6eKoTnTPHBHlVHQIHZpMxacbFOAkJr
# qAVkYZdz7ikNXTxV+GRb36tC4ByMNxE2DF7vFdvaiZP0CVZ5ByJ2gAhXMdK9+usx
# zVk913qKde1OAuWdv+rndqkAIm8fUlRnr4saSCg7cIbUwCCf116wUJ7EuJDg0vHe
# yhnCeHnBbyH3RZkHEi2ofmfgnFISJZDdMAeVZGVOh20Jp50XBzqokpPzeZ6zc1/g
# yILNyiVgE+RPkjnUQshd1f1PMgn3tns2Cz7bJiVUaqEO3n9qRFgy5JuLae6UweGf
# AeOo3dgLZxikKzYs3hDMaEtJq8IP71cX7QXe6lnMmXU/Hdfz2p897Zd+kU+vZvKI
# 3cwLfuVQgK2RZ2z+Kc3K3dRPz2rXycK5XCuRZmvGab/WbrZiC7wJQapgBodltMI5
# GMdFrBg9IeF7/rP4EqVQXeKtevTlZXjpuNhhjuR+2DMt/dWufjXpiW91bo3aH6Ea
# jOALXmoxgltCp1K7hrS6gmsvj94cLRf50QQ4U8Qwggd6MIIFYqADAgECAgphDpDS
# AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK
# V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0
# IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0
# ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla
# MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS
# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT
# H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB
# AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG
# OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S
# 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz
# y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7
# 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u
# M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33
# X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl
# XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP
# 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB
# l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF
# RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM
# CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ
# BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud
# DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO
# 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0
# LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y
# Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p
# Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y
# Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB
# FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw
# cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA
# XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY
# 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj
# 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd
# d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ
# Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf
# wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ
# aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j
# NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B
# xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96
# eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7
# r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I
# RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVWzCCFVcCAQEwgZUwfjELMAkG
# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx
# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z
# b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAYdyF3IVWUDHCQAAAAABhzAN
# BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor
# BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgOQvu7NUq
# wmve+qCoalj/s9HX5Hz9/zYISdJyOFTC4FIwQgYKKwYBBAGCNwIBDDE0MDKgFIAS
# AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN
# BgkqhkiG9w0BAQEFAASCAQAHbtGz0AChe0qMPM3c7iU8BQCfJklePUlAlhwFSuCx
# careoloxao+ZtS+dQRlrxLu/ZSqtmJHNsyRoWzsHdOs65pwUYhV3svzaXd7pJwkc
# nbDXedLBbNuQrQrrL2xbGtzT3U+EwgpJ1TTEYwHgqkTFogIelGa2sjD5N+4Vvalq
# t+vxaYrWwkTtsm0qczLKGRUjJqCjARjviE1xsOvs4zwbpXx/bEs/6M7U9tR+w/DS
# nDY/5KAKYET0DCVDhmsMmzJi3xXdBr4sAz0484AAB0CIRVgPCgdgr8E0NQUESJzm
# xm3K4bMAgTMWRiGTL4MRYSuMIn09sbfYXP9hjXLvTV4YoYIS5TCCEuEGCisGAQQB
# gjcDAwExghLRMIISzQYJKoZIhvcNAQcCoIISvjCCEroCAQMxDzANBglghkgBZQME
# AgEFADCCAVEGCyqGSIb3DQEJEAEEoIIBQASCATwwggE4AgEBBgorBgEEAYRZCgMB
# MDEwDQYJYIZIAWUDBAIBBQAEIJBynrmlQmGS0UNGTk53HVKEc4aHvNdYrs5eCcHM
# puc5AgZfEgElnvMYEzIwMjAwNzI0MTgwNDM3Ljg3NlowBIACAfSggdCkgc0wgcox
# CzAJBgNVBAYTAlVTMQswCQYDVQQIEwJXQTEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG
# A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQg
# SXJlbGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJjAkBgNVBAsTHVRoYWxlcyBUU1Mg
# RVNOOkUwNDEtNEJFRS1GQTdFMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFt
# cCBzZXJ2aWNloIIOPDCCBPEwggPZoAMCAQICEzMAAAEHfjdomIdaN9YAAAAAAQcw
# DQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0
# b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3Jh
# dGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwHhcN
# MTkxMDA4MTczODM1WhcNMjEwMTAzMTczODM1WjCByjELMAkGA1UEBhMCVVMxCzAJ
# BgNVBAgTAldBMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQg
# Q29ycG9yYXRpb24xLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJhdGlv
# bnMgTGltaXRlZDEmMCQGA1UECxMdVGhhbGVzIFRTUyBFU046RTA0MS00QkVFLUZB
# N0UxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIHNlcnZpY2UwggEiMA0G
# CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDUuqOUlbaeWirgwbCwhhNIOqTshpo+
# QdSYxAt9JnkeulQFeKrQ6rOSECXxwgOjL/TNMIXtkig1MaifFON6si/Ri+AsV8Gu
# rQp4fylJzLDMFdJcGSpV3CGRdpDb0au8kNQLmnZuxLxAL91R7//3mH2QDQI20w3G
# 06s+Xv8+js9wQksXAfclXX1TJoBIx1Pi1FGqCnY3KlW81+Plhz0T4yStm1MgnqH4
# RKYyPdcempCYC/BI04Ph2EJL+uQQfAfYdbf9vGqpKYjsuktnWr5uowD3H5At+x3l
# YH5rz4JCleKjeLpB/j74H7VZ0I5eTEbls9e2lEKaUzb9o0wjnjDc+t4BAgMBAAGj
# ggEbMIIBFzAdBgNVHQ4EFgQUNOHjlxlIJXMcP9n/0ogYdX8p6HcwHwYDVR0jBBgw
# FoAU1WM6XIoxkPNDe3xGG8UzaFqFbVUwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDov
# L2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljVGltU3RhUENB
# XzIwMTAtMDctMDEuY3JsMFoGCCsGAQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0
# cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNUaW1TdGFQQ0FfMjAx
# MC0wNy0wMS5jcnQwDAYDVR0TAQH/BAIwADATBgNVHSUEDDAKBggrBgEFBQcDCDAN
# BgkqhkiG9w0BAQsFAAOCAQEAGN3/7XWSzHGKjk444w+2q1D3k7Bh/ZahUvWHFJ6E
# UKU5vLzEGsdsgJSvWXHZDRrpf5rcUGQyjnlo1hAY1mDteNKFushS6bedxcxPHJje
# lVZ9N2/e5+/7zLu18YjnKw5bFu7dWqYBMI3J0FOr56XJOJ1KTtMiJhpxuib+FWy+
# pyhVVgHGTUHuUdbE09dY9WxuRsbpb4DdWAWNrPDB6VAOO50QfEj+0tW+zF6h3RhB
# TI0ilj0+AzgXE+6DyJ7/br6aVvCEvNRJzE6akJnMyn/kzmC32LxvRZWKEwWDR0Fn
# zeXj5ynSStZ6iifTBP7gqiDsidguxh+BFX7HxhN1eHf7jTCCBnEwggRZoAMCAQIC
# CmEJgSoAAAAAAAIwDQYJKoZIhvcNAQELBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYD
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRp
# ZmljYXRlIEF1dGhvcml0eSAyMDEwMB4XDTEwMDcwMTIxMzY1NVoXDTI1MDcwMTIx
# NDY1NVowfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNV
# BAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQG
# A1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwggEiMA0GCSqGSIb3
# DQEBAQUAA4IBDwAwggEKAoIBAQCpHQ28dxGKOiDs/BOX9fp/aZRrdFQQ1aUKAIKF
# ++18aEssX8XD5WHCdrc+Zitb8BVTJwQxH0EbGpUdzgkTjnxhMFmxMEQP8WCIhFRD
# DNdNuDgIs0Ldk6zWczBXJoKjRQ3Q6vVHgc2/JGAyWGBG8lhHhjKEHnRhZ5FfgVSx
# z5NMksHEpl3RYRNuKMYa+YaAu99h/EbBJx0kZxJyGiGKr0tkiVBisV39dx898Fd1
# rL2KQk1AUdEPnAY+Z3/1ZsADlkR+79BL/W7lmsqxqPJ6Kgox8NpOBpG2iAg16Hgc
# sOmZzTznL0S6p/TcZL2kAcEgCZN4zfy8wMlEXV4WnAEFTyJNAgMBAAGjggHmMIIB
# 4jAQBgkrBgEEAYI3FQEEAwIBADAdBgNVHQ4EFgQU1WM6XIoxkPNDe3xGG8UzaFqF
# bVUwGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud
# EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU1fZWy4/oolxiaNE9lJBb186aGMQwVgYD
# VR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwv
# cHJvZHVjdHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3JsMFoGCCsGAQUFBwEB
# BE4wTDBKBggrBgEFBQcwAoY+aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9j
# ZXJ0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcnQwgaAGA1UdIAEB/wSBlTCB
# kjCBjwYJKwYBBAGCNy4DMIGBMD0GCCsGAQUFBwIBFjFodHRwOi8vd3d3Lm1pY3Jv
# c29mdC5jb20vUEtJL2RvY3MvQ1BTL2RlZmF1bHQuaHRtMEAGCCsGAQUFBwICMDQe
# MiAdAEwAZQBnAGEAbABfAFAAbwBsAGkAYwB5AF8AUwB0AGEAdABlAG0AZQBuAHQA
# LiAdMA0GCSqGSIb3DQEBCwUAA4ICAQAH5ohRDeLG4Jg/gXEDPZ2joSFvs+umzPUx
# vs8F4qn++ldtGTCzwsVmyWrf9efweL3HqJ4l4/m87WtUVwgrUYJEEvu5U4zM9GAS
# inbMQEBBm9xcF/9c+V4XNZgkVkt070IQyK+/f8Z/8jd9Wj8c8pl5SpFSAK84Dxf1
# L3mBZdmptWvkx872ynoAb0swRCQiPM/tA6WWj1kpvLb9BOFwnzJKJ/1Vry/+tuWO
# M7tiX5rbV0Dp8c6ZZpCM/2pif93FSguRJuI57BlKcWOdeyFtw5yjojz6f32WapB4
# pm3S4Zz5Hfw42JT0xqUKloakvZ4argRCg7i1gJsiOCC1JeVk7Pf0v35jWSUPei45
# V3aicaoGig+JFrphpxHLmtgOR5qAxdDNp9DvfYPw4TtxCd9ddJgiCGHasFAeb73x
# 4QDf5zEHpJM692VHeOj4qEir995yfmFrb3epgcunCaw5u+zGy9iCtHLNHfS4hQEe
# gPsbiSpUObJb2sgNVZl6h3M7COaYLeqN4DMuEin1wC9UJyH3yKxO2ii4sanblrKn
# QqLJzxlBTeCG+SqaoxFmMNO7dDJL32N79ZmKLxvHIa9Zta7cRDyXUHHXodLFVeNp
# 3lfB0d4wwP3M5k37Db9dT+mdHhk4L7zPWAUu7w2gUDXa7wknHNWzfjUeCLraNtvT
# X4/edIhJEqGCAs4wggI3AgEBMIH4oYHQpIHNMIHKMQswCQYDVQQGEwJVUzELMAkG
# A1UECBMCV0ExEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBD
# b3Jwb3JhdGlvbjEtMCsGA1UECxMkTWljcm9zb2Z0IElyZWxhbmQgT3BlcmF0aW9u
# cyBMaW1pdGVkMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjpFMDQxLTRCRUUtRkE3
# RTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgc2VydmljZaIjCgEBMAcG
# BSsOAwIaAxUAwwu+tfgG3rC7RZrxuFO2CmZSfPiggYMwgYCkfjB8MQswCQYDVQQG
# EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG
# A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQg
# VGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUFAAIFAOLFEVUwIhgPMjAy
# MDA3MjQxNTUwNDVaGA8yMDIwMDcyNTE1NTA0NVowdzA9BgorBgEEAYRZCgQBMS8w
# LTAKAgUA4sURVQIBADAKAgEAAgIa9QIB/zAHAgEAAgIR9DAKAgUA4sZi1QIBADA2
# BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIBAAIDB6EgoQowCAIB
# AAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBADwvhE9bln801RR+oEXjtPJXTqtYMakR
# ymItUlO2HRorDqEv2SJR/V/kQjcsqS6ig54bOiKs0Il2fW/s/pi+x1ydJMpOyhM7
# zzqm3acQ9kbYHIDoPWVT/Rq2Oo33Dq380zXENcc0hpLAKF3Cu06SbbNbqu+A/wbI
# z5IClz6kU8kiMYIDDTCCAwkCAQEwgZMwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
# Cldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29m
# dCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENB
# IDIwMTACEzMAAAEHfjdomIdaN9YAAAAAAQcwDQYJYIZIAWUDBAIBBQCgggFKMBoG
# CSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQxIgQg6+NCew+c
# OhYIOzhUKofOF7MxtgOvSMWQCMCIWlTFNMgwgfoGCyqGSIb3DQEJEAIvMYHqMIHn
# MIHkMIG9BCBBYvCj4pFkwhumagATn0gLh9fdDNzImQkKNeOtRj/LHjCBmDCBgKR+
# MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS
# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMT
# HU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAABB343aJiHWjfWAAAA
# AAEHMCIEIGIH6vLdbEFNnxTxBhtIN7CtmhcKy/9m6/xoAA3LHzXUMA0GCSqGSIb3
# DQEBCwUABIIBAKGg3zNulscnGBDlD6Q/U6yLQ5dN3gF9UrprgACiQ1gs/DexU7oC
# hjNZxBnH5RTA/7q9TFf2a1rBydHWVnqXuuQQJ0HuskdpXahxR4y1jboDdGwr7F08
# v/gmPeeUik28Je72QZp5m/R0O61/kMQaDpLO9iPH0Z9iMGfqJonFPDeY4VX8Da2n
# cPY7mrv6YAI+ydZ+mUdBp2yjas7+/N8MntcNtAO0HpWFXQTAmb77RrSssfeZphRA
# mBD+gLx5C3q4uSmuOqaQxUaF0y8FeuetHp0bw2sfce6GlMXJwzTpC6HvXnaVtMy0
# pgzd/KPHW7EgSvmRVKmvwiQGiZBoRG/Gcg8=
# SIG # End signature block

View File

@@ -0,0 +1,89 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: MIT
# REPLACE WITH DROP-TO-ADMIN-USER-PREFIX.ps1
# REPLACE WITH UTILITY-PREFIX.ps1
$VisualStudioBootstrapperUrl = 'https://aka.ms/vs/17/release/vs_enterprise.exe'
$Workloads = @(
'Microsoft.VisualStudio.Workload.NativeDesktop',
'Microsoft.VisualStudio.Workload.Universal',
'Microsoft.VisualStudio.Component.VC.Tools.x86.x64',
'Microsoft.VisualStudio.Component.VC.Tools.ARM',
'Microsoft.VisualStudio.Component.VC.Tools.ARM64',
'Microsoft.VisualStudio.Component.VC.ATL',
'Microsoft.VisualStudio.Component.VC.ATLMFC',
'Microsoft.VisualStudio.Component.VC.ATL.ARM',
'Microsoft.VisualStudio.Component.VC.ATL.ARM64',
'Microsoft.VisualStudio.Component.VC.MFC.ARM',
'Microsoft.VisualStudio.Component.VC.MFC.ARM64',
'Microsoft.VisualStudio.Component.Windows10SDK',
'Microsoft.Net.Component.4.8.SDK',
'Microsoft.Net.Component.4.7.2.TargetingPack',
'Microsoft.Component.NetFX.Native',
'Microsoft.VisualStudio.Component.VC.Llvm.ClangToolset',
'Microsoft.VisualStudio.Component.VC.Llvm.Clang',
'Microsoft.VisualStudio.ComponentGroup.UWP.VC.BuildTools',
'Microsoft.VisualStudio.Component.VC.CMake.Project'
)
<#
.SYNOPSIS
Install Visual Studio.
.DESCRIPTION
InstallVisualStudio takes the $Workloads array, and installs it with the
installer that's pointed at by $BootstrapperUrl.
.PARAMETER Workloads
The set of VS workloads to install.
.PARAMETER BootstrapperUrl
The URL of the Visual Studio installer, i.e. one of vs_*.exe.
.PARAMETER InstallPath
The path to install Visual Studio at.
.PARAMETER Nickname
The nickname to give the installation.
#>
Function InstallVisualStudio {
Param(
[String[]]$Workloads,
[String]$BootstrapperUrl,
[String]$InstallPath = $null,
[String]$Nickname = $null
)
try {
Write-Host 'Downloading Visual Studio...'
[string]$bootstrapperExe = Get-TempFilePath -Extension 'exe'
curl.exe -L -o $bootstrapperExe -s -S $BootstrapperUrl
Write-Host 'Installing Visual Studio...'
$vsArgs = @('/c', $bootstrapperExe, '--quiet', '--norestart', '--wait', '--nocache')
foreach ($workload in $Workloads) {
$vsArgs += '--add'
$vsArgs += $workload
}
if (-not ([String]::IsNullOrWhiteSpace($InstallPath))) {
$vsArgs += '--installpath'
$vsArgs += $InstallPath
}
if (-not ([String]::IsNullOrWhiteSpace($Nickname))) {
$vsArgs += '--nickname'
$vsArgs += $Nickname
}
$proc = Start-Process -FilePath cmd.exe -ArgumentList $vsArgs -Wait -PassThru
PrintMsiExitCodeMessage $proc.ExitCode
}
catch {
Write-Error "Failed to install Visual Studio! $($_.Exception.Message)"
throw
}
}
InstallVisualStudio -Workloads $Workloads -BootstrapperUrl $VisualStudioBootstrapperUrl -Nickname 'Stable'

View File

@@ -0,0 +1,49 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: MIT
# REPLACE WITH DROP-TO-ADMIN-USER-PREFIX.ps1
# REPLACE WITH UTILITY-PREFIX.ps1
<#
.SYNOPSIS
Installs Windows PSDK/WDK
.DESCRIPTION
Downloads the Windows PSDK/DDK installer located at $Url, and installs it with the
correct flags.
.PARAMETER Url
The URL of the installer.
#>
Function InstallWindowsDK {
Param(
[String]$Url
)
try {
Write-Host "Downloading Windows PSDK or DDK $Url..."
[string]$installerPath = Get-TempFilePath -Extension 'exe'
curl.exe -L -o $installerPath -s -S $Url
Write-Host 'Installing...'
$proc = Start-Process -FilePath $installerPath -ArgumentList @('/features', '+', '/q') -Wait -PassThru
$exitCode = $proc.ExitCode
if ($exitCode -eq 0) {
Write-Host 'Installation successful!'
}
else {
Write-Error "Installation failed! Exited with $exitCode."
throw
}
}
catch {
Write-Error "Failed to install Windows PSDK or DDK! $($_.Exception.Message)"
throw
}
}
# Windows 10 SDK, version 2004 (10.0.19041.0)
InstallWindowsDK 'https://go.microsoft.com/fwlink/?linkid=2120843'
# Windows 10 WDK, version 2004
InstallWindowsDK 'https://go.microsoft.com/fwlink/?linkid=2128854'

View File

@@ -0,0 +1,35 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: MIT
#
<#
.SYNOPSIS
Prints total and free disk space for each disk on the system
#>
Function Format-Size {
[CmdletBinding()]
Param([long]$Size)
if ($Size -lt 1024) {
$Size = [int]$Size
return "$Size B"
}
$Size = $Size / 1024
if ($Size -lt 1024) {
$Size = [int]$Size
return "$Size KiB"
}
$Size = $Size / 1024
if ($Size -lt 1024) {
$Size = [int]$Size
return "$Size MiB"
}
$Size = [int]($Size / 1024)
return "$Size GiB"
}
Get-CimInstance -ClassName Win32_LogicalDisk | Format-Table -Property @{Label="Disk"; Expression={ $_.DeviceID }},@{Label="Label"; Expression={ $_.VolumeName }},@{Label="Size"; Expression={ Format-Size($_.Size) }},@{Label="Free Space"; Expression={ Format-Size($_.FreeSpace) }}

View File

@@ -0,0 +1,27 @@
param(
[string]$AdminUserPassword = $null
)
$ErrorActionPreference = 'Stop'
$ProgressPreference = 'SilentlyContinue'
if (-Not [string]::IsNullOrEmpty($AdminUserPassword)) {
$PsExecPath = 'C:\PsExec64.exe'
$PsExecArgs = @(
'-u',
'AdminUser',
'-p',
$AdminUserPassword,
'-accepteula',
'-i',
'-h',
'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe',
'-ExecutionPolicy',
'Unrestricted',
'-File',
$PSCommandPath
)
Write-Host "Executing: $PsExecPath $PsExecArgs"
$proc = Start-Process -FilePath $PsExecPath -ArgumentList $PsExecArgs -Wait -PassThru
exit $proc.ExitCode
}

View File

@@ -0,0 +1,18 @@
# This script runs all the scripts we run on Azure machines to deploy prerequisites,
# and assumes it is being run as an admin user.
. "$PSScriptRoot\utility-prefix.ps1"
. "$PSScriptRoot\deploy-tlssettings.ps1" -RebootIfRequired 0
. "$PSScriptRoot\deploy-windows-sdks.ps1"
. "$PSScriptRoot\deploy-visual-studio.ps1"
. "$PSScriptRoot\deploy-mpi.ps1"
. "$PSScriptRoot\deploy-cuda.ps1"
. "$PSScriptRoot\deploy-inteloneapi.ps1"
. "$PSScriptRoot\deploy-pwsh.ps1"
try {
Copy-Item "$PSScriptRoot\deploy-settings.txt" "$PSScriptRoot\deploy-settings.ps1"
. "$PSScriptRoot\deploy-settings.ps1"
} finally {
Remove-Item "$PSScriptRoot\deploy-settings.ps1"
}

View File

@@ -0,0 +1,17 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: MIT
#
<#
.SYNOPSIS
Prepares the virtual machine for imaging.
.DESCRIPTION
Runs the `sysprep` utility to prepare the system for imaging.
See https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/sysprep--system-preparation--overview
for more information.
#>
$ErrorActionPreference = 'Stop'
Write-Host 'Running sysprep'
& C:\Windows\system32\sysprep\sysprep.exe /oobe /generalize /mode:vm /shutdown

View File

@@ -0,0 +1,125 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: MIT
<#
.SYNOPSIS
Gets a random file path in the temp directory.
.DESCRIPTION
Get-TempFilePath takes an extension, and returns a path with a random
filename component in the temporary directory with that extension.
.PARAMETER Extension
The extension to use for the path.
#>
Function Get-TempFilePath {
Param(
[String]$Extension
)
if ([String]::IsNullOrWhiteSpace($Extension)) {
throw 'Missing Extension'
}
$tempPath = [System.IO.Path]::GetTempPath()
$tempName = [System.IO.Path]::GetRandomFileName() + '.' + $Extension
return Join-Path $tempPath $tempName
}
<#
.SYNOPSIS
Writes a message to the screen depending on ExitCode.
.DESCRIPTION
Since msiexec can return either 0 or 3010 successfully, in both cases
we write that installation succeeded, and which exit code it exited with.
If msiexec returns anything else, we write an error.
.PARAMETER ExitCode
The exit code that msiexec returned.
#>
Function PrintMsiExitCodeMessage {
Param(
$ExitCode
)
# 3010 is probably ERROR_SUCCESS_REBOOT_REQUIRED
if ($ExitCode -eq 0 -or $ExitCode -eq 3010) {
Write-Host "Installation successful! Exited with $ExitCode."
}
else {
Write-Error "Installation failed! Exited with $ExitCode."
throw
}
}
<#
.SYNOPSIS
Install a .msi file.
.DESCRIPTION
InstallMSI takes a url where an .msi lives, and installs that .msi to the system.
.PARAMETER Name
The name of the thing to install.
.PARAMETER Url
The URL at which the .msi lives.
#>
Function InstallMSI {
Param(
[String]$Name,
[String]$Url
)
try {
Write-Host "Downloading $Name..."
[string]$msiPath = Get-TempFilePath -Extension 'msi'
curl.exe -L -o $msiPath -s -S $Url
Write-Host "Installing $Name..."
$args = @('/i', $msiPath, '/norestart', '/quiet', '/qn')
$proc = Start-Process -FilePath 'msiexec.exe' -ArgumentList $args -Wait -PassThru
PrintMsiExitCodeMessage $proc.ExitCode
}
catch {
Write-Error "Failed to install $Name! $($_.Exception.Message)"
throw
}
}
<#
.SYNOPSIS
Unpacks a zip file to $Dir.
.DESCRIPTION
InstallZip takes a URL of a zip file, and unpacks the zip file to the directory
$Dir.
.PARAMETER Name
The name of the tool being installed.
.PARAMETER Url
The URL of the zip file to unpack.
.PARAMETER Dir
The directory to unpack the zip file to.
#>
Function InstallZip {
Param(
[String]$Name,
[String]$Url,
[String]$Dir
)
try {
Write-Host "Downloading $Name..."
[string]$zipPath = Get-TempFilePath -Extension 'zip'
curl.exe -L -o $zipPath -s -S $Url
Write-Host "Installing $Name..."
Expand-Archive -Path $zipPath -DestinationPath $Dir -Force
}
catch {
Write-Error "Failed to install $Name! $($_.Exception.Message)"
throw
}
}

View File

@@ -0,0 +1,29 @@
./vcpkg.exe --feature-flags=versions x-ci-verify-versions --verbose |
ForEach-Object -Begin {
$long_error = ''
} -Process {
if ($long_error -ne '' -and $_ -match '^$|^ ') {
# Extend multi-line message
$long_error = -join($long_error, "%0D%0A", $_ -replace '^ ','' `
-replace '(git add) [^ ]*\\ports\\([^ ]*)', '$1 ports/$2' )
} else {
if ($long_error -ne '') {
# Flush multi-line message
$long_error
$long_error = ''
}
if ($_ -match '^Error: ') {
# Start multi-line message
$long_error = $_ -replace '^Error: ', '##vso[task.logissue type=error]' `
-replace '(^##vso[^\]]*)](.*) [^ ]*\\versions\\(.-)\\(.*.json)(.*)', '$1;sourcepath=versions/$3/$4;linenumber=2]$2 version/$3/$4$5'
} else {
# Normal line
$_
}
}
} -End {
if ($long_error -ne '') {
# Flush multi-line message
$long_error
}
}