Private/Common.ps1
|
<# .SYNOPSIS Common utility functions used across the PurviewDLP module. .DESCRIPTION This file contains shared utility functions that are used by multiple cmdlets in the PurviewDLP module, including console output, connection testing, module management, and path resolution. .NOTES Internal module file - not exported to users. Functions are available to all module cmdlets. #> function Write-ColorOutput { <# .SYNOPSIS Writes colored output to the console. .DESCRIPTION Provides consistent colored console output across all module cmdlets. Supports different message types with predefined colors. .PARAMETER Message The message to display. .PARAMETER Type The type of message which determines the color. Valid values: Info, Success, Warning, Error, Header Default: Info .EXAMPLE Write-ColorOutput -Message "Operation completed" -Type Success .EXAMPLE Write-ColorOutput "Processing..." -Type Info #> [CmdletBinding()] param( [Parameter(Mandatory = $true, Position = 0)] [string]$Message, [Parameter(Mandatory = $false, Position = 1)] [ValidateSet('Info', 'Success', 'Warning', 'Error', 'Header')] [string]$Type = 'Info' ) $color = switch ($Type) { 'Success' { 'Green' } 'Error' { 'Red' } 'Warning' { 'Yellow' } 'Info' { 'Cyan' } 'Header' { 'Magenta' } } Write-Host $Message -ForegroundColor $color } function Write-Banner { <# .SYNOPSIS Writes a formatted banner to the console. .DESCRIPTION Creates a visually distinct banner with decorative borders. Useful for section headers and important status messages. .PARAMETER Message The message to display in the banner. .PARAMETER Type The type/color of the banner. Valid values: Info, Success, Warning, Error Default: Info .PARAMETER Char The character to use for the border line. Default: "═" .EXAMPLE Write-Banner -Message "DLP Policy Export" -Type Info .EXAMPLE Write-Banner "Export Complete" -Type Success -Char "-" #> [CmdletBinding()] param( [Parameter(Mandatory = $true, Position = 0)] [string]$Message, [Parameter(Mandatory = $false)] [ValidateSet('Info', 'Success', 'Warning', 'Error')] [string]$Type = 'Info', [Parameter(Mandatory = $false)] [string]$Char = '═' ) $color = switch ($Type) { 'Success' { 'Green' } 'Error' { 'Red' } 'Warning' { 'Yellow' } 'Info' { 'Cyan' } } $border = $Char * 80 Write-Host "" Write-Host $border -ForegroundColor $color Write-Host " $Message" -ForegroundColor $color Write-Host $border -ForegroundColor $color Write-Host "" } function Test-SecurityComplianceConnection { <# .SYNOPSIS Tests if there is an active connection to Security & Compliance Center. .DESCRIPTION Attempts to retrieve a DLP policy to verify that a connection to Security & Compliance Center is active and functional. .OUTPUTS System.Boolean Returns $true if connected, $false otherwise. .EXAMPLE if (Test-SecurityComplianceConnection) { Write-Host "Connected" } .EXAMPLE $connected = Test-SecurityComplianceConnection #> [CmdletBinding()] [OutputType([bool])] param() try { # Try to get a DLP policy to verify connection $null = Get-DlpCompliancePolicy -ErrorAction Stop | Select-Object -First 1 return $true } catch { return $false } } function Test-ModuleInstalled { <# .SYNOPSIS Tests if a PowerShell module is installed. .DESCRIPTION Checks if a specified module is available in the current PowerShell session. .PARAMETER ModuleName The name of the module to check. .OUTPUTS System.Boolean Returns $true if module is installed, $false otherwise. .EXAMPLE if (Test-ModuleInstalled -ModuleName "ExchangeOnlineManagement") { Write-Host "Module is installed" } .EXAMPLE $hasModule = Test-ModuleInstalled "ExchangeOnlineManagement" #> [CmdletBinding()] [OutputType([bool])] param( [Parameter(Mandatory = $true, Position = 0)] [string]$ModuleName ) $module = Get-Module -ListAvailable -Name $ModuleName return ($null -ne $module) } function Install-RequiredModule { <# .SYNOPSIS Installs a required PowerShell module. .DESCRIPTION Attempts to install a PowerShell module from the PowerShell Gallery in the current user scope. Provides feedback on success or failure. .PARAMETER ModuleName The name of the module to install. .OUTPUTS System.Boolean Returns $true if installation succeeds, $false otherwise. .EXAMPLE if (Install-RequiredModule -ModuleName "ExchangeOnlineManagement") { Write-Host "Installation successful" } .EXAMPLE $installed = Install-RequiredModule "ExchangeOnlineManagement" #> [CmdletBinding()] [OutputType([bool])] param( [Parameter(Mandatory = $true, Position = 0)] [string]$ModuleName ) Write-ColorOutput "Module '$ModuleName' not found. Attempting to install..." -Type Warning try { Install-Module -Name $ModuleName -Scope CurrentUser -Force -AllowClobber -ErrorAction Stop Write-ColorOutput "✓ Module '$ModuleName' installed successfully." -Type Success return $true } catch { Write-ColorOutput "✗ Failed to install module '$ModuleName'." -Type Error Write-ColorOutput "Error: $($_.Exception.Message)" -Type Error return $false } } function Get-DefaultOutputPath { <# .SYNOPSIS Returns the default output path for generated files. .DESCRIPTION Determines the appropriate output path for generated files. If no path is specified, uses the current working directory. Creates the directory if it doesn't exist. .PARAMETER OutputPath Optional. The desired output path. If not specified, uses current location. .OUTPUTS System.String Returns the resolved output path. .EXAMPLE $path = Get-DefaultOutputPath # Returns current directory .EXAMPLE $path = Get-DefaultOutputPath -OutputPath "C:\Reports" # Returns "C:\Reports", creates if needed #> [CmdletBinding()] [OutputType([string])] param( [Parameter(Mandatory = $false)] [string]$OutputPath ) # If no path specified, use current directory if ([string]::IsNullOrWhiteSpace($OutputPath)) { $OutputPath = (Get-Location).Path } # Resolve to absolute path $resolvedPath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($OutputPath) # Create directory if it doesn't exist if (-not (Test-Path -Path $resolvedPath)) { try { New-Item -Path $resolvedPath -ItemType Directory -Force | Out-Null Write-Verbose "Created output directory: $resolvedPath" } catch { Write-ColorOutput "Warning: Could not create directory '$resolvedPath'. Using current directory." -Type Warning $resolvedPath = (Get-Location).Path } } return $resolvedPath } function Get-TemplateFile { <# .SYNOPSIS Resolves the path to a template file within the module. .DESCRIPTION Locates template files (HTML, CSV, etc.) stored in the module's Templates directory. Returns the full path to the template file. .PARAMETER TemplateName The name of the template file (e.g., "standard-notification.html"). .PARAMETER TemplateType The type/subdirectory of template. Valid values: PolicyTips, EmailBodies, Reports .OUTPUTS System.String Returns the full path to the template file, or $null if not found. .EXAMPLE $template = Get-TemplateFile -TemplateName "standard-notification.html" -TemplateType "EmailBodies" .EXAMPLE $policyTip = Get-TemplateFile "simulation-tip.html" -TemplateType PolicyTips #> [CmdletBinding()] [OutputType([string])] param( [Parameter(Mandatory = $true, Position = 0)] [string]$TemplateName, [Parameter(Mandatory = $true, Position = 1)] [ValidateSet('PolicyTips', 'EmailBodies', 'Reports')] [string]$TemplateType ) # Get module root directory $moduleRoot = Split-Path -Parent $PSScriptRoot # Build path to template file $templatePath = Join-Path -Path $moduleRoot -ChildPath "Templates\$TemplateType\$TemplateName" if (Test-Path -Path $templatePath) { Write-Verbose "Found template: $templatePath" return $templatePath } else { Write-ColorOutput "Warning: Template file not found: $templatePath" -Type Warning return $null } } function Invoke-WithErrorHandling { <# .SYNOPSIS Executes a script block with standardized error handling. .DESCRIPTION Wraps script block execution with consistent error handling, logging, and error reporting. Useful for maintaining consistent error handling patterns across cmdlets. .PARAMETER ScriptBlock The script block to execute. .PARAMETER ErrorMessage The error message prefix to display if execution fails. .PARAMETER ContinueOnError If specified, errors are logged but execution continues. Otherwise, errors are thrown. .OUTPUTS System.Object Returns the result of the script block, or $null on error. .EXAMPLE Invoke-WithErrorHandling -ScriptBlock { Get-DlpCompliancePolicy -Identity "Test" } -ErrorMessage "Failed to retrieve policy" .EXAMPLE $result = Invoke-WithErrorHandling -ScriptBlock { Get-Content $file } -ErrorMessage "File read failed" -ContinueOnError #> [CmdletBinding()] param( [Parameter(Mandatory = $true, Position = 0)] [ScriptBlock]$ScriptBlock, [Parameter(Mandatory = $true, Position = 1)] [string]$ErrorMessage, [Parameter(Mandatory = $false)] [switch]$ContinueOnError ) try { & $ScriptBlock } catch { $fullErrorMessage = "$ErrorMessage : $($_.Exception.Message)" if ($ContinueOnError) { Write-ColorOutput $fullErrorMessage -Type Warning Write-Verbose "Stack Trace: $($_.ScriptStackTrace)" return $null } else { Write-ColorOutput $fullErrorMessage -Type Error throw $_ } } } |