Private/DlpAdvancedParser.ps1
# Enhanced DLP parsing functions to handle nested SubConditions and compound property paths # These functions extend the basic DLP parsing to support: # - Nested SubConditions (for DLP_4.6, DLP_4.7, DLP_4.8) # - Compound property paths like "Sensitivetypes > Name", "Sensitivetypes > MinCount", etc. function Test-DlpAdvancedRuleProperty { param( [PSCustomObject]$AdvRule, [string]$DeepProp, [string]$DeepVal, [string]$ControlId ) $result = @{ Found = $false AnyTypesFound = $false HighestMinCount = 0 ClassifierTypeFound = $false AllNames = @() } # Handle both simple "Sensitivetypes" and compound "Sensitivetypes > Property" paths if ($DeepProp -like "Sensitivetypes*" -and $AdvRule.Condition.SubConditions) { # Parse the deeper property if it exists (e.g., "Sensitivetypes > Name") $sensitivetypesParts = $DeepProp -split ' > ' $targetProperty = if ($sensitivetypesParts.Count -ge 2) { $sensitivetypesParts[1].Trim() } else { $null } # Process top-level SubConditions foreach ($subCond in $AdvRule.Condition.SubConditions) { if ($subCond.ConditionName -eq "ContentContainsSensitiveInformation" -and $subCond.Value) { foreach ($valueItem in $subCond.Value) { if ($valueItem.Groups) { foreach ($group in $valueItem.Groups) { if ($group.Sensitivetypes -and $group.Sensitivetypes.Count -gt 0) { $sensTypes = $group.Sensitivetypes $result.AnyTypesFound = $true # Collect all Names foreach ($sensType in $sensTypes) { if ($sensType.Name) { $result.AllNames += $sensType.Name } # Track highest MinCount (handle both Mincount and MinCount) $minCountValue = if ($sensType.Mincount) { $sensType.Mincount } elseif ($sensType.MinCount) { $sensType.MinCount } else { 0 } if ($minCountValue -gt $result.HighestMinCount) { $result.HighestMinCount = $minCountValue } # Check for ClassifierType (handle both variants) $classifierTypeValue = if ($sensType.Classifiertype) { $sensType.Classifiertype } elseif ($sensType.ClassifierType) { $sensType.ClassifierType } else { $null } if ($classifierTypeValue -eq "MLModel") { $result.ClassifierTypeFound = $true } } } } } } } # For specific failing controls (DLP_4.6, DLP_4.7, DLP_4.8), also check one level deeper if (($ControlId -eq "DLP_4.6" -or $ControlId -eq "DLP_4.7" -or $ControlId -eq "DLP_4.8") -and $subCond.SubConditions -and $subCond.SubConditions.Count -gt 0) { foreach ($nestedSubCond in $subCond.SubConditions) { if ($nestedSubCond.ConditionName -eq "ContentContainsSensitiveInformation" -and $nestedSubCond.Value) { foreach ($valueItem in $nestedSubCond.Value) { if ($valueItem.Groups) { foreach ($group in $valueItem.Groups) { if ($group.Sensitivetypes -and $group.Sensitivetypes.Count -gt 0) { $sensTypes = $group.Sensitivetypes $result.AnyTypesFound = $true # Collect all Names foreach ($sensType in $sensTypes) { if ($sensType.Name) { $result.AllNames += $sensType.Name } # Track highest MinCount (handle both variants) $minCountValue = if ($sensType.Mincount) { $sensType.Mincount } elseif ($sensType.MinCount) { $sensType.MinCount } else { 0 } if ($minCountValue -gt $result.HighestMinCount) { $result.HighestMinCount = $minCountValue } # Check for ClassifierType (handle both variants) $classifierTypeValue = if ($sensType.Classifiertype) { $sensType.Classifiertype } elseif ($sensType.ClassifierType) { $sensType.ClassifierType } else { $null } if ($classifierTypeValue -eq "MLModel") { $result.ClassifierTypeFound = $true } } } } } } } } } } # Check if the specific property requirements are met if ($targetProperty -eq "Name" -and $DeepVal -eq 'Not Null') { $result.Found = $result.AnyTypesFound } elseif ($targetProperty -eq "MinCount") { $result.Found = ($result.HighestMinCount -ge [int]$DeepVal) } elseif ($targetProperty -eq "Name" -and $DeepVal -match ",") { # For comma-separated names check $requiredNames = $DeepVal -split ',' | ForEach-Object { $_.Trim() } $allFound = $true foreach ($reqName in $requiredNames) { if ($result.AllNames -notcontains $reqName) { $allFound = $false break } } $result.Found = $allFound } elseif ($targetProperty -eq "ClassifierType") { $result.Found = $result.ClassifierTypeFound } elseif ($targetProperty -eq "Name") { # For specific Name match $result.Found = ($result.AllNames -contains $DeepVal) } elseif ($targetProperty -eq $null -and $DeepVal -eq 'Not Null') { # For legacy format compatibility - old format without target property $result.Found = $result.AnyTypesFound } } return $result } function Get-DlpPropertyComment { param( [string]$DeepProp, [string]$DeepVal, [string]$CommentType = "Found" # "Found", "NotFoundWithSimulation", "NotFound" ) # Parse deeper properties if they exist (e.g., "Sensitivetypes > MinCount") $targetProperty = $null if ($DeepProp -like "*>*") { $deepPropParts = $DeepProp -split ' > ' if ($deepPropParts.Count -ge 2) { $targetProperty = $deepPropParts[1].Trim() } } switch ($CommentType) { "Found" { if ($targetProperty -eq "MinCount") { return "Found DLP rule with $DeepProp >= $DeepVal" } elseif ($targetProperty -eq "Name" -and $DeepVal -match ",") { return "Found DLP rule with all required sensitive type names: $DeepVal" } elseif ($targetProperty -eq "ClassifierType") { return "Found DLP rule with $DeepProp = $DeepVal" } elseif ($DeepVal -eq 'Not Null') { return "Found DLP rule with $DeepProp configured" } else { return "Found DLP rule with $DeepProp = $DeepVal" } } "NotFoundWithSimulation" { if ($targetProperty -eq "MinCount") { return "No enabled DLP rule found with $DeepProp >= $DeepVal. Found matching rule(s) in simulation/test mode" } elseif ($targetProperty -eq "Name" -and $DeepVal -match ",") { return "No enabled DLP rule found with all required sensitive type names: $DeepVal. Found matching rule(s) in simulation/test mode" } elseif ($targetProperty -eq "ClassifierType") { return "No enabled DLP rule found with $DeepProp = $DeepVal. Found matching rule(s) in simulation/test mode" } else { return "No enabled DLP rule found with $DeepProp in AdvancedRule. Found matching rule(s) in simulation/test mode" } } "NotFound" { if ($targetProperty -eq "MinCount") { return "No DLP rule found with $DeepProp >= $DeepVal" } elseif ($targetProperty -eq "Name" -and $DeepVal -match ",") { return "No DLP rule found with all required sensitive type names: $DeepVal" } elseif ($targetProperty -eq "ClassifierType") { return "No DLP rule found with $DeepProp = $DeepVal" } else { return "No DLP rule found with $DeepProp in AdvancedRule" } } } } |