diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ea0d81..dee1c74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.2.0] - 2024-09-12 +### Added + +- New helper function `Validate-SIDFormat` to verify SID value upon retrieval +in `Get-ProfilePathFromSID` + + ### Added - Added core functions diff --git a/source/Private/Get-SIDProfileInfo.ps1 b/source/Private/Get-SIDProfileInfo.ps1 index b4eb834..c4f3331 100644 --- a/source/Private/Get-SIDProfileInfo.ps1 +++ b/source/Private/Get-SIDProfileInfo.ps1 @@ -64,9 +64,8 @@ function Get-SIDProfileInfo $ProfileRegistryItems = foreach ($sid in $subKeyNames) { # Validate SID format (SIDs typically start with 'S-1-' and follow a specific pattern) - if ($sid -notmatch '^S-1-\d+-\d+(-\d+){1,}$') + if (-not (Validate-SIDFormat -SID $sid)) { - Write-Warning "Invalid SID format encountered: '$sid'. Skipping." continue } diff --git a/source/Private/Validate-SIDFormat.ps1 b/source/Private/Validate-SIDFormat.ps1 new file mode 100644 index 0000000..5505782 --- /dev/null +++ b/source/Private/Validate-SIDFormat.ps1 @@ -0,0 +1,57 @@ +<# +.SYNOPSIS + Validates whether a given string follows the correct SID (Security Identifier) format. + +.DESCRIPTION + The Validate-SIDFormat function checks if a given string matches the standard SID format. + SIDs typically start with 'S-1-' followed by a series of digits separated by hyphens. + This function returns $true if the SID format is valid and $false if it is not. + +.PARAMETER SID + The SID string to validate. This should follow the typical format: 'S-1-' followed by + a series of digits and hyphens. + +.OUTPUTS + [bool] + Returns $true if the SID format is valid; otherwise, returns $false. + +.EXAMPLE + PS> Validate-SIDFormat -SID 'S-1-5-18' + True + + This example checks if the SID 'S-1-5-18' is valid. + +.EXAMPLE + PS> Validate-SIDFormat -SID 'Invalid-SID' + WARNING: Invalid SID format encountered: 'Invalid-SID'. + False + + This example demonstrates how the function handles an invalid SID format by returning $false + and issuing a warning. + +.NOTES + +.LINK + https://docs.microsoft.com/en-us/windows/win32/secauthz/security-identifiers + +#> +function Validate-SIDFormat +{ + param ( + [OutPutType([bool])] + [CmdletBinding()] + [Parameter(Mandatory = $true)] + [string]$SID + ) + + # Regular expression pattern for validating the SID format + $sidPattern = '^S-1-\d+(-\d+)+$' + + if ($SID -notmatch $sidPattern) + { + Write-Warning "Invalid SID format encountered: '$SID'." + return $false + } + + return $true +} diff --git a/tests/Unit/Private/Validate-SIDFormat.tests.ps1 b/tests/Unit/Private/Validate-SIDFormat.tests.ps1 new file mode 100644 index 0000000..4c31956 --- /dev/null +++ b/tests/Unit/Private/Validate-SIDFormat.tests.ps1 @@ -0,0 +1,87 @@ +BeforeAll { + $script:dscModuleName = "WinProfileOps" + + # Import the module that contains the function being tested + Import-Module -Name $script:dscModuleName + + # Set default parameters for the module scope in Pester + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} + +AfterAll { + # Remove the default parameters + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + # Unload the module after the tests are completed + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force +} + +Describe 'Validate-SIDFormat Tests' -Tag 'Private' { + + Context 'Valid SID Tests' { + It 'Should return true for a valid SID S-1-5-18' { + InModuleScope $script:dscModuleName { + $result = Validate-SIDFormat -SID 'S-1-5-18' + $result | Should -Be $true + } + } + + It 'Should return true for a valid SID with multiple components S-1-5-21-3623811015-3361044348-30300820-1013' { + InModuleScope $script:dscModuleName { + $result = Validate-SIDFormat -SID 'S-1-5-21-3623811015-3361044348-30300820-1013' + $result | Should -Be $true + } + } + } + + Context 'Invalid SID Tests' { + It 'Should return false for an invalid SID S-1-5' { + InModuleScope $script:dscModuleName { + $result = Validate-SIDFormat -SID 'S-1-5' + $result | Should -Be $false + } + } + + It 'Should return false for an invalid SID S-1-XYZ-18' { + InModuleScope $script:dscModuleName { + $result = Validate-SIDFormat -SID 'S-1-XYZ-18' + $result | Should -Be $false + } + } + + It 'Should throw for an empty string' { + InModuleScope $script:dscModuleName { + { Validate-SIDFormat -SID '' } | Should -Throw "Cannot bind argument to parameter 'SID' because it is an empty string." + } + } + } + + Context 'Warning Messages' { + + BeforeAll { + Mock Write-Warning + } + + It 'Should show a warning for an invalid SID' { + InModuleScope $script:dscModuleName { + # Call the function directly + Validate-SIDFormat -SID 'S-1-5' + # Assert that Write-Warning was invoked + Should -Invoke Write-Warning -Exactly 1 -Scope It + } + } + + It 'Should not show a warning for a valid SID' { + InModuleScope $script:dscModuleName { + # Call the function directly + Validate-SIDFormat -SID 'S-1-5-18' + # Assert that Write-Warning was not invoked + Should -Invoke Write-Warning -Exactly 0 -Scope It + } + } + } +}