From 25e80cefdb14d0c69eaa976314e31d035aeddd73 Mon Sep 17 00:00:00 2001 From: Justin Chung <124807742+jshigetomi@users.noreply.github.com> Date: Fri, 10 Apr 2026 16:27:13 -0500 Subject: [PATCH 01/15] Fix the package pipeline by adding in PDP-Media directory (#27254) --- .pipelines/store/PDP/PDP-Media/en-US/.gitkeep | 0 .pipelines/templates/package-store-package.yml | 2 ++ 2 files changed, 2 insertions(+) create mode 100644 .pipelines/store/PDP/PDP-Media/en-US/.gitkeep diff --git a/.pipelines/store/PDP/PDP-Media/en-US/.gitkeep b/.pipelines/store/PDP/PDP-Media/en-US/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/.pipelines/templates/package-store-package.yml b/.pipelines/templates/package-store-package.yml index 7667b1361e7..6abddae6851 100644 --- a/.pipelines/templates/package-store-package.yml +++ b/.pipelines/templates/package-store-package.yml @@ -195,6 +195,7 @@ jobs: contents: '*.msixBundle' outSBName: 'PowerShellStorePackage' pdpPath: '$(System.DefaultWorkingDirectory)/PowerShell/.pipelines/store/PDP/PDP' + pdpMediaPath: '$(System.DefaultWorkingDirectory)/PowerShell/.pipelines/store/PDP/PDP-Media' - task: MS-RDX-MRO.windows-store-publish.package-task.store-package@3 displayName: 'Create StoreBroker Package (Stable/LTS)' @@ -206,6 +207,7 @@ jobs: contents: '*.msixBundle' outSBName: 'PowerShellStorePackage' pdpPath: '$(System.DefaultWorkingDirectory)/PowerShell/.pipelines/store/PDP/PDP' + pdpMediaPath: '$(System.DefaultWorkingDirectory)/PowerShell/.pipelines/store/PDP/PDP-Media' - pwsh: | $outputDirectory = "$(ob_outputDirectory)" From 30d14eafaa02d2815970b99d14e00de297909b6d Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Wed, 15 Apr 2026 17:30:19 -0400 Subject: [PATCH 02/15] Externalize `findMissingNotices` target framework selection with ordered Windows fallback (#27269) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: TravisEz13 <10873629+TravisEz13@users.noreply.github.com> Co-authored-by: Travis Plunk --- tools/findMissingNotices.ps1 | 113 ++++++++++++++++++++++---- tools/findMissingNotices.targets.json | 5 ++ 2 files changed, 100 insertions(+), 18 deletions(-) create mode 100644 tools/findMissingNotices.targets.json diff --git a/tools/findMissingNotices.ps1 b/tools/findMissingNotices.ps1 index 884eff50664..5ed931c5caa 100644 --- a/tools/findMissingNotices.ps1 +++ b/tools/findMissingNotices.ps1 @@ -16,6 +16,45 @@ Import-Module "$PSScriptRoot\..\.github\workflows\GHWorkflowHelper" -Force . "$PSScriptRoot\..\tools\buildCommon\startNativeExecution.ps1" . "$PSScriptRoot\clearlyDefined\Find-LastHarvestedVersion.ps1" +$targetsConfigPath = Join-Path -Path $PSScriptRoot -ChildPath 'findMissingNotices.targets.json' +if (-not (Test-Path -LiteralPath $targetsConfigPath)) { + throw "Missing target framework config file '$targetsConfigPath'. Add '/tools/findMissingNotices.targets.json' with 'dotnetTargetName' and 'windowsTargetNames' entries." +} + +try { + $targetsConfig = Get-Content -LiteralPath $targetsConfigPath -Raw -ErrorAction Stop | ConvertFrom-Json -AsHashtable -ErrorAction Stop +} catch { + throw "Failed to load target framework config from '$targetsConfigPath'. Ensure the file contains valid JSON. Error: $($_.Exception.Message)" +} + +if ($targetsConfig -isnot [hashtable]) { + throw "Invalid target framework config '$targetsConfigPath': expected a JSON object with 'dotnetTargetName' and 'windowsTargetNames'." +} + +if (-not $targetsConfig.ContainsKey('dotnetTargetName') -or [string]::IsNullOrWhiteSpace($targetsConfig['dotnetTargetName'])) { + throw "Invalid target framework config '$targetsConfigPath': 'dotnetTargetName' must be a non-empty string." +} + +if (-not $targetsConfig.ContainsKey('windowsTargetNames')) { + throw "Invalid target framework config '$targetsConfigPath': 'windowsTargetNames' must be present and must be an array." +} + +if ($null -eq $targetsConfig['windowsTargetNames'] -or $targetsConfig['windowsTargetNames'] -isnot [array]) { + throw "Invalid target framework config '$targetsConfigPath': 'windowsTargetNames' must be an array (empty array is allowed)." +} + +$script:dotnetTargetName = [string]$targetsConfig['dotnetTargetName'] +$script:windowsTargetNames = @() +foreach ($windowsTargetName in $targetsConfig['windowsTargetNames']) { + if ($windowsTargetName -isnot [string] -or [string]::IsNullOrWhiteSpace($windowsTargetName)) { + throw "Invalid target framework config '$targetsConfigPath': every entry in 'windowsTargetNames' must be a non-empty string." + } + + $script:windowsTargetNames += $windowsTargetName +} + +# Empty windowsTargetNames is valid and means "use base target fallback only". + $packageSourceName = 'findMissingNoticesNugetOrg' if (!(Get-PackageSource -Name $packageSourceName -ErrorAction SilentlyContinue)) { $null = Register-PackageSource -Name $packageSourceName -Location https://www.nuget.org/api/v2 -ProviderName NuGet @@ -195,8 +234,7 @@ function Get-CGRegistrations { $registrationChanged = $false - $dotnetTargetName = 'net11.0' - $dotnetTargetNameWin7 = 'net11.0-windows8.0' + $baseTargetName = $script:dotnetTargetName $unixProjectName = 'powershell-unix' $windowsProjectName = 'powershell-win-core' $actualRuntime = $Runtime @@ -204,35 +242,30 @@ function Get-CGRegistrations { switch -regex ($Runtime) { "alpine-.*" { $folder = $unixProjectName - $target = "$dotnetTargetName|$Runtime" - $neutralTarget = "$dotnetTargetName" + $target = "$baseTargetName|$Runtime" + $neutralTarget = "$baseTargetName" } "linux-.*" { $folder = $unixProjectName - $target = "$dotnetTargetName|$Runtime" - $neutralTarget = "$dotnetTargetName" + $target = "$baseTargetName|$Runtime" + $neutralTarget = "$baseTargetName" } "osx-.*" { $folder = $unixProjectName - $target = "$dotnetTargetName|$Runtime" - $neutralTarget = "$dotnetTargetName" - } - "win-x*" { - $sdkToUse = $winDesktopSdk - $folder = $windowsProjectName - $target = "$dotnetTargetNameWin7|$Runtime" - $neutralTarget = "$dotnetTargetNameWin7" + $target = "$baseTargetName|$Runtime" + $neutralTarget = "$baseTargetName" } "win-.*" { + $sdkToUse = $winDesktopSdk $folder = $windowsProjectName - $target = "$dotnetTargetNameWin7|$Runtime" - $neutralTarget = "$dotnetTargetNameWin7" + $target = "$baseTargetName|$actualRuntime" + $neutralTarget = "$baseTargetName" } "modules" { $folder = "modules" $actualRuntime = 'linux-x64' - $target = "$dotnetTargetName|$actualRuntime" - $neutralTarget = "$dotnetTargetName" + $target = "$baseTargetName|$actualRuntime" + $neutralTarget = "$baseTargetName" } Default { throw "Invalid runtime name: $Runtime" @@ -247,6 +280,50 @@ function Get-CGRegistrations { dotnet restore --runtime $actualRuntime "/property:SDKToUse=$sdkToUse" } $null = New-PADrive -Path $PSScriptRoot\..\src\$folder\obj\project.assets.json -Name $folder + + if ($Runtime -like "win-*") { + # Windows target selection is optional and ordered: + # 1. Try full Windows TFMs from config in order. + # 2. Fall back to the base non-Windows TFM if present. + try { + $availableTargets = @(Get-ChildItem -Path "${folder}:/targets" -ErrorAction Stop | Select-Object -ExpandProperty Name) + } catch { + throw "Unable to enumerate available targets for runtime '$Runtime' in '$folder'. Ensure dotnet restore succeeded and project.assets.json contains target data. Error: $($_.Exception.Message)" + } + + $selectedTargetName = $null + + foreach ($windowsTargetName in $script:windowsTargetNames) { + if ($windowsTargetName -in $availableTargets) { + $selectedTargetName = $windowsTargetName + break + } + } + + if (-not $selectedTargetName -and $baseTargetName -in $availableTargets) { + Write-Verbose "No configured windows target matched for '$Runtime'. Falling back to base target '$baseTargetName'." -Verbose + $selectedTargetName = $baseTargetName + } + + if (-not $selectedTargetName) { + Write-Verbose "Available targets for '$folder': $($availableTargets -join ', ')" -Verbose + if ($script:windowsTargetNames.Count -eq 0) { + throw "Unable to find a target for '$Runtime'. Tried fallback base target '$baseTargetName' (no windowsTargetNames configured). Ensure project.assets.json contains this target or update dotnetTargetName in '$targetsConfigPath'." + } + + throw "Unable to find a target for '$Runtime'. Tried configured windowsTargetNames '$($script:windowsTargetNames -join "', '")' and fallback base target '$baseTargetName'. Update '$targetsConfigPath' with a valid windows target from the available list." + } + + $target = "$selectedTargetName|$actualRuntime" + $neutralTarget = $selectedTargetName + } + + # Defensive check: non-Windows paths set targets in the switch block, + # Windows path may override them after inspecting available assets targets. + if (-not $target -or -not $neutralTarget) { + throw "Unable to determine restore targets for runtime '$Runtime'." + } + try { $targets = Get-ChildItem -Path "${folder}:/targets/$target" -ErrorAction Stop | Where-Object { $_.Type -eq 'package' } | select-object -ExpandProperty name $targets += Get-ChildItem -Path "${folder}:/targets/$neutralTarget" -ErrorAction Stop | Where-Object { $_.Type -eq 'project' } | select-object -ExpandProperty name diff --git a/tools/findMissingNotices.targets.json b/tools/findMissingNotices.targets.json new file mode 100644 index 00000000000..a347ee4c3be --- /dev/null +++ b/tools/findMissingNotices.targets.json @@ -0,0 +1,5 @@ +{ + "dotnetTargetName": "net11.0", + "windowsTargetNames": [ + ] +} From 72be78e6beb39c122297478b3d6d0135cbca7367 Mon Sep 17 00:00:00 2001 From: Justin Chung <124807742+jshigetomi@users.noreply.github.com> Date: Thu, 16 Apr 2026 14:01:35 -0500 Subject: [PATCH 03/15] Remove MSI from publishing pipeline (#27213) Co-authored-by: Justin Chung Co-authored-by: Aditya Patwardhan --- .github/CONTRIBUTING.md | 16 +- ...rshell-module-organization.instructions.md | 2 +- .../templates/packaging/windows/package.yml | 19 +- .../templates/packaging/windows/sign.yml | 109 +-- .pipelines/templates/release-githubNuget.yml | 7 + .../release-validate-packagenames.yml | 6 +- .pipelines/templates/uploadToAzure.yml | 20 +- .../RegisterMicrosoftUpdate.ps1 | 70 -- assets/wix/ExeLicense.rtf | 206 ------ assets/wix/Product.wxs | 654 ------------------ assets/wix/WixUIBannerBmp.png | Bin 3855 -> 0 bytes assets/wix/WixUIDialogBmp.png | Bin 30804 -> 0 bytes assets/wix/WixUIInfoIco.png | Bin 1638 -> 0 bytes assets/wix/bundle.wxs | 40 -- build.psm1 | 5 - docs/maintainers/releasing.md | 12 +- .../powershell-win-core.csproj | 2 +- test/perf/benchmarks/assets/compiler.test.ps1 | 20 - .../Installer/WindowsInstaller.Tests.ps1 | 39 -- tools/UpdateDotnetRuntime.ps1 | 28 - tools/ci.psm1 | 66 +- tools/packaging/boms/windows.json | 5 - tools/packaging/packaging.psd1 | 3 - tools/packaging/packaging.psm1 | 470 +------------ 24 files changed, 53 insertions(+), 1746 deletions(-) delete mode 100644 assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 delete mode 100644 assets/wix/ExeLicense.rtf delete mode 100644 assets/wix/Product.wxs delete mode 100644 assets/wix/WixUIBannerBmp.png delete mode 100644 assets/wix/WixUIDialogBmp.png delete mode 100644 assets/wix/WixUIInfoIco.png delete mode 100644 assets/wix/bundle.wxs delete mode 100644 test/powershell/Installer/WindowsInstaller.Tests.ps1 diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 776a9a8c60f..35eab8c9b5b 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -91,7 +91,7 @@ To run the link-checker, follow these steps: 1. Issues marked as [`First-Time-Issue`][first-time-issue], are identified as being easy and a great way to learn about this project and making contributions. - + ### Finding or creating an issue 1. Follow the instructions in [Contributing to Issues][contribute-issues] to find or open an issue. @@ -264,18 +264,10 @@ Please see PowerShell [Testing Guidelines - Running Tests Outside of CI][running * Our CI contains automated spell checking and link checking for Markdown files. If there is any false-positive, [run the spell checker command-line tool in interactive mode](#spell-checking-documentation) to add words to the `.spelling` file. -* Our packaging test may not pass and ask you to update `files.wxs` file if you add/remove/update nuget package references or add/remove assert files. - - You could update the file manually in accordance with messages in the test log file. Or you can use automatically generated file. To get the file you should build the msi package locally: - - ```powershell - Import-Module .\build.psm1 - Start-PSBuild -Clean -CrossGen -PSModuleRestore -Runtime win7-x64 -Configuration Release -ReleaseTag - Import-Module .\tools\packaging - Start-PSPackage -Type msi -ReleaseTag -WindowsRuntime 'win7-x64' -SkipReleaseChecks - ``` - Last command will report where new file is located. + You could update the `.spelling` file manually in accordance with messages in the test log file, or + [run the spell checker command-line tool in interactive mode](#spell-checking-documentation) + to add the false-positive words directly. #### Pull Request - Workflow diff --git a/.github/instructions/powershell-module-organization.instructions.md b/.github/instructions/powershell-module-organization.instructions.md index 461d19fb5df..9cdba06c364 100644 --- a/.github/instructions/powershell-module-organization.instructions.md +++ b/.github/instructions/powershell-module-organization.instructions.md @@ -83,7 +83,7 @@ PowerShell code in GitHub Actions YAML files should be kept minimal. Move code t **Examples**: - `Start-PSPackage` - Create packages -- `New-MSIPackage` - Create Windows MSI +- `New-MSIXPackage` - Create Windows MSIX - `New-DotnetSdkContainerFxdPackage` - Create container packages **When NOT to use**: diff --git a/.pipelines/templates/packaging/windows/package.yml b/.pipelines/templates/packaging/windows/package.yml index 1cc0e9d0e94..8b0e230b6b8 100644 --- a/.pipelines/templates/packaging/windows/package.yml +++ b/.pipelines/templates/packaging/windows/package.yml @@ -161,9 +161,9 @@ jobs: } $packageTypes = switch ($runtime) { - 'x64' { @('msi', 'zip', 'msix') } - 'x86' { @('msi', 'zip', 'msix') } - 'arm64' { @('msi', 'zip', 'msix') } + 'x64' { @('zip', 'msix') } + 'x86' { @('zip', 'msix') } + 'arm64' { @('zip', 'msix') } 'fxdependent' { 'fxdependent' } 'fxdependentWinDesktop' { 'fxdependent-win-desktop' } 'minsize' { 'min-size' } @@ -193,9 +193,9 @@ jobs: Write-Verbose -Verbose "runtime = '$(Runtime)'" $packageTypes = switch ($runtime) { - 'x64' { @('msi', 'zip', 'msix') } - 'x86' { @('msi', 'zip', 'msix') } - 'arm64' { @('msi', 'zip', 'msix') } + 'x64' { @('zip', 'msix') } + 'x86' { @('zip', 'msix') } + 'arm64' { @('zip', 'msix') } 'fxdependent' { 'fxdependent' } 'fxdependentWinDesktop' { 'fxdependent-win-desktop' } 'minsize' { 'min-size' } @@ -205,13 +205,6 @@ jobs: New-Item -ItemType Directory -Path $(ob_outputDirectory) -Force } - if ($packageTypes -contains 'msi') { - $msiPkgNameFilter = "powershell-*.msi" - $msiPkgPath = Get-ChildItem -Path $(Pipeline.Workspace) -Filter $msiPkgNameFilter -Recurse -File | Select-Object -ExpandProperty FullName - Write-Verbose -Verbose "unsigned msiPkgPath: $msiPkgPath" - Copy-Item -Path $msiPkgPath -Destination '$(ob_outputDirectory)' -Force -Verbose - } - if ($packageTypes -contains 'zip' -or $packageTypes -contains 'fxdependent' -or $packageTypes -contains 'min-size' -or $packageTypes -contains 'fxdependent-win-desktop') { $zipPkgNameFilter = "powershell-*.zip" $zipPkgPath = Get-ChildItem -Path $(Pipeline.Workspace) -Filter $zipPkgNameFilter -Recurse -File | Select-Object -ExpandProperty FullName diff --git a/.pipelines/templates/packaging/windows/sign.yml b/.pipelines/templates/packaging/windows/sign.yml index f7a2e5e03e8..151b5d676fb 100644 --- a/.pipelines/templates/packaging/windows/sign.yml +++ b/.pipelines/templates/packaging/windows/sign.yml @@ -67,110 +67,25 @@ jobs: - template: /.pipelines/templates/install-dotnet.yml@self - # Import build.psm1 and bootstrap packaging dependencies (WiX Toolset) + # Import build.psm1 and bootstrap packaging dependencies - pwsh: | $repoRoot = "$env:REPOROOT" Import-Module "$repoRoot\build.psm1" Import-Module "$repoRoot\tools\packaging" Write-Verbose -Verbose "Modules imported successfully" - - # Install WiX Toolset for EXE package creation - $isArm64 = '$(Runtime)' -eq 'arm64' - $env:RUNTIME = '$(Runtime)' - Start-PSBootstrap -Scenario Package - displayName: 'Import modules and install WiX Toolset' + displayName: 'Import modules' env: ob_restore_phase: true - # Sign MSI packages - - task: onebranch.pipeline.signing@1 - displayName: Sign MSI packages - inputs: - command: 'sign' - signing_profile: external_distribution - files_to_sign: '**\*.msi' - search_root: '$(Pipeline.Workspace)' - - # Create EXE package from signed MSI (for x64, x86, arm64 only) - - pwsh: | - $runtime = '$(Runtime)' - Write-Verbose -Verbose "runtime = '$(Runtime)'" - - $repoRoot = "$env:REPOROOT" - Import-Module "$repoRoot\build.psm1" - Import-Module "$repoRoot\tools\packaging" - - $noExeRuntimes = @('fxdependent', 'fxdependentWinDesktop', 'minsize') - - if ($runtime -in $noExeRuntimes) { - Write-Verbose -Verbose "No EXE generated for $runtime" - return - } - - $version = '$(Version)' - - $msiLocation = Get-ChildItem -Path $(Pipeline.Workspace) -Recurse -Filter "powershell-*$runtime.msi" | Select-Object -ExpandProperty FullName - Write-Verbose -Verbose "msiLocation: $msiLocation" - - Set-Location $repoRoot - - $exePath = New-ExePackage -ProductVersion $version -ProductTargetArchitecture $runtime -MsiLocationPath $msiLocation - Write-Verbose -Verbose "setting vso[task.setvariable variable=exePath]$exePath" - Write-Host "##vso[task.setvariable variable=exePath]$exePath" - Write-Verbose -Verbose "exePath: $exePath" - - $enginePath = Join-Path -Path '$(System.ArtifactsDirectory)\unsignedEngine' -ChildPath engine.exe - Expand-ExePackageEngine -ExePath $exePath -EnginePath $enginePath -ProductTargetArchitecture $runtime - displayName: 'Make exe and expand package' - - # Sign EXE engine - - task: onebranch.pipeline.signing@1 - displayName: Sign exe engine - inputs: - command: 'sign' - signing_profile: $(msft_3rd_party_cert_id) - files_to_sign: '$(System.ArtifactsDirectory)\unsignedEngine\*.exe' - search_root: '$(Pipeline.Workspace)' - - # Compress signed EXE engine back into package - - pwsh: | - $runtime = '$(Runtime)' - Write-Verbose -Verbose "runtime = '$(Runtime)'" - $repoRoot = "$env:REPOROOT" - Import-Module "$repoRoot\build.psm1" - Import-Module "$repoRoot\tools\packaging" - - $noExeRuntimes = @('fxdependent', 'fxdependentWinDesktop', 'minsize') - - if ($runtime -in $noExeRuntimes) { - Write-Verbose -Verbose "No EXE generated for $runtime" - return - } - - $exePath = '$(exePath)' - $enginePath = Join-Path -Path '$(System.ArtifactsDirectory)\unsignedEngine' -ChildPath engine.exe - $enginePath | Get-AuthenticodeSignature | out-string | Write-Verbose -verbose - Compress-ExePackageEngine -ExePath $exePath -EnginePath $enginePath -ProductTargetArchitecture $runtime - displayName: Compress signed exe package - - # Sign final EXE packages - - task: onebranch.pipeline.signing@1 - displayName: Sign exe packages - inputs: - command: 'sign' - signing_profile: external_distribution - files_to_sign: '**\*.exe' - search_root: '$(Pipeline.Workspace)' - # Copy all signed packages to output directory - pwsh: | $runtime = '$(Runtime)' Write-Verbose -Verbose "runtime = '$(Runtime)'" $packageTypes = switch ($runtime) { - 'x64' { @('msi', 'zip', 'msix', 'exe') } - 'x86' { @('msi', 'zip', 'msix', 'exe') } - 'arm64' { @('msi', 'zip', 'msix', 'exe') } + 'x64' { @('zip', 'msix') } + 'x86' { @('zip', 'msix') } + 'arm64' { @('zip', 'msix') } 'fxdependent' { 'fxdependent' } 'fxdependentWinDesktop' { 'fxdependent-win-desktop' } 'minsize' { 'min-size' } @@ -180,20 +95,6 @@ jobs: New-Item -ItemType Directory -Path $(ob_outputDirectory) -Force } - if ($packageTypes -contains 'msi') { - $msiPkgNameFilter = "powershell-*.msi" - $msiPkgPath = Get-ChildItem -Path $(Pipeline.Workspace) -Filter $msiPkgNameFilter -Recurse -File | Select-Object -ExpandProperty FullName - Write-Verbose -Verbose "signed msiPkgPath: $msiPkgPath" - Copy-Item -Path $msiPkgPath -Destination '$(ob_outputDirectory)' -Force -Verbose - } - - if ($packageTypes -contains 'exe') { - $exePkgNameFilter = "powershell-*.exe" - $exePkgPath = Get-ChildItem -Path $(Pipeline.Workspace) -Filter $exePkgNameFilter -Recurse -File | Select-Object -ExpandProperty FullName - Write-Verbose -Verbose "signed exePkgPath: $exePkgPath" - Copy-Item -Path $exePkgPath -Destination '$(ob_outputDirectory)' -Force -Verbose - } - if ($packageTypes -contains 'zip' -or $packageTypes -contains 'fxdependent' -or $packageTypes -contains 'min-size' -or $packageTypes -contains 'fxdependent-win-desktop') { $zipPkgNameFilter = "powershell-*.zip" $zipPkgPath = Get-ChildItem -Path $(Pipeline.Workspace) -Filter $zipPkgNameFilter -Recurse -File | Select-Object -ExpandProperty FullName diff --git a/.pipelines/templates/release-githubNuget.yml b/.pipelines/templates/release-githubNuget.yml index 95698554c40..e7c36a49fe6 100644 --- a/.pipelines/templates/release-githubNuget.yml +++ b/.pipelines/templates/release-githubNuget.yml @@ -43,6 +43,13 @@ jobs: $exefiles | Remove-Item -Force -Verbose } + # The .msi packages should not be uploaded to GitHub release. + $msifiles = Get-ChildItem -Path $Path -Filter *.msi + if ($msifiles) { + Write-Verbose -Verbose "Remove .msi packages:" + $msifiles | Remove-Item -Force -Verbose + } + $OutputPath = Join-Path $Path 'hashes.sha256' $packages = Get-ChildItem -Path $Path -Include * -Recurse -File $checksums = $packages | diff --git a/.pipelines/templates/release-validate-packagenames.yml b/.pipelines/templates/release-validate-packagenames.yml index 6344418cd8f..7271ffc05a8 100644 --- a/.pipelines/templates/release-validate-packagenames.yml +++ b/.pipelines/templates/release-validate-packagenames.yml @@ -94,8 +94,8 @@ jobs: - pwsh: | $message = @() - Get-ChildItem $(System.ArtifactsDirectory)\* -recurse -include *.zip, *.msi | ForEach-Object { - if($_.Name -notmatch 'PowerShell-\d+\.\d+\.\d+\-([a-z]*.\d+\-)?win\-(fxdependent|x64|arm64|x86|fxdependentWinDesktop)\.(msi|zip){1}') + Get-ChildItem $(System.ArtifactsDirectory)\* -recurse -include *.zip | ForEach-Object { + if($_.Name -notmatch 'PowerShell-\d+\.\d+\.\d+\-([a-z]*.\d+\-)?win\-(fxdependent|x64|arm64|x86|fxdependentWinDesktop)\.(zip){1}') { $messageInstance = "$($_.Name) is not a valid package name" $message += $messageInstance @@ -104,7 +104,7 @@ jobs: } if($message.count -gt 0){throw ($message | out-string)} - displayName: Validate Zip and MSI Package Names + displayName: Validate Zip Package Names - pwsh: | $message = @() diff --git a/.pipelines/templates/uploadToAzure.yml b/.pipelines/templates/uploadToAzure.yml index ce7f26131cc..de6f8e0d7fd 100644 --- a/.pipelines/templates/uploadToAzure.yml +++ b/.pipelines/templates/uploadToAzure.yml @@ -149,10 +149,8 @@ jobs: buildType: 'current' artifact: drop_windows_package_package_win_arm64 itemPattern: | - **/*.msi **/*.msix **/*.zip - **/*.exe targetPath: '$(Build.ArtifactStagingDirectory)/downloads' displayName: Download windows arm64 packages @@ -185,10 +183,8 @@ jobs: buildType: 'current' artifact: drop_windows_package_package_win_x64 itemPattern: | - **/*.msi **/*.msix **/*.zip - **/*.exe targetPath: '$(Build.ArtifactStagingDirectory)/downloads' displayName: Download windows x64 packages @@ -197,10 +193,8 @@ jobs: buildType: 'current' artifact: drop_windows_package_package_win_x86 itemPattern: | - **/*.msi **/*.msix **/*.zip - **/*.exe targetPath: '$(Build.ArtifactStagingDirectory)/downloads' displayName: Download windows x86 packages @@ -246,17 +240,17 @@ jobs: - pwsh: | Write-Verbose -Verbose "Copying Github Release files in $(Build.ArtifactStagingDirectory)/downloads to use in Release Pipeline" - + Write-Verbose -Verbose "Creating output directory for GitHub Release files: $(ob_outputDirectory)/GitHubPackages" New-Item -Path $(ob_outputDirectory)/GitHubPackages -ItemType Directory -Force - Get-ChildItem -Path "$(Build.ArtifactStagingDirectory)/downloads/*" -Recurse | - Where-Object { $_.Extension -notin '.msix', '.nupkg' -and $_.Name -notmatch '-gc'} | + Get-ChildItem -Path "$(Build.ArtifactStagingDirectory)/downloads/*" -Recurse | + Where-Object { $_.Extension -notin '.msix', '.nupkg' -and $_.Name -notmatch '-gc'} | Copy-Item -Destination $(ob_outputDirectory)/GitHubPackages -Recurse -Verbose - + Write-Verbose -Verbose "Creating output directory for NuGet packages: $(ob_outputDirectory)/NuGetPackages" New-Item -Path $(ob_outputDirectory)/NuGetPackages -ItemType Directory -Force - Get-ChildItem -Path "$(Build.ArtifactStagingDirectory)/downloads/*" -Recurse | - Where-Object { $_.Extension -eq '.nupkg' } | + Get-ChildItem -Path "$(Build.ArtifactStagingDirectory)/downloads/*" -Recurse | + Where-Object { $_.Extension -eq '.nupkg' } | Copy-Item -Destination $(ob_outputDirectory)/NuGetPackages -Recurse -Verbose displayName: Copy downloads to Artifacts @@ -395,7 +389,7 @@ jobs: } # To use -Include parameter, we need to use \* to get all files - $files = Get-ChildItem -Path $downloadsDirectory\* -Include @("*.deb", "*.tar.gz", "*.rpm", "*.msi", "*.zip", "*.pkg") + $files = Get-ChildItem -Path $downloadsDirectory\* -Include @("*.deb", "*.tar.gz", "*.rpm", "*.zip", "*.pkg") Write-Verbose -Verbose "files to upload." $files | Write-Verbose -Verbose diff --git a/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 b/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 deleted file mode 100644 index da89768f74a..00000000000 --- a/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -param( - [ValidateSet('Hang', 'Fail')] - $TestHook -) - -$waitTimeoutSeconds = 300 -switch ($TestHook) { - 'Hang' { - $waitTimeoutSeconds = 10 - $jobScript = { Start-Sleep -Seconds 600 } - } - 'Fail' { - $jobScript = { throw "This job script should fail" } - } - default { - $jobScript = { - # This registers Microsoft Update via a predefined GUID with the Windows Update Agent. - # https://learn.microsoft.com/windows/win32/wua_sdk/opt-in-to-microsoft-update - - $serviceManager = (New-Object -ComObject Microsoft.Update.ServiceManager) - $isRegistered = $serviceManager.QueryServiceRegistration('7971f918-a847-4430-9279-4a52d1efe18d').Service.IsRegisteredWithAu - - if (!$isRegistered) { - Write-Verbose -Verbose "Opting into Microsoft Update as the Automatic Update Service" - # 7 is the combination of asfAllowPendingRegistration, asfAllowOnlineRegistration, asfRegisterServiceWithAU - # AU means Automatic Updates - $null = $serviceManager.AddService2('7971f918-a847-4430-9279-4a52d1efe18d', 7, '') - } - else { - Write-Verbose -Verbose "Microsoft Update is already registered for Automatic Updates" - } - - $isRegistered = $serviceManager.QueryServiceRegistration('7971f918-a847-4430-9279-4a52d1efe18d').Service.IsRegisteredWithAu - - # Return if it was successful, which is the opposite of Pending. - return $isRegistered - } - } -} - -Write-Verbose "Running job script: $jobScript" -Verbose -$job = Start-ThreadJob -ScriptBlock $jobScript - -Write-Verbose "Waiting on Job for $waitTimeoutSeconds seconds" -Verbose -$null = Wait-Job -Job $job -Timeout $waitTimeoutSeconds - -if ($job.State -ne 'Running') { - Write-Verbose "Job finished. State: $($job.State)" -Verbose - $result = Receive-Job -Job $job -Verbose - Write-Verbose "Result: $result" -Verbose - if ($result) { - Write-Verbose "Registration succeeded" -Verbose - exit 0 - } - else { - Write-Verbose "Registration failed" -Verbose - # at the time this was written, the MSI is ignoring the exit code - exit 1 - } -} -else { - Write-Verbose "Job timed out" -Verbose - Write-Verbose "Stopping Job. State: $($job.State)" -Verbose - Stop-Job -Job $job - # at the time this was written, the MSI is ignoring the exit code - exit 258 -} diff --git a/assets/wix/ExeLicense.rtf b/assets/wix/ExeLicense.rtf deleted file mode 100644 index 09b0b1402a5..00000000000 --- a/assets/wix/ExeLicense.rtf +++ /dev/null @@ -1,206 +0,0 @@ -{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff0\deff0\stshfdbch0\stshfloch31506\stshfhich31506\stshfbi31506\deflang1033\deflangfe1033\themelang1033\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;} -{\f37\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhimajor\f31502\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0302020204030204}Calibri Light;} -{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;} -{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f1032\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f1033\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\f1035\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f1036\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f1037\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\f1038\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f1039\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f1040\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\f1372\fbidi \froman\fcharset238\fprq2 Cambria Math CE;}{\f1373\fbidi \froman\fcharset204\fprq2 Cambria Math Cyr;}{\f1375\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f1376\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;} -{\f1379\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;}{\f1380\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);}{\f1402\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\f1403\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;} -{\f1405\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\f1406\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\f1407\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);}{\f1408\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);} -{\f1409\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\f1410\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fhimajor\f31528\fbidi \fswiss\fcharset238\fprq2 Calibri Light CE;}{\fhimajor\f31529\fbidi \fswiss\fcharset204\fprq2 Calibri Light Cyr;}{\fhimajor\f31531\fbidi \fswiss\fcharset161\fprq2 Calibri Light Greek;} -{\fhimajor\f31532\fbidi \fswiss\fcharset162\fprq2 Calibri Light Tur;}{\fhimajor\f31533\fbidi \fswiss\fcharset177\fprq2 Calibri Light (Hebrew);}{\fhimajor\f31534\fbidi \fswiss\fcharset178\fprq2 Calibri Light (Arabic);} -{\fhimajor\f31535\fbidi \fswiss\fcharset186\fprq2 Calibri Light Baltic;}{\fhimajor\f31536\fbidi \fswiss\fcharset163\fprq2 Calibri Light (Vietnamese);}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;} -{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;} -{\fhiminor\f31573\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);}{\fhiminor\f31574\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);}{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;} -{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}} -{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0; -\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;\red0\green0\blue0;\red0\green0\blue0;\chyperlink\ctint255\cshade255\red5\green99\blue193;\red96\green94\blue92;\red225\green223\blue221;} -{\*\defchp \f31506\fs24 }{\*\defpap \ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 -\af0\afs24\alang1025 \ltrch\fcs0 \f31506\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext0 \sqformat \spriority0 Normal;}{\*\cs10 \additive \sunhideused \spriority1 Default Paragraph Font;}{\* -\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv -\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31506\afs24\alang1025 \ltrch\fcs0 \f31506\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext11 \ssemihidden \sunhideused Normal Table;}{\* -\cs15 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \ul\cf19 \sbasedon10 \sunhideused \styrsid11998831 Hyperlink;}{\*\cs16 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \cf20\chshdng0\chcfpat0\chcbpat21 \sbasedon10 \ssemihidden \sunhideused \styrsid11998831 -Unresolved Mention;}{\s17\ql \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 -\sbasedon0 \snext17 \ssemihidden \sunhideused \styrsid11998831 Normal (Web);}}{\*\pgptbl {\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}}{\*\rsidtbl \rsid203718\rsid534261\rsid10121125\rsid11155465 -\rsid11998831\rsid15422468\rsid15613908}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\author Travis Plunk}{\operator Travis Plunk} -{\creatim\yr2021\mo2\dy19\hr9\min23}{\revtim\yr2021\mo2\dy19\hr12\min33}{\version4}{\edmins5}{\nofpages1}{\nofwords75}{\nofchars430}{\nofcharsws504}{\vern6021}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}} -\paperw12240\paperh15840\margl1440\margr1440\margt1440\margb1440\gutter0\ltrsect -\widowctrl\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont1\relyonvml0\donotembedlingdata0\grfdocevents0\validatexml1\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors1\noxlattoyen -\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1440\dgvorigin1440\dghshow1\dgvshow1 -\jexpand\viewkind1\viewscale100\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct -\asianbrkrule\rsidroot11998831\newtblstyruls\nogrowautofit\usenormstyforlist\noindnmbrts\felnbrelev\nocxsptable\indrlsweleven\noafcnsttbl\afelev\utinl\hwelev\spltpgpar\notcvasp\notbrkcnstfrctbl\notvatxbx\krnprsnet\cachedcolbal \nouicompat \fet0 -{\*\wgrffmtfilter 2450}\nofeaturethrottle1\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang -{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang -{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}} -\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid15422468 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 \f31506\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 -\ltrch\fcs0 \insrsid15422468\charrsid15422468 This application is licensed under the\~}{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11155465 HYPERLINK "https://aka.ms/PowerShellLicense"}{\rtlch\fcs1 \af0 \ltrch\fcs0 -\insrsid11155465\charrsid15422468 {\*\datafield -00d0c9ea79f9bace118c8200aa004ba90b0200000003000000e0c9ea79f9bace118c8200aa004ba90b5a000000680074007400700073003a002f002f0061006b0061002e006d0073002f0050006f007700650072005300680065006c006c004c006900630065006e00730065000000795881f43b1d7f48af2c825dc4852763 -0000000085ab000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs15\ul\cf19\insrsid15422468\charrsid15422468 MIT License}}}\sectd \ltrsect\linex0\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid15422468\charrsid15422468 -. -\par You may review the\~}{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11155465 HYPERLINK "https://aka.ms/PowerShellThirdPartyNotices"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11155465\charrsid15422468 {\*\datafield -00d0c9ea79f9bace118c8200aa004ba90b0200000003000000e0c9ea79f9bace118c8200aa004ba90b6e000000680074007400700073003a002f002f0061006b0061002e006d0073002f0050006f007700650072005300680065006c006c0054006800690072006400500061007200740079004e006f007400690063006500 -73000000795881f43b1d7f48af2c825dc48527630000000085ab000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs15\ul\cf19\insrsid15422468\charrsid15422468 ThirdPartyNotices}}}\sectd \ltrsect\linex0\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\rtlch\fcs1 \af0 -\ltrch\fcs0 \insrsid15422468\charrsid15422468 . -\par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid15422468\charrsid15422468 This application collects telemetry under the\~}{\field\fldedit{\*\fldinst {\rtlch\fcs1 -\af0 \ltrch\fcs0 \insrsid534261 HYPERLINK "https://aka.ms/PrivacyPolicy"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid534261 {\*\datafield -00d0c9ea79f9bace118c8200aa004ba90b0200000003000000e0c9ea79f9bace118c8200aa004ba90b52000000680074007400700073003a002f002f0061006b0061002e006d0073002f00500072006900760061006300790050006f006c006900630079000000795881f43b1d7f48af2c825dc48527630000000085ab0000} -}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs15\ul\cf19\insrsid15422468\charrsid15422468 Microsoft Privacy Statement}}}\sectd \ltrsect\linex0\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid15422468\charrsid15422468 -. To opt out, see\~}{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11155465 HYPERLINK "https://aka.ms/PowerShellTelemetryOptOut" \\o "Original URL:https://github.com/PowerShell/PowerS -hell/blob/master/README.md#telemetryClick to follow link."}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11155465\charrsid15422468 {\*\datafield -10d0c9ea79f9bace118c8200aa004ba90b0200000003000000e0c9ea79f9bace118c8200aa004ba90b6a000000680074007400700073003a002f002f0061006b0061002e006d0073002f0050006f007700650072005300680065006c006c00540065006c0065006d0065007400720079004f00700074004f00750074000000 -795881f43b1d7f48af2c825dc48527630000000085ab000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs15\ul\cf19\insrsid15422468\charrsid15422468 here}}}\sectd \ltrsect\linex0\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\rtlch\fcs1 \af0 \ltrch\fcs0 -\insrsid15422468\charrsid15422468 .}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11998831 -\par }{\*\themedata 504b030414000600080000002100e9de0fbfff0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb4ec3301045f748fc83e52d4a -9cb2400825e982c78ec7a27cc0c8992416c9d8b2a755fbf74cd25442a820166c2cd933f79e3be372bd1f07b5c3989ca74aaff2422b24eb1b475da5df374fd9ad -5689811a183c61a50f98f4babebc2837878049899a52a57be670674cb23d8e90721f90a4d2fa3802cb35762680fd800ecd7551dc18eb899138e3c943d7e503b6 -b01d583deee5f99824e290b4ba3f364eac4a430883b3c092d4eca8f946c916422ecab927f52ea42b89a1cd59c254f919b0e85e6535d135a8de20f20b8c12c3b0 -0c895fcf6720192de6bf3b9e89ecdbd6596cbcdd8eb28e7c365ecc4ec1ff1460f53fe813d3cc7f5b7f020000ffff0300504b030414000600080000002100a5d6 -a7e7c0000000360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4f -c7060abb0884a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b6309512 -0f88d94fbc52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462 -a1a82fe353bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f746865 -6d652f7468656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b -4b0d592c9c070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b -4757e8d3f729e245eb2b260a0238fd010000ffff0300504b030414000600080000002100b6f4679893070000c9200000160000007468656d652f7468656d652f -7468656d65312e786d6cec59cd8b1bc915bf07f23f347d97f5d5ad8fc1f2a24fcfda33b6b164873dd648a5eef2547789aad28cc56208de532e81c026e49085bd -ed21842cecc22eb9e48f31d8249b3f22afaa5bdd5552c99e191c3061463074977eefd5afde7bf5de53d5ddcf5e26d4bbc05c1096f6fcfa9d9aefe174ce16248d -7afeb3d9a4d2f13d2151ba4094a5b8e76fb0f03fbbf7eb5fdd454732c609f6403e1547a8e7c752ae8eaa5531876124eeb0154ee1bb25e30992f0caa3ea82a34b -d09bd06aa3566b55134452df4b51026a1f2f97648ebd9952e9dfdb2a1f53784da5500373caa74a35b6243476715e5708b11143cabd0b447b3eccb3609733fc52 -fa1e4542c2173dbfa6fffceabdbb5574940b517940d6909be8bf5c2e17589c37f49c3c3a2b260d823068f50bfd1a40e53e6edc1eb7c6ad429f06a0f91c569a71 -b175b61bc320c71aa0ecd1a17bd41e35eb16ded0dfdce3dc0fd5c7c26b50a63fd8c34f2643b0a285d7a00c1feee1c3417730b2f56b50866fede1dbb5fe28685b -fa3528a6243ddf43d7c25673b85d6d0159327aec8477c360d26ee4ca4b144443115d6a8a254be5a1584bd00bc6270050408a24493db959e1259a43140f112567 -9c7827248a21f056286502866b8ddaa4d684ffea13e827ed5174849121ad780113b137a4f87862cec94af6fc07a0d537206f7ffef9cdeb1fdfbcfee9cd575fbd -79fdf77c6eadca923b466964cafdf2dd1ffef3cd6fbd7ffff0ed2f5fff319b7a172f4cfcbbbffdeedd3ffef93ef5b0e2d2146ffff4fdbb1fbf7ffbe7dfffebaf -5f3bb4f7393a33e1339260e13dc297de5396c0021dfcf119bf9ec42c46c494e8a791402952b338f48f656ca11f6d10450edc00db767cce21d5b880f7d72f2cc2 -d398af2571687c182716f094313a60dc6985876a2ec3ccb3751ab927e76b13f714a10bd7dc43945a5e1eaf579063894be530c616cd2714a5124538c5d253dfb1 -738c1dabfb8210cbaea764ce99604be97d41bc01224e93ccc899154da5d03149c02f1b1741f0b7659bd3e7de8051d7aa47f8c246c2de40d4417e86a965c6fb68 -2d51e252394309350d7e8264ec2239ddf0b9891b0b099e8e3065de78818570c93ce6b05ec3e90f21cdb8dd7e4a37898de4929cbb749e20c64ce4889d0f6394ac -5cd829496313fbb938871045de13265df05366ef10f50e7e40e941773f27d872f787b3c133c8b026a53240d4376beef0e57dccacf89d6ee8126157aae9f3c44a -b17d4e9cd131584756689f604cd1255a60ec3dfbdcc160c05696cd4bd20f62c82ac7d815580f901dabea3dc5027a25d5dcece7c91322ac909de2881de073bad9 -493c1b9426881fd2fc08bc6eda7c0ca52e7105c0633a3f37818f08f480102f4ea33c16a0c308ee835a9fc4c82a60ea5db8e375c32dff5d658fc1be7c61d1b8c2 -be04197c6d1948eca6cc7b6d3343d49aa00c9819822ec3956e41c4727f29a28aab165b3be596f6a62ddd00dd91d5f42424fd6007b4d3fb84ffbbde073a8cb77f -f9c6b10f3e4ebfe3566c25ab6b763a8792c9f14e7f7308b7dbd50c195f904fbfa919a175fa04431dd9cf58b73dcd6d4fe3ffdff73487f6f36d2773a8dfb8ed64 -7ce8306e3b99fc70e5e3743265f3027d8d3af0c80e7af4b14f72f0d46749289dca0dc527421ffc08f83db398c0a092d3279eb838055cc5f0a8ca1c4c60e1228e -b48cc799fc0d91f134462b381daafb4a492472d591f0564cc0a1911e76ea5678ba4e4ed9223becacd7d5c16656590592e5782d2cc6e1a04a66e856bb3cc02bd4 -6bb6913e68dd1250b2d721614c6693683a48b4b783ca48fa58178ce620a157f65158741d2c3a4afdd6557b2c805ae115f8c1edc1cff49e1f06200242701e07cd -f942f92973f5d6bbda991fd3d3878c69450034d8db08283ddd555c0f2e4fad2e0bb52b78da2261849b4d425b46377822869fc17974aad1abd0b8aeafbba54b2d -7aca147a3e08ad9246bbf33e1637f535c8ede6069a9a9982a6de65cf6f35430899395af5fc251c1ac363b282d811ea3717a211dcbccc25cf36fc4d32cb8a0b39 -4222ce0cae934e960d122231f728497abe5a7ee1069aea1ca2b9d51b90103e59725d482b9f1a3970baed64bc5ce2b934dd6e8c284b67af90e1b35ce1fc568bdf -1cac24d91adc3d8d1797de195df3a708422c6cd795011744c0dd413db3e682c0655891c8caf8db294c79da356fa3740c65e388ae62945714339967709dca0b3a -faadb081f196af190c6a98242f8467912ab0a651ad6a5a548d8cc3c1aafb6121653923699635d3ca2aaa6abab39835c3b60cecd8f26645de60b53531e434b3c2 -67a97b37e576b7b96ea74f28aa0418bcb09fa3ea5ea12018d4cac92c6a8af17e1a56393b1fb56bc776811fa07695226164fdd656ed8edd8a1ae19c0e066f54f9 -416e376a6168b9ed2bb5a5f5adb979b1cdce5e40f2184197bba6526857c2c92e47d0104d754f92a50dd8222f65be35e0c95b73d2f3bfac85fd60d80887955a27 -1c57826650ab74c27eb3d20fc3667d1cd66ba341e31514161927f530bbb19fc00506dde4f7f67a7cefee3ed9ded1dc99b3a4caf4dd7c5513d777f7f5c6e1bb7b -8f40d2f9b2d598749bdd41abd26df627956034e854bac3d6a0326a0ddba3c9681876ba9357be77a1c141bf390c5ae34ea5551f0e2b41aba6e877ba9576d068f4 -8376bf330efaaff23606569ea58fdc16605ecdebde7f010000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d65 -2f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d36 -3f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e -3198720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d985 -0528a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100e9de0fbfff0000001c020000130000000000000000000000 -0000000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b00000000000000000000 -000000300100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c0000000000000000000000000019020000 -7468656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d0014000600080000002100b6f4679893070000c92000001600000000000000 -000000000000d60200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b01000027000000 -000000000000000000009d0a00007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000980b00000000} -{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d -617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 -6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 -656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} -{\*\latentstyles\lsdstimax376\lsdlockeddef0\lsdsemihiddendef0\lsdunhideuseddef0\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1; -\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4; -\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7; -\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 1; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 5; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 7;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 9; -\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 1;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 2;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 3; -\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 4;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 5;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 6; -\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 7;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 8;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal Indent; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 header;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footer; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index heading;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of figures; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope return;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation reference; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 line number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 page number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote text; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of authorities;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 macro;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 toa heading;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 3; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 3; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 3; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 5;\lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Closing; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Signature;\lsdsemihidden1 \lsdunhideused1 \lsdpriority1 \lsdlocked0 Default Paragraph Font;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 4; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Message Header;\lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Salutation; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Date;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Note Heading; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 3; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Block Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 FollowedHyperlink;\lsdqformat1 \lsdpriority22 \lsdlocked0 Strong; -\lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Document Map;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Plain Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 E-mail Signature; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Top of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Bottom of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal (Web);\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Acronym; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Cite;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Code;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Definition; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Keyboard;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Preformatted;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Sample;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Typewriter; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Variable;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation subject;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 No List;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 1; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Balloon Text;\lsdpriority39 \lsdlocked0 Table Grid; -\lsdsemihidden1 \lsdlocked0 Placeholder Text;\lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdpriority60 \lsdlocked0 Light Shading;\lsdpriority61 \lsdlocked0 Light List;\lsdpriority62 \lsdlocked0 Light Grid; -\lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdpriority65 \lsdlocked0 Medium List 1;\lsdpriority66 \lsdlocked0 Medium List 2;\lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdpriority68 \lsdlocked0 Medium Grid 2; -\lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdpriority70 \lsdlocked0 Dark List;\lsdpriority71 \lsdlocked0 Colorful Shading;\lsdpriority72 \lsdlocked0 Colorful List;\lsdpriority73 \lsdlocked0 Colorful Grid;\lsdpriority60 \lsdlocked0 Light Shading Accent 1; -\lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 1; -\lsdsemihidden1 \lsdlocked0 Revision;\lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 1; -\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 1; -\lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdpriority60 \lsdlocked0 Light Shading Accent 2;\lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdpriority62 \lsdlocked0 Light Grid Accent 2; -\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 2; -\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2;\lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 2; -\lsdpriority72 \lsdlocked0 Colorful List Accent 2;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdpriority61 \lsdlocked0 Light List Accent 3;\lsdpriority62 \lsdlocked0 Light Grid Accent 3; -\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 3; -\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdpriority70 \lsdlocked0 Dark List Accent 3;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 3; -\lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 3;\lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdpriority62 \lsdlocked0 Light Grid Accent 4; -\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 4;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 4; -\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 4; -\lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdpriority60 \lsdlocked0 Light Shading Accent 5;\lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdpriority62 \lsdlocked0 Light Grid Accent 5; -\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 5; -\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5;\lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 5; -\lsdpriority72 \lsdlocked0 Colorful List Accent 5;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdpriority61 \lsdlocked0 Light List Accent 6;\lsdpriority62 \lsdlocked0 Light Grid Accent 6; -\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 6; -\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdpriority70 \lsdlocked0 Dark List Accent 6;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 6; -\lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 6;\lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis; -\lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference;\lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdsemihidden1 \lsdunhideused1 \lsdpriority37 \lsdlocked0 Bibliography; -\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;\lsdpriority41 \lsdlocked0 Plain Table 1;\lsdpriority42 \lsdlocked0 Plain Table 2;\lsdpriority43 \lsdlocked0 Plain Table 3;\lsdpriority44 \lsdlocked0 Plain Table 4; -\lsdpriority45 \lsdlocked0 Plain Table 5;\lsdpriority40 \lsdlocked0 Grid Table Light;\lsdpriority46 \lsdlocked0 Grid Table 1 Light;\lsdpriority47 \lsdlocked0 Grid Table 2;\lsdpriority48 \lsdlocked0 Grid Table 3;\lsdpriority49 \lsdlocked0 Grid Table 4; -\lsdpriority50 \lsdlocked0 Grid Table 5 Dark;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 1; -\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 1;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 1;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 1; -\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 1;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 2;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 2; -\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 2;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 2; -\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 3;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 3;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 3;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 3; -\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 3;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 4; -\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 4;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 4;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 4;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 4; -\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 4;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 5; -\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 5;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 5;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 5; -\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 5;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 6;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 6; -\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 6;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 6; -\lsdpriority46 \lsdlocked0 List Table 1 Light;\lsdpriority47 \lsdlocked0 List Table 2;\lsdpriority48 \lsdlocked0 List Table 3;\lsdpriority49 \lsdlocked0 List Table 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark; -\lsdpriority51 \lsdlocked0 List Table 6 Colorful;\lsdpriority52 \lsdlocked0 List Table 7 Colorful;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 List Table 2 Accent 1;\lsdpriority48 \lsdlocked0 List Table 3 Accent 1; -\lsdpriority49 \lsdlocked0 List Table 4 Accent 1;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 1;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 1; -\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 List Table 2 Accent 2;\lsdpriority48 \lsdlocked0 List Table 3 Accent 2;\lsdpriority49 \lsdlocked0 List Table 4 Accent 2; -\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 2;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 3; -\lsdpriority47 \lsdlocked0 List Table 2 Accent 3;\lsdpriority48 \lsdlocked0 List Table 3 Accent 3;\lsdpriority49 \lsdlocked0 List Table 4 Accent 3;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 3; -\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 4;\lsdpriority47 \lsdlocked0 List Table 2 Accent 4; -\lsdpriority48 \lsdlocked0 List Table 3 Accent 4;\lsdpriority49 \lsdlocked0 List Table 4 Accent 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 4;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 4; -\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 List Table 2 Accent 5;\lsdpriority48 \lsdlocked0 List Table 3 Accent 5; -\lsdpriority49 \lsdlocked0 List Table 4 Accent 5;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 5;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 5; -\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 List Table 2 Accent 6;\lsdpriority48 \lsdlocked0 List Table 3 Accent 6;\lsdpriority49 \lsdlocked0 List Table 4 Accent 6; -\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Mention; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hashtag;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Unresolved Mention;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Link;}}{\*\datastore }} \ No newline at end of file diff --git a/assets/wix/Product.wxs b/assets/wix/Product.wxs deleted file mode 100644 index 0b525288ae1..00000000000 --- a/assets/wix/Product.wxs +++ /dev/null @@ -1,654 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - not INSTALLFOLDER and PREVIOUS_INSTALLFOLDER - - - - - - - - not ADD_PATH and PREVIOUS_ADD_PATH - - - not ADD_PATH - - - ADD_PATH<>1 - - - not ADD_PATH - - - - - - - - not REGISTER_MANIFEST and PREVIOUS_REGISTER_MANIFEST - - - not REGISTER_MANIFEST - - - REGISTER_MANIFEST<>1 - - - not REGISTER_MANIFEST - - - - - - - - not ENABLE_PSREMOTING and PREVIOUS_ENABLE_PSREMOTING - - - ENABLE_PSREMOTING<>1 - - - not ENABLE_PSREMOTING - - - - - - - - not DISABLE_TELEMETRY and PREVIOUS_DISABLE_TELEMETRY - - - DISABLE_TELEMETRY<>1 - - - not DISABLE_TELEMETRY - - - - - - - - not ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL and PREVIOUS_ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL - - - ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL<>1 - - - not ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL - - - - - - - - not ADD_FILE_CONTEXT_MENU_RUNPOWERSHELL and PREVIOUS_ADD_FILE_CONTEXT_MENU_RUNPOWERSHELL - - - ADD_FILE_CONTEXT_MENU_RUNPOWERSHELL<>1 - - - not ADD_FILE_CONTEXT_MENU_RUNPOWERSHELL - - - - - - - - not USE_MU and PREVIOUS_USE_MU - - - not USE_MU - - - USE_MU<>1 - - - not USE_MU - - - - - - - - not ENABLE_MU and PREVIOUS_ENABLE_MU - - - not ENABLE_MU - - - ENABLE_MU<>1 - - - not ENABLE_MU - - - - - - - - - - - - - Installed AND NOT UPGRADINGPRODUCTCODE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - LAUNCHAPPONEXIT=1 - - - - 1 OR VersionNT >= 603 ]]> - - - = 602 ]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - USE_MU=1 - - - - - - - - - - - - - - - - - - - - - - - - - DISABLE_TELEMETRY=1 - - - - - ADD_PATH=1 - - - - - - - - - ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL=1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ADD_FILE_CONTEXT_MENU_RUNPOWERSHELL=1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - The application is distributed under the MIT license.]]> - - - Please review the ThirdPartyNotices.txt]]> - - - - - - - 1 - - - - - - - - - - - - - - - - - - - - "1"]]> - "1" AND USE_MU="1"]]> - - - See the Microsoft Update FAQ]]> - - - Read the Microsoft Update Privacy Statement]]> - - - - - - - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - "1"]]> - - NOT Installed - Installed AND PATCH - - 1 - 1 - 1 - 1 - - 1 - 1 - NOT WIXUI_DONTVALIDATEPATH - "1"]]> - WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID="1" - 1 - 1 - 1 - - NOT Installed - Installed AND NOT PATCH - Installed AND PATCH - - 1 - - 1 - 1 - 1 - - - - - - - diff --git a/assets/wix/WixUIBannerBmp.png b/assets/wix/WixUIBannerBmp.png deleted file mode 100644 index 2a1922c1d7c83c687f6abf001a773d0d5387c095..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3855 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 diff --git a/assets/wix/bundle.wxs b/assets/wix/bundle.wxs deleted file mode 100644 index a2d93b47099..00000000000 --- a/assets/wix/bundle.wxs +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build.psm1 b/build.psm1 index 737b3e6182f..d353eb251e5 100644 --- a/build.psm1 +++ b/build.psm1 @@ -3003,11 +3003,6 @@ function Start-PSBootstrap { $psInstallFile = [System.IO.Path]::Combine($PSScriptRoot, "tools", "install-powershell.ps1") & $psInstallFile -AddToPath } - if ($Scenario -eq 'Both' -or $Scenario -eq 'Package') { - Import-Module "$PSScriptRoot\tools\wix\wix.psm1" - $isArm64 = "$env:RUNTIME" -eq 'arm64' - Install-Wix -arm64:$isArm64 - } Write-LogGroupEnd -Title "Install Windows Dependencies" } diff --git a/docs/maintainers/releasing.md b/docs/maintainers/releasing.md index 3562962e68f..ccb4e5529d7 100644 --- a/docs/maintainers/releasing.md +++ b/docs/maintainers/releasing.md @@ -57,17 +57,13 @@ It **requires** that PowerShell Core has been built via `Start-PSBuild` from the #### Windows -The `Start-PSPackage` function delegates to `New-MSIPackage` which creates a Windows Installer Package of PowerShell. +`Start-PSPackage` supports creating ZIP and MSIX packages for Windows. +When called without `-Type` on Windows, it defaults to creating both ZIP and MSIX packages. The packages *must* be published in release mode, so make sure `-Configuration Release` is specified when running `Start-PSBuild`. -It uses the Windows Installer XML Toolset (WiX) to generate a MSI package, -which copies the output of the published PowerShell files to a version-specific folder in Program Files, -and installs a shortcut in the Start Menu. -It can be uninstalled through `Programs and Features`. - Note that PowerShell is always self-contained, thus using it does not require installing it. -The output of `Start-PSBuild` includes a `powershell.exe` executable which can simply be launched. +The output of `Start-PSBuild` includes a `pwsh.exe` executable which can simply be launched. #### Linux / macOS @@ -169,8 +165,8 @@ Start-PSBuild -Clean -CrossGen -PSModuleRestore -Runtime win7-x64 -Configuration ```powershell # Create packages for v6.0.0-beta.1 release targeting Windows universal package. # 'win7-x64' / 'win7-x86' should be used for -WindowsRuntime. -Start-PSPackage -Type msi -ReleaseTag v6.0.0-beta.1 -WindowsRuntime 'win7-x64' Start-PSPackage -Type zip -ReleaseTag v6.0.0-beta.1 -WindowsRuntime 'win7-x64' +Start-PSPackage -Type msix -ReleaseTag v6.0.0-beta.1 -WindowsRuntime 'win7-x64' ``` ## NuGet Packages diff --git a/src/powershell-win-core/powershell-win-core.csproj b/src/powershell-win-core/powershell-win-core.csproj index e6efeac10f0..dddbb915eca 100644 --- a/src/powershell-win-core/powershell-win-core.csproj +++ b/src/powershell-win-core/powershell-win-core.csproj @@ -33,7 +33,7 @@ PreserveNewest PreserveNewest - + PreserveNewest PreserveNewest diff --git a/test/perf/benchmarks/assets/compiler.test.ps1 b/test/perf/benchmarks/assets/compiler.test.ps1 index 5105ae9b408..be731373036 100644 --- a/test/perf/benchmarks/assets/compiler.test.ps1 +++ b/test/perf/benchmarks/assets/compiler.test.ps1 @@ -2238,26 +2238,6 @@ function Start-PSPackage { } } } - "msi" { - $TargetArchitecture = "x64" - if ($Runtime -match "-x86") { - $TargetArchitecture = "x86" - } - Write-Verbose "TargetArchitecture = $TargetArchitecture" -Verbose - - $Arguments = @{ - ProductNameSuffix = $NameSuffix - ProductSourcePath = $Source - ProductVersion = $Version - AssetsPath = "$RepoRoot\assets" - ProductTargetArchitecture = $TargetArchitecture - Force = $Force - } - - if ($PSCmdlet.ShouldProcess("Create MSI Package")) { - New-MSIPackage @Arguments - } - } "msix" { $Arguments = @{ ProductNameSuffix = $NameSuffix diff --git a/test/powershell/Installer/WindowsInstaller.Tests.ps1 b/test/powershell/Installer/WindowsInstaller.Tests.ps1 deleted file mode 100644 index 66bd08e74f5..00000000000 --- a/test/powershell/Installer/WindowsInstaller.Tests.ps1 +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -Describe "Windows Installer" -Tags "Scenario" { - - BeforeAll { - $skipTest = -not $IsWindows - $preRequisitesLink = 'https://aka.ms/pscore6-prereq' - $linkCheckTestCases = @( - @{ Name = "Universal C Runtime"; Url = $preRequisitesLink } - @{ Name = "WMF 4.0"; Url = "https://www.microsoft.com/download/details.aspx?id=40855" } - @{ Name = "WMF 5.0"; Url = "https://www.microsoft.com/download/details.aspx?id=50395" } - @{ Name = "WMF 5.1"; Url = "https://www.microsoft.com/download/details.aspx?id=54616" } - ) - } - - It "WiX (Windows Installer XML) file contains pre-requisites link $preRequisitesLink" -Skip:$skipTest { - $wixProductFile = Join-Path -Path $PSScriptRoot -ChildPath "..\..\..\assets\wix\Product.wxs" - (Get-Content $wixProductFile -Raw).Contains($preRequisitesLink) | Should -BeTrue - } - - ## Running 'Invoke-WebRequest' with WMF download URLs has been failing intermittently, - ## because sometimes the URLs lead to a 'this download is no longer available' page. - ## We use a retry logic here. Retry for 5 times with 1 second interval. - # It "Pre-Requisistes link for '' is reachable: " -TestCases $linkCheckTestCases -Skip:$skipTest { - It "Pre-Requisistes link for '' is reachable: " -TestCases $linkCheckTestCases -Pending { - param ($Url) - - foreach ($i in 1..5) { - try { - $result = Invoke-WebRequest $Url -UseBasicParsing - break; - } catch { - Start-Sleep -Seconds 1 - } - } - - $result | Should -Not -Be $null - } -} diff --git a/tools/UpdateDotnetRuntime.ps1 b/tools/UpdateDotnetRuntime.ps1 index 339153bcf0c..f62a16cfe14 100644 --- a/tools/UpdateDotnetRuntime.ps1 +++ b/tools/UpdateDotnetRuntime.ps1 @@ -9,9 +9,6 @@ param ( [Parameter()] [switch]$UseNuGetOrg, - [Parameter()] - [switch]$UpdateMSIPackaging, - [Parameter()] [string]$RuntimeSourceFeed, @@ -366,31 +363,6 @@ if ($dotnetUpdate.ShouldUpdate) { Write-Verbose -Message "Updating project files completed." -Verbose - if ($UpdateMSIPackaging) { - if (-not $environment.IsWindows) { - throw "UpdateMSIPackaging can only be done on Windows" - } - - Import-Module "$PSScriptRoot/../build.psm1" -Force - Import-Module "$PSScriptRoot/packaging" -Force - Start-PSBootstrap -Package - Start-PSBuild -Clean -Configuration Release -InteractiveAuth:$InteractiveAuth - - $publishPath = Split-Path (Get-PSOutput) - Remove-Item -Path "$publishPath\*.pdb" - - try { - Start-PSPackage -Type msi -SkipReleaseChecks -InformationVariable wxsData - } catch { - if ($_.Exception.Message -like "Current files to not match *") { - Copy-Item -Path $($wxsData.MessageData.NewFile) -Destination ($wxsData.MessageData.FilesWxsPath) - Write-Verbose -Message "Updating files.wxs file completed." -Verbose - } else { - throw $_ - } - } - } - Update-DevContainer } else { diff --git a/tools/ci.psm1 b/tools/ci.psm1 index b9d150ceacd..33700ac9024 100644 --- a/tools/ci.psm1 +++ b/tools/ci.psm1 @@ -241,7 +241,7 @@ function Install-CIPester Write-Verbose "Checking for Pester module (required: $MinimumVersion - $MaximumVersion)" -Verbose # Check if a compatible version of Pester is already installed - $installedPester = Get-Module -Name Pester -ListAvailable | + $installedPester = Get-Module -Name Pester -ListAvailable | Where-Object { $_.Version -ge $MinimumVersion -and $_.Version -le $MaximumVersion } | Sort-Object -Property Version -Descending | Select-Object -First 1 @@ -616,20 +616,9 @@ function Invoke-CIFinish Restore-PSOptions -PSOptionsPath "${buildFolder}/psoptions.json" $preReleaseVersion = $env:CI_FINISH_RELASETAG - # Build packages $preReleaseVersion = "$previewPrefix-$previewLabel.$prereleaseIteration" - switch -regex ($Runtime){ - default { - $runPackageTest = $true - $packageTypes = 'msi', 'zip', 'zip-pdb', 'msix' - } - 'win-arm.*' { - $runPackageTest = $false - $packageTypes = 'msi', 'zip', 'zip-pdb', 'msix' - } - } + # Build packages + $packageTypes = 'zip', 'zip-pdb', 'msix' - Import-Module "$PSScriptRoot\wix\wix.psm1" - Install-Wix -arm64:$true $packages = Start-PSPackage -Type $packageTypes -ReleaseTag $preReleaseVersion -SkipReleaseChecks -WindowsRuntime $Runtime foreach ($package in $packages) { @@ -641,40 +630,9 @@ function Invoke-CIFinish if ($package -is [string]) { $null = $artifacts.Add($package) - } elseif ($package -is [pscustomobject] -and $package.psobject.Properties['msi']) { - $null = $artifacts.Add($package.msi) - $null = $artifacts.Add($package.wixpdb) } } - if ($runPackageTest) { - # the packaging tests find the MSI package using env:PSMsiX64Path - $env:PSMsiX64Path = $artifacts | Where-Object { $_.EndsWith(".msi")} - $architechture = $Runtime.Split('-')[1] - $exePath = New-ExePackage -ProductVersion ($preReleaseVersion -replace '^v') -ProductTargetArchitecture $architechture -MsiLocationPath $env:PSMsiX64Path - Write-Verbose "exe Path: $exePath" -Verbose - $artifacts.Add($exePath) - $env:PSExePath = $exePath - $env:PSMsiChannel = $Channel - $env:PSMsiRuntime = $Runtime - - # Install the latest Pester and import it - $maximumPesterVersion = '4.99' - Install-CIPester -MinimumVersion '4.0.0' -MaximumVersion $maximumPesterVersion -Force - Import-Module Pester -Force -MaximumVersion $maximumPesterVersion - - $testResultPath = Join-Path -Path $env:TEMP -ChildPath "win-package-$channel-$runtime.xml" - - # start the packaging tests and get the results - $packagingTestResult = Invoke-Pester -Script (Join-Path $repoRoot '.\test\packaging\windows\') -PassThru -OutputFormat NUnitXml -OutputFile $testResultPath - - Publish-TestResults -Title "win-package-$channel-$runtime" -Path $testResultPath - - # fail the CI job if the tests failed, or nothing passed - if (-not $packagingTestResult -is [pscustomobject] -or $packagingTestResult.FailedCount -ne 0 -or $packagingTestResult.PassedCount -eq 0) { - throw "Packaging tests failed ($($packagingTestResult.FailedCount) failed/$($packagingTestResult.PassedCount) passed)" - } - } } } catch { Get-Error -InputObject $_ @@ -932,12 +890,12 @@ function New-LinuxPackage } else { "${env:BUILD_ARTIFACTSTAGINGDIRECTORY}" } - + # Ensure artifacts directory exists if (-not (Test-Path $artifactsDir)) { New-Item -ItemType Directory -Path $artifactsDir -Force | Out-Null } - + Write-Log -message "Artifacts directory: $artifactsDir" Copy-Item $packageObj.FullName -Destination $artifactsDir -Force } @@ -950,7 +908,7 @@ function New-LinuxPackage } else { "${env:BUILD_ARTIFACTSTAGINGDIRECTORY}" } - + # Create and package Raspbian .tgz # Build must be clean for Raspbian Start-PSBuild -PSModuleRestore -Clean -Runtime linux-arm -Configuration 'Release' @@ -1062,13 +1020,13 @@ Function Test-MergeConflictMarker [string]$OutputPath, [string]$SummaryPath ) - + # Output results to GitHub Actions if ($OutputPath) { "files-checked=0" | Out-File -FilePath $OutputPath -Append -Encoding utf8 "conflicts-found=0" | Out-File -FilePath $OutputPath -Append -Encoding utf8 } - + # Create GitHub Actions job summary if ($SummaryPath) { $summaryContent = @" @@ -1097,11 +1055,11 @@ $Message # Filter out *.cs files from merge conflict checking $filesToCheck = @($File | Where-Object { $_ -notlike "*.cs" }) $filteredCount = $File.Count - $filesToCheck.Count - + if ($filteredCount -gt 0) { Write-Host "Filtered out $filteredCount *.cs file(s) from merge conflict checking" -ForegroundColor Yellow } - + if ($filesToCheck.Count -eq 0) { Write-Host "No files to check after filtering (all files were *.cs)" -ForegroundColor Yellow Write-NoFilesOutput -Message "All $filteredCount file(s) were filtered out (*.cs files are excluded from merge conflict checking)." -OutputPath $OutputPath -SummaryPath $SummaryPath @@ -1135,14 +1093,14 @@ $Message } $filesChecked++ - + # Get relative path for display $relativePath = if ($WorkspacePath -and $filePath.StartsWith($WorkspacePath)) { $filePath.Substring($WorkspacePath.Length).TrimStart([System.IO.Path]::DirectorySeparatorChar, [System.IO.Path]::AltDirectorySeparatorChar) } else { $filePath } - + Write-Host " Checking: $relativePath" -ForegroundColor Gray # Search for conflict markers using Select-String diff --git a/tools/packaging/boms/windows.json b/tools/packaging/boms/windows.json index 8d900902bc2..8d8154e7445 100644 --- a/tools/packaging/boms/windows.json +++ b/tools/packaging/boms/windows.json @@ -4616,11 +4616,6 @@ "FileType": "Product", "Architecture": null }, - { - "Pattern": "RegisterMicrosoftUpdate.ps1", - "FileType": "Product", - "Architecture": null - }, { "Pattern": "System.Management.Automation.dll", "FileType": "Product", diff --git a/tools/packaging/packaging.psd1 b/tools/packaging/packaging.psd1 index 0053428a481..b72c14b80f1 100644 --- a/tools/packaging/packaging.psd1 +++ b/tools/packaging/packaging.psd1 @@ -7,13 +7,10 @@ PowerShellVersion = "5.0" CmdletsToExport = @() FunctionsToExport = @( - 'Compress-ExePackageEngine' - 'Expand-ExePackageEngine' 'Expand-PSSignedBuild' 'Invoke-AzDevOpsLinuxPackageBuild' 'Invoke-AzDevOpsLinuxPackageCreation' 'New-DotnetSdkContainerFxdPackage' - 'New-ExePackage' 'Start-PrepForGlobalToolNupkg' 'New-GlobalToolNupkgSource' 'New-GlobalToolNupkgFromSource' diff --git a/tools/packaging/packaging.psm1 b/tools/packaging/packaging.psm1 index 361f82769f0..a551a483c8d 100644 --- a/tools/packaging/packaging.psm1 +++ b/tools/packaging/packaging.psm1 @@ -52,7 +52,7 @@ function Start-PSPackage { [string]$Name = "powershell", # Ubuntu, CentOS, Fedora, macOS, and Windows packages are supported - [ValidateSet("msix", "deb", "osxpkg", "rpm", "rpm-fxdependent", "rpm-fxdependent-arm64", "msi", "zip", "zip-pdb", "tar", "tar-arm", "tar-arm64", "tar-alpine", "fxdependent", "fxdependent-win-desktop", "min-size", "tar-alpine-fxdependent")] + [ValidateSet("msix", "deb", "osxpkg", "rpm", "rpm-fxdependent", "rpm-fxdependent-arm64", "zip", "zip-pdb", "tar", "tar-arm", "tar-arm64", "tar-alpine", "fxdependent", "fxdependent-win-desktop", "min-size", "tar-alpine-fxdependent")] [string[]]$Type, # Generate windows downlevel package @@ -346,7 +346,7 @@ function Start-PSPackage { } elseif ($Environment.IsMacOS) { "osxpkg", "tar" } elseif ($Environment.IsWindows) { - "msi", "msix" + "zip", "msix" } Write-Warning "-Type was not specified, continuing with $Type!" } @@ -493,34 +493,6 @@ function Start-PSPackage { } } } - "msi" { - $TargetArchitecture = "x64" - $r2rArchitecture = "amd64" - if ($Runtime -match "-x86") { - $TargetArchitecture = "x86" - $r2rArchitecture = "i386" - } - elseif ($Runtime -match "-arm64") - { - $TargetArchitecture = "arm64" - $r2rArchitecture = "arm64" - } - - Write-Verbose "TargetArchitecture = $TargetArchitecture" -Verbose - - $Arguments = @{ - ProductNameSuffix = $NameSuffix - ProductSourcePath = $Source - ProductVersion = $Version - AssetsPath = "$RepoRoot\assets" - ProductTargetArchitecture = $TargetArchitecture - Force = $Force - } - - if ($PSCmdlet.ShouldProcess("Create MSI Package")) { - New-MSIPackage @Arguments - } - } "msix" { $Arguments = @{ ProductNameSuffix = $NameSuffix @@ -3769,443 +3741,6 @@ function Get-NugetSemanticVersion $packageSemanticVersion } -# Get the paths to various WiX tools -function Get-WixPath -{ - [CmdletBinding()] - param ( - [bool] $IsProductArchitectureArm = $false - ) - - $wixToolsetBinPath = $IsProductArchitectureArm ? "${env:ProgramFiles(x86)}\Arm Support WiX Toolset *\bin" : "${env:ProgramFiles(x86)}\WiX Toolset *\bin" - - Write-Verbose -Verbose "Ensure Wix Toolset is present on the machine @ $wixToolsetBinPath" - if (-not (Test-Path $wixToolsetBinPath)) - { - if (!$IsProductArchitectureArm) - { - throw "The latest version of Wix Toolset 3.11 is required to create MSI package. Please install it from https://github.com/wixtoolset/wix3/releases" - } - else { - throw "The latest version of Wix Toolset 3.14 is required to create MSI package for arm. Please install it from https://aka.ms/ps-wix-3-14-zip" - } - } - - ## Get the latest if multiple versions exist. - $wixToolsetBinPath = (Get-ChildItem $wixToolsetBinPath).FullName | Sort-Object -Descending | Select-Object -First 1 - - Write-Verbose "Initialize Wix executables..." - $wixHeatExePath = Join-Path $wixToolsetBinPath "heat.exe" - $wixMeltExePath = Join-Path $wixToolsetBinPath "melt.exe" - $wixTorchExePath = Join-Path $wixToolsetBinPath "torch.exe" - $wixPyroExePath = Join-Path $wixToolsetBinPath "pyro.exe" - $wixCandleExePath = Join-Path $wixToolsetBinPath "Candle.exe" - $wixLightExePath = Join-Path $wixToolsetBinPath "Light.exe" - $wixInsigniaExePath = Join-Path $wixToolsetBinPath "Insignia.exe" - - return [PSCustomObject] @{ - WixHeatExePath = $wixHeatExePath - WixMeltExePath = $wixMeltExePath - WixTorchExePath = $wixTorchExePath - WixPyroExePath = $wixPyroExePath - WixCandleExePath = $wixCandleExePath - WixLightExePath = $wixLightExePath - WixInsigniaExePath = $wixInsigniaExePath - } -} - -<# - .Synopsis - Creates a Windows installer MSI package and assumes that the binaries are already built using 'Start-PSBuild'. - This only works on a Windows machine due to the usage of WiX. - .EXAMPLE - # This example shows how to produce a Debug-x64 installer for development purposes. - cd $RootPathOfPowerShellRepo - Import-Module .\build.psm1; Import-Module .\tools\packaging\packaging.psm1 - New-MSIPackage -Verbose -ProductSourcePath '.\src\powershell-win-core\bin\Debug\net8.0\win7-x64\publish' -ProductTargetArchitecture x64 -ProductVersion '1.2.3' -#> -function New-MSIPackage -{ - [CmdletBinding()] - param ( - - # Name of the Product - [ValidateNotNullOrEmpty()] - [string] $ProductName = 'PowerShell', - - # Suffix of the Name - [string] $ProductNameSuffix, - - # Version of the Product - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] $ProductVersion, - - # Source Path to the Product Files - required to package the contents into an MSI - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] $ProductSourcePath, - - # File describing the MSI Package creation semantics - [ValidateNotNullOrEmpty()] - [ValidateScript( {Test-Path $_})] - [string] $ProductWxsPath = "$RepoRoot\assets\wix\Product.wxs", - - # File describing the MSI Package creation semantics - [ValidateNotNullOrEmpty()] - [ValidateScript({Test-Path $_})] - [string] $BundleWxsPath = "$RepoRoot\assets\wix\bundle.wxs", - - # Path to Assets folder containing artifacts such as icons, images - [ValidateNotNullOrEmpty()] - [ValidateScript( {Test-Path $_})] - [string] $AssetsPath = "$RepoRoot\assets", - - # Architecture to use when creating the MSI - [Parameter(Mandatory = $true)] - [ValidateSet("x86", "x64", "arm64")] - [ValidateNotNullOrEmpty()] - [string] $ProductTargetArchitecture, - - # Force overwrite of package - [Switch] $Force, - - [string] $CurrentLocation = (Get-Location) - ) - - $wixPaths = Get-WixPath -IsProductArchitectureArm ($ProductTargetArchitecture -eq "arm64") - - $windowsNames = Get-WindowsNames -ProductName $ProductName -ProductNameSuffix $ProductNameSuffix -ProductVersion $ProductVersion - $productSemanticVersionWithName = $windowsNames.ProductSemanticVersionWithName - $ProductSemanticVersion = $windowsNames.ProductSemanticVersion - $packageName = $windowsNames.PackageName - $ProductVersion = $windowsNames.ProductVersion - Write-Verbose "Create MSI for Product $productSemanticVersionWithName" -Verbose - Write-Verbose "ProductSemanticVersion = $productSemanticVersion" -Verbose - Write-Verbose "packageName = $packageName" -Verbose - Write-Verbose "ProductVersion = $ProductVersion" -Verbose - - $simpleProductVersion = [string]([Version]$ProductVersion).Major - $isPreview = Test-IsPreview -Version $ProductSemanticVersion - if ($isPreview) - { - $simpleProductVersion += '-preview' - } - - $staging = "$PSScriptRoot/staging" - New-StagingFolder -StagingPath $staging -PackageSourcePath $ProductSourcePath - - $assetsInSourcePath = Join-Path $staging 'assets' - - New-Item $assetsInSourcePath -type directory -Force | Write-Verbose - - Write-Verbose "Place dependencies such as icons to $assetsInSourcePath" - Copy-Item "$AssetsPath\*.ico" $assetsInSourcePath -Force - - - - $fileArchitecture = 'amd64' - $ProductProgFilesDir = "ProgramFiles64Folder" - if ($ProductTargetArchitecture -eq "x86") - { - $fileArchitecture = 'x86' - $ProductProgFilesDir = "ProgramFilesFolder" - } - elseif ($ProductTargetArchitecture -eq "arm64") - { - $fileArchitecture = 'arm64' - $ProductProgFilesDir = "ProgramFiles64Folder" - } - - $wixFragmentPath = Join-Path $env:Temp "Fragment.wxs" - - # cleanup any garbage on the system - Remove-Item -ErrorAction SilentlyContinue $wixFragmentPath -Force - - $msiLocationPath = Join-Path $CurrentLocation "$packageName.msi" - $msiPdbLocationPath = Join-Path $CurrentLocation "$packageName.wixpdb" - - if (!$Force.IsPresent -and (Test-Path -Path $msiLocationPath)) { - Write-Error -Message "Package already exists, use -Force to overwrite, path: $msiLocationPath" -ErrorAction Stop - } - - Write-Log "Generating wxs file manifest..." - $arguments = @{ - IsPreview = $isPreview - ProductSourcePath = $staging - ProductName = $ProductName - ProductVersion = $ProductVersion - SimpleProductVersion = $simpleProductVersion - ProductSemanticVersion = $ProductSemanticVersion - ProductVersionWithName = $productVersionWithName - ProductProgFilesDir = $ProductProgFilesDir - FileArchitecture = $fileArchitecture - } - - $buildArguments = New-MsiArgsArray -Argument $arguments - - Test-Bom -Path $staging -BomName windows -Architecture $ProductTargetArchitecture -Verbose - Start-NativeExecution -VerboseOutputOnError { & $wixPaths.wixHeatExePath dir $staging -dr VersionFolder -cg ApplicationFiles -ag -sfrag -srd -scom -sreg -out $wixFragmentPath -var var.ProductSourcePath $buildArguments -v} - - Send-AzdoFile -Path $wixFragmentPath - - $wixObjFragmentPath = Join-Path $env:Temp "Fragment.wixobj" - - # cleanup any garbage on the system - Remove-Item -ErrorAction SilentlyContinue $wixObjFragmentPath -Force - - Start-MsiBuild -WxsFile $ProductWxsPath, $wixFragmentPath -ProductTargetArchitecture $ProductTargetArchitecture -Argument $arguments -MsiLocationPath $msiLocationPath -MsiPdbLocationPath $msiPdbLocationPath - - Remove-Item -ErrorAction SilentlyContinue $wixFragmentPath -Force - - if ((Test-Path $msiLocationPath) -and (Test-Path $msiPdbLocationPath)) - { - Write-Verbose "You can find the WixPdb @ $msiPdbLocationPath" -Verbose - Write-Verbose "You can find the MSI @ $msiLocationPath" -Verbose - [pscustomobject]@{ - msi=$msiLocationPath - wixpdb=$msiPdbLocationPath - } - } - else - { - $errorMessage = "Failed to create $msiLocationPath" - throw $errorMessage - } -} - -function Get-WindowsNames { - param( - # Name of the Product - [ValidateNotNullOrEmpty()] - [string] $ProductName = 'PowerShell', - - # Suffix of the Name - [string] $ProductNameSuffix, - - # Version of the Product - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] $ProductVersion - ) - - Write-Verbose -Message "Getting Windows Names for ProductName: $ProductName; ProductNameSuffix: $ProductNameSuffix; ProductVersion: $ProductVersion" -Verbose - - $ProductSemanticVersion = Get-PackageSemanticVersion -Version $ProductVersion - $ProductVersion = Get-PackageVersionAsMajorMinorBuildRevision -Version $ProductVersion -IncrementBuildNumber - - $productVersionWithName = $ProductName + '_' + $ProductVersion - $productSemanticVersionWithName = $ProductName + '-' + $ProductSemanticVersion - - $packageName = $productSemanticVersionWithName - if ($ProductNameSuffix) { - $packageName += "-$ProductNameSuffix" - } - - return [PSCustomObject]@{ - PackageName = $packageName - ProductVersionWithName = $productVersionWithName - ProductSemanticVersion = $ProductSemanticVersion - ProductSemanticVersionWithName = $productSemanticVersionWithName - ProductVersion = $ProductVersion - } -} - -function New-ExePackage { - param( - # Name of the Product - [ValidateNotNullOrEmpty()] - [string] $ProductName = 'PowerShell', - - # Version of the Product - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - - [string] $ProductVersion, - - # File describing the MSI Package creation semantics - [ValidateNotNullOrEmpty()] - [ValidateScript({Test-Path $_})] - [string] $BundleWxsPath = "$RepoRoot\assets\wix\bundle.wxs", - - # Architecture to use when creating the MSI - [Parameter(Mandatory = $true)] - [ValidateSet("x86", "x64", "arm64")] - [ValidateNotNullOrEmpty()] - [string] $ProductTargetArchitecture, - - # Location of the signed MSI - [Parameter(Mandatory = $true)] - [string] - $MsiLocationPath, - - [string] $CurrentLocation = (Get-Location) - ) - - $productNameSuffix = "win-$ProductTargetArchitecture" - - $windowsNames = Get-WindowsNames -ProductName $ProductName -ProductNameSuffix $productNameSuffix -ProductVersion $ProductVersion - $productSemanticVersionWithName = $windowsNames.ProductSemanticVersionWithName - $packageName = $windowsNames.PackageName - $isPreview = Test-IsPreview -Version $windowsNames.ProductSemanticVersion - - Write-Verbose "Create EXE for Product $productSemanticVersionWithName" -verbose - Write-Verbose "packageName = $packageName" -Verbose - - $exeLocationPath = Join-Path $CurrentLocation "$packageName.exe" - $exePdbLocationPath = Join-Path $CurrentLocation "$packageName.exe.wixpdb" - $windowsVersion = Get-WindowsVersion -packageName $packageName - - Start-MsiBuild -WxsFile $BundleWxsPath -ProductTargetArchitecture $ProductTargetArchitecture -Argument @{ - IsPreview = $isPreview - TargetPath = $MsiLocationPath - WindowsVersion = $windowsVersion - } -MsiLocationPath $exeLocationPath -MsiPdbLocationPath $exePdbLocationPath - - return $exeLocationPath -} - -<# -Allows you to extract the engine of exe package, mainly for signing -Any existing signature will be removed. - #> -function Expand-ExePackageEngine { - param( - # Location of the unsigned EXE - [Parameter(Mandatory = $true)] - [string] - $ExePath, - - # Location to put the expanded engine. - [Parameter(Mandatory = $true)] - [string] - $EnginePath, - - [Parameter(Mandatory = $true)] - [ValidateSet("x86", "x64", "arm64")] - [ValidateNotNullOrEmpty()] - [string] $ProductTargetArchitecture - ) - - <# - 2. detach the engine from TestInstaller.exe: - insignia -ib TestInstaller.exe -o engine.exe - #> - - $wixPaths = Get-WixPath -IsProductArchitectureArm ($ProductTargetArchitecture -eq "arm64") - - $resolvedExePath = (Resolve-Path -Path $ExePath).ProviderPath - $resolvedEnginePath = [System.IO.Path]::GetFullPath($EnginePath) - - Start-NativeExecution -VerboseOutputOnError { & $wixPaths.wixInsigniaExePath -ib $resolvedExePath -o $resolvedEnginePath} -} - -<# -Allows you to replace the engine (installer) in the exe package. -Used to replace the engine with a signed version -#> -function Compress-ExePackageEngine { - param( - # Location of the unsigned EXE - [Parameter(Mandatory = $true)] - [string] - $ExePath, - - # Location of the signed engine - [Parameter(Mandatory = $true)] - [string] - $EnginePath, - - [Parameter(Mandatory = $true)] - [ValidateSet("x86", "x64", "arm64")] - [ValidateNotNullOrEmpty()] - [string] $ProductTargetArchitecture - ) - - - <# - 4. re-attach the signed engine.exe to the bundle: - insignia -ab engine.exe TestInstaller.exe -o TestInstaller.exe - #> - - $wixPaths = Get-WixPath -IsProductArchitectureArm ($ProductTargetArchitecture -eq "arm64") - - $resolvedEnginePath = (Resolve-Path -Path $EnginePath).ProviderPath - $resolvedExePath = (Resolve-Path -Path $ExePath).ProviderPath - - Start-NativeExecution -VerboseOutputOnError { & $wixPaths.wixInsigniaExePath -ab $resolvedEnginePath $resolvedExePath -o $resolvedExePath} -} - -function New-MsiArgsArray { - param( - [Parameter(Mandatory)] - [Hashtable]$Argument - ) - - $buildArguments = @() - foreach ($key in $Argument.Keys) { - $buildArguments += "-d$key=$($Argument.$key)" - } - - return $buildArguments -} - -function Start-MsiBuild { - param( - [string[]] $WxsFile, - [string[]] $Extension = @('WixUIExtension', 'WixUtilExtension', 'WixBalExtension'), - [string] $ProductTargetArchitecture, - [Hashtable] $Argument, - [string] $MsiLocationPath, - [string] $MsiPdbLocationPath - ) - - $outDir = $env:Temp - - $wixPaths = Get-WixPath -IsProductArchitectureArm ($ProductTargetArchitecture -eq "arm64") - - $extensionArgs = @() - foreach ($extensionName in $Extension) { - $extensionArgs += '-ext' - $extensionArgs += $extensionName - } - - $buildArguments = New-MsiArgsArray -Argument $Argument - - $objectPaths = @() - foreach ($file in $WxsFile) { - $fileName = [system.io.path]::GetFileNameWithoutExtension($file) - $objectPaths += Join-Path $outDir -ChildPath "${filename}.wixobj" - } - - foreach ($file in $objectPaths) { - Remove-Item -ErrorAction SilentlyContinue $file -Force - Remove-Item -ErrorAction SilentlyContinue $file -Force - } - - $resolvedWxsFiles = @() - foreach ($file in $WxsFile) { - $resolvedWxsFiles += (Resolve-Path -Path $file).ProviderPath - } - - Write-Verbose "$resolvedWxsFiles" -Verbose - - Write-Log "running candle..." - Start-NativeExecution -VerboseOutputOnError { & $wixPaths.wixCandleExePath $resolvedWxsFiles -out "$outDir\\" $extensionArgs -arch $ProductTargetArchitecture $buildArguments -v} - - Write-Log "running light..." - # suppress ICE61, because we allow same version upgrades - # suppress ICE57, this suppresses an error caused by our shortcut not being installed per user - # suppress ICE40, REINSTALLMODE is defined in the Property table. - Start-NativeExecution -VerboseOutputOnError {& $wixPaths.wixLightExePath -sice:ICE61 -sice:ICE40 -sice:ICE57 -out $msiLocationPath -pdbout $msiPdbLocationPath $objectPaths $extensionArgs } - - foreach($file in $objectPaths) - { - Remove-Item -ErrorAction SilentlyContinue $file -Force - Remove-Item -ErrorAction SilentlyContinue $file -Force - } -} - <# .Synopsis Creates a Windows AppX MSIX package and assumes that the binaries are already built using 'Start-PSBuild'. @@ -4372,6 +3907,7 @@ function New-MSIXPackage Write-Verbose "Creating msix package" -Verbose Start-NativeExecution -VerboseOutputOnError { & $makeappx pack /o /v /h SHA256 /d $ProductSourcePath /p (Join-Path -Path $CurrentLocation -ChildPath "$packageName.msix") } Write-Verbose "Created $packageName.msix" -Verbose + Join-Path -Path $CurrentLocation -ChildPath "$packageName.msix" } } From 558c886d87c55979758576d19a9e6e105b93f70c Mon Sep 17 00:00:00 2001 From: Dongbo Wang Date: Fri, 17 Apr 2026 10:05:33 -0700 Subject: [PATCH 04/15] Remove package verification from the notice pipeline (#27289) --- .pipelines/apiscan-gen-notice.yml | 4 ---- .pipelines/templates/compliance/generateNotice.yml | 7 ------- 2 files changed, 11 deletions(-) diff --git a/.pipelines/apiscan-gen-notice.yml b/.pipelines/apiscan-gen-notice.yml index 9cc83e7136a..df5ebaac091 100644 --- a/.pipelines/apiscan-gen-notice.yml +++ b/.pipelines/apiscan-gen-notice.yml @@ -8,9 +8,6 @@ parameters: displayName: Debugging - Enable CodeQL and set cadence to 1 hour type: boolean default: false - - name: SkipVerifyPackages - type: boolean - default: false variables: # PAT permissions NOTE: Declare a SymbolServerPAT variable in this group with a 'microsoft' organizanization scoped PAT with 'Symbols' Read permission. @@ -112,4 +109,3 @@ extends: - template: /.pipelines/templates/compliance/generateNotice.yml@self parameters: parentJobs: [] - SkipVerifyPackages: ${{ parameters.SkipVerifyPackages }} diff --git a/.pipelines/templates/compliance/generateNotice.yml b/.pipelines/templates/compliance/generateNotice.yml index 90fd08dd8d9..aec44b9b8f6 100644 --- a/.pipelines/templates/compliance/generateNotice.yml +++ b/.pipelines/templates/compliance/generateNotice.yml @@ -4,8 +4,6 @@ parameters: - name: parentJobs type: jobList - - name: SkipVerifyPackages - type: boolean jobs: - job: generateNotice @@ -57,11 +55,6 @@ jobs: inputs: sourceScanPath: '$(repoRoot)\tools\cgmanifest\tpn' - - pwsh: | - $(repoRoot)/tools/clearlyDefined/ClearlyDefined.ps1 -TestAndHarvest - displayName: Verify that packages have license data - condition: eq(${{ parameters.SkipVerifyPackages }}, false) - - task: msospo.ospo-extension.8d7f9abb-6896-461d-9e25-4f74ed65ddb2.notice@0 displayName: 'NOTICE File Generator' inputs: From 6cc1e7071d40162e01fd2b47f6c33a02c0d046e6 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Fri, 17 Apr 2026 14:03:11 -0400 Subject: [PATCH 05/15] [master] Update branch for release (#27291) --- CHANGELOG/v7.7/dependencychanges.json | 15 +++ DotnetRuntimeMetadata.json | 2 +- global.json | 2 +- ...oft.PowerShell.Commands.Diagnostics.csproj | 2 +- ...soft.PowerShell.Commands.Management.csproj | 2 +- ...crosoft.PowerShell.Commands.Utility.csproj | 2 +- ...crosoft.PowerShell.CoreCLR.Eventing.csproj | 2 +- .../Microsoft.PowerShell.SDK.csproj | 10 +- .../Microsoft.WSMan.Management.csproj | 2 +- .../System.Management.Automation.csproj | 12 +- test/tools/TestService/TestService.csproj | 2 +- test/tools/WebListener/WebListener.csproj | 2 +- test/xUnit/xUnit.tests.csproj | 2 +- tools/cgmanifest/main/cgmanifest.json | 110 ++++++++---------- 14 files changed, 86 insertions(+), 81 deletions(-) create mode 100644 CHANGELOG/v7.7/dependencychanges.json diff --git a/CHANGELOG/v7.7/dependencychanges.json b/CHANGELOG/v7.7/dependencychanges.json new file mode 100644 index 00000000000..21cd1577251 --- /dev/null +++ b/CHANGELOG/v7.7/dependencychanges.json @@ -0,0 +1,15 @@ +[ + { + "ChangeType": "NonSecurity", + "Branch": "master", + "PackageId": ".NET SDK", + "FromVersion": "11.0.100-preview.2.26159.112", + "ToVersion": "11.0.100-preview.3.26207.106", + "VulnerabilityId": [], + "Severity": [], + "VulnerableRanges": [], + "AdvisoryUrls": [], + "Justification": "Updated .NET SDK. Building with the latest SDK is required.", + "TimestampUtc": "2026-04-17T17:16:15.7099916Z" + } +] diff --git a/DotnetRuntimeMetadata.json b/DotnetRuntimeMetadata.json index 7c4a2191467..f8288b53b67 100644 --- a/DotnetRuntimeMetadata.json +++ b/DotnetRuntimeMetadata.json @@ -4,7 +4,7 @@ "quality": "daily", "qualityFallback": "preview", "packageVersionPattern": "9.0.0-preview.6", - "sdkImageVersion": "11.0.100-preview.1.26104.118", + "sdkImageVersion": "11.0.100-preview.3.26207.106", "nextChannel": "9.0.0-preview.7", "azureFeed": "", "sdkImageOverride": "" diff --git a/global.json b/global.json index ef31c0723ff..d31f5220d83 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "11.0.100-preview.2.26159.112" + "version": "11.0.100-preview.3.26207.106" } } diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj b/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj index 8e5a6b3f2e3..9552f72c83a 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj index 8bb897e0095..8ce2a97d67b 100644 --- a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj +++ b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj @@ -47,7 +47,7 @@ - + diff --git a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj index d6cd95677ab..cc98893c5b6 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj +++ b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj @@ -33,7 +33,7 @@ - + diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj index 1a63891ef77..dadff652e53 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj index ecc224713cc..50d431225c7 100644 --- a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj +++ b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj @@ -16,19 +16,19 @@ - - + + - - + + - + - + diff --git a/src/System.Management.Automation/System.Management.Automation.csproj b/src/System.Management.Automation/System.Management.Automation.csproj index fa797a7f0de..beec0c4a495 100644 --- a/src/System.Management.Automation/System.Management.Automation.csproj +++ b/src/System.Management.Automation/System.Management.Automation.csproj @@ -32,12 +32,12 @@ - - - - - - + + + + + + diff --git a/test/tools/TestService/TestService.csproj b/test/tools/TestService/TestService.csproj index 906820d262b..37b73426f6c 100644 --- a/test/tools/TestService/TestService.csproj +++ b/test/tools/TestService/TestService.csproj @@ -15,7 +15,7 @@ - + diff --git a/test/tools/WebListener/WebListener.csproj b/test/tools/WebListener/WebListener.csproj index c632e960a53..3567cd93c68 100644 --- a/test/tools/WebListener/WebListener.csproj +++ b/test/tools/WebListener/WebListener.csproj @@ -7,6 +7,6 @@ - + diff --git a/test/xUnit/xUnit.tests.csproj b/test/xUnit/xUnit.tests.csproj index 4cf097c7956..a2a9fe041e9 100644 --- a/test/xUnit/xUnit.tests.csproj +++ b/test/xUnit/xUnit.tests.csproj @@ -30,7 +30,7 @@ all - + diff --git a/tools/cgmanifest/main/cgmanifest.json b/tools/cgmanifest/main/cgmanifest.json index 5322bc102bd..5d2de074cae 100644 --- a/tools/cgmanifest/main/cgmanifest.json +++ b/tools/cgmanifest/main/cgmanifest.json @@ -1,5 +1,4 @@ { - "$schema": "https://json.schemastore.org/component-detection-manifest.json", "Registrations": [ { "Component": { @@ -86,7 +85,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Bcl.AsyncInterfaces", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -126,7 +125,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Extensions.ObjectPool", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -166,7 +165,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Win32.Registry.AccessControl", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -176,7 +175,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Win32.SystemEvents", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -186,7 +185,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Windows.Compatibility", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -206,7 +205,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-arm.runtime.native.System.IO.Ports", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -216,7 +215,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-arm64.runtime.native.System.IO.Ports", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -226,7 +225,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-x64.runtime.native.System.IO.Ports", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -236,7 +235,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-x86.runtime.native.System.IO.Ports", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -246,7 +245,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-arm.runtime.native.System.IO.Ports", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -256,7 +255,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-arm64.runtime.native.System.IO.Ports", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -266,7 +265,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-bionic-arm64.runtime.native.System.IO.Ports", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -276,7 +275,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-bionic-x64.runtime.native.System.IO.Ports", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -286,7 +285,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-musl-arm.runtime.native.System.IO.Ports", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -296,7 +295,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-musl-arm64.runtime.native.System.IO.Ports", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -306,7 +305,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-musl-x64.runtime.native.System.IO.Ports", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -316,7 +315,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-x64.runtime.native.System.IO.Ports", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -326,7 +325,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.maccatalyst-arm64.runtime.native.System.IO.Ports", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -336,7 +335,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.maccatalyst-x64.runtime.native.System.IO.Ports", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -356,7 +355,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.native.System.IO.Ports", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -366,7 +365,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.osx-arm64.runtime.native.System.IO.Ports", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -376,7 +375,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.osx-x64.runtime.native.System.IO.Ports", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -436,7 +435,7 @@ "Type": "nuget", "Nuget": { "Name": "System.CodeDom", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -446,7 +445,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ComponentModel.Composition.Registration", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -456,7 +455,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ComponentModel.Composition", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -466,7 +465,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Configuration.ConfigurationManager", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -476,7 +475,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Data.Odbc", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -486,7 +485,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Data.OleDb", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -506,7 +505,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Diagnostics.EventLog", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -516,7 +515,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Diagnostics.PerformanceCounter", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -526,7 +525,7 @@ "Type": "nuget", "Nuget": { "Name": "System.DirectoryServices.AccountManagement", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -536,7 +535,7 @@ "Type": "nuget", "Nuget": { "Name": "System.DirectoryServices.Protocols", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -546,7 +545,7 @@ "Type": "nuget", "Nuget": { "Name": "System.DirectoryServices", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -556,7 +555,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Drawing.Common", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -566,7 +565,7 @@ "Type": "nuget", "Nuget": { "Name": "System.IO.Packaging", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -576,7 +575,7 @@ "Type": "nuget", "Nuget": { "Name": "System.IO.Ports", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -586,7 +585,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Management", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -596,7 +595,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Net.Http.WinHttpHandler", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -606,7 +605,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Reflection.Context", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -616,7 +615,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Runtime.Caching", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -626,7 +625,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Cryptography.Pkcs", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -636,7 +635,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Cryptography.ProtectedData", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -646,7 +645,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Cryptography.Xml", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -656,7 +655,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Permissions", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -706,7 +705,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ServiceModel.Syndication", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -716,7 +715,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ServiceProcess.ServiceController", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -726,17 +725,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Speech", - "Version": "10.0.5" - } - }, - "DevelopmentDependency": false - }, - { - "Component": { - "Type": "nuget", - "Nuget": { - "Name": "System.Text.Encoding.CodePages", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false @@ -756,10 +745,11 @@ "Type": "nuget", "Nuget": { "Name": "System.Windows.Extensions", - "Version": "10.0.5" + "Version": "10.0.6" } }, "DevelopmentDependency": false } - ] + ], + "$schema": "https://json.schemastore.org/component-detection-manifest.json" } From 2475feb87698ca064e561d85abea5ed643152364 Mon Sep 17 00:00:00 2001 From: Patrick Meinecke Date: Mon, 20 Apr 2026 12:49:52 -0400 Subject: [PATCH 06/15] Enable usage in AppContainers (#27266) Co-authored-by: Travis Plunk --- .../engine/Modules/ModuleIntrinsics.cs | 4 ++- .../namespaces/FileSystemProvider.cs | 27 +++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs b/src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs index 301ee8c3b49..538c4775f0a 100644 --- a/src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs +++ b/src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs @@ -967,7 +967,9 @@ internal static string GetPersonalModulePath() #if UNIX return Platform.SelectProductNameForDirectory(Platform.XDG_Type.USER_MODULES); #else - string myDocumentsPath = InternalTestHooks.SetMyDocumentsSpecialFolderToBlank ? string.Empty : Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); + string myDocumentsPath = InternalTestHooks.SetMyDocumentsSpecialFolderToBlank + ? string.Empty + : Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments, Environment.SpecialFolderOption.DoNotVerify); return string.IsNullOrEmpty(myDocumentsPath) ? null : Path.Combine(myDocumentsPath, Utils.ModuleDirectory); #endif } diff --git a/src/System.Management.Automation/namespaces/FileSystemProvider.cs b/src/System.Management.Automation/namespaces/FileSystemProvider.cs index 71de4e8ac67..05c8fff76e0 100644 --- a/src/System.Management.Automation/namespaces/FileSystemProvider.cs +++ b/src/System.Management.Automation/namespaces/FileSystemProvider.cs @@ -569,7 +569,7 @@ protected override PSDriveInfo NewDrive(PSDriveInfo drive) if (driveIsFixed) { // Since the drive is fixed, ensure the root is valid. - validDrive = Directory.Exists(drive.Root); + validDrive = SafeDoesPathExist(drive.Root); } if (validDrive) @@ -908,7 +908,7 @@ protected override Collection InitializeDefaultDrives() if (newDrive.DriveType == DriveType.Fixed) { - if (!newDrive.RootDirectory.Exists) + if (!SafeDoesPathExist(newDrive.RootDirectory.FullName)) { continue; } @@ -1227,6 +1227,29 @@ protected override void GetItem(string path) } } + private static bool SafeDoesPathExist(string rootDirectory) + { + if (Directory.Exists(rootDirectory)) + { + return true; + } + + try + { + return (File.GetAttributes(rootDirectory) & FileAttributes.Directory) is not 0; + } + // In some scenarios (like AppContainers) direct access to the root directory may + // be prevented, but more specific paths may be accessible. + catch (UnauthorizedAccessException) + { + return true; + } + catch + { + return false; + } + } + private FileSystemInfo GetFileSystemItem(string path, ref bool isContainer, bool showHidden) { path = NormalizePath(path); From e2784b8867a368f78916829d0c25f2e9a1e2eba3 Mon Sep 17 00:00:00 2001 From: Patrick Meinecke Date: Mon, 20 Apr 2026 13:56:25 -0400 Subject: [PATCH 07/15] Update `MaxVisitCount` and `MaxHashtableKeyCount` if `VisitorSafeValueContext` indicates `SkipLimitCheck` is true (#27306) Co-authored-by: Dongbo Wang --- .../engine/parser/SafeValues.cs | 14 +++++++++----- .../PowerShellData.tests.ps1 | 6 ++++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/System.Management.Automation/engine/parser/SafeValues.cs b/src/System.Management.Automation/engine/parser/SafeValues.cs index 05c87daab5b..38181168a66 100644 --- a/src/System.Management.Automation/engine/parser/SafeValues.cs +++ b/src/System.Management.Automation/engine/parser/SafeValues.cs @@ -47,11 +47,15 @@ public static bool IsAstSafe(Ast ast, GetSafeValueVisitor.SafeValueContext safeV internal IsSafeValueVisitor(GetSafeValueVisitor.SafeValueContext safeValueContext) { _safeValueContext = safeValueContext; + + bool skipSizeCheck = safeValueContext is GetSafeValueVisitor.SafeValueContext.SkipHashtableSizeCheck; + _maxVisitCount = skipSizeCheck ? uint.MaxValue : 5000; + _maxHashtableKeyCount = skipSizeCheck ? int.MaxValue : 500; } internal bool IsAstSafe(Ast ast) { - if ((bool)ast.Accept(this) && _visitCount < MaxVisitCount) + if ((bool)ast.Accept(this) && _visitCount < _maxVisitCount) { return true; } @@ -65,8 +69,8 @@ internal bool IsAstSafe(Ast ast) // This is a check of the number of visits private uint _visitCount = 0; - private const uint MaxVisitCount = 5000; - private const int MaxHashtableKeyCount = 500; + private readonly uint _maxVisitCount; + private readonly int _maxHashtableKeyCount; // Used to determine if we are being called within a GetPowerShell() context, // which does some additional security verification outside of the scope of @@ -330,7 +334,7 @@ public object VisitArrayLiteral(ArrayLiteralAst arrayLiteralAst) public object VisitHashtable(HashtableAst hashtableAst) { - if (hashtableAst.KeyValuePairs.Count > MaxHashtableKeyCount) + if (hashtableAst.KeyValuePairs.Count > _maxHashtableKeyCount) { return false; } @@ -373,7 +377,7 @@ public static object GetSafeValue(Ast ast, ExecutionContext context, SafeValueCo { t_context = context; - if (safeValueContext == SafeValueContext.SkipHashtableSizeCheck || IsSafeValueVisitor.IsAstSafe(ast, safeValueContext)) + if (IsSafeValueVisitor.IsAstSafe(ast, safeValueContext)) { return ast.Accept(new GetSafeValueVisitor()); } diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/PowerShellData.tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/PowerShellData.tests.ps1 index cfba4a4cbed..148993b69b1 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/PowerShellData.tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/PowerShellData.tests.ps1 @@ -49,4 +49,10 @@ Describe "Tests for the Import-PowerShellDataFile cmdlet" -Tags "CI" { $result = Import-PowerShellDataFile $largePsd1Path -SkipLimitCheck $result.Keys.Count | Should -Be 501 } + + It 'Fails if psd1 file is insecure while -SkipLimitCheck is used' { + $path = Setup -f insecure2.psd1 -Content '@{ Foo = [object] (calc.exe) }' -pass + { Import-PowerShellDataFile $path -SkipLimitCheck -ErrorAction Stop } | + Should -Throw -ErrorId "System.InvalidOperationException,Microsoft.PowerShell.Commands.ImportPowerShellDataFileCommand" + } } From 5093967db8e2eb9de77263514ad9aaaf62c5aff8 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Tue, 21 Apr 2026 12:05:36 -0700 Subject: [PATCH 08/15] Update Changelog for release v7.6.1 (#27304) --- CHANGELOG/7.6.md | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/CHANGELOG/7.6.md b/CHANGELOG/7.6.md index 47a8d33182f..cd09b76272c 100644 --- a/CHANGELOG/7.6.md +++ b/CHANGELOG/7.6.md @@ -1,5 +1,50 @@ # 7.6 Changelog +## [7.6.1] + +### General Cmdlet Updates and Fixes + +- Delay update notification for one week to ensure all packages become available (#27215) + +### Tests + +- Fix the `PSNativeCommandArgumentPassing` test (#27179) + +### Build and Packaging Improvements + +
+ + + +

Update to .NET SDK 10.0.202

+ +
+ +
    +
  • Fix PMC Repo URL for RHEL10 (#27061) (#27062)
  • +
  • Update branch for release (#27287)
  • +
  • Fix package pipeline by adding in PDP-Media directory (#27257)
  • +
  • Pin ready-to-merge.yml reusable workflow to commit SHA (#27245)
  • +
  • [StepSecurity] ci: Harden GitHub Actions tags (#27236)
  • +
  • Build, package, and create VPack for the PowerShell-LTS store package within the same msixbundle-vpack pipeline (#27237)
  • +
  • Change the display name of PowerShell-LTS package to PowerShell LTS (#27219)
  • +
  • [StepSecurity] ci: Harden GitHub Actions tokens (#27218)
  • +
  • Redo windows image fix to use latest image (#27217)
  • +
  • Add comment-based help documentation to build.psm1 functions (#27216)
  • +
  • Separate Store Package Creation, Skip Polling for Store Publish, Clean up PDP-Media (#27214)
  • +
  • Bump github/codeql-action from 4.34.1 to 4.35.1 (#27184)
  • +
  • Bump github/codeql-action from 4.32.6 to 4.34.1 (#27182)
  • +
  • Select New MSIX Package Name (#27183)
  • +
  • Update the PhoneProductId to be the official LTS id used by Store (#27181)
  • +
  • release-upload-buildinfo: replace version-comparison channel gating with metadata flags (#27180)
  • +
  • Move _GetDependencies MSBuild target from dynamic generation in build.psm1 into Microsoft.PowerShell.SDK.csproj (#27177)
  • +
  • Separate Official and NonOfficial templates for ADO pipelines (#27176)
  • +
+ +
+ +[7.6.1]: https://github.com/PowerShell/PowerShell/compare/v7.6.0...v7.6.1 + ## [7.6.0] ### General Cmdlet Updates and Fixes From 156906e0504ef82f566376ae53042a1b1f8debf1 Mon Sep 17 00:00:00 2001 From: Dongbo Wang Date: Tue, 21 Apr 2026 13:05:14 -0700 Subject: [PATCH 09/15] PMC release: Use slash instead of back-slash for Linux container (#27315) --- .pipelines/templates/release-prep-for-ev2.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pipelines/templates/release-prep-for-ev2.yml b/.pipelines/templates/release-prep-for-ev2.yml index e644bece68f..f73caa10450 100644 --- a/.pipelines/templates/release-prep-for-ev2.yml +++ b/.pipelines/templates/release-prep-for-ev2.yml @@ -23,7 +23,7 @@ stages: - group: 'mscodehub-code-read-akv' - group: 'packages.microsoft.com' - name: ob_sdl_credscan_suppressionsFile - value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json + value: $(Build.SourcesDirectory)/PowerShell/.config/suppress.json steps: - checkout: self ## the global setting on lfs didn't work lfs: false From d50bc2cb73304b18c0505e6d233d61ea361a1220 Mon Sep 17 00:00:00 2001 From: Justin Chung <124807742+jshigetomi@users.noreply.github.com> Date: Tue, 21 Apr 2026 15:29:46 -0500 Subject: [PATCH 10/15] Correct Variable Template Reference in NonOfficial Pipeline Templates (#27275) Co-authored-by: Justin Chung --- .github/agents/SplitADOPipelines.agent.md | 52 ++++++++++++------- ...Shell-Coordinated_Packages-NonOfficial.yml | 5 +- .../PowerShell-Packages-NonOfficial.yml | 4 +- .../PowerShell-Release-Azure-NonOfficial.yml | 2 +- .../PowerShell-Release-NonOfficial.yml | 4 +- .../PowerShell-vPack-NonOfficial.yml | 4 +- .../stages/PowerShell-vPack-Stages.yml | 2 +- 7 files changed, 45 insertions(+), 28 deletions(-) diff --git a/.github/agents/SplitADOPipelines.agent.md b/.github/agents/SplitADOPipelines.agent.md index 8322f473e7b..9454670061f 100644 --- a/.github/agents/SplitADOPipelines.agent.md +++ b/.github/agents/SplitADOPipelines.agent.md @@ -6,7 +6,7 @@ tools: ['vscode', 'execute', 'read', 'agent', 'edit', 'search', 'todo'] This agent will implement and restructure the repository's existing ADO pipelines into Official and NonOfficial pipelines. -A repository will have under the ./pipelines directory a series of yaml files that define the ADO pipelines for the repository. +A repository will have under the .pipelines directory a series of yaml files that define the ADO pipelines for the repository. First confirm if the pipelines are using a toggle switch for Official and NonOfficial. This will look something like this @@ -25,15 +25,31 @@ extends: This is an indicator that this work needs to be done. This toggle switch is no longer allowed and the templates need to be hard coded. +## Template Reference Convention (MUST follow) + +All `- template:` references to files **inside this repo** must use the **absolute** form anchored at the repo root, with the `@self` suffix: + +```yaml +- template: /.pipelines/templates//.yml@self +``` + +Do **not** use relative paths such as `templates/...`, `../templates/...`, or bare filenames. Rationale: + +- Absolute paths resolve identically regardless of where the referring file lives, so moving a pipeline file between directories (for example, into `.pipelines/NonOfficial/`) does not silently break includes. +- Relative paths are resolved by Azure DevOps against the directory of the referring file, which has caused real outages in this repo when a relative include was composed into a nonexistent nested path like `.pipelines/templates/stages/.pipelines/templates/...`. +- The majority of existing includes already use the absolute form; keeping new work consistent reduces review burden. + +The only acceptable non-absolute references are to external repositories resolved via the `resources.repositories` block, for example `v2/OneBranch.Official.CrossPlat.yml@onebranchTemplates`. + ## Refactoring Steps ### Step 1: Extract Shared Templates -For each pipeline file that uses the toggle switch pattern (e.g., `PowerShell-Packages.yml`): +For each pipeline file that uses the toggle switch pattern (e.g., `PowerShell-Packages-Official.yml`): -1. Create a `./pipelines/templates` directory if it doesn't exist -2. Extract the **variables section** into `./pipelines/templates/PowerShell-Packages-Variables.yml` -3. Extract the **stages section** into `./pipelines/templates/PowerShell-Packages-Stages.yml` +1. Create the `.pipelines/templates/variables` and `.pipelines/templates/stages` directories if they don't exist +2. Extract the **variables section** into `.pipelines/templates/variables/PowerShell-Packages-Variables.yml` +3. Extract the **stages section** into `.pipelines/templates/stages/PowerShell-Packages-Stages.yml` **IMPORTANT**: Only extract the `variables:` and `stages:` sections. All other sections (parameters, resources, extends, etc.) remain in the pipeline files. @@ -41,7 +57,7 @@ For each pipeline file that uses the toggle switch pattern (e.g., `PowerShell-Pa The original toggle-based file becomes the Official pipeline: -1. **Keep the file in its original location** (e.g., `./pipelines/PowerShell-Packages.yml` stays where it is) +1. **Keep the file in its original location** (e.g., `.pipelines/PowerShell-Packages-Official.yml` stays where it is) 2. Remove the toggle switch parameter (`templateFile` parameter) 3. Hard-code the Official template reference: ```yaml @@ -51,18 +67,18 @@ The original toggle-based file becomes the Official pipeline: 4. Replace the `variables:` section with a template reference: ```yaml variables: - - template: templates/PowerShell-Packages-Variables.yml + - template: /.pipelines/templates/variables/PowerShell-Packages-Variables.yml@self ``` 5. Replace the `stages:` section with a template reference: ```yaml stages: - - template: templates/PowerShell-Packages-Stages.yml + - template: /.pipelines/templates/stages/PowerShell-Packages-Stages.yml@self ``` ### Step 3: Create NonOfficial Pipeline -1. Create `./pipelines/NonOfficial` directory if it doesn't exist -2. Create the NonOfficial pipeline file (e.g., `./pipelines/NonOfficial/PowerShell-Packages-NonOfficial.yml`) +1. Create `.pipelines/NonOfficial` directory if it doesn't exist +2. Create the NonOfficial pipeline file (e.g., `.pipelines/NonOfficial/PowerShell-Packages-NonOfficial.yml`) 3. Copy the structure from the refactored Official pipeline 4. Hard-code the NonOfficial template reference: ```yaml @@ -72,13 +88,13 @@ The original toggle-based file becomes the Official pipeline: 5. Reference the same shared templates: ```yaml variables: - - template: ../templates/PowerShell-Packages-Variables.yml + - template: /.pipelines/templates/variables/PowerShell-Packages-Variables.yml@self stages: - - template: ../templates/PowerShell-Packages-Stages.yml + - template: /.pipelines/templates/stages/PowerShell-Packages-Stages.yml@self ``` -**Note**: The NonOfficial pipeline uses `../templates/` because it's one directory deeper than the Official pipeline. +**Note**: Always use **absolute** template paths of the form `/.pipelines/templates/...@self`. Do not use relative paths like `templates/...` or `../templates/...`. Absolute paths are anchored at the repo root and resolve consistently from any referring file, preventing breakage when files are moved between directories. ### Step 4: Link NonOfficial Pipelines to NonOfficial Dependencies @@ -124,29 +140,29 @@ Then you must configure the `ob_release_environment` parameter when referencing #### Official Pipeline Configuration -In the Official pipeline (e.g., `./pipelines/PowerShell-Packages.yml`): +In the Official pipeline (e.g., `.pipelines/PowerShell-Packages-Official.yml`): ```yaml stages: - - template: templates/PowerShell-Packages-Stages.yml + - template: /.pipelines/templates/stages/PowerShell-Packages-Stages.yml@self parameters: ob_release_environment: Production ``` #### NonOfficial Pipeline Configuration -In the NonOfficial pipeline (e.g., `./pipelines/NonOfficial/PowerShell-Packages-NonOfficial.yml`): +In the NonOfficial pipeline (e.g., `.pipelines/NonOfficial/PowerShell-Packages-NonOfficial.yml`): ```yaml stages: - - template: ../templates/PowerShell-Packages-Stages.yml + - template: /.pipelines/templates/stages/PowerShell-Packages-Stages.yml@self parameters: ob_release_environment: Test ``` #### Update Stages Template to Accept Parameter -The extracted stages template (e.g., `./pipelines/templates/PowerShell-Packages-Stages.yml`) must declare the parameter at the top: +The extracted stages template (e.g., `.pipelines/templates/stages/PowerShell-Packages-Stages.yml`) must declare the parameter at the top: ```yaml parameters: diff --git a/.pipelines/NonOfficial/PowerShell-Coordinated_Packages-NonOfficial.yml b/.pipelines/NonOfficial/PowerShell-Coordinated_Packages-NonOfficial.yml index 0b417df5c05..69506750c34 100644 --- a/.pipelines/NonOfficial/PowerShell-Coordinated_Packages-NonOfficial.yml +++ b/.pipelines/NonOfficial/PowerShell-Coordinated_Packages-NonOfficial.yml @@ -45,7 +45,7 @@ resources: ref: refs/heads/main variables: - - template: ./pipelines/templates/variables/PowerShell-Coordinated_Packages-Variables.yml@self + - template: /.pipelines/templates/variables/PowerShell-Coordinated_Packages-Variables.yml@self parameters: InternalSDKBlobURL: ${{ parameters.InternalSDKBlobURL }} ReleaseTagVar: ${{ parameters.ReleaseTagVar }} @@ -61,6 +61,7 @@ extends: LinuxHostVersion: Network: KS3 WindowsHostVersion: + Version: 2022 Network: KS3 incrementalSDLBinaryAnalysis: true globalSdl: @@ -90,7 +91,7 @@ extends: tsaOptionsFile: .config\tsaoptions.json stages: - - template: ./pipelines/templates/stages/PowerShell-Coordinated_Packages-Stages.yml@self + - template: /.pipelines/templates/stages/PowerShell-Coordinated_Packages-Stages.yml@self parameters: RUN_WINDOWS: ${{ parameters.RUN_WINDOWS }} RUN_TEST_AND_RELEASE: ${{ parameters.RUN_TEST_AND_RELEASE }} diff --git a/.pipelines/NonOfficial/PowerShell-Packages-NonOfficial.yml b/.pipelines/NonOfficial/PowerShell-Packages-NonOfficial.yml index 9419d3f29b5..0993cd69546 100644 --- a/.pipelines/NonOfficial/PowerShell-Packages-NonOfficial.yml +++ b/.pipelines/NonOfficial/PowerShell-Packages-NonOfficial.yml @@ -31,7 +31,7 @@ parameters: # parameters are shown up in ADO UI in a build queue time name: pkgs-$(BUILD.SOURCEBRANCHNAME)-nonofficial-$(Build.BuildId) variables: - - template: ./pipelines/templates/variables/PowerShell-Packages-Variables.yml@self + - template: /.pipelines/templates/variables/PowerShell-Packages-Variables.yml@self parameters: debug: ${{ parameters.debug }} ForceAzureBlobDelete: ${{ parameters.ForceAzureBlobDelete }} @@ -92,6 +92,6 @@ extends: enabled: false tsaOptionsFile: .config\tsaoptions.json stages: - - template: ./pipelines/templates/stages/PowerShell-Packages-Stages.yml@self + - template: /.pipelines/templates/stages/PowerShell-Packages-Stages.yml@self parameters: OfficialBuild: false diff --git a/.pipelines/NonOfficial/PowerShell-Release-Azure-NonOfficial.yml b/.pipelines/NonOfficial/PowerShell-Release-Azure-NonOfficial.yml index b524cb0ff81..4d406fbf9d5 100644 --- a/.pipelines/NonOfficial/PowerShell-Release-Azure-NonOfficial.yml +++ b/.pipelines/NonOfficial/PowerShell-Release-Azure-NonOfficial.yml @@ -17,7 +17,7 @@ parameters: # parameters are shown up in ADO UI in a build queue time name: ev2-$(BUILD.SOURCEBRANCHNAME)-nonofficial-$(Build.BuildId) variables: - - template: ./pipelines/templates/variables/PowerShell-Release-Azure-Variables.yml@self + - template: /.pipelines/templates/variables/PowerShell-Release-Azure-Variables.yml@self parameters: debug: ${{ parameters.debug }} diff --git a/.pipelines/NonOfficial/PowerShell-Release-NonOfficial.yml b/.pipelines/NonOfficial/PowerShell-Release-NonOfficial.yml index 7864513fc2c..ebfc599e42a 100644 --- a/.pipelines/NonOfficial/PowerShell-Release-NonOfficial.yml +++ b/.pipelines/NonOfficial/PowerShell-Release-NonOfficial.yml @@ -33,7 +33,7 @@ parameters: # parameters are shown up in ADO UI in a build queue time name: release-$(BUILD.SOURCEBRANCHNAME)-nonofficial-$(Build.BuildId) variables: - - template: ./pipelines/templates/variables/PowerShell-Release-Variables.yml@self + - template: /.pipelines/templates/variables/PowerShell-Release-Variables.yml@self parameters: debug: ${{ parameters.debug }} ReleaseTagVar: ${{ parameters.ReleaseTagVar }} @@ -98,7 +98,7 @@ extends: tsaOptionsFile: .config\tsaoptions.json stages: - - template: ./pipelines/templates/stages/PowerShell-Release-Stages.yml@self + - template: /.pipelines/templates/stages/PowerShell-Release-Stages.yml@self parameters: releaseEnvironment: Test SkipPublish: ${{ parameters.SkipPublish }} diff --git a/.pipelines/NonOfficial/PowerShell-vPack-NonOfficial.yml b/.pipelines/NonOfficial/PowerShell-vPack-NonOfficial.yml index f1f4211ca8f..071db02cff8 100644 --- a/.pipelines/NonOfficial/PowerShell-vPack-NonOfficial.yml +++ b/.pipelines/NonOfficial/PowerShell-vPack-NonOfficial.yml @@ -33,7 +33,7 @@ parameters: # parameters are shown up in ADO UI in a build queue time name: vPack_$(Build.SourceBranchName)_NonOfficial_Create.${{ parameters.createVPack }}_Name.${{ parameters.vPackName}}_$(date:yyyyMMdd).$(rev:rr) variables: - - template: ./pipelines/templates/variables/PowerShell-vPack-Variables.yml@self + - template: /.pipelines/templates/variables/PowerShell-vPack-Variables.yml@self parameters: debug: ${{ parameters.debug }} ReleaseTagVar: ${{ parameters.ReleaseTagVar }} @@ -82,7 +82,7 @@ extends: enabled: false tsaOptionsFile: .config/tsaoptions.json stages: - - template: ./pipelines/templates/stages/PowerShell-vPack-Stages.yml@self + - template: /.pipelines/templates/stages/PowerShell-vPack-Stages.yml@self parameters: createVPack: ${{ parameters.createVPack }} vPackName: ${{ parameters.vPackName }} diff --git a/.pipelines/templates/stages/PowerShell-vPack-Stages.yml b/.pipelines/templates/stages/PowerShell-vPack-Stages.yml index f0d49e8b489..01a83a5b161 100644 --- a/.pipelines/templates/stages/PowerShell-vPack-Stages.yml +++ b/.pipelines/templates/stages/PowerShell-vPack-Stages.yml @@ -50,7 +50,7 @@ stages: env: ob_restore_phase: true - - template: .pipelines/templates/SetVersionVariables.yml@self + - template: /.pipelines/templates/SetVersionVariables.yml@self parameters: ReleaseTagVar: $(ReleaseTagVar) CreateJson: yes From 63544d18bcb533623ddf9d442302a881803adc8b Mon Sep 17 00:00:00 2001 From: Justin Chung <124807742+jshigetomi@users.noreply.github.com> Date: Wed, 22 Apr 2026 15:25:39 -0500 Subject: [PATCH 11/15] Download PMC Packages through `TemplateContext` (#27326) Co-authored-by: Justin Chung --- .../PowerShell-Release-Azure-NonOfficial.yml | 8 ++- .../PowerShell-Release-Official-Azure.yml | 2 +- .pipelines/templates/release-prep-for-ev2.yml | 46 ++++++------- .pipelines/templates/release-publish-pmc.yml | 65 ++++++++++++------- 4 files changed, 70 insertions(+), 51 deletions(-) diff --git a/.pipelines/NonOfficial/PowerShell-Release-Azure-NonOfficial.yml b/.pipelines/NonOfficial/PowerShell-Release-Azure-NonOfficial.yml index 4d406fbf9d5..b0bb4d79b39 100644 --- a/.pipelines/NonOfficial/PowerShell-Release-Azure-NonOfficial.yml +++ b/.pipelines/NonOfficial/PowerShell-Release-Azure-NonOfficial.yml @@ -67,10 +67,16 @@ extends: exactToolVersion: 4.4.2 policheck: break: true # always break the build on policheck issues. You can disable it by setting to 'false' - tsaOptionsFile: .config\tsaoptions.json + tsaOptionsFile: $(Build.SourcesDirectory)\.config\tsaoptions.json stages: - template: /.pipelines/templates/release-prep-for-ev2.yml@self parameters: skipPublish: ${{ parameters.skipPublish }} + # NonOfficial: run the publish stage to verify templateContext artifact download, + # but skip the actual Ev2 push to PMC. - template: /.pipelines/templates/release-publish-pmc.yml@self + parameters: + releaseEnvironment: Test + stagePrefix: Test + skipEv2Push: true diff --git a/.pipelines/PowerShell-Release-Official-Azure.yml b/.pipelines/PowerShell-Release-Official-Azure.yml index 24040a2463d..b5f57438925 100644 --- a/.pipelines/PowerShell-Release-Official-Azure.yml +++ b/.pipelines/PowerShell-Release-Official-Azure.yml @@ -67,7 +67,7 @@ extends: exactToolVersion: 4.4.2 policheck: break: true # always break the build on policheck issues. You can disable it by setting to 'false' - tsaOptionsFile: .config\tsaoptions.json + tsaOptionsFile: $(Build.SourcesDirectory)\.config\tsaoptions.json stages: - template: /.pipelines/templates/release-prep-for-ev2.yml@self parameters: diff --git a/.pipelines/templates/release-prep-for-ev2.yml b/.pipelines/templates/release-prep-for-ev2.yml index f73caa10450..3ad716a3af4 100644 --- a/.pipelines/templates/release-prep-for-ev2.yml +++ b/.pipelines/templates/release-prep-for-ev2.yml @@ -11,6 +11,20 @@ stages: displayName: 'Copy EV2 Files to Artifact' pool: type: linux + templateContext: + inputs: + - input: pipelineArtifact + pipeline: PSPackagesOfficial + artifactName: drop_linux_package_deb + - input: pipelineArtifact + pipeline: PSPackagesOfficial + artifactName: drop_linux_package_rpm + - input: pipelineArtifact + pipeline: PSPackagesOfficial + artifactName: drop_linux_package_mariner_x64 + - input: pipelineArtifact + pipeline: PSPackagesOfficial + artifactName: drop_linux_package_mariner_arm64 variables: - name: ob_outputDirectory value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT' @@ -24,6 +38,8 @@ stages: - group: 'packages.microsoft.com' - name: ob_sdl_credscan_suppressionsFile value: $(Build.SourcesDirectory)/PowerShell/.config/suppress.json + - name: ob_sdl_tsa_configFile + value: $(Build.SourcesDirectory)/PowerShell/.config/tsaoptions.json steps: - checkout: self ## the global setting on lfs didn't work lfs: false @@ -99,39 +115,17 @@ stages: env: ob_restore_phase: true - - download: PSPackagesOfficial - artifact: 'drop_linux_package_deb' - displayName: 'Download artifact containing .deb_amd64.deb file from PSPackagesOfficial triggering pipeline' - env: - ob_restore_phase: true - - - download: PSPackagesOfficial - artifact: 'drop_linux_package_rpm' - displayName: 'Download artifact containing .rh.x64_86.rpm file from PSPackagesOfficial triggering pipeline' - env: - ob_restore_phase: true - - - download: PSPackagesOfficial - artifact: 'drop_linux_package_mariner_x64' - displayName: 'Download artifact containing .cm.x86_64.rpm file from PSPackagesOfficial triggering pipeline' - env: - ob_restore_phase: true - - - download: PSPackagesOfficial - artifact: 'drop_linux_package_mariner_arm64' - displayName: 'Download artifact containing .cm.aarch64.rpm file from PSPackagesOfficial triggering pipeline' - env: - ob_restore_phase: true - - pwsh: | Write-Verbose -Verbose "Copy ESRP signed .deb and .rpm packages" - $downloadedPipelineFolder = Join-Path '$(Pipeline.Workspace)' -ChildPath 'PSPackagesOfficial' + # templateContext.inputs places the PSPackagesOfficial pipelineArtifact files + # directly under $(Pipeline.Workspace), not in per-artifact subfolders. + $downloadedPipelineFolder = '$(Pipeline.Workspace)' $srcFilesFolder = Join-Path -Path '$(Pipeline.Workspace)' -ChildPath 'SourceFiles' New-Item -Path $srcFilesFolder -ItemType Directory $packagesFolder = Join-Path -Path $srcFilesFolder -ChildPath 'packages' New-Item -Path $packagesFolder -ItemType Directory - $packageFiles = Get-ChildItem -Path $downloadedPipelineFolder -Recurse -Directory -Filter "drop_*" | Get-ChildItem -File -Include *.deb, *.rpm + $packageFiles = Get-ChildItem -Path $downloadedPipelineFolder -File | Where-Object { $_.Extension -in '.deb', '.rpm' } foreach ($file in $packageFiles) { Write-Verbose -Verbose "copying file: $($file.FullName)" diff --git a/.pipelines/templates/release-publish-pmc.yml b/.pipelines/templates/release-publish-pmc.yml index d5454845211..dc7fc8534e3 100644 --- a/.pipelines/templates/release-publish-pmc.yml +++ b/.pipelines/templates/release-publish-pmc.yml @@ -1,37 +1,56 @@ +parameters: +- name: releaseEnvironment + type: string + default: Production + values: + - Production + - PPE + - Test +- name: approvalServiceEnvironment + type: string + default: Production + values: + - Production + - PPE + - Test +# OneBranch requires the stage name to be prefixed with the release environment. +# Official uses 'Prod' for Production; NonProd validators require '' (e.g. 'Test', 'PPE'). +- name: stagePrefix + type: string + default: Prod +# When true, the Ev2 push step is skipped. Useful for NonOfficial dry-runs that +# only want to validate artifact download via templateContext.inputs. +- name: skipEv2Push + type: boolean + default: false + stages: -- stage: 'Prod_Release' +- stage: ${{ parameters.stagePrefix }}_Release displayName: 'Deploy packages to PMC with EV2' dependsOn: - PrepForEV2 variables: - name: ob_release_environment - value: "Production" + value: ${{ parameters.releaseEnvironment }} - name: repoRoot value: $(Build.SourcesDirectory) jobs: - - job: Prod_ReleaseJob + - job: ${{ parameters.stagePrefix }}_ReleaseJob displayName: Publish to PMC pool: type: release - - steps: - - task: DownloadPipelineArtifact@2 + templateContext: inputs: - targetPath: '$(Pipeline.Workspace)' - artifact: drop_PrepForEV2_CopyEv2FilesToArtifact - displayName: 'Download drop_PrepForEV2_CopyEv2FilesToArtifact artifact that has all files needed' + - input: pipelineArtifact + artifactName: drop_PrepForEV2_CopyEv2FilesToArtifact - - task: DownloadPipelineArtifact@2 - inputs: - buildType: 'current' - targetPath: '$(Pipeline.Workspace)' - displayName: 'Download to get EV2 Files' - - - task: vsrm-ev2.vss-services-ev2.adm-release-task.ExpressV2Internal@1 - displayName: 'Ev2: Push to PMC' - inputs: - UseServerMonitorTask: true - EndpointProviderType: ApprovalService - ApprovalServiceEnvironment: Production - ServiceRootPath: '$(Pipeline.Workspace)/drop_PrepForEV2_CopyEV2FilesToArtifact/EV2Specs/ServiceGroupRoot' - RolloutSpecPath: '$(Pipeline.Workspace)/drop_PrepForEV2_CopyEV2FilesToArtifact/EV2Specs/ServiceGroupRoot/RolloutSpec.json' + steps: + - ${{ if not(parameters.skipEv2Push) }}: + - task: vsrm-ev2.vss-services-ev2.adm-release-task.ExpressV2Internal@1 + displayName: 'Ev2: Push to PMC' + inputs: + UseServerMonitorTask: true + EndpointProviderType: ApprovalService + ApprovalServiceEnvironment: ${{ parameters.approvalServiceEnvironment }} + ServiceRootPath: '$(Pipeline.Workspace)/EV2Specs/ServiceGroupRoot' + RolloutSpecPath: '$(Pipeline.Workspace)/EV2Specs/ServiceGroupRoot/RolloutSpec.json' From 8ac408a172b8d1e0cd440276bf4d6fe921512355 Mon Sep 17 00:00:00 2001 From: Patrick Meinecke Date: Wed, 22 Apr 2026 16:42:08 -0400 Subject: [PATCH 12/15] Update CHANGELOG for v7.4.15 (#27314) --- CHANGELOG/7.4.md | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/CHANGELOG/7.4.md b/CHANGELOG/7.4.md index f999c20315f..eb506a7ddbc 100644 --- a/CHANGELOG/7.4.md +++ b/CHANGELOG/7.4.md @@ -1,5 +1,56 @@ # 7.4 Changelog +## [7.4.15] + +### General Cmdlet Updates and Fixes + +- Delay update notification for one week to ensure all packages become available (#27229) +- Close pipe client handles after creating the child ssh process (#27139) + +### Tests + +- Fix the `PSNativeCommandArgumentPassing` test (#27146) + +### Build and Packaging Improvements + +
+ + + +

Update .NET SDK to 8.0.420

+ +
+ +
    +
  • Fix the container image for vPack, MSIX vPack and Package pipelines (#27018)
  • +
  • Update branch for release (#27279)
  • +
  • Fix package pipeline by adding in PDP-Media directory (#27255)
  • +
  • Pin ready-to-merge.yml reusable workflow to commit SHA (#27247)
  • +
  • [StepSecurity] ci: Harden GitHub Actions tags (#27244)
  • +
  • Build, package, and create VPack for the PowerShell-LTS store package within the same msixbundle-vpack pipeline (#27242)
  • +
  • Change the display name of PowerShell-LTS package to PowerShell LTS (#27232)
  • +
  • [StepSecurity] ci: Harden GitHub Actions tokens (#27231)
  • +
  • Redo windows image fix to use latest image (#27230)
  • +
  • Separate Store Package Creation, Skip Polling for Store Publish, Clean up PDP-Media (#27228)
  • +
  • Add comment-based help documentation to build.psm1 functions (#27227)
  • +
  • Fix a preview detection test for the packaging script (#27226)
  • +
  • Update the PhoneProductId to be the official LTS id used by Store (#27169)
  • +
  • Select New MSIX Package Name (#27173)
  • +
  • Publish .msixbundle package as a VPack (#27187)
  • +
  • Bump github/codeql-action from 4.32.4 to 4.35.1 (#27143) (#27171) (#27175)
  • +
  • release-upload-buildinfo: replace version-comparison channel gating with metadata flags (#27147)
  • +
  • Create infrastructure to create two msixs and msixbundles for LTS and Stable (#27145)
  • +
  • Move _GetDependencies MSBuild target from dynamic generation in build.psm1 into Microsoft.PowerShell.SDK.csproj (#27144)
  • +
  • Bump actions/dependency-review-action from 4.8.3 to 4.9.0 (#27142)
  • +
  • Bump actions/upload-artifact from 6 to 7 (#27141)
  • +
  • Separate Official and NonOfficial templates for ADO pipelines (#27140)
  • +
  • Mirror .NET/runtime ICU version range in PowerShell (#27138)
  • +
+ +
+ +[7.4.15]: https://github.com/PowerShell/PowerShell/compare/v7.4.14...v7.4.15 + ## [7.4.14] ### General Cmdlet Updates and Fixes From 17996679387097b0942e8bea6a155e837ba191ca Mon Sep 17 00:00:00 2001 From: Dongbo Wang Date: Wed, 22 Apr 2026 13:42:33 -0700 Subject: [PATCH 13/15] Update changelog for the v7.5.6 release (#27320) --- CHANGELOG/7.5.md | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/CHANGELOG/7.5.md b/CHANGELOG/7.5.md index d908532ff82..b4f173bcff6 100644 --- a/CHANGELOG/7.5.md +++ b/CHANGELOG/7.5.md @@ -1,5 +1,54 @@ # 7.5 Changelog +## [7.5.6] + +### General Cmdlet Updates and Fixes + +- Delay update notification for one week to ensure all packages become available (#27220) + +### Tests + +- Fix the `PSNativeCommandArgumentPassing` test (#27166) + +### Build and Packaging Improvements + +
+ + + +

Update to .NET SDK 9.0.313

+ +
+ +
    +
  • Update branch for the v7.5.6 release (#27268)
  • +
  • Fix package pipeline by adding in PDP-Media directory (#27256)
  • +
  • Pin ready-to-merge.yml reusable workflow to commit SHA (#27246)
  • +
  • [StepSecurity] ci: Harden GitHub Actions tags (#27239)
  • +
  • Build, package, and create VPack for the PowerShell-LTS store package within the same msixbundle-vpack pipeline (#27240)
  • +
  • Add comment-based help documentation to build.psm1 functions (#27221)
  • +
  • Separate store package creation, skip polling for store publish, clean up PDP-Media (#27225)
  • +
  • [StepSecurity] ci: Harden GitHub Actions tokens (#27224)
  • +
  • Change the display name of "PowerShell-LTS" package to "PowerShell LTS" (#27223)
  • +
  • Redo windows image fix to use latest image (#27222)
  • +
  • Bump github/codeql-action from 4.32.4 to 4.35.1 (#27159) (#27170) (#27174)
  • +
  • Select new MSIX package name (#27172)
  • +
  • Update the PhoneProductId to be the official LTS id used by Store (#27168)
  • +
  • release-upload-buildinfo: replace version-comparison channel gating with metadata flags (#27167)
  • +
  • Create infrastructure to create two msixs and msixbundles for LTS and Stable (#27165)
  • +
  • Move _GetDependencies MSBuild target from dynamic generation in build.psm1 into Microsoft.PowerShell.SDK.csproj (#27164)
  • +
  • Create Linux LTS deb/rpm packages for LTS releases (#27163)
  • +
  • Fix the container image for vPack, MSIX vPack and Package pipelines (#27161)
  • +
  • Create LTS pkg and non-LTS pkg for macOS for LTS releases (#27162)
  • +
  • Bump actions/dependency-review-action from 4.8.3 to 4.9.0 (#27158)
  • +
  • Bump actions/upload-artifact from 6 to 7 (#27157)
  • +
  • Separate "Official" and "NonOfficial" templates for ADO pipelines (#27155)
  • +
+ +
+ +[7.5.6]: https://github.com/PowerShell/PowerShell/compare/v7.5.5...v7.5.6 + ## [7.5.5] ### Engine Updates and Fixes From 0458f16cc5acd475170afdd546d19021af590e9e Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Fri, 24 Apr 2026 12:33:53 -0400 Subject: [PATCH 14/15] Remove mariner2.0 from PMC mapping (#27068) Co-authored-by: Justin Chung <124807742+jshigetomi@users.noreply.github.com> --- tools/packages.microsoft.com/mapping.json | 32 ----------------------- 1 file changed, 32 deletions(-) diff --git a/tools/packages.microsoft.com/mapping.json b/tools/packages.microsoft.com/mapping.json index 154a9582872..7cb212ffee3 100644 --- a/tools/packages.microsoft.com/mapping.json +++ b/tools/packages.microsoft.com/mapping.json @@ -28,38 +28,6 @@ ], "PackageFormat": "PACKAGE_NAME-POWERSHELL_RELEASE-1.rh.x86_64.rpm" }, - { - "url": "cbl-mariner-2.0-prod-Microsoft-aarch64", - "distribution": [ - "bionic" - ], - "PackageFormat": "PACKAGE_NAME-POWERSHELL_RELEASE-1.cm.aarch64.rpm", - "channel": "stable" - }, - { - "url": "cbl-mariner-2.0-prod-Microsoft-x86_64", - "distribution": [ - "bionic" - ], - "PackageFormat": "PACKAGE_NAME-POWERSHELL_RELEASE-1.cm.x86_64.rpm", - "channel": "stable" - }, - { - "url": "cbl-mariner-2.0-preview-Microsoft-aarch64", - "distribution": [ - "bionic" - ], - "PackageFormat": "PACKAGE_NAME-POWERSHELL_RELEASE-1.cm.aarch64.rpm", - "channel": "preview" - }, - { - "url": "cbl-mariner-2.0-preview-Microsoft-x86_64", - "distribution": [ - "bionic" - ], - "PackageFormat": "PACKAGE_NAME-POWERSHELL_RELEASE-1.cm.x86_64.rpm", - "channel": "preview" - }, { "url": "azurelinux-3.0-prod-ms-oss-aarch64", "distribution": [ From 65e6a8055cf5c4bee0911411cdba667bacad2d9d Mon Sep 17 00:00:00 2001 From: Dongbo Wang Date: Fri, 24 Apr 2026 09:52:06 -0700 Subject: [PATCH 15/15] Update PowerShell telemetry to respect the diagnostics and feedback setting on Windows (#27328) --- .../PowerShell.Core.Instrumentation.man | 202 +++++++++++++++--- .../CoreCLR/CorePsPlatform.cs | 9 +- .../engine/remoting/common/PSETWTracer.cs | 4 + .../utils/Telemetry.cs | 10 +- .../utils/WindowsDataCollectionSetting.cs | 185 ++++++++++++++++ .../engine/Basic/Telemetry.Tests.ps1 | 50 +++++ 6 files changed, 427 insertions(+), 33 deletions(-) create mode 100644 src/System.Management.Automation/utils/WindowsDataCollectionSetting.cs diff --git a/src/PowerShell.Core.Instrumentation/PowerShell.Core.Instrumentation.man b/src/PowerShell.Core.Instrumentation/PowerShell.Core.Instrumentation.man index fb221cfe964..bb4e15351e5 100644 --- a/src/PowerShell.Core.Instrumentation/PowerShell.Core.Instrumentation.man +++ b/src/PowerShell.Core.Instrumentation/PowerShell.Core.Instrumentation.man @@ -121,6 +121,18 @@ value="0x3002" version="1" /> + + - + + @@ -2409,6 +2445,12 @@ symbol="T_EXPERIMENTALFEATURE" value="107" /> + - + + @@ -2593,11 +2647,23 @@ name="PSWorkflow" symbol="K_PSWORKFLOW" /> - + + @@ -4004,6 +4070,20 @@ name="StackTrace" /> + - + + + @@ -5535,6 +5647,14 @@ id="PS_PROVIDER.task.T_ExperimentalFeature.message" value="PowerShell Experimental Features" /> + + + + + + + + diff --git a/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs b/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs index 8be65502543..4cbb346fb14 100644 --- a/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs +++ b/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs @@ -179,9 +179,12 @@ public static bool IsStaSupported { int result = Interop.Windows.CoInitializeEx(IntPtr.Zero, Interop.Windows.COINIT_APARTMENTTHREADED); - // If 0 is returned the thread has been initialized for the first time - // as an STA and thus supported and needs to be uninitialized. - if (result > 0) + // Per COM documentation: Each successful call to CoInitializeEx (including S_FALSE) + // must be balanced by a corresponding call to CoUninitialize. + // - S_OK (0) means we initialized for the first time. + // - S_FALSE (1) means already initialized, but still increments the reference count. + // Both require CoUninitialize to decrement the reference count. + if (result >= 0) { Interop.Windows.CoUninitialize(); } diff --git a/src/System.Management.Automation/engine/remoting/common/PSETWTracer.cs b/src/System.Management.Automation/engine/remoting/common/PSETWTracer.cs index 2fd2dc0a913..989ad33e987 100644 --- a/src/System.Management.Automation/engine/remoting/common/PSETWTracer.cs +++ b/src/System.Management.Automation/engine/remoting/common/PSETWTracer.cs @@ -166,6 +166,9 @@ internal enum PSEventId : int ExperimentalFeature_InvalidName = 0x3001, ExperimentalFeature_ReadConfig_Error = 0x3002, + // Windows Diagnostics And Usage Data Settings + Telemetry_Setting_Error = 0x3011, + // Scheduled Jobs ScheduledJob_Start = 0xD001, ScheduledJob_Complete = 0xD002, @@ -240,6 +243,7 @@ internal enum PSTask : int ProviderStop = 0x69, ExecutePipeline = 0x6A, ExperimentalFeature = 0x6B, + Telemetry = 0x6C, ScheduledJob = 0x6E, NamedPipe = 0x6F, ISEOperation = 0x78, diff --git a/src/System.Management.Automation/utils/Telemetry.cs b/src/System.Management.Automation/utils/Telemetry.cs index 9a67f4bb6ed..fbb7f588283 100644 --- a/src/System.Management.Automation/utils/Telemetry.cs +++ b/src/System.Management.Automation/utils/Telemetry.cs @@ -177,12 +177,20 @@ public static class ApplicationInsightsTelemetry /// static ApplicationInsightsTelemetry() { - // If we can't send telemetry, there's no reason to do any of this CanSendTelemetry = !Utils.GetEnvironmentVariableAsBool(name: _telemetryOptoutEnvVar, defaultValue: false) && Platform.TryDeriveFromCache("telemetry.uuid", out s_uuidPath); +#if !UNIX + if (CanSendTelemetry) + { + // Respect the diagnostics and feedback setting in Windows. + CanSendTelemetry = WindowsDataCollectionSetting.CanCollectDiagnostics(PlatformDataCollectionLevel.Enhanced); + } +#endif + if (!CanSendTelemetry) { + // Avoid the initialization work if we can't send telemetry. return; } diff --git a/src/System.Management.Automation/utils/WindowsDataCollectionSetting.cs b/src/System.Management.Automation/utils/WindowsDataCollectionSetting.cs new file mode 100644 index 00000000000..5f8b607550a --- /dev/null +++ b/src/System.Management.Automation/utils/WindowsDataCollectionSetting.cs @@ -0,0 +1,185 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#if !UNIX + +using System; +using System.Management.Automation.Internal; +using System.Management.Automation.Tracing; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.Marshalling; + +namespace Microsoft.PowerShell.Telemetry; + +internal enum PlatformDataCollectionLevel : int +{ + /// + /// Minimum — only security-related data. Enterprise/education editions only. + /// + Security = 0, + + /// + /// Device info, capabilities, and basic reliability data. + /// + Basic = 1, + + /// + /// More detailed usage and reliability data, including app/feature usage patterns. + /// Removed as a user-facing option in Windows 11 (collapsed into Full). + /// + Enhanced = 2, + + /// + /// All of the above plus advanced diagnostics data that can help Microsoft fix problems. + /// + Full = 3, +} + +/// +/// Minimal projection of IInspectable, the base interface for all WinRT objects. +/// Slots 3–5 in every WinRT interface vtable (after IUnknown's QueryInterface/AddRef/Release). +/// +[GeneratedComInterface] +[Guid("AF86E2E0-B12D-4C6A-9C5A-D7AA65101E90")] +internal partial interface IInspectable +{ + void GetIids(out uint iidCount, out nint iids); + + nint GetRuntimeClassName(); + + int GetTrustLevel(); +} + +/// +/// Projection of the WinRT interface Windows.System.Profile.IPlatformDiagnosticsAndUsageDataSettingsStatics +/// (IID B6E24C1B-7B1C-4B32-8C62-A66597CE723A). +/// Vtable slots 6–9, following the three IInspectable slots. +/// +[GeneratedComInterface] +[Guid("B6E24C1B-7B1C-4B32-8C62-A66597CE723A")] +internal partial interface IPlatformDiagnosticsAndUsageDataSettingsStatics : IInspectable +{ + PlatformDataCollectionLevel GetCollectionLevel(); + + long AddCollectionLevelChanged(nint handler); + + void RemoveCollectionLevelChanged(long token); + + // WinRT marshals bool as a byte; use byte to avoid any MarshalAs ambiguity with the source generator. + byte CanCollectDiagnostics(PlatformDataCollectionLevel level); +} + +/// +/// Wraps Windows.System.Profile.PlatformDiagnosticsAndUsageDataSettings using compile-time COM interop +/// and source-generated P/Invoke. No extra runtime DLLs are required. +/// +internal static partial class WindowsDataCollectionSetting +{ + /// + /// Returns if the device's diagnostic data collection policy permits collecting at or above . + /// + /// The minimum to test against. + internal static bool CanCollectDiagnostics(PlatformDataCollectionLevel level) + { + const string ClassName = "Windows.System.Profile.PlatformDiagnosticsAndUsageDataSettings"; + + // When initializing WinRT on the calling thread, use the multi-threaded apartment (MTA). + // This is to cover the case where PowerShell gets used in a thread-pool thread. + // See the doc at https://learn.microsoft.com/windows/win32/api/roapi/ne-roapi-ro_init_type + const int RO_INIT_MULTITHREADED = 1; + + // Return values for 'RoInitialize': + // - S_OK (0) - we successfully initialized; must call 'RoUninitialize'. + // - S_FALSE (1) - already initialized with the same apartment type; must still call 'RoUninitialize'. + // - RPC_E_CHANGED_MODE - already initialized with a different apartment type; WinRT still works, do NOT call 'RoUninitialize'. + const int RPC_E_CHANGED_MODE = unchecked((int)0x80010106); + + int initHr = -1; + nint hstring = default; + nint factoryPtr = default; + + try + { + // Initialize WinRT on the calling thread. 'RoGetActivationFactory' requires it. + initHr = RoInitialize(RO_INIT_MULTITHREADED); + if (initHr < 0 && initHr != RPC_E_CHANGED_MODE) + { + // The call to initialize the Windows Runtime failed. + // Throw an exception with the HRESULT error code to provide more context on the failure. + Marshal.ThrowExceptionForHR(initHr); + } + + Marshal.ThrowExceptionForHR( + WindowsCreateString(ClassName, (uint)ClassName.Length, out hstring)); + + Guid iid = new("B6E24C1B-7B1C-4B32-8C62-A66597CE723A"); + Marshal.ThrowExceptionForHR( + RoGetActivationFactory(hstring, ref iid, out factoryPtr)); + + var comWrappers = new StrategyBasedComWrappers(); + var comObject = comWrappers.GetOrCreateObjectForComInstance(factoryPtr, CreateObjectFlags.None); + var platformSetting = (IPlatformDiagnosticsAndUsageDataSettingsStatics)comObject; + + return platformSetting.CanCollectDiagnostics(level) != 0; + } + catch (Exception ex) + { + // Log any exceptions that occur during this process, but swallow them and return false to disable telemetry rather than crashing the product. + // This API is only used to gate telemetry collection, so failure should be non-fatal. + PSEtwLog.LogOperationalError( + PSEventId.Telemetry_Setting_Error, + PSOpcode.Exception, + PSTask.Telemetry, + PSKeyword.UseAlwaysOperational, + ex.GetType().FullName, + ex.Message, + ex.StackTrace); + + return false; + } + finally + { + if (factoryPtr != default) + { + Marshal.Release(factoryPtr); + } + + if (hstring != default) + { + _ = WindowsDeleteString(hstring); + } + + // Per COM documentation: Each successful call to 'RoInitialize' (including S_FALSE) + // must be balanced by a corresponding call to 'RoUninitialize'. + if (initHr >= 0) + { + RoUninitialize(); + } + } + } + + [LibraryImport("api-ms-win-core-winrt-string-l1-1-0.dll", StringMarshalling = StringMarshalling.Utf16)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + private static partial int WindowsCreateString( + string sourceString, + uint length, + out nint hstring); + + [LibraryImport("api-ms-win-core-winrt-string-l1-1-0.dll")] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + private static partial int WindowsDeleteString(nint hstring); + + [LibraryImport("api-ms-win-core-winrt-l1-1-0.dll")] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + private static partial int RoGetActivationFactory(nint activatableClassId, ref Guid iid, out nint factory); + + [LibraryImport("api-ms-win-core-winrt-l1-1-0.dll")] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + private static partial int RoInitialize(int initType); + + [LibraryImport("api-ms-win-core-winrt-l1-1-0.dll")] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + private static partial void RoUninitialize(); +} + +#endif diff --git a/test/powershell/engine/Basic/Telemetry.Tests.ps1 b/test/powershell/engine/Basic/Telemetry.Tests.ps1 index 2378b9e5a66..0da08316a56 100644 --- a/test/powershell/engine/Basic/Telemetry.Tests.ps1 +++ b/test/powershell/engine/Basic/Telemetry.Tests.ps1 @@ -5,8 +5,53 @@ # these tests aren't going to check that telemetry is being sent # only that we're not treating the telemetry.uuid file correctly +function Get-OSTelemetryLevel { + <# + .SYNOPSIS + Returns the effective Windows Telemetry level (0-3). + Logic: Checks GPO overrides, then System preferences, then defaults to 1. + #> + + $gpoPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection" + $sysPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\DataCollection" + $valueName = "AllowTelemetry" + + # 1. Check the "Managed" Policy (Group Policy) + if (Test-Path $gpoPath) { + $gpoValue = Get-ItemProperty -Path $gpoPath -Name $valueName -ErrorAction SilentlyContinue + if ($gpoValue -and $gpoValue.$valueName) { + return [int]$gpoValue.$valueName + } + } + + # 2. Check the "User/System" Preference (Settings App) + if (Test-Path $sysPath) { + $sysValue = Get-ItemProperty -Path $sysPath -Name $valueName -ErrorAction SilentlyContinue + if ($sysValue -and $sysValue.$valueName) { + return [int]$sysValue.$valueName + } + } + + # 3. Fallback to OS Default (Basic/Required) + return 1 +} + Describe "Telemetry for shell startup" -Tag CI { BeforeAll { + $skipTelemetryTests = $false + + if ($IsWindows) { + ## Skip telemetry tests if the OS telemetry level is less than 2 (Enhanced) -- PS telemetry is disabled in this case. + $osTelemetryLevel = Get-OSTelemetryLevel + $skipTelemetryTests = $osTelemetryLevel -lt 2 + } + + if ($skipTelemetryTests) { + $originalDefaultParameterValues = $PSDefaultParameterValues.Clone() + $PSDefaultParameterValues["it:skip"] = $true + return + } + # if the telemetry file exists, move it out of the way # the member is internal, but we can retrieve it via reflection $cacheDir = [System.Management.Automation.Platform].GetField("CacheDirectory","NonPublic,Static").GetValue($null) @@ -23,6 +68,11 @@ Describe "Telemetry for shell startup" -Tag CI { } AfterAll { + if ($skipTelemetryTests) { + $global:PSDefaultParameterValues = $originalDefaultParameterValues + return + } + # check and reset the telemetry.uuid file if ( $uuidFileExists ) { if ( Test-Path -Path "${uuidPath}.original" ) {