Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
msi.tests.ps1398 linesDownload Raw Back to windows
1# Copyright (c) Microsoft Corporation.2# Licensed under the MIT License.3 4Describe -Name "Windows MSI" -Fixture {5    BeforeAll {6        Set-StrictMode -Off7        function Test-Elevated {8            [CmdletBinding()]9            [OutputType([bool])]10            Param()11 12            # if the current Powershell session was called with administrator privileges,13            # the Administrator Group's well-known SID will show up in the Groups for the current identity.14            # Note that the SID won't show up unless the process is elevated.15            return (([Security.Principal.WindowsIdentity]::GetCurrent()).Groups -contains "S-1-5-32-544")16        }17 18        function Test-IsMuEnabled {19            $sm = (New-Object -ComObject Microsoft.Update.ServiceManager)20            $mu = $sm.Services | Where-Object { $_.ServiceId -eq '7971f918-a847-4430-9279-4a52d1efe18d' }21            if ($mu) {22                return $true23            }24            return $false25        }26 27        function Invoke-TestAndUploadLogOnFailure {28            param (29                [scriptblock] $Test30            )31 32            try {33                & $Test34            }35            catch {36                Send-VstsLogFile -Path $msiLog37                throw38            }39        }40 41        function Get-UseMU {42            $useMu = $null43            $key = 'HKLM:\SOFTWARE\Microsoft\PowerShellCore\'44            if ($runtime -like '*x86*') {45                $key = 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\PowerShellCore\'46            }47 48            try {49                $useMu = Get-ItemPropertyValue -Path $key -Name UseMU -ErrorAction SilentlyContinue50            } catch {}51 52            if (!$useMu) {53                $useMu = 054            }55 56            return $useMu57        }58 59        function Set-UseMU {60            param(61                [int]62                $Value63            )64            $key = 'HKLM:\SOFTWARE\Microsoft\PowerShellCore\'65            if ($runtime -like '*x86*') {66                $key = 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\PowerShellCore\'67            }68 69            Set-ItemProperty -Path $key -Name UseMU -Value $Value -Type DWord70 71            return $useMu72        }73 74        function Invoke-Msiexec {75            param(76                [Parameter(ParameterSetName = 'Install', Mandatory)]77                [Switch]$Install,78 79                [Parameter(ParameterSetName = 'Uninstall', Mandatory)]80                [Switch]$Uninstall,81 82                [Parameter(Mandatory)]83                [ValidateScript({Test-Path -Path $_})]84                [String]$MsiPath,85 86                [Parameter(ParameterSetName = 'Install')]87                [HashTable] $Properties88 89            )90            $action = "$($PSCmdlet.ParameterSetName)ing"91            if ($Install.IsPresent) {92                $switch = '/I'93            } else {94                $switch = '/x'95            }96 97            $additionalOptions = @()98            if ($Properties) {99                foreach ($key in $Properties.Keys) {100                    $additionalOptions += "$key=$($Properties.$key)"101                }102            }103 104            $argumentList = "$switch $MsiPath /quiet /l*vx $msiLog $additionalOptions"105            Write-Verbose -Message "running msiexec $argumentList"106            $msiExecProcess = Start-Process msiexec.exe -Wait -ArgumentList $argumentList -NoNewWindow -PassThru107            if ($msiExecProcess.ExitCode -ne 0) {108                $exitCode = $msiExecProcess.ExitCode109                throw "$action MSI failed and returned error code $exitCode."110            }111        }112 113        $msiX64Path = $env:PsMsiX64Path114        $channel = $env:PSMsiChannel115        $runtime = $env:PSMsiRuntime116        $muEnabled = Test-IsMuEnabled117 118        if ($runtime -like '*x86*') {119            $propertiesRegKeyParent = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\PowerShellCore"120        } else {121            $propertiesRegKeyParent = "HKLM:\SOFTWARE\Microsoft\PowerShellCore"122        }123 124        if ($channel -eq "preview") {125            $propertiesRegKeyName = "PreviewInstallerProperties"126        } else {127            $propertiesRegKeyName = "InstallerProperties"128        }129 130        # Rename the registry key that contains the saved installer131        # properties so that the tests don't overwrite them.132        $propertiesRegKeyPath = Join-Path -Path $propertiesRegKeyParent -ChildPath $propertiesRegKeyName133        $propertiesBackupRegKeyName = "BackupInstallerProperties"134        $propertiesBackupRegKeyPath = Join-Path -Path $propertiesRegKeyParent -ChildPath $propertiesBackupRegKeyName135        if (Test-Path -Path $propertiesRegKeyPath) {136            Rename-Item -Path $propertiesRegKeyPath -NewName $propertiesBackupRegKeyName137        }138 139        # Get any existing powershell in the path140        $beforePath = @(([System.Environment]::GetEnvironmentVariable('PATH', 'MACHINE')) -split ';' |141                Where-Object {$_ -like '*files\powershell*'})142 143        $msiLog = Join-Path -Path $TestDrive -ChildPath 'msilog.txt'144 145        foreach ($pathPart in $beforePath) {146            Write-Warning "Found existing PowerShell path: $pathPart"147        }148 149        if (!(Test-Elevated)) {150            Write-Warning "Tests must be elevated"151        }152        $uploadedLog = $false153    }154 155    AfterAll {156        Set-StrictMode -Version 3.0157 158        # Restore the original saved installer properties registry key.159        Remove-Item -Path $propertiesRegKeyPath -ErrorAction SilentlyContinue160        if (Test-Path -Path $propertiesBackupRegKeyPath) {161            Rename-Item -Path $propertiesBackupRegKeyPath -NewName $propertiesRegKeyName162        }163    }164 165    BeforeEach {166        $error.Clear()167        Remove-Item -Path $propertiesRegKeyPath -ErrorAction SilentlyContinue168    }169 170    Context "Upgrade code" {171        BeforeAll {172            Write-Verbose "cr-$channel-$runtime" -Verbose173            $pwshPath = Join-Path $env:ProgramFiles -ChildPath "PowerShell"174            $pwshx86Path = Join-Path ${env:ProgramFiles(x86)} -ChildPath "PowerShell"175            $regKeyPath = "HKLM:\SOFTWARE\Microsoft\PowerShellCore\InstalledVersions"176 177            switch ("$channel-$runtime") {178                "preview-win7-x64" {179                    $versionPath = Join-Path -Path $pwshPath -ChildPath '7-preview'180                    $revisionRange = 0, 99181                    $msiUpgradeCode = '39243d76-adaf-42b1-94fb-16ecf83237c8'182                    $regKeyPath = Join-Path $regKeyPath -ChildPath $msiUpgradeCode183                }184                "stable-win7-x64" {185                    $versionPath = Join-Path -Path $pwshPath -ChildPath '7'186                    $revisionRange = 500, 500187                    $msiUpgradeCode = '31ab5147-9a97-4452-8443-d9709f0516e1'188                    $regKeyPath = Join-Path $regKeyPath -ChildPath $msiUpgradeCode189                }190                "preview-win7-x86" {191                    $versionPath = Join-Path -Path $pwshx86Path -ChildPath '7-preview'192                    $revisionRange = 0, 99193                    $msiUpgradeCode = '86abcfbd-1ccc-4a88-b8b2-0facfde29094'194                    $regKeyPath = Join-Path $regKeyPath -ChildPath $msiUpgradeCode195                }196                "stable-win7-x86" {197                    $versionPath = Join-Path -Path $pwshx86Path -ChildPath '7'198                    $revisionRange = 500, 500199                    $msiUpgradeCode = '1d00683b-0f84-4db8-a64f-2f98ad42fe06'200                    $regKeyPath = Join-Path $regKeyPath -ChildPath $msiUpgradeCode201                }202                default {203                    throw "'$_' not a valid channel runtime combination"204                }205            }206        }207 208        It "$Channel MSI should not be installed before test" -Skip:(!(Test-Elevated)) {209            $result = @(Get-CimInstance -Query "SELECT Value FROM Win32_Property WHERE Property='UpgradeCode' and Value = '{$msiUpgradeCode}'")210            $result.Count | Should -Be 0 -Because "Query should return nothing if $channel $runtime is not installed"211        }212 213        It "MSI should install without error" -Skip:(!(Test-Elevated)) {214            {215                Invoke-MsiExec -Install -MsiPath $msiX64Path -Properties @{ADD_PATH = 1}216            } | Should -Not -Throw217        }218 219        It "Upgrade code should be correct" -Skip:(!(Test-Elevated)) {220            $result = @(Get-CimInstance -Query "SELECT Value FROM Win32_Property WHERE Property='UpgradeCode' and Value = '{$msiUpgradeCode}'")221            $result.Count | Should -Be 1 -Because "Query should return 1 result if Upgrade code is for $runtime $channel"222        }223 224        It "Revision should be in correct range" -Skip:(!(Test-Elevated)) {225            $pwshDllPath = Join-Path -Path $versionPath -ChildPath "pwsh.dll"226            [version] $version = (Get-ChildItem $pwshDllPath).VersionInfo.FileVersion227            Write-Verbose "pwsh.dll version: $version" -Verbose228            $version.Revision | Should -BeGreaterOrEqual $revisionRange[0] -Because "$channel revision should between $($revisionRange[0]) and $($revisionRange[1])"229            $version.Revision | Should -BeLessOrEqual $revisionRange[1] -Because "$channel revision should between $($revisionRange[0]) and $($revisionRange[1])"230        }231 232        It 'MSI should add ProductCode in registry' -Skip:(!(Test-Elevated)) {233 234            $productCode = if ($msiUpgradeCode -eq '39243d76-adaf-42b1-94fb-16ecf83237c8' -or235                $msiUpgradeCode -eq '31ab5147-9a97-4452-8443-d9709f0516e1') {236                # x64237                $regKeyPath | Should -Exist238                Get-ItemPropertyValue -Path $regKeyPath -Name 'ProductCode'239            } elseif ($msiUpgradeCode -eq '86abcfbd-1ccc-4a88-b8b2-0facfde29094' -or240                $msiUpgradeCode -eq '1d00683b-0f84-4db8-a64f-2f98ad42fe06') {241                # x86 - need to open the 32bit reghive242                $wow32RegKey = [Microsoft.Win32.RegistryKey]::OpenBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine, [Microsoft.Win32.RegistryView]::Registry32)243                $subKey = $wow32RegKey.OpenSubKey("Software\Microsoft\PowerShellCore\InstalledVersions\$msiUpgradeCode")244                $subKey.GetValue("ProductCode")245            }246 247            $productCode | Should -Not -BeNullOrEmpty248            $productCodeGuid = [Guid]$productCode249            $productCodeGuid | Should -BeOfType "Guid"250            $productCodeGuid.Guid | Should -Not -Be $msiUpgradeCode251        }252 253        It "MSI should uninstall without error" -Skip:(!(Test-Elevated)) {254            {255                Invoke-MsiExec -Uninstall -MsiPath $msiX64Path256            } | Should -Not -Throw257        }258    }259 260    Context "Add Path disabled" {261        BeforeAll {262            Set-UseMU -Value 0263        }264 265        It "UseMU should be 0 before install" -Skip:(!(Test-Elevated)) {266            $useMu = Get-UseMU267            $useMu | Should -Be 0268        }269 270        It "MSI should install without error" -Skip:(!(Test-Elevated)) {271            {272                Invoke-MsiExec -Install -MsiPath $msiX64Path -Properties @{ADD_PATH = 0; USE_MU = 1; ENABLE_MU = 1}273            } | Should -Not -Throw274        }275 276        It "MSI should have not be updated path" -Skip:(!(Test-Elevated)) {277            $psPath = ([System.Environment]::GetEnvironmentVariable('PATH', 'MACHINE')) -split ';' |278                Where-Object { $_ -like '*files\powershell*' -and $_ -notin $beforePath }279 280            $psPath | Should -BeNullOrEmpty281        }282 283        It "UseMU should be 1" -Skip:(!(Test-Elevated)) {284            Invoke-TestAndUploadLogOnFailure -Test {285                $useMu = Get-UseMU286                $useMu | Should -Be 1287            }288        }289 290        It "MSI should uninstall without error" -Skip:(!(Test-Elevated)) {291            {292                Invoke-MsiExec -Uninstall -MsiPath $msiX64Path293            } | Should -Not -Throw294        }295    }296 297    Context "USE_MU disabled" {298        BeforeAll {299            Set-UseMU -Value 0300        }301 302        It "UseMU should be 0 before install" -Skip:(!(Test-Elevated)) {303            $useMu = Get-UseMU304            $useMu | Should -Be 0305        }306 307        It "MSI should install without error" -Skip:(!(Test-Elevated)) {308            {309                Invoke-MsiExec -Install -MsiPath $msiX64Path -Properties @{USE_MU = 0}310            } | Should -Not -Throw311        }312 313        It "UseMU should be 0" -Skip:(!(Test-Elevated)) {314            Invoke-TestAndUploadLogOnFailure -Test {315                $useMu = Get-UseMU316                $useMu | Should -Be 0317            }318        }319 320        It "MSI should uninstall without error" -Skip:(!(Test-Elevated)) {321            {322                Invoke-MsiExec -Uninstall -MsiPath $msiX64Path323            } | Should -Not -Throw324        }325    }326 327    Context "Add Path enabled" {328        It "MSI should install without error" -Skip:(!(Test-Elevated)) {329            {330                Invoke-MsiExec -Install -MsiPath $msiX64Path -Properties @{ADD_PATH = 1}331            } | Should -Not -Throw332        }333 334        It "MSI should have updated path" -Skip:(!(Test-Elevated)) {335            if ($channel -eq 'preview') {336                $pattern = '*files*\powershell*\preview*'337            } else {338                $pattern = '*files*\powershell*'339            }340 341            $psPath = ([System.Environment]::GetEnvironmentVariable('PATH', 'MACHINE')) -split ';' |342            Where-Object { $_ -like $pattern -and $_ -notin $beforePath }343 344            if (!$psPath) {345                ([System.Environment]::GetEnvironmentVariable('PATH', 'MACHINE')) -split ';' |346                Where-Object { $_ -notin $beforePath } |347                ForEach-Object { Write-Verbose -Verbose $_ }348            }349 350            $psPath | Should -Not -BeNullOrEmpty351        }352 353        It "MSI should uninstall without error" -Skip:(!(Test-Elevated)) {354            {355                Invoke-MsiExec -Uninstall -MsiPath $msiX64Path356            } | Should -Not -Throw357        }358 359        Context "Disable Telemetry" {360            It "MSI should set POWERSHELL_TELEMETRY_OPTOUT env variable when MSI property DISABLE_TELEMETRY is set to 1" -Skip:(!(Test-Elevated)) {361                try {362                    $originalValue = [System.Environment]::GetEnvironmentVariable('POWERSHELL_TELEMETRY_OPTOUT', [System.EnvironmentVariableTarget]::Machine)363                    [System.Environment]::SetEnvironmentVariable('POWERSHELL_TELEMETRY_OPTOUT', '0', [System.EnvironmentVariableTarget]::Machine)364                    {365                        Invoke-MsiExec -Install -MsiPath $msiX64Path -Properties @{DISABLE_TELEMETRY = 1 }366                    } | Should -Not -Throw367                    [System.Environment]::GetEnvironmentVariable('POWERSHELL_TELEMETRY_OPTOUT', [System.EnvironmentVariableTarget]::Machine) |368                        Should -Be 1369                }370                finally {371                    [System.Environment]::SetEnvironmentVariable('POWERSHELL_TELEMETRY_OPTOUT', $originalValue, [System.EnvironmentVariableTarget]::Machine)372                    {373                        Invoke-MsiExec -Uninstall -MsiPath $msiX64Path374                    } | Should -Not -Throw375                }376            }377 378            It "MSI should not change POWERSHELL_TELEMETRY_OPTOUT env variable when MSI property DISABLE_TELEMETRY not set" -Skip:(!(Test-Elevated)) {379                try {380                    $originalValue = [System.Environment]::GetEnvironmentVariable('POWERSHELL_TELEMETRY_OPTOUT', [System.EnvironmentVariableTarget]::Machine)381                    [System.Environment]::SetEnvironmentVariable('POWERSHELL_TELEMETRY_OPTOUT', 'untouched', [System.EnvironmentVariableTarget]::Machine)382                    {383                        Invoke-MsiExec -Install -MsiPath $msiX64Path384                    } | Should -Not -Throw385                    [System.Environment]::GetEnvironmentVariable('POWERSHELL_TELEMETRY_OPTOUT', [System.EnvironmentVariableTarget]::Machine) |386                        Should -Be 'untouched'387                }388                finally {389                    [System.Environment]::SetEnvironmentVariable('POWERSHELL_TELEMETRY_OPTOUT', $originalValue, [System.EnvironmentVariableTarget]::Machine)390                    {391                        Invoke-MsiExec -Uninstall -MsiPath $msiX64Path392                    } | Should -Not -Throw393                }394            }395        }396    }397}398