Public/Tests/Get-IntunePackagingTool.Tests.ps1
|
BeforeAll { $env:TCS_CONFIG_ROOT = Join-Path -Path $TestDrive -ChildPath 'config' $env:TCS_SKIP_UPDATE_CHECK = '1' $env:TCS_TELEMETRY_OPTOUT = '1' $ModuleRoot = Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent Import-Module -Name (Join-Path -Path $ModuleRoot -ChildPath 'tcs.intune.packaging.psd1') -Force } AfterAll { Remove-Module -Name tcs.intune.packaging -Force -ErrorAction SilentlyContinue } Describe 'Get-IntunePackagingTool' { BeforeAll { # Builds a zip that looks like a GitHub release archive of the Win32 Content Prep Tool $ArchiveSource = Join-Path -Path $TestDrive -ChildPath 'archive-src' $null = New-Item -Path (Join-Path -Path $ArchiveSource -ChildPath 'Microsoft-Win32-Content-Prep-Tool-1.8.6') -ItemType Directory -Force Set-Content -Path (Join-Path -Path $ArchiveSource -ChildPath 'Microsoft-Win32-Content-Prep-Tool-1.8.6/IntuneWinAppUtil.exe') -Value 'tool' $ArchivePath = Join-Path -Path $TestDrive -ChildPath 'release.zip' Compress-Archive -Path (Join-Path -Path $ArchiveSource -ChildPath '*') -DestinationPath $ArchivePath # SHA256 of the file content 'tool' written by Set-Content (with the platform newline) $ToolHash = (Get-FileHash -Path (Join-Path -Path $ArchiveSource -ChildPath 'Microsoft-Win32-Content-Prep-Tool-1.8.6/IntuneWinAppUtil.exe') -Algorithm SHA256).Hash # Get-AuthenticodeSignature only exists on Windows; give Pester something to mock elsewhere $script:DefinedStub = $false if (-not (Get-Command -Name Get-AuthenticodeSignature -ErrorAction SilentlyContinue)) { function global:Get-AuthenticodeSignature { param($FilePath, $LiteralPath) } $script:DefinedStub = $true } } AfterAll { if ($script:DefinedStub) { Remove-Item -Path Function:\Get-AuthenticodeSignature -ErrorAction SilentlyContinue } } BeforeEach { Mock -ModuleName tcs.intune.packaging Invoke-WebRequest { Copy-Item -Path $ArchivePath -Destination $OutFile } Mock -ModuleName tcs.intune.packaging Invoke-RestMethod { [PSCustomObject]@{ tag_name = 'v9.9.9' } } Mock -ModuleName tcs.intune.packaging Get-AuthenticodeSignature { [PSCustomObject]@{ Status = 'Valid'; StatusMessage = 'Signature verified.'; SignerCertificate = [PSCustomObject]@{ Subject = 'CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US' } } } $Target = Join-Path -Path $TestDrive -ChildPath ([guid]::NewGuid().ToString()) } It 'Downloads the latest release and copies IntuneWinAppUtil.exe' { $file = Get-IntunePackagingTool -Path $Target $file.Name | Should -Be 'IntuneWinAppUtil.exe' Join-Path -Path $Target -ChildPath 'IntuneWinAppUtil.exe' | Should -Exist Should -Invoke -ModuleName tcs.intune.packaging Invoke-WebRequest -Times 1 -Exactly -ParameterFilter { $Uri -eq 'https://github.com/microsoft/Microsoft-Win32-Content-Prep-Tool/archive/refs/tags/v9.9.9.zip' } } It 'Downloads the requested tag' { $null = Get-IntunePackagingTool -Path $Target -DownloadTag 'v1.8.6' Should -Invoke -ModuleName tcs.intune.packaging Invoke-RestMethod -Times 0 -Exactly Should -Invoke -ModuleName tcs.intune.packaging Invoke-WebRequest -Times 1 -Exactly -ParameterFilter { $Uri -eq 'https://github.com/microsoft/Microsoft-Win32-Content-Prep-Tool/archive/refs/tags/v1.8.6.zip' } } It 'Refuses to overwrite an existing tool without -Force' { $null = Get-IntunePackagingTool -Path $Target -DownloadTag 'v1.8.6' { Get-IntunePackagingTool -Path $Target -DownloadTag 'v1.8.6' } | Should -Throw '*-Force*' { Get-IntunePackagingTool -Path $Target -DownloadTag 'v1.8.6' -Force } | Should -Not -Throw } It 'Throws instead of exiting the session when the download fails' { Mock -ModuleName tcs.intune.packaging Invoke-WebRequest { throw 'offline' } { Get-IntunePackagingTool -Path $Target -DownloadTag 'v1.8.6' } | Should -Throw '*offline*' } It 'Removes its temporary files' { $before = @(Get-ChildItem -Path ([System.IO.Path]::GetTempPath()) -Filter 'IntuneWinAppUtil-*' -ErrorAction SilentlyContinue).Count $null = Get-IntunePackagingTool -Path $Target -DownloadTag 'v1.8.6' @(Get-ChildItem -Path ([System.IO.Path]::GetTempPath()) -Filter 'IntuneWinAppUtil-*' -ErrorAction SilentlyContinue).Count | Should -Be $before } Context 'Verifying the download' { It 'Checks the Authenticode signature of the downloaded tool' { $null = Get-IntunePackagingTool -Path $Target -DownloadTag 'v1.8.6' Should -Invoke -ModuleName tcs.intune.packaging Get-AuthenticodeSignature -Times 1 -Exactly -ParameterFilter { $LiteralPath -like '*IntuneWinAppUtil.exe' } } It 'Refuses a tool without a valid signature' { Mock -ModuleName tcs.intune.packaging Get-AuthenticodeSignature { [PSCustomObject]@{ Status = 'NotSigned'; StatusMessage = 'Not signed.'; SignerCertificate = $null } } { Get-IntunePackagingTool -Path $Target -DownloadTag 'v1.8.6' } | Should -Throw '*valid Authenticode signature*' Join-Path -Path $Target -ChildPath 'IntuneWinAppUtil.exe' | Should -Not -Exist } It 'Refuses a tool signed by someone other than Microsoft' { Mock -ModuleName tcs.intune.packaging Get-AuthenticodeSignature { [PSCustomObject]@{ Status = 'Valid'; StatusMessage = ''; SignerCertificate = [PSCustomObject]@{ Subject = 'CN=Contoso, O=Not Microsoft Corporation Ltd' } } } { Get-IntunePackagingTool -Path $Target -DownloadTag 'v1.8.6' } | Should -Throw '*not by Microsoft Corporation*' Join-Path -Path $Target -ChildPath 'IntuneWinAppUtil.exe' | Should -Not -Exist } It 'Refuses a tool whose hash does not match -ExpectedSha256' { { Get-IntunePackagingTool -Path $Target -DownloadTag 'v1.8.6' -ExpectedSha256 ('0' * 64) } | Should -Throw '*does not match*' Join-Path -Path $Target -ChildPath 'IntuneWinAppUtil.exe' | Should -Not -Exist } It 'Accepts a tool whose hash matches -ExpectedSha256' { $file = Get-IntunePackagingTool -Path $Target -DownloadTag 'v1.8.6' -ExpectedSha256 $ToolHash.ToLowerInvariant() $file.Name | Should -Be 'IntuneWinAppUtil.exe' } It 'Requires -ExpectedSha256 where signatures cannot be checked' { Mock -ModuleName tcs.intune.packaging Get-Command { } -ParameterFilter { $Name -eq 'Get-AuthenticodeSignature' } { Get-IntunePackagingTool -Path $Target -DownloadTag 'v1.8.6' } | Should -Throw '*-ExpectedSha256*' $null = Get-IntunePackagingTool -Path $Target -DownloadTag 'v1.8.6' -ExpectedSha256 $ToolHash Join-Path -Path $Target -ChildPath 'IntuneWinAppUtil.exe' | Should -Exist } } } |