Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 79 additions & 3 deletions Task/Deploy-CheckExtension.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,22 @@ Enable Debug Logging. Maps to "Enable Debug Logging" in Activity Log settings.
A list of URLs that will completely bypass blocking. Entering **ANY** will decrease security on that website significantly.
'@)][string[]]$urlAllowlist,

[Parameter(HelpMessage=@'
Enable Generic Webhook. Maps to "Generic Webhook Enabled" in webhook settings.
| State | Effect |
|-------|-----------------------------------------------------|
| `0` | Disabled (default) |
| `1` | Enabled (requires GenericWebhookUrl and Events) |
'@)][ValidateSet(0,1)][int]$EnableGenericWebhook = 0,
[Parameter(HelpMessage=@'
Generic Webhook URL. Required if EnableGenericWebhook=1. Blank by default.
'@)][string]$GenericWebhookUrl = '',
[Parameter(HelpMessage=@'
Generic Webhook Event Types. Array of event types to send to the webhook.
Valid values: detection_alert, false_positive_report, page_blocked, rogue_app_detected, threat_detected, validation_event
'@)][ValidateSet('detection_alert','false_positive_report','page_blocked','rogue_app_detected','threat_detected','validation_event')]
[string[]]$GenericWebhookEvents,

[Parameter(HelpMessage=@'
Branding: Company Name shown in extension UI.
'@)][string]$CompanyName = 'CyberDrain',
Expand Down Expand Up @@ -142,6 +158,44 @@ Write-Host "Starting enforcement for Extensions: Chrome=$ChromeExtensionId Edge=
# [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter','')] param([string]$FutureParam)
# Prefer explicit functional parameters over relying on script scope to satisfy analyzers & improve clarity.

function ConvertTo-StringArray {
<#
.SYNOPSIS
Safely converts input to a properly typed string array for registry MultiString values.
.DESCRIPTION
Ensures the returned value is always System.String[] type, never Object[].
Handles null, empty arrays, and arrays with values correctly.
Uses [string[]] casting with explicit array conversion to ensure type survives $using: scope transfer.
#>
param([Parameter(ValueFromPipeline)]$InputArray)

# If null, return empty string array with explicit type
if ($null -eq $InputArray) {
$emptyArray = [string[]]::new(0)
return ,$emptyArray
}

# Ensure it's treated as an array
$arr = @($InputArray)
if ($arr.Count -eq 0) {
$emptyArray = [string[]]::new(0)
return ,$emptyArray
}

# Use strongly typed array creation
$stringArray = [string[]]::new($arr.Count)
for ($i = 0; $i -lt $arr.Count; $i++) {
if ($null -ne $arr[$i]) {
$stringArray[$i] = [string]$arr[$i]
} else {
$stringArray[$i] = [string]::Empty
}
}

# Return with unary comma to prevent unwrapping
return ,$stringArray
}

function Get-ManagedStorageBasePath {
param(
[string]$ChromeExtensionId,
Expand Down Expand Up @@ -171,6 +225,9 @@ function Get-DesiredItem {
[int]$UpdateInterval,
[int]$EnableDebugLogging,
[string[]]$urlAllowlist,
[int]$EnableGenericWebhook,
[string]$GenericWebhookUrl,
[string[]]$GenericWebhookEvents,
[string]$CompanyName,
[string]$CompanyUrl,
[string]$ProductName,
Expand All @@ -187,6 +244,7 @@ function Get-DesiredItem {
foreach($b in $bases){
# Build canonical Present arrays once
$brandingKey = Join-Path $b.ManagedKey 'customBranding'
$webhookKey = Join-Path $b.ManagedKey 'genericWebhook'
$policyItems = @(
@{ Path=$b.ManagedKey; Name='showNotifications'; Type='DWord'; Value=$ShowNotifications },
@{ Path=$b.ManagedKey; Name='enableValidPageBadge'; Type='DWord'; Value=$EnableValidPageBadge },
Expand All @@ -197,7 +255,12 @@ function Get-DesiredItem {
@{ Path=$b.ManagedKey; Name='customRulesUrl'; Type='String'; Value=$CustomRulesUrl },
@{ Path=$b.ManagedKey; Name='updateInterval'; Type='DWord'; Value=$UpdateInterval },
@{ Path=$b.ManagedKey; Name='enableDebugLogging'; Type='DWord'; Value=$EnableDebugLogging }
@{ Path=$b.ManagedKey; Name='urlAllowlist'; Type='MultiString'; Value=$urlAllowlist }
@{ Path=$b.ManagedKey; Name='urlAllowlist'; Type='MultiString'; Value=(ConvertTo-StringArray $urlAllowlist) }
)
$webhookItems = @(
@{ Path=$webhookKey; Name='enabled'; Type='DWord'; Value=$EnableGenericWebhook },
@{ Path=$webhookKey; Name='url'; Type='String'; Value=$GenericWebhookUrl },
@{ Path=$webhookKey; Name='events'; Type='MultiString'; Value=(ConvertTo-StringArray $GenericWebhookEvents) }
)
$brandingItems = @(
@{ Path=$brandingKey; Name='companyName'; Type='String'; Value=$CompanyName },
Expand All @@ -213,16 +276,17 @@ function Get-DesiredItem {
)

if($Ensure -eq 'Present'){
$policyItems + $brandingItems + $settingsItems | ForEach-Object { $_ }
$policyItems + $webhookItems + $brandingItems + $settingsItems | ForEach-Object { $_ }
} else {
# Transform for Absent: null policy & branding values, block extension, drop update_url
$absentPolicy = $policyItems | ForEach-Object { @{ Path=$_.Path; Name=$_.Name; Type=$_.Type; Value=$null } }
$absentWebhook = $webhookItems | ForEach-Object { @{ Path=$_.Path; Name=$_.Name; Type=$_.Type; Value=$null } }
$absentBranding = $brandingItems | ForEach-Object { @{ Path=$_.Path; Name=$_.Name; Type=$_.Type; Value=$null } }
$absentSettings = @(
@{ Path=$b.SettingsKey; Name='installation_mode'; Type='String'; Value='blocked' },
@{ Path=$b.SettingsKey; Name='update_url'; Type='Remove'; Value=$null }
)
$absentPolicy + $absentBranding + $absentSettings | ForEach-Object { $_ }
$absentPolicy + $absentWebhook + $absentBranding + $absentSettings | ForEach-Object { $_ }
}
}
}
Expand All @@ -234,6 +298,15 @@ if($EnableCippReporting -eq 1){
}
}

if($EnableGenericWebhook -eq 1){
if([string]::IsNullOrWhiteSpace($GenericWebhookUrl)){
throw 'GenericWebhookUrl must be provided when EnableGenericWebhook=1.'
}
if($null -eq $GenericWebhookEvents -or $GenericWebhookEvents.Count -eq 0){
throw 'At least one event type must be specified in GenericWebhookEvents when EnableGenericWebhook=1.'
}
}

# Build desired items once
$desiredItems = Get-DesiredItem `
-Ensure $Ensure `
Expand All @@ -251,6 +324,9 @@ $desiredItems = Get-DesiredItem `
-UpdateInterval $UpdateInterval `
-EnableDebugLogging $EnableDebugLogging `
-urlAllowlist $urlAllowlist `
-EnableGenericWebhook $EnableGenericWebhook `
-GenericWebhookUrl $GenericWebhookUrl `
-GenericWebhookEvents $GenericWebhookEvents `
-CompanyName $CompanyName `
-CompanyUrl $CompanyUrl `
-ProductName $ProductName `
Expand Down