AaTurpin.PSConfig.psm1
function Read-SettingsFile { <# .SYNOPSIS Reads and parses the settings.json configuration file with validation. .DESCRIPTION This cmdlet reads the settings.json file, parses the JSON content, validates drive mappings and monitored directories, and returns a PowerShell object containing the configuration settings. If the settings file doesn't exist, it will be created automatically using New-SettingsFile. .PARAMETER SettingsPath The path to the settings.json file. Defaults to "settings.json" in current directory. .PARAMETER LogPath The path to the log file where operations will be logged using PSLogger. .EXAMPLE $config = Read-SettingsFile -LogPath "C:\Logs\app.log" .EXAMPLE $config = Read-SettingsFile -SettingsPath "C:\Config\settings.json" -LogPath "C:\Logs\app.log" .OUTPUTS PSCustomObject containing the validated settings configuration. #> [CmdletBinding()] param( [Parameter(Mandatory = $false)] [string]$SettingsPath = "settings.json", [Parameter(Mandatory = $true)] [string]$LogPath ) Write-LogInfo -LogPath $LogPath -Message "Reading settings from: $SettingsPath" try { # Check if file exists, create if not if (-not (Test-Path -Path $SettingsPath -PathType Leaf)) { Write-LogInfo -LogPath $LogPath -Message "Settings file not found, creating new file: $SettingsPath" New-SettingsFile -SettingsPath $SettingsPath -LogPath $LogPath } # Read and parse JSON $jsonContent = Get-Content -Path $SettingsPath -Raw -ErrorAction Stop $settings = $jsonContent | ConvertFrom-Json -ErrorAction Stop # Set default staging area if missing if (-not $settings.PSObject.Properties.Name -contains "stagingArea" -or [string]::IsNullOrWhiteSpace($settings.stagingArea)) { $settings | Add-Member -MemberType NoteProperty -Name "stagingArea" -Value "C:\StagingArea" -Force Write-LogWarning -LogPath $LogPath -Message "Using default staging area: C:\StagingArea" } # Initialize driveMappings if missing if (-not ($settings.PSObject.Properties.Name -contains "driveMappings")) { $settings | Add-Member -MemberType NoteProperty -Name "driveMappings" -Value @() -Force } # Initialize monitoredDirectories if missing if (-not ($settings.PSObject.Properties.Name -contains "monitoredDirectories")) { $settings | Add-Member -MemberType NoteProperty -Name "monitoredDirectories" -Value @() -Force } # Validate drive mappings $validDriveMappings = @() if ($settings.driveMappings -and $settings.driveMappings.Count -gt 0) { foreach ($mapping in $settings.driveMappings) { if (Test-DriveMapping -Mapping $mapping -LogPath $LogPath) { $validDriveMappings += $mapping } } } $settings.driveMappings = $validDriveMappings # Validate monitored directories $validMonitoredDirs = @() if ($settings.monitoredDirectories -and $settings.monitoredDirectories.Count -gt 0) { foreach ($dir in $settings.monitoredDirectories) { if (Test-MonitoredDirectory -Directory $dir -LogPath $LogPath) { $validMonitoredDirs += $dir } } } $settings.monitoredDirectories = $validMonitoredDirs Write-LogInfo -LogPath $LogPath -Message "Configuration loaded: $($validDriveMappings.Count) drive mappings, $($validMonitoredDirs.Count) monitored directories" return $settings } catch { Write-LogError -LogPath $LogPath -Message "Failed to read settings file" -Exception $_.Exception throw } } function New-SettingsFile { <# .SYNOPSIS Creates a new settings.json configuration file with default values and returns the settings object. .DESCRIPTION This cmdlet creates a new settings.json file with default configuration values. The file will contain a default staging area path and empty arrays for drive mappings and monitored directories. If the file already exists, it will be overwritten. Returns the created settings object for immediate use. .PARAMETER SettingsPath The path where the settings.json file will be created. Defaults to "settings.json" in current directory. .PARAMETER LogPath The path to the log file where operations will be logged using PSLogger. .PARAMETER StagingArea The staging area path to use. Defaults to "C:\StagingArea". .EXAMPLE $settings = New-SettingsFile -LogPath "C:\Logs\app.log" Creates a new settings.json file in the current directory with default values and returns the settings object. .EXAMPLE $config = New-SettingsFile -SettingsPath "C:\Config\settings.json" -LogPath "C:\Logs\app.log" Creates a new settings.json file at the specified path, overwriting if it exists, and returns the settings. .EXAMPLE $settings = New-SettingsFile -LogPath "C:\Logs\app.log" -StagingArea "D:\MyStaging" Creates a new settings.json file with a custom staging area path and returns the settings object. .OUTPUTS PSCustomObject containing the created settings configuration. #> [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory = $false)] [string]$SettingsPath = "settings.json", [Parameter(Mandatory = $true)] [string]$LogPath, [Parameter(Mandatory = $false)] [string]$StagingArea = "C:\StagingArea" ) Write-LogInfo -LogPath $LogPath -Message "Creating new settings file: $SettingsPath" try { # Check if file already exists if (Test-Path -Path $SettingsPath -PathType Leaf) { Write-LogWarning -LogPath $LogPath -Message "Overwriting existing settings file: $SettingsPath" } # Create default settings object $defaultSettings = [PSCustomObject]@{ stagingArea = $StagingArea driveMappings = @() monitoredDirectories = @() } # Convert to JSON with proper formatting $jsonContent = $defaultSettings | ConvertTo-Json -Depth 10 -Compress:$false # Ensure directory exists $settingsDir = Split-Path -Path $SettingsPath -Parent if ($settingsDir -and -not (Test-Path -Path $settingsDir -PathType Container)) { Write-LogInfo -LogPath $LogPath -Message "Creating directory: $settingsDir" New-Item -Path $settingsDir -ItemType Directory -Force | Out-Null } # Write the file if ($PSCmdlet.ShouldProcess($SettingsPath, "Create settings file")) { Set-Content -Path $SettingsPath -Value $jsonContent -Encoding UTF8 -ErrorAction Stop Write-LogInfo -LogPath $LogPath -Message "Successfully created settings file: $SettingsPath" Write-LogDebug -LogPath $LogPath -Message "Default staging area: $StagingArea" } # Return the settings object for immediate use Write-LogDebug -LogPath $LogPath -Message "Returning created settings object" return $defaultSettings } catch { Write-LogError -LogPath $LogPath -Message "Failed to create settings file" -Exception $_.Exception throw } } function Set-StagingArea { <# .SYNOPSIS Sets the staging area path in the configuration file. .DESCRIPTION This cmdlet updates the stagingArea property in the settings.json file with a new path. The settings file is read, modified, and written back to disk. .PARAMETER StagingAreaPath The new staging area path to set. .PARAMETER SettingsPath The path to the settings.json file. Defaults to "settings.json" in current directory. .PARAMETER LogPath The path to the log file where operations will be logged using PSLogger. .EXAMPLE Set-StagingArea -StagingAreaPath "D:\NewStaging" -LogPath "C:\Logs\app.log" .EXAMPLE Set-StagingArea -StagingAreaPath "E:\Temp\Staging" -SettingsPath "C:\Config\settings.json" -LogPath "C:\Logs\app.log" .OUTPUTS PSCustomObject containing the updated settings configuration. #> [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$StagingAreaPath, [Parameter(Mandatory = $false)] [string]$SettingsPath = "settings.json", [Parameter(Mandatory = $true)] [string]$LogPath ) Write-LogInfo -LogPath $LogPath -Message "Setting staging area to: $StagingAreaPath" try { # Read current settings $settings = Read-SettingsFile -SettingsPath $SettingsPath -LogPath $LogPath # Update staging area $oldStagingArea = $settings.stagingArea $settings.stagingArea = $StagingAreaPath # Save updated settings if ($PSCmdlet.ShouldProcess($SettingsPath, "Update staging area from '$oldStagingArea' to '$StagingAreaPath'")) { Save-SettingsFile -Settings $settings -SettingsPath $SettingsPath -LogPath $LogPath Write-LogInfo -LogPath $LogPath -Message "Successfully updated staging area from '$oldStagingArea' to '$StagingAreaPath'" } return $settings } catch { Write-LogError -LogPath $LogPath -Message "Failed to set staging area" -Exception $_.Exception throw } } function Add-DriveMapping { <# .SYNOPSIS Adds a new drive mapping to the configuration file. .DESCRIPTION This cmdlet adds a new drive mapping with the specified letter and UNC path to the settings.json file. The drive letter must be unique and the UNC path must be valid. .PARAMETER Letter The drive letter for the mapping (single alphabetic character). .PARAMETER Path The UNC path for the drive mapping. .PARAMETER SettingsPath The path to the settings.json file. Defaults to "settings.json" in current directory. .PARAMETER LogPath The path to the log file where operations will be logged using PSLogger. .EXAMPLE Add-DriveMapping -Letter "X" -Path "\\server\share" -LogPath "C:\Logs\app.log" .EXAMPLE Add-DriveMapping -Letter "Y" -Path "\\nas\data" -SettingsPath "C:\Config\settings.json" -LogPath "C:\Logs\app.log" .OUTPUTS PSCustomObject containing the updated settings configuration. #> [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory = $true)] [ValidateLength(1, 1)] [ValidateScript({[char]::IsLetter($_)})] [string]$Letter, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [ValidateScript({$_.StartsWith("\\") -and $_.Length -gt 2})] [string]$Path, [Parameter(Mandatory = $false)] [string]$SettingsPath = "settings.json", [Parameter(Mandatory = $true)] [string]$LogPath ) $Letter = $Letter.ToUpper() Write-LogInfo -LogPath $LogPath -Message "Adding drive mapping: $Letter -> $Path" try { # Read current settings $settings = Read-SettingsFile -SettingsPath $SettingsPath -LogPath $LogPath # Check if drive letter already exists $existingMapping = $settings.driveMappings | Where-Object { $_.letter -eq $Letter } if ($existingMapping) { $errorMsg = "Drive letter '$Letter' already exists with path '$($existingMapping.path)'" Write-LogError -LogPath $LogPath -Message $errorMsg throw $errorMsg } # Create new mapping $newMapping = [PSCustomObject]@{ letter = $Letter path = $Path } # Add to settings $settings.driveMappings += $newMapping # Save updated settings if ($PSCmdlet.ShouldProcess($SettingsPath, "Add drive mapping '$Letter' -> '$Path'")) { Save-SettingsFile -Settings $settings -SettingsPath $SettingsPath -LogPath $LogPath Write-LogInfo -LogPath $LogPath -Message "Successfully added drive mapping: $Letter -> $Path" } return $settings } catch { Write-LogError -LogPath $LogPath -Message "Failed to add drive mapping" -Exception $_.Exception throw } } function Remove-DriveMapping { <# .SYNOPSIS Removes a drive mapping from the configuration file. .DESCRIPTION This cmdlet removes the drive mapping with the specified letter from the settings.json file. .PARAMETER Letter The drive letter of the mapping to remove. .PARAMETER SettingsPath The path to the settings.json file. Defaults to "settings.json" in current directory. .PARAMETER LogPath The path to the log file where operations will be logged using PSLogger. .EXAMPLE Remove-DriveMapping -Letter "X" -LogPath "C:\Logs\app.log" .EXAMPLE Remove-DriveMapping -Letter "Y" -SettingsPath "C:\Config\settings.json" -LogPath "C:\Logs\app.log" .OUTPUTS PSCustomObject containing the updated settings configuration. #> [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory = $true)] [ValidateLength(1, 1)] [ValidateScript({[char]::IsLetter($_)})] [string]$Letter, [Parameter(Mandatory = $false)] [string]$SettingsPath = "settings.json", [Parameter(Mandatory = $true)] [string]$LogPath ) $Letter = $Letter.ToUpper() Write-LogInfo -LogPath $LogPath -Message "Removing drive mapping: $Letter" try { # Read current settings $settings = Read-SettingsFile -SettingsPath $SettingsPath -LogPath $LogPath # Find existing mapping $existingMapping = $settings.driveMappings | Where-Object { $_.letter -eq $Letter } if (-not $existingMapping) { $errorMsg = "Drive letter '$Letter' not found in configuration" Write-LogError -LogPath $LogPath -Message $errorMsg throw $errorMsg } # Remove mapping $settings.driveMappings = $settings.driveMappings | Where-Object { $_.letter -ne $Letter } # Save updated settings if ($PSCmdlet.ShouldProcess($SettingsPath, "Remove drive mapping '$Letter' -> '$($existingMapping.path)'")) { Save-SettingsFile -Settings $settings -SettingsPath $SettingsPath -LogPath $LogPath Write-LogInfo -LogPath $LogPath -Message "Successfully removed drive mapping: $Letter -> $($existingMapping.path)" } return $settings } catch { Write-LogError -LogPath $LogPath -Message "Failed to remove drive mapping" -Exception $_.Exception throw } } function Set-DriveMapping { <# .SYNOPSIS Modifies an existing drive mapping in the configuration file. .DESCRIPTION This cmdlet updates the UNC path for an existing drive mapping identified by its letter. .PARAMETER Letter The drive letter of the mapping to modify. .PARAMETER Path The new UNC path for the drive mapping. .PARAMETER SettingsPath The path to the settings.json file. Defaults to "settings.json" in current directory. .PARAMETER LogPath The path to the log file where operations will be logged using PSLogger. .EXAMPLE Set-DriveMapping -Letter "X" -Path "\\newserver\share" -LogPath "C:\Logs\app.log" .EXAMPLE Set-DriveMapping -Letter "Y" -Path "\\nas\newdata" -SettingsPath "C:\Config\settings.json" -LogPath "C:\Logs\app.log" .OUTPUTS PSCustomObject containing the updated settings configuration. #> [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory = $true)] [ValidateLength(1, 1)] [ValidateScript({[char]::IsLetter($_)})] [string]$Letter, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [ValidateScript({$_.StartsWith("\\") -and $_.Length -gt 2})] [string]$Path, [Parameter(Mandatory = $false)] [string]$SettingsPath = "settings.json", [Parameter(Mandatory = $true)] [string]$LogPath ) $Letter = $Letter.ToUpper() Write-LogInfo -LogPath $LogPath -Message "Modifying drive mapping: $Letter -> $Path" try { # Read current settings $settings = Read-SettingsFile -SettingsPath $SettingsPath -LogPath $LogPath # Find existing mapping $existingMapping = $settings.driveMappings | Where-Object { $_.letter -eq $Letter } if (-not $existingMapping) { $errorMsg = "Drive letter '$Letter' not found in configuration" Write-LogError -LogPath $LogPath -Message $errorMsg throw $errorMsg } $oldPath = $existingMapping.path # Update the path $existingMapping.path = $Path # Save updated settings if ($PSCmdlet.ShouldProcess($SettingsPath, "Update drive mapping '$Letter' from '$oldPath' to '$Path'")) { Save-SettingsFile -Settings $settings -SettingsPath $SettingsPath -LogPath $LogPath Write-LogInfo -LogPath $LogPath -Message "Successfully updated drive mapping: $Letter from '$oldPath' to '$Path'" } return $settings } catch { Write-LogError -LogPath $LogPath -Message "Failed to modify drive mapping" -Exception $_.Exception throw } } function Add-MonitoredDirectory { <# .SYNOPSIS Adds a new monitored directory to the configuration file. .DESCRIPTION This cmdlet adds a new monitored directory with the specified path and optional exclusions to the settings.json file. The path must be unique in the configuration. .PARAMETER Path The path of the directory to monitor. .PARAMETER Exclusions Optional array of subdirectory names to exclude from monitoring. .PARAMETER SettingsPath The path to the settings.json file. Defaults to "settings.json" in current directory. .PARAMETER LogPath The path to the log file where operations will be logged using PSLogger. .EXAMPLE Add-MonitoredDirectory -Path "C:\MyFolder" -LogPath "C:\Logs\app.log" .EXAMPLE Add-MonitoredDirectory -Path "D:\Data" -Exclusions @("temp", "cache") -LogPath "C:\Logs\app.log" .EXAMPLE Add-MonitoredDirectory -Path "V:\aeapps\newtools" -Exclusions @("logs") -SettingsPath "C:\Config\settings.json" -LogPath "C:\Logs\app.log" .OUTPUTS PSCustomObject containing the updated settings configuration. #> [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$Path, [Parameter(Mandatory = $false)] [string[]]$Exclusions = @(), [Parameter(Mandatory = $false)] [string]$SettingsPath = "settings.json", [Parameter(Mandatory = $true)] [string]$LogPath ) Write-LogInfo -LogPath $LogPath -Message "Adding monitored directory: $Path" try { # Read current settings $settings = Read-SettingsFile -SettingsPath $SettingsPath -LogPath $LogPath # Check if path already exists $existingDir = $settings.monitoredDirectories | Where-Object { $_.path -eq $Path } if ($existingDir) { $errorMsg = "Monitored directory path '$Path' already exists" Write-LogError -LogPath $LogPath -Message $errorMsg throw $errorMsg } # Create new monitored directory $newDirectory = [PSCustomObject]@{ path = $Path exclusions = $Exclusions } # Add to settings $settings.monitoredDirectories += $newDirectory # Save updated settings if ($PSCmdlet.ShouldProcess($SettingsPath, "Add monitored directory '$Path' with $($Exclusions.Count) exclusions")) { Save-SettingsFile -Settings $settings -SettingsPath $SettingsPath -LogPath $LogPath Write-LogInfo -LogPath $LogPath -Message "Successfully added monitored directory: $Path (exclusions: $($Exclusions.Count))" } return $settings } catch { Write-LogError -LogPath $LogPath -Message "Failed to add monitored directory" -Exception $_.Exception throw } } function Remove-MonitoredDirectory { <# .SYNOPSIS Removes a monitored directory from the configuration file. .DESCRIPTION This cmdlet removes the monitored directory with the specified path from the settings.json file. .PARAMETER Path The path of the monitored directory to remove. .PARAMETER SettingsPath The path to the settings.json file. Defaults to "settings.json" in current directory. .PARAMETER LogPath The path to the log file where operations will be logged using PSLogger. .EXAMPLE Remove-MonitoredDirectory -Path "C:\OldFolder" -LogPath "C:\Logs\app.log" .EXAMPLE Remove-MonitoredDirectory -Path "V:\aeapps\oldtools" -SettingsPath "C:\Config\settings.json" -LogPath "C:\Logs\app.log" .OUTPUTS PSCustomObject containing the updated settings configuration. #> [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$Path, [Parameter(Mandatory = $false)] [string]$SettingsPath = "settings.json", [Parameter(Mandatory = $true)] [string]$LogPath ) Write-LogInfo -LogPath $LogPath -Message "Removing monitored directory: $Path" try { # Read current settings $settings = Read-SettingsFile -SettingsPath $SettingsPath -LogPath $LogPath # Find existing directory $existingDir = $settings.monitoredDirectories | Where-Object { $_.path -eq $Path } if (-not $existingDir) { $errorMsg = "Monitored directory path '$Path' not found in configuration" Write-LogError -LogPath $LogPath -Message $errorMsg throw $errorMsg } # Remove directory $settings.monitoredDirectories = $settings.monitoredDirectories | Where-Object { $_.path -ne $Path } # Save updated settings if ($PSCmdlet.ShouldProcess($SettingsPath, "Remove monitored directory '$Path'")) { Save-SettingsFile -Settings $settings -SettingsPath $SettingsPath -LogPath $LogPath Write-LogInfo -LogPath $LogPath -Message "Successfully removed monitored directory: $Path" } return $settings } catch { Write-LogError -LogPath $LogPath -Message "Failed to remove monitored directory" -Exception $_.Exception throw } } function Set-MonitoredDirectory { <# .SYNOPSIS Modifies an existing monitored directory in the configuration file. .DESCRIPTION This cmdlet updates the exclusions list for an existing monitored directory identified by its path. .PARAMETER Path The path of the monitored directory to modify. .PARAMETER Exclusions The new array of subdirectory names to exclude from monitoring. .PARAMETER SettingsPath The path to the settings.json file. Defaults to "settings.json" in current directory. .PARAMETER LogPath The path to the log file where operations will be logged using PSLogger. .EXAMPLE Set-MonitoredDirectory -Path "C:\MyFolder" -Exclusions @("temp", "cache", "logs") -LogPath "C:\Logs\app.log" .EXAMPLE Set-MonitoredDirectory -Path "V:\aeapps\tools" -Exclusions @() -LogPath "C:\Logs\app.log" # Removes all exclusions for the specified path .OUTPUTS PSCustomObject containing the updated settings configuration. #> [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$Path, [Parameter(Mandatory = $true)] [AllowEmptyCollection()] [string[]]$Exclusions, [Parameter(Mandatory = $false)] [string]$SettingsPath = "settings.json", [Parameter(Mandatory = $true)] [string]$LogPath ) Write-LogInfo -LogPath $LogPath -Message "Modifying monitored directory: $Path" try { # Read current settings $settings = Read-SettingsFile -SettingsPath $SettingsPath -LogPath $LogPath # Find existing directory $existingDir = $settings.monitoredDirectories | Where-Object { $_.path -eq $Path } if (-not $existingDir) { $errorMsg = "Monitored directory path '$Path' not found in configuration" Write-LogError -LogPath $LogPath -Message $errorMsg throw $errorMsg } $oldExclusionsCount = $existingDir.exclusions.Count # Update the exclusions $existingDir.exclusions = $Exclusions # Save updated settings if ($PSCmdlet.ShouldProcess($SettingsPath, "Update monitored directory '$Path' exclusions from $oldExclusionsCount to $($Exclusions.Count) items")) { Save-SettingsFile -Settings $settings -SettingsPath $SettingsPath -LogPath $LogPath Write-LogInfo -LogPath $LogPath -Message "Successfully updated monitored directory: $Path (exclusions changed from $oldExclusionsCount to $($Exclusions.Count) items)" } return $settings } catch { Write-LogError -LogPath $LogPath -Message "Failed to modify monitored directory" -Exception $_.Exception throw } } function Save-SettingsFile { <# .SYNOPSIS Saves the settings object to the specified JSON file. .DESCRIPTION This is a helper function that converts the settings object to JSON and writes it to the file. Used internally by other configuration management cmdlets. .PARAMETER Settings The settings object to save. .PARAMETER SettingsPath The path to the settings.json file. .PARAMETER LogPath The path to the log file where operations will be logged using PSLogger. #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] $Settings, [Parameter(Mandatory = $true)] [string]$SettingsPath, [Parameter(Mandatory = $true)] [string]$LogPath ) try { # Convert to JSON with proper formatting $jsonContent = $Settings | ConvertTo-Json -Depth 10 -Compress:$false # Ensure directory exists $settingsDir = Split-Path -Path $SettingsPath -Parent if ($settingsDir -and -not (Test-Path -Path $settingsDir -PathType Container)) { Write-LogInfo -LogPath $LogPath -Message "Creating directory: $settingsDir" New-Item -Path $settingsDir -ItemType Directory -Force | Out-Null } # Write the file Set-Content -Path $SettingsPath -Value $jsonContent -Encoding UTF8 -ErrorAction Stop Write-LogDebug -LogPath $LogPath -Message "Successfully saved settings to: $SettingsPath" } catch { Write-LogError -LogPath $LogPath -Message "Failed to save settings file" -Exception $_.Exception throw } } function Test-DriveMapping { <# .SYNOPSIS Validates a drive mapping object. .PARAMETER Mapping The drive mapping object to validate. .PARAMETER LogPath Path to log file for validation messages. .OUTPUTS Boolean indicating if the mapping is valid. #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] $Mapping, [Parameter(Mandatory = $true)] [string]$LogPath ) try { # Check required properties exist if (-not ($Mapping.PSObject.Properties.Name -contains "letter" -and $Mapping.PSObject.Properties.Name -contains "path")) { Write-LogWarning -LogPath $LogPath -Message "Drive mapping missing required properties (letter/path)" return $false } # Validate letter is single alphabetic character if ([string]::IsNullOrWhiteSpace($Mapping.letter) -or $Mapping.letter.Length -ne 1 -or -not [char]::IsLetter($Mapping.letter)) { Write-LogWarning -LogPath $LogPath -Message "Invalid drive letter: '$($Mapping.letter)'" return $false } # Validate UNC path format if ([string]::IsNullOrWhiteSpace($Mapping.path) -or -not $Mapping.path.StartsWith("\\") -or $Mapping.path.Length -le 2) { Write-LogWarning -LogPath $LogPath -Message "Invalid UNC path for drive $($Mapping.letter): '$($Mapping.path)'" return $false } Write-LogDebug -LogPath $LogPath -Message "Valid drive mapping: $($Mapping.letter) -> $($Mapping.path)" return $true } catch { Write-LogWarning -LogPath $LogPath -Message "Error validating drive mapping" -Exception $_.Exception return $false } } function Test-MonitoredDirectory { <# .SYNOPSIS Validates a monitored directory object. .PARAMETER Directory The monitored directory object to validate. .PARAMETER LogPath Path to log file for validation messages. .OUTPUTS Boolean indicating if the directory configuration is valid. #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] $Directory, [Parameter(Mandatory = $true)] [string]$LogPath ) try { # Check required path property if (-not ($Directory.PSObject.Properties.Name -contains "path") -or [string]::IsNullOrWhiteSpace($Directory.path)) { Write-LogWarning -LogPath $LogPath -Message "Monitored directory missing or empty path" return $false } # Ensure exclusions property exists and is array if (-not ($Directory.PSObject.Properties.Name -contains "exclusions")) { $Directory | Add-Member -MemberType NoteProperty -Name "exclusions" -Value @() -Force } elseif ($Directory.exclusions -isnot [array]) { $Directory.exclusions = @($Directory.exclusions) } Write-LogDebug -LogPath $LogPath -Message "Valid monitored directory: $($Directory.path) (exclusions: $($Directory.exclusions.Count))" return $true } catch { Write-LogWarning -LogPath $LogPath -Message "Error validating monitored directory" -Exception $_.Exception return $false } } # Export all public functions Export-ModuleMember -Function Read-SettingsFile, New-SettingsFile, Set-StagingArea, Add-DriveMapping, Remove-DriveMapping, Set-DriveMapping, Add-MonitoredDirectory, Remove-MonitoredDirectory, Set-MonitoredDirectory |