Public/Tests/New-IntuneWin32Rule.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 'New-IntuneWin32Rule' { It 'Is exported under its file name' { Get-Command -Name New-IntuneWin32Rule -Module tcs.intune.packaging | Should -Not -BeNullOrEmpty } It 'Creates a file system detection rule with Graph property names' { # Test-Path -IsValid only accepts paths of the current platform, so use a TestDrive path $folder = Join-Path -Path $TestDrive -ChildPath 'MyApp' $rule = New-IntuneWin32Rule -RuleParentType detection -RuleType FileOrFolder -Path $folder -FileOrFolderName 'MyApp.exe' -OperationType exists $rule['@odata.type'] | Should -Be '#microsoft.graph.win32LobAppFileSystemRule' $rule['ruleType'] | Should -Be 'detection' $rule['path'] | Should -Be $folder $rule['fileOrFolderName'] | Should -Be 'MyApp.exe' $rule['operationType'] | Should -Be 'exists' $rule['check32BitOn64System'] | Should -BeFalse $rule.ContainsKey('verbose') | Should -BeFalse } It 'Maps Check32BitOn64BitSystem to check32BitOn64System' { $rule = New-IntuneWin32Rule -RuleParentType detection -RuleType FileOrFolder -Path $TestDrive -FileOrFolderName 'a.exe' -OperationType exists -Check32BitOn64BitSystem $rule['check32BitOn64System'] | Should -BeTrue $rule.Keys | Should -Not -Contain 'check32BitOn64BitSystem' } It 'Leaves common parameters out of the rule' { $rule = New-IntuneWin32Rule -RuleParentType detection -RuleType Registry -Path 'HKEY_LOCAL_MACHINE\Software' -KeyName 'MyApp' -Verbose 4>$null $rule.Keys | Should -Not -Contain 'verbose' } It 'Creates a registry <Case> rule with Graph property names' -ForEach @( @{ Case = 'exists'; Extra = @{ Operator = 'exists' }; OperationType = 'exists'; Operator = 'notConfigured'; Comparison = $null } @{ Case = 'does not exist'; Extra = @{ Operator = 'notExists' }; OperationType = 'doesNotExist'; Operator = 'notConfigured'; Comparison = $null } @{ Case = 'version comparison'; Extra = @{ Operator = 'greaterThanOrEqual'; DataType = 'version'; Value = '1.2' }; OperationType = 'version'; Operator = 'greaterThanOrEqual'; Comparison = '1.2' } ) { $rule = New-IntuneWin32Rule -RuleParentType requirement -RuleType Registry -Path 'HKEY_LOCAL_MACHINE\Software\' -KeyName 'MyApp' -ValueName 'Version' @Extra $rule['@odata.type'] | Should -Be '#microsoft.graph.win32LobAppRegistryRule' $rule['ruleType'] | Should -Be 'requirement' $rule['keyPath'] | Should -Be 'HKEY_LOCAL_MACHINE\Software\MyApp' $rule['valueName'] | Should -Be 'Version' $rule['check32BitOn64System'] | Should -BeFalse $rule['operationType'] | Should -Be $OperationType $rule['operator'] | Should -Be $Operator $rule['comparisonValue'] | Should -Be $Comparison @($rule.Keys | Where-Object { $_ -in 'path', 'keyName', 'dataType', 'value' }) | Should -BeNullOrEmpty } It 'Requires a data type for a registry comparison' { { New-IntuneWin32Rule -RuleParentType detection -RuleType Registry -Path 'HKLM\Software' -Operator equal -Value 1 } | Should -Throw '*DataType*' } It 'Adds the comparison to a file version rule' { $rule = New-IntuneWin32Rule -RuleParentType detection -RuleType FileOrFolder -Path $TestDrive -FileOrFolderName 'app.exe' -OperationType version -Operator greaterThanOrEqual -ComparisonValue '2.0' $rule['operator'] | Should -Be 'greaterThanOrEqual' $rule['comparisonValue'] | Should -Be '2.0' } It 'Leaves displayName and runAsAccount out of script detection rules and sets them for requirement rules' { $script = Join-Path -Path $TestDrive -ChildPath 'req.ps1' Set-Content -Path $script -Value 'Write-Output 1' $detection = New-IntuneWin32Rule -RuleParentType detection -RuleType Script -ScriptPath $script $detection.Keys | Should -Not -Contain 'displayName' $detection.Keys | Should -Not -Contain 'runAsAccount' $requirement = New-IntuneWin32Rule -RuleParentType requirement -RuleType Script -ScriptPath $script -RunAsAccount user -OperationType integer -Operator equal -ComparisonValue '1' $requirement['runAsAccount'] | Should -Be 'user' $requirement['displayName'] | Should -Be 'req.ps1' $requirement['operationType'] | Should -Be 'integer' $requirement['comparisonValue'] | Should -Be '1' } It 'Only allows MSI rules for detection' { $msi = Join-Path -Path $TestDrive -ChildPath 'app.msi' Set-Content -Path $msi -Value 'x' { New-IntuneWin32Rule -RuleParentType requirement -RuleType MSI -MSIPath $msi -ProductCode '{A}' } | Should -Throw '*detection*' } It 'Embeds the script content as Base64' { $script = Join-Path -Path $TestDrive -ChildPath 'detect.ps1' Set-Content -Path $script -Value 'Write-Output "found"' -NoNewline $rule = New-IntuneWin32Rule -RuleParentType detection -RuleType Script -ScriptPath $script [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($rule['scriptContent'])) | Should -Be 'Write-Output "found"' $rule['@odata.type'] | Should -Be '#microsoft.graph.win32LobAppPowerShellScriptRule' $rule['operationType'] | Should -Be 'notConfigured' $rule.Keys | Should -Not -Contain 'scriptPath' } It 'Reads the product code from the MSI when AutoDetect is used' { Mock -ModuleName tcs.intune.packaging Get-MSIProperty { [PSCustomObject]@{ ProductCode = '{ABC}'; ProductVersion = '1.2.3' } } $msi = Join-Path -Path $TestDrive -ChildPath 'app.msi' Set-Content -Path $msi -Value 'x' $rule = New-IntuneWin32Rule -RuleParentType detection -RuleType MSI -MSIPath $msi -AutoDetect $true $rule['productCode'] | Should -Be '{ABC}' $rule['productVersion'] | Should -Be '1.2.3' $rule['productVersionOperator'] | Should -Be 'equal' $rule.Keys | Should -Not -Contain 'msiPath' } } Describe 'New-IntuneWin32Rule telemetry' { BeforeEach { Mock -ModuleName tcs.intune.packaging Invoke-TelemetryCollection { } } It 'Reports Start and a successful End' { $null = New-IntuneWin32Rule -RuleParentType detection -RuleType Registry -Path 'HKEY_LOCAL_MACHINE\Software\MyApp' -Operator exists Should -Invoke -ModuleName tcs.intune.packaging Invoke-TelemetryCollection -Times 1 -Exactly -ParameterFilter { $Stage -eq 'Start' -and $CommandName -eq 'New-IntuneWin32Rule' } Should -Invoke -ModuleName tcs.intune.packaging Invoke-TelemetryCollection -Times 1 -Exactly -ParameterFilter { $Stage -eq 'End' -and -not $Failed } } It 'Reports a failed End once and still throws' { { New-IntuneWin32Rule -RuleParentType detection -RuleType Registry -Path 'HKEY_LOCAL_MACHINE\Software\MyApp' -ValueName 'Version' -Operator equal -Value '1.0' } | Should -Throw '*DataType*' Should -Invoke -ModuleName tcs.intune.packaging Invoke-TelemetryCollection -Times 1 -Exactly -ParameterFilter { $Stage -eq 'Start' } Should -Invoke -ModuleName tcs.intune.packaging Invoke-TelemetryCollection -Times 1 -Exactly -ParameterFilter { $Stage -eq 'End' -and $Failed -eq $true } Should -Invoke -ModuleName tcs.intune.packaging Invoke-TelemetryCollection -Times 0 -Exactly -ParameterFilter { $Stage -eq 'End' -and -not $Failed } } } |