Initial commit
This commit is contained in:
commit
e46472393a
|
|
@ -0,0 +1 @@
|
|||
config.json
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
@{
|
||||
ModuleVersion = '1.0.0'
|
||||
GUID = 'affc6c50-b639-478a-a2f2-b7356f1ace16'
|
||||
Author = 'Alex Kohut'
|
||||
Description = 'Handles logging operations.'
|
||||
FunctionsToExport = @('Initialize-Logging', 'Write-Log')
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
# Modules/Logging/Logging.psm1
|
||||
|
||||
# Function to initialize the log file path
|
||||
function Initialize-Logging {
|
||||
param (
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$Path
|
||||
)
|
||||
|
||||
# Store the log file path in a module-scoped variable
|
||||
$Script:LogFile = $Path
|
||||
}
|
||||
|
||||
# Function to log messages with timestamps
|
||||
function Write-Log {
|
||||
param (
|
||||
[string]$Message,
|
||||
[ValidateSet("INFO", "WARNING", "ERROR")]
|
||||
[string]$Type = "INFO"
|
||||
)
|
||||
|
||||
if (-not $Script:LogFile) {
|
||||
Throw "Log file path is not initialized. Please run Initialize-Logging first."
|
||||
}
|
||||
|
||||
$logTimestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||
$logMessage = "$logTimestamp [$Type] - $Message"
|
||||
|
||||
Add-Content -Path $Script:LogFile -Value $logMessage
|
||||
|
||||
switch ($Type) {
|
||||
"INFO" { Write-Verbose $logMessage }
|
||||
"WARNING" { Write-Warning $logMessage }
|
||||
"ERROR" { Write-Error $logMessage }
|
||||
}
|
||||
}
|
||||
|
||||
# Export the functions
|
||||
Export-ModuleMember -Function Initialize-Logging, Write-Log
|
||||
|
|
@ -0,0 +1,423 @@
|
|||
<#
|
||||
.SYNOPSIS
|
||||
Compares the last two versions of a specified file for a given company based on the manifest.json.
|
||||
|
||||
.DESCRIPTION
|
||||
This script takes a company name and a file name as input, reads the manifest.json to find the last two backup versions of the file,
|
||||
extracts them, locates the specific files within the backups, and performs a comparison. The results are logged for audit control.
|
||||
|
||||
.PARAMETER CompanyName
|
||||
The name of the company whose file you want to compare.
|
||||
|
||||
.PARAMETER FileName
|
||||
The specific file within the company's directory to compare.
|
||||
|
||||
.EXAMPLE
|
||||
.\Compare-NWABackup.ps1 -CompanyName "CompanyA" -FileName "DataFile.DAT"
|
||||
|
||||
.NOTES
|
||||
Ensure that the manifest.json is correctly formatted and accessible.
|
||||
#>
|
||||
|
||||
param (
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$CompanyName,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$FileName
|
||||
)
|
||||
|
||||
# ----------- Step 1: Define Variables -----------
|
||||
# Assuming manifest.json is located in the backup root directory
|
||||
$backupRoot = "C:\Users\$env:USERNAME\Desktop\NWABackup" # Adjust as necessary
|
||||
$manifestFilePath = Join-Path -Path $backupRoot -ChildPath "manifest.json"
|
||||
|
||||
# Define log file path
|
||||
$logDirectory = Join-Path -Path $backupRoot -ChildPath "Logs"
|
||||
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
|
||||
$logFile = Join-Path -Path $logDirectory -ChildPath "$timestamp.log"
|
||||
|
||||
# Define temporary extraction directories
|
||||
$tempExtractionRoot = Join-Path -Path $backupRoot -ChildPath "TempComparisons"
|
||||
$tempDirLatest = Join-Path -Path $tempExtractionRoot -ChildPath "$FileName\Latest_$timestamp"
|
||||
$tempDirPrevious = Join-Path -Path $tempExtractionRoot -ChildPath "$FileName\Previous_$timestamp"
|
||||
|
||||
# ----------- Step 0: Import Logging Module -----------
|
||||
$modulesPath = Join-Path -Path (Split-Path -Parent $MyInvocation.MyCommand.Path) -ChildPath ""
|
||||
Import-Module (Join-Path -Path $modulesPath -ChildPath "Logging\Logging.psm1") -Force
|
||||
|
||||
# Create log directory if it doesn't exist
|
||||
if (!(Test-Path -Path $logDirectory)) {
|
||||
try {
|
||||
New-Item -ItemType Directory -Path $logDirectory -Force | Out-Null
|
||||
# Initialize Logging after creating the log directory
|
||||
Initialize-Logging -Path $logFile
|
||||
Write-Log -Message "Log directory created at ${logDirectory}" -Type "INFO"
|
||||
}
|
||||
catch {
|
||||
Write-Error "Failed to create log directory at ${logDirectory}: $_"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
else {
|
||||
# Initialize Logging if log directory already exists
|
||||
Initialize-Logging -Path $logFile
|
||||
}
|
||||
|
||||
# ----------- Step 2: Initialize Logging -----------
|
||||
# Create log directory if it doesn't exist
|
||||
if (!(Test-Path -Path $logDirectory)) {
|
||||
try {
|
||||
New-Item -ItemType Directory -Path $logDirectory -Force | Out-Null
|
||||
# Initialize Logging after creating the log directory
|
||||
Initialize-Logging -Path $logFile
|
||||
Write-Log -Message "Log directory created at ${logDirectory}" -Type "INFO"
|
||||
}
|
||||
catch {
|
||||
Write-Error "Failed to create log directory at ${logDirectory}: $_"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
else {
|
||||
# Initialize Logging if log directory already exists
|
||||
Initialize-Logging -Path $logFile
|
||||
}
|
||||
|
||||
# Log the start of the comparison process
|
||||
Write-Log -Message "=== NWABackup Comparison Process Started at $timestamp ===" -Type "INFO"
|
||||
|
||||
# ----------- Step 3: Load the Manifest and Find the File -----------
|
||||
if (!(Test-Path -Path $manifestFilePath)) {
|
||||
Write-Log -Message "Manifest file not found at $manifestFilePath." -Type "ERROR"
|
||||
exit 1
|
||||
}
|
||||
|
||||
try {
|
||||
$manifestContent = Get-Content -Path $manifestFilePath -Raw | ConvertFrom-Json
|
||||
Write-Log -Message "Manifest file loaded successfully." -Type "INFO"
|
||||
}
|
||||
catch {
|
||||
Write-Log -Message "Failed to load manifest file: $_" -Type "ERROR"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Check if the company exists in the manifest
|
||||
if (-not ($manifestContent.PSObject.Properties.Name -contains $CompanyName)) {
|
||||
Write-Log -Message "Company '$CompanyName' not found in the manifest." -Type "ERROR"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Navigate to the specific part for the given company
|
||||
$companyData = $manifestContent.$CompanyName
|
||||
$targetPart = $null
|
||||
$targetZipPaths = @()
|
||||
|
||||
foreach ($partName in $companyData.PSObject.Properties.Name) {
|
||||
# Check if the part contains a 'DAT' entry
|
||||
if ($companyData.$partName.PSObject.Properties.Name -contains 'DAT') {
|
||||
# Retrieve the list of zip files for 'DAT'
|
||||
$datFiles = $companyData.$partName.DAT
|
||||
|
||||
# Check if the part name matches the provided file name (excluding extension)
|
||||
$fileBaseName = [System.IO.Path]::GetFileNameWithoutExtension($FileName)
|
||||
if ($fileBaseName -eq $partName) {
|
||||
$targetPart = $partName
|
||||
$targetZipPaths = $datFiles
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (-not $targetPart) {
|
||||
Write-Log -Message "File '$FileName' not found under any part for company '$CompanyName'." -Type "ERROR"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Log -Message "Found '$FileName' under part '$targetPart' for company '$CompanyName'." -Type "INFO"
|
||||
|
||||
# Use the matching zip paths for comparison
|
||||
$backupZips = $targetZipPaths
|
||||
|
||||
# ----------- Step 4: Check Number of Versions -----------
|
||||
if ($backupZips.Count -lt 2) {
|
||||
Write-Log -Message "Only $($backupZips.Count) version(s) found for $CompanyName\$FileName. At least two versions are required for comparison." -Type "WARNING"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# ----------- Step 5: Get Locations of the Two Prior Backups -----------
|
||||
# Function to extract DateTime from zip file name
|
||||
function Get-ZipTimestamp {
|
||||
param (
|
||||
[string]$ZipPath
|
||||
)
|
||||
|
||||
# Extract the zip file name without extension
|
||||
$zipName = [System.IO.Path]::GetFileNameWithoutExtension($ZipPath)
|
||||
|
||||
# Assuming zip file name contains the timestamp in 'yyyyMMdd_HHmmss' format
|
||||
$timestampString = $zipName -replace '^.*?(\d{8}_\d{6}).*$', '$1'
|
||||
|
||||
try {
|
||||
return [datetime]::ParseExact($timestampString, 'yyyyMMdd_HHmmss', $null)
|
||||
}
|
||||
catch {
|
||||
Write-Log -Message "Failed to parse timestamp from zip file name '$zipName'. Ensure the zip file name contains a timestamp in 'yyyyMMdd_HHmmss' format." -Type "ERROR"
|
||||
return $null
|
||||
}
|
||||
}
|
||||
|
||||
# Create a list of objects containing zip paths and their timestamps
|
||||
$backupList = @()
|
||||
|
||||
foreach ($zip in $backupZips) {
|
||||
if (!(Test-Path -Path $zip)) {
|
||||
Write-Log -Message "Backup zip file not found: $zip" -Type "ERROR"
|
||||
continue
|
||||
}
|
||||
|
||||
$timestamp = Get-ZipTimestamp -ZipPath $zip
|
||||
if ($timestamp -ne $null) {
|
||||
$backupList += [PSCustomObject]@{
|
||||
ZipPath = $zip
|
||||
Timestamp = $timestamp
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Check if we have at least two valid backups
|
||||
if ($backupList.Count -lt 2) {
|
||||
Write-Log -Message "Not enough valid backup versions found for $CompanyName\$FileName." -Type "ERROR"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Sort the backups by timestamp in descending order (latest first)
|
||||
$sortedBackups = $backupList | Sort-Object -Property Timestamp -Descending
|
||||
|
||||
# Select the top two backups
|
||||
$latestBackup = $sortedBackups[0]
|
||||
$previousBackup = $sortedBackups[1]
|
||||
|
||||
Write-Log -Message "Latest backup: $($latestBackup.ZipPath) (Timestamp: $($latestBackup.Timestamp))" -Type "INFO"
|
||||
Write-Log -Message "Previous backup: $($previousBackup.ZipPath) (Timestamp: $($previousBackup.Timestamp))" -Type "INFO"
|
||||
|
||||
# ----------- Step 6: Unzip the Two Folders for Inspection -----------
|
||||
# Ensure temporary extraction directories exist
|
||||
try {
|
||||
New-Item -ItemType Directory -Path $tempDirLatest -Force | Out-Null
|
||||
New-Item -ItemType Directory -Path $tempDirPrevious -Force | Out-Null
|
||||
Write-Log -Message "Created temporary directories for extraction." -Type "INFO"
|
||||
}
|
||||
catch {
|
||||
Write-Log -Message "Failed to create temporary extraction directories: $_" -Type "ERROR"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Function to extract a specific file from a zip archive
|
||||
function Extract-SpecificFile {
|
||||
param (
|
||||
[string]$ZipPath,
|
||||
[string]$CompanyName,
|
||||
[string]$FileName,
|
||||
[string]$DestinationDir
|
||||
)
|
||||
|
||||
try {
|
||||
# Expand-Archive extracts all files; to optimize, you could extract only the specific file if needed
|
||||
Expand-Archive -Path $ZipPath -DestinationPath $DestinationDir -Force
|
||||
Write-Log -Message "Extracted '$FileName' from '$ZipPath' to '$DestinationDir'." -Type "INFO"
|
||||
}
|
||||
catch {
|
||||
Write-Log -Message "Failed to extract '$FileName' from '$ZipPath': $_" -Type "ERROR"
|
||||
throw $_
|
||||
}
|
||||
}
|
||||
|
||||
# Extract the specified file from the latest backup
|
||||
try {
|
||||
Extract-SpecificFile -ZipPath $latestBackup.ZipPath -CompanyName $CompanyName -FileName $FileName -DestinationDir $tempDirLatest
|
||||
}
|
||||
catch {
|
||||
Write-Log -Message "Extraction failed for the latest backup. Aborting comparison." -Type "ERROR"
|
||||
# Cleanup before exiting
|
||||
Remove-Item -Path $tempDirLatest -Recurse -Force -ErrorAction SilentlyContinue
|
||||
Remove-Item -Path $tempDirPrevious -Recurse -Force -ErrorAction SilentlyContinue
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Extract the specified file from the previous backup
|
||||
try {
|
||||
Extract-SpecificFile -ZipPath $previousBackup.ZipPath -CompanyName $CompanyName -FileName $FileName -DestinationDir $tempDirPrevious
|
||||
}
|
||||
catch {
|
||||
Write-Log -Message "Extraction failed for the previous backup. Aborting comparison." -Type "ERROR"
|
||||
# Cleanup before exiting
|
||||
Remove-Item -Path $tempDirLatest -Recurse -Force -ErrorAction SilentlyContinue
|
||||
Remove-Item -Path $tempDirPrevious -Recurse -Force -ErrorAction SilentlyContinue
|
||||
exit 1
|
||||
}
|
||||
|
||||
# ----------- Step 7: Locate the Files in Each Folder -----------
|
||||
# Construct the expected file paths after extraction
|
||||
$extractedFileLatest = Join-Path -Path (Join-Path -Path $tempDirLatest -ChildPath $CompanyName) -ChildPath $FileName
|
||||
$extractedFilePrevious = Join-Path -Path (Join-Path -Path $tempDirPrevious -ChildPath $CompanyName) -ChildPath $FileName
|
||||
|
||||
# Verify that the extracted files exist
|
||||
if (!(Test-Path -Path $extractedFileLatest)) {
|
||||
Write-Log -Message "Latest extracted file not found at '$extractedFileLatest'." -Type "ERROR"
|
||||
# Cleanup before exiting
|
||||
Remove-Item -Path $tempDirLatest -Recurse -Force -ErrorAction SilentlyContinue
|
||||
Remove-Item -Path $tempDirPrevious -Recurse -Force -ErrorAction SilentlyContinue
|
||||
exit 1
|
||||
}
|
||||
|
||||
if (!(Test-Path -Path $extractedFilePrevious)) {
|
||||
Write-Log -Message "Previous extracted file not found at '$extractedFilePrevious'." -Type "ERROR"
|
||||
# Cleanup before exiting
|
||||
Remove-Item -Path $tempDirLatest -Recurse -Force -ErrorAction SilentlyContinue
|
||||
Remove-Item -Path $tempDirPrevious -Recurse -Force -ErrorAction SilentlyContinue
|
||||
exit 1
|
||||
}
|
||||
|
||||
# ----------- Step 8: Run a Diff Against the Two Files -----------
|
||||
# Determine if the files are text or binary based on extension
|
||||
$extension = [System.IO.Path]::GetExtension($FileName).ToLower()
|
||||
|
||||
# Function to compare text files
|
||||
function Compare-TextFiles {
|
||||
param (
|
||||
[string]$ReferenceFile,
|
||||
[string]$DifferenceFile
|
||||
)
|
||||
|
||||
try {
|
||||
# Read all lines from both files
|
||||
$refLines = Get-Content -Path $ReferenceFile
|
||||
$diffLines = Get-Content -Path $DifferenceFile
|
||||
|
||||
# Determine the maximum number of lines between both files
|
||||
$maxLines = [Math]::Max($refLines.Count, $diffLines.Count)
|
||||
|
||||
# Initialize an array to store detailed differences
|
||||
$differences = @()
|
||||
|
||||
# Loop through each line number
|
||||
for ($i = 0; $i -lt $maxLines; $i++) {
|
||||
$lineNumber = $i + 1
|
||||
$refLine = if ($i -lt $refLines.Count) { $refLines[$i] } else { $null }
|
||||
$diffLine = if ($i -lt $diffLines.Count) { $diffLines[$i] } else { $null }
|
||||
|
||||
if ($refLine -ne $diffLine) {
|
||||
if ($refLine -ne $null -and $diffLine -ne $null) {
|
||||
# Line exists in both files but is different (Modified)
|
||||
$differences += "Line ${lineNumber}: Modified"
|
||||
$differences += " Reference: $refLine"
|
||||
$differences += " Difference: $diffLine"
|
||||
}
|
||||
elseif ($refLine -ne $null) {
|
||||
# Line exists only in the reference file (Removed)
|
||||
$differences += "Line ${lineNumber}: Removed"
|
||||
$differences += " Reference: $refLine"
|
||||
}
|
||||
elseif ($diffLine -ne $null) {
|
||||
# Line exists only in the difference file (Added)
|
||||
$differences += "Line ${lineNumber}: Added"
|
||||
$differences += " Difference: $diffLine"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($differences.Count -gt 0) {
|
||||
Write-Log -Message "Differences found between '$ReferenceFile' and '$DifferenceFile':" -Type "INFO"
|
||||
|
||||
# Log each difference
|
||||
foreach ($diff in $differences) {
|
||||
Write-Log -Message $diff -Type "INFO"
|
||||
}
|
||||
|
||||
# Define the differences output file path
|
||||
# Ensure that $logFile and $timestamp are accessible within this function
|
||||
if ($global:LogFile -and $global:timestamp) {
|
||||
$logDir = Split-Path -Path $global:LogFile -Parent
|
||||
$differenceFileName = "$(Split-Path -Path $DifferenceFile -Leaf)-Differences-$($global:timestamp).txt"
|
||||
|
||||
# Sanitize the difference file name to remove any invalid characters
|
||||
$invalidChars = [System.IO.Path]::GetInvalidFileNameChars()
|
||||
foreach ($char in $invalidChars) {
|
||||
$differenceFileName = $differenceFileName -replace [regex]::Escape($char), '_'
|
||||
}
|
||||
|
||||
$diffFilePath = Join-Path -Path $logDir -ChildPath $differenceFileName
|
||||
}
|
||||
else {
|
||||
# Fallback if $global:LogFile or $global:timestamp is not defined
|
||||
$logDir = Split-Path -Path $DifferenceFile -Parent
|
||||
$differenceFileName = "Differences-$(Get-Date -Format 'yyyyMMdd_HHmmss').txt"
|
||||
$diffFilePath = Join-Path -Path $logDir -ChildPath $differenceFileName
|
||||
}
|
||||
|
||||
# Export differences to the separate file
|
||||
$differences | Out-File -FilePath $diffFilePath -Encoding UTF8
|
||||
|
||||
Write-Output $differences
|
||||
|
||||
Write-Log -Message "Differences exported to '$diffFilePath'." -Type "INFO"
|
||||
}
|
||||
else {
|
||||
Write-Output "No differences found between '$ReferenceFile' and '$DifferenceFile'."
|
||||
Write-Log -Message "No differences found between '$ReferenceFile' and '$DifferenceFile'." -Type "INFO"
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Log -Message "Failed to compare text files: $_" -Type "ERROR"
|
||||
}
|
||||
}
|
||||
|
||||
# Function to compare binary files using hash comparison
|
||||
function Compare-BinaryFiles {
|
||||
param (
|
||||
[string]$ReferenceFile,
|
||||
[string]$DifferenceFile
|
||||
)
|
||||
|
||||
try {
|
||||
$hashReference = Get-FileHash -Path $ReferenceFile -Algorithm SHA256
|
||||
$hashDifference = Get-FileHash -Path $DifferenceFile -Algorithm SHA256
|
||||
|
||||
if ($hashReference.Hash -ne $hashDifference.Hash) {
|
||||
Write-Log -Message "Hash mismatch detected between '$ReferenceFile' and '$DifferenceFile'." -Type "INFO"
|
||||
Write-Log -Message "Reference Hash: $($hashReference.Hash)" -Type "INFO"
|
||||
Write-Log -Message "Difference Hash: $($hashDifference.Hash)" -Type "INFO"
|
||||
}
|
||||
else {
|
||||
Write-Log -Message "No hash differences found between '$ReferenceFile' and '$DifferenceFile'." -Type "INFO"
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Log -Message "Failed to compare binary files: $_" -Type "ERROR"
|
||||
}
|
||||
}
|
||||
|
||||
# Execute the appropriate comparison based on file type
|
||||
if ($extension -eq '.dat' -or $extension -eq '.nwh') {
|
||||
# Assuming .DAT and .NWH are text files; adjust if they are binary
|
||||
Compare-TextFiles -ReferenceFile $extractedFilePrevious -DifferenceFile $extractedFileLatest
|
||||
}
|
||||
else {
|
||||
# For other file types, perform binary comparison
|
||||
Compare-BinaryFiles -ReferenceFile $extractedFilePrevious -DifferenceFile $extractedFileLatest
|
||||
}
|
||||
|
||||
# ----------- Step 9: Cleanup Temporary Directories -----------
|
||||
try {
|
||||
Remove-Item -Path $tempDirLatest -Recurse -Force
|
||||
Remove-Item -Path $tempDirPrevious -Recurse -Force
|
||||
Remove-Item -Path $tempExtractionRoot -Recurse -Force
|
||||
Write-Log -Message "Cleaned up temporary extraction directories." -Type "INFO"
|
||||
}
|
||||
catch {
|
||||
Write-Log -Message "Failed to remove temporary directories: $_" -Type "WARNING"
|
||||
}
|
||||
|
||||
# ----------- Step 10: Completion Message -----------
|
||||
Write-Log -Message "Comparison process completed for $CompanyName\$FileName." -Type "INFO"
|
||||
Write-Host "Comparison completed. Check the log file at '$logFile' for details."
|
||||
|
|
@ -0,0 +1,279 @@
|
|||
# --------------------------------------------
|
||||
# Northwest Analytics (NWA) Backup Script
|
||||
# --------------------------------------------
|
||||
# This script backs up .DAT and .NWH files from the shared
|
||||
# directory to a user-specific backup folder, preserving
|
||||
# the company directory structure and compressing the
|
||||
# backup into a zip file. It also maintains a global
|
||||
# manifest in JSON format.
|
||||
# --------------------------------------------
|
||||
|
||||
function ConvertTo-Hashtable {
|
||||
param (
|
||||
[Parameter(Mandatory = $true)]
|
||||
[object]$InputObject
|
||||
)
|
||||
|
||||
if ($InputObject -is [System.Management.Automation.PSCustomObject]) {
|
||||
$hash = @{}
|
||||
foreach ($prop in $InputObject.PSObject.Properties) {
|
||||
$hash[$prop.Name] = ConvertTo-Hashtable -InputObject $prop.Value
|
||||
}
|
||||
return $hash
|
||||
}
|
||||
elseif ($InputObject -is [System.Array]) {
|
||||
return $InputObject | ForEach-Object { ConvertTo-Hashtable -InputObject $_ }
|
||||
}
|
||||
else {
|
||||
return $InputObject
|
||||
}
|
||||
}
|
||||
|
||||
# ----------- Step 0: Import Logging Module -----------
|
||||
$modulesPath = Join-Path -Path (Split-Path -Parent $MyInvocation.MyCommand.Path) -ChildPath ""
|
||||
Import-Module (Join-Path -Path $modulesPath -ChildPath "Logging\Logging.psm1") -Force
|
||||
|
||||
# ----------- Step 1: Define Variables -----------
|
||||
|
||||
$sharedDirectory = "X:\dev\BOYD\%NWA\Data Collection" # Using environment variable
|
||||
$username = $env:USERNAME
|
||||
$backupRoot = "C:\Users\$username\Desktop\NWABackup"
|
||||
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
|
||||
$daysBack = 4
|
||||
$thresholdDate = (Get-Date).AddDays(-$daysBack)
|
||||
|
||||
$backupDirectory = Join-Path -Path $backupRoot -ChildPath $timestamp
|
||||
$zipFilePath = Join-Path -Path $backupRoot -ChildPath "$timestamp.zip"
|
||||
$manifestFilePath = Join-Path -Path $backupRoot -ChildPath "manifest.json"
|
||||
|
||||
|
||||
# Define log file path
|
||||
$logDirectory = Join-Path -Path $backupRoot -ChildPath "Logs"
|
||||
$logFile = Join-Path -Path $logDirectory -ChildPath "$timestamp.log"
|
||||
|
||||
# ----------- Step 2: Initialize Logging -----------
|
||||
|
||||
# Create log directory if it doesn't exist
|
||||
if (!(Test-Path -Path $logDirectory)) {
|
||||
try {
|
||||
New-Item -ItemType Directory -Path $logDirectory -Force | Out-Null
|
||||
# Initialize Logging after creating the log directory
|
||||
Initialize-Logging -Path $logFile
|
||||
Write-Log -Message "Log directory created at ${logDirectory}" -Type "INFO"
|
||||
}
|
||||
catch {
|
||||
Write-Error "Failed to create log directory at ${logDirectory}: $_"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
else {
|
||||
# Initialize Logging if log directory already exists
|
||||
Initialize-Logging -Path $logFile
|
||||
}
|
||||
|
||||
# Log the start of the backup process
|
||||
Write-Log -Message "=== NWABackup Process Started at $timestamp ===" -Type "INFO"
|
||||
|
||||
# ----------- Step 3: Create Backup Directory -----------
|
||||
|
||||
if (!(Test-Path -Path $backupDirectory)) {
|
||||
try {
|
||||
New-Item -ItemType Directory -Path $backupDirectory -Force | Out-Null
|
||||
Write-Log -Message "Backup directory created at ${backupDirectory}" -Type "INFO"
|
||||
}
|
||||
catch {
|
||||
Write-Log -Message "Failed to create backup directory at ${backupDirectory}. Error: $_" -Type "ERROR"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
else {
|
||||
Write-Log -Message "Backup directory already exists at ${backupDirectory}" -Type "INFO"
|
||||
}
|
||||
|
||||
# ----------- Step 4: Copy .DAT and .NWH Files -----------
|
||||
|
||||
# Define the file extensions to include (case-insensitive)
|
||||
$fileExtensions = @('.DAT', '.NWH')
|
||||
|
||||
Write-Log -Message "Starting file retrieval and copy process." -Type "INFO"
|
||||
|
||||
# Get all files recursively and filter by extension and modification date in a single pass
|
||||
try {
|
||||
$files = Get-ChildItem -Path $sharedDirectory -Recurse -File | Where-Object {
|
||||
($fileExtensions -contains $_.Extension.ToUpper()) -and ($_.LastWriteTime -ge $thresholdDate)
|
||||
}
|
||||
Write-Log -Message "Found $($files.Count) files with specified extensions modified in the last $daysBack days." -Type "INFO"
|
||||
}
|
||||
catch {
|
||||
Write-Log -Message "Error retrieving files: $_" -Type "ERROR"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Initialize a hashtable to build the manifest
|
||||
$manifest = @{}
|
||||
|
||||
foreach ($file in $files) {
|
||||
# Extract company name from the folder structure
|
||||
$relativePath = $file.FullName.Substring($sharedDirectory.Length).TrimStart("\")
|
||||
$pathParts = $relativePath.Split("\")
|
||||
if ($pathParts.Length -lt 2) {
|
||||
Write-Log -Message "Invalid file path structure: $relativePath" -Type "WARNING"
|
||||
continue
|
||||
}
|
||||
|
||||
$companyName = $pathParts[0]
|
||||
$fileName = $pathParts[-1]
|
||||
|
||||
# Extract part name and file type from the file name
|
||||
$partName, $fileType = $fileName -split '\.', 2
|
||||
|
||||
if (-not $fileType) {
|
||||
Write-Log -Message "Invalid file format: $fileName" -Type "WARNING"
|
||||
continue
|
||||
}
|
||||
|
||||
# Initialize company entry if not exists
|
||||
if (-not $manifest.ContainsKey($companyName)) {
|
||||
$manifest[$companyName] = @{}
|
||||
}
|
||||
|
||||
# Initialize part entry if not exists
|
||||
if (-not $manifest[$companyName].ContainsKey($partName)) {
|
||||
$manifest[$companyName][$partName] = @{} # This must be a hash table, not an array
|
||||
}
|
||||
|
||||
# Initialize file type entry if not exists
|
||||
if (-not $manifest[$companyName][$partName].ContainsKey($fileType)) {
|
||||
$manifest[$companyName][$partName][$fileType] = @()
|
||||
}
|
||||
|
||||
# Add the current backup zip file to the file type's backup array
|
||||
if (-not $manifest[$companyName][$partName][$fileType].Contains($zipFilePath)) {
|
||||
$manifest[$companyName][$partName][$fileType] += $zipFilePath
|
||||
}
|
||||
|
||||
# Define the destination path
|
||||
$destinationPath = Join-Path -Path $backupDirectory -ChildPath $relativePath
|
||||
|
||||
# Get the destination directory
|
||||
$destinationDir = Split-Path -Path $destinationPath -Parent
|
||||
|
||||
# Create the destination directory if it doesn't exist
|
||||
if (!(Test-Path -Path $destinationDir)) {
|
||||
try {
|
||||
New-Item -ItemType Directory -Path $destinationDir -Force | Out-Null
|
||||
Write-Log -Message "Created directory: ${destinationDir}" -Type "INFO"
|
||||
}
|
||||
catch {
|
||||
Write-Log -Message "Failed to create directory ${destinationDir}: $_" -Type "ERROR"
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
# Copy the file to the backup directory
|
||||
try {
|
||||
Copy-Item -Path $file.FullName -Destination $destinationPath -Force -ErrorAction Stop
|
||||
Write-Log -Message "Copied: $($file.FullName) to ${destinationPath}" -Type "INFO"
|
||||
}
|
||||
catch {
|
||||
Write-Log -Message "Failed to copy $($file.FullName) to ${destinationPath}: $_" -Type "ERROR"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
# ----------- Step 5: Update and Save the Manifest JSON -----------
|
||||
if (Test-Path -Path $manifestFilePath) {
|
||||
try {
|
||||
$existingManifest = Get-Content -Path $manifestFilePath | ConvertFrom-Json
|
||||
Write-Log -Message "Loaded existing manifest file." -Type "INFO"
|
||||
}
|
||||
catch {
|
||||
Write-Log -Message "Failed to load existing manifest file. Creating a new one. Error: $_" -Type "ERROR"
|
||||
$existingManifest = @{}
|
||||
}
|
||||
}
|
||||
else {
|
||||
$existingManifest = @{}
|
||||
}
|
||||
|
||||
# Convert PSCustomObject to Hashtable
|
||||
$existingManifest = ConvertTo-Hashtable -InputObject $existingManifest
|
||||
|
||||
# Merge the current manifest into the existing manifest
|
||||
foreach ($company in $manifest.Keys) {
|
||||
if (-not $existingManifest.ContainsKey($company)) {
|
||||
$existingManifest[$company] = @{}
|
||||
Write-Log -Message "Added new company '$company' to manifest." -Type "INFO"
|
||||
}
|
||||
|
||||
foreach ($partName in $manifest[$company].Keys) {
|
||||
if (-not $existingManifest[$company].ContainsKey($partName)) {
|
||||
$existingManifest[$company][$partName] = @{}
|
||||
Write-Log -Message "Added new part '$partName' under company '$company' to manifest." -Type "INFO"
|
||||
}
|
||||
|
||||
foreach ($fileType in $manifest[$company][$partName].Keys) {
|
||||
if (-not $existingManifest[$company][$partName].ContainsKey($fileType)) {
|
||||
$existingManifest[$company][$partName][$fileType] = @()
|
||||
Write-Log -Message "Added new file type '$fileType' under part '$partName' for company '$company' to manifest." -Type "INFO"
|
||||
}
|
||||
|
||||
foreach ($zip in $manifest[$company][$partName][$fileType]) {
|
||||
# Ensure the value is treated as an array
|
||||
if ($existingManifest[$company][$partName][$fileType] -isnot [System.Collections.ArrayList]) {
|
||||
$existingManifest[$company][$partName][$fileType] = @($existingManifest[$company][$partName][$fileType])
|
||||
}
|
||||
|
||||
# Add the zip path to the array if it doesn't already exist
|
||||
if (-not $existingManifest[$company][$partName][$fileType].Contains($zip)) {
|
||||
$existingManifest[$company][$partName][$fileType] += $zip
|
||||
Write-Log -Message "Added zip '$zip' to '$company\\$partName\\$fileType' in manifest." -Type "INFO"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Convert the hashtable to JSON with formatting
|
||||
$jsonContent = $existingManifest | ConvertTo-Json -Depth 10 -Compress:$false
|
||||
|
||||
# Save the updated manifest
|
||||
try {
|
||||
Set-Content -Path $manifestFilePath -Value $jsonContent -Encoding UTF8
|
||||
Write-Log -Message "Manifest file updated at $manifestFilePath" -Type "INFO"
|
||||
}
|
||||
catch {
|
||||
Write-Log -Message "Failed to update manifest file at $manifestFilePath. Error: $_" -Type "ERROR"
|
||||
}
|
||||
|
||||
|
||||
# ----------- Step 6: Compress the Backup Directory -----------
|
||||
|
||||
try {
|
||||
# Compress the *contents* of the backup directory, not the directory itself
|
||||
Compress-Archive -Path "$backupDirectory\*" -DestinationPath $zipFilePath -Force
|
||||
Write-Log -Message "Successfully compressed backup to $zipFilePath" -Type "INFO"
|
||||
}
|
||||
catch {
|
||||
Write-Log -Message "Failed to compress backup directory: $_" -Type "ERROR"
|
||||
# Optionally, decide whether to exit or continue
|
||||
}
|
||||
|
||||
# ----------- Step 7: Cleanup (Optional) -----------
|
||||
|
||||
# Optionally, remove the uncompressed backup directory after compression
|
||||
try {
|
||||
Remove-Item -Path $backupDirectory -Recurse -Force
|
||||
Write-Log -Message "Removed uncompressed backup directory: ${backupDirectory}" -Type "INFO"
|
||||
}
|
||||
catch {
|
||||
Write-Log -Message "Failed to remove uncompressed backup directory ${backupDirectory}: $_" -Type "ERROR"
|
||||
}
|
||||
|
||||
# ----------- Step 8: Completion Message -----------
|
||||
|
||||
Write-Log -Message "Backup process completed." -Type "INFO"
|
||||
|
||||
# Optionally, display a message to the user
|
||||
Write-Host "Backup completed successfully. Log file located at $logFile"
|
||||
|
|
@ -0,0 +1,258 @@
|
|||
$configFilePath = Join-Path -Path $PSScriptRoot -ChildPath "config.json"
|
||||
|
||||
# Check if the configuration file exists
|
||||
if (-Not (Test-Path $configFilePath)) {
|
||||
Write-Error "Configuration file not found at $configFilePath"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Load the configuration file
|
||||
$config = Get-Content $configFilePath | ConvertFrom-Json
|
||||
|
||||
# Variables for script paths
|
||||
$backupScriptPath = $config.BackupScriptPath
|
||||
$compareScriptPath = $config.CompareScriptPath
|
||||
$outputPath = $config.OutputPath
|
||||
|
||||
# Import necessary assemblies for GUI
|
||||
Add-Type -AssemblyName System.Windows.Forms
|
||||
Add-Type -AssemblyName System.Drawing
|
||||
|
||||
$processing = $false
|
||||
|
||||
# Create Form
|
||||
$form = New-Object System.Windows.Forms.Form
|
||||
$form.Text = "NWA Sentinel"
|
||||
$form.Size = New-Object System.Drawing.Size(800, 700)
|
||||
$form.StartPosition = "CenterScreen"
|
||||
|
||||
# Create Backup Button
|
||||
$backupButton = New-Object System.Windows.Forms.Button
|
||||
$backupButton.Text = "Backup"
|
||||
$backupButton.Size = New-Object System.Drawing.Size(100, 30)
|
||||
$backupButton.Location = New-Object System.Drawing.Point(10, 10)
|
||||
$form.Controls.Add($backupButton)
|
||||
|
||||
# Create Company List Box
|
||||
$companyList = New-Object System.Windows.Forms.ListBox
|
||||
$companyList.Size = New-Object System.Drawing.Size(200, 300)
|
||||
$companyList.Location = New-Object System.Drawing.Point(10, 50)
|
||||
$form.Controls.Add($companyList)
|
||||
|
||||
# Create File Details List Box
|
||||
$fileDetailsListBox = New-Object System.Windows.Forms.ListBox
|
||||
$fileDetailsListBox.Size = New-Object System.Drawing.Size(550, 300)
|
||||
$fileDetailsListBox.Location = New-Object System.Drawing.Point(220, 50)
|
||||
$form.Controls.Add($fileDetailsListBox)
|
||||
|
||||
# Create Compare Button
|
||||
$compareButton = New-Object System.Windows.Forms.Button
|
||||
$compareButton.Text = "Compare"
|
||||
$compareButton.Size = New-Object System.Drawing.Size(100, 30)
|
||||
$compareButton.Location = New-Object System.Drawing.Point(10, 360)
|
||||
$compareButton.Enabled = $false
|
||||
$form.Controls.Add($compareButton)
|
||||
|
||||
# Create QXP Button
|
||||
$qxpButton = New-Object System.Windows.Forms.Button
|
||||
$qxpButton.Text = "QXP"
|
||||
$qxpButton.Size = New-Object System.Drawing.Size(100, 30)
|
||||
$qxpButton.Location = New-Object System.Drawing.Point(120, 360)
|
||||
$qxpButton.Enabled = $false
|
||||
$form.Controls.Add($qxpButton)
|
||||
|
||||
# Create Compare Output Text Box
|
||||
$compareOutputBox = New-Object System.Windows.Forms.TextBox
|
||||
$compareOutputBox.Multiline = $true
|
||||
$compareOutputBox.ReadOnly = $true
|
||||
$compareOutputBox.ScrollBars = "Vertical"
|
||||
$compareOutputBox.Size = New-Object System.Drawing.Size(760, 200)
|
||||
$compareOutputBox.Location = New-Object System.Drawing.Point(10, 400)
|
||||
$form.Controls.Add($compareOutputBox)
|
||||
|
||||
# Load Company Names into ListBox from manifest.json
|
||||
$manifestPath = "C:\Users\$env:USERNAME\Desktop\NWABackup\manifest.json"
|
||||
$manifestData = $null
|
||||
if (Test-Path $manifestPath) {
|
||||
try {
|
||||
$manifestData = Get-Content -Path $manifestPath | ConvertFrom-Json
|
||||
$companyNames = $manifestData.PSObject.Properties.Name
|
||||
$companyList.Items.AddRange($companyNames)
|
||||
} catch {
|
||||
[System.Windows.Forms.MessageBox]::Show("Failed to parse manifest.json: $_", "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error)
|
||||
}
|
||||
} else {
|
||||
[System.Windows.Forms.MessageBox]::Show("Manifest file not found at $manifestPath", "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error)
|
||||
}
|
||||
|
||||
# Event: When a company is selected, populate file details
|
||||
$companyList.Add_SelectedIndexChanged({
|
||||
$selectedCompany = $companyList.SelectedItem
|
||||
$compareOutputBox.Text = ""
|
||||
$qxpButton.Enabled = $false # Disable the QXP button when the company changes
|
||||
|
||||
if ($selectedCompany -and $manifestData) {
|
||||
$fileDetailsListBox.Items.Clear()
|
||||
try {
|
||||
# Retrieve the file groups for the selected company
|
||||
$fileGroups = $manifestData.$selectedCompany.PSObject.Properties
|
||||
|
||||
foreach ($group in $fileGroups) {
|
||||
$fileData = $group.Value
|
||||
$datFiles = $fileData.DAT
|
||||
$qxpFiles = $fileData.QXP
|
||||
|
||||
# Extract dates from zip file paths
|
||||
$dates = $datFiles | ForEach-Object {
|
||||
if ($_ -match "\\(\d{8})_(\d{6})\.zip$") {
|
||||
# Combine date and time into a single string
|
||||
$dateTimeString = "$($matches[1])$($matches[2])"
|
||||
[datetime]::ParseExact($dateTimeString, "yyyyMMddHHmmss", $null)
|
||||
} else {
|
||||
$null
|
||||
}
|
||||
}
|
||||
|
||||
# Get the latest date
|
||||
$latestDate = $dates | Where-Object { $_ } | Sort-Object -Descending | Select-Object -First 1
|
||||
|
||||
# Display the file group and its latest date
|
||||
$latestDateText = if ($latestDate) {
|
||||
$latestDate.ToString("yyyy-MM-dd HH:mm:ss")
|
||||
} else {
|
||||
"No valid date found"
|
||||
}
|
||||
|
||||
$groupName = [string]$group.Name
|
||||
$fileDetailsListBox.Items.Add("$latestDateText :: $groupName")
|
||||
}
|
||||
} catch {
|
||||
[System.Windows.Forms.MessageBox]::Show("Error processing files for company '$selectedCompany': $_", "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
$fileDetailsListBox.Add_SelectedIndexChanged({
|
||||
$compareOutputBox.Text = "" # Clear the output box
|
||||
$compareButton.Enabled = $true # Enable the Compare button
|
||||
|
||||
$selectedFileGroup = $fileDetailsListBox.SelectedItem
|
||||
$selectedCompany = $companyList.SelectedItem
|
||||
$qxpButton.Enabled = $false # Disable the QXP button by default
|
||||
|
||||
if ($selectedFileGroup -and $selectedCompany -and $manifestData) {
|
||||
try {
|
||||
# Extract the part name from the selected file group
|
||||
$partName = $selectedFileGroup -replace ".* :: ", ""
|
||||
|
||||
# Check if the selected part has QXP files
|
||||
$qxpFiles = $manifestData.$selectedCompany.$partName.QXP
|
||||
|
||||
if ($qxpFiles -and $qxpFiles.Count -gt 0) {
|
||||
$qxpButton.Enabled = $true
|
||||
}
|
||||
} catch {
|
||||
[System.Windows.Forms.MessageBox]::Show("Error checking QXP availability for '$selectedFileGroup': $_", "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
# Backup Button Click Event
|
||||
$backupButton.Add_Click({
|
||||
if (Test-Path $backupScriptPath) {
|
||||
Start-Process -FilePath "powershell.exe" -ArgumentList "-File `"$backupScriptPath`"" -NoNewWindow -Wait
|
||||
[System.Windows.Forms.MessageBox]::Show("Backup completed.", "Information", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Information)
|
||||
} else {
|
||||
[System.Windows.Forms.MessageBox]::Show("Backup script not found at $backupScriptPath", "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error)
|
||||
}
|
||||
})
|
||||
|
||||
# Compare Button Click Event
|
||||
$compareButton.Add_Click({
|
||||
if ($processing) {
|
||||
[System.Windows.Forms.MessageBox]::Show("Please wait for the current operation to complete.", "Info", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Information)
|
||||
return
|
||||
}
|
||||
|
||||
$selectedCompany = $companyList.SelectedItem
|
||||
$selectedFileGroup = $fileDetailsListBox.SelectedItem
|
||||
|
||||
if (-not $selectedCompany) {
|
||||
[System.Windows.Forms.MessageBox]::Show("Please select a company from the list.", "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error)
|
||||
return
|
||||
}
|
||||
|
||||
if (-not $selectedFileGroup) {
|
||||
[System.Windows.Forms.MessageBox]::Show("Please select a file group from the list.", "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error)
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
$processing = $true
|
||||
$backupButton.Enabled = $false
|
||||
$compareButton.Enabled = $false
|
||||
|
||||
$compareOutputBox.text = ""
|
||||
# Extract the file name (ignore the date and time)
|
||||
$fileName = $selectedFileGroup -replace ".* :: ", ""
|
||||
|
||||
# Construct the PowerShell command
|
||||
$command = "$compareScriptPath -CompanyName '$selectedCompany' -FileName '$fileName.DAT'"
|
||||
|
||||
# Run the compare script and redirect output
|
||||
$processInfo = New-Object System.Diagnostics.ProcessStartInfo
|
||||
$processInfo.FileName = "powershell.exe"
|
||||
$processInfo.Arguments = "-NoProfile -Command `"$command`""
|
||||
$processInfo.RedirectStandardOutput = $true
|
||||
$processInfo.RedirectStandardError = $true
|
||||
$processInfo.UseShellExecute = $false
|
||||
$processInfo.CreateNoWindow = $true
|
||||
|
||||
$process = New-Object System.Diagnostics.Process
|
||||
$process.StartInfo = $processInfo
|
||||
$process.Start() | Out-Null
|
||||
|
||||
# Read both standard output and error output
|
||||
$output = $process.StandardOutput.ReadToEnd()
|
||||
$errorOutput = $process.StandardError.ReadToEnd()
|
||||
$process.WaitForExit()
|
||||
|
||||
# Display the output or errors in the Compare Output TextBox
|
||||
if ($output) {
|
||||
$compareOutputBox.Text = $output -join "`r`n"
|
||||
} elseif ($errorOutput) {
|
||||
$compareOutputBox.Text = "Error: $errorOutput"
|
||||
} else {
|
||||
$compareOutputBox.Text = "No output received from the compare script."
|
||||
}
|
||||
|
||||
} catch {
|
||||
[System.Windows.Forms.MessageBox]::Show("Error running compare script: $($_.Exception.Message)", "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error)
|
||||
} finally {
|
||||
$processing = $false
|
||||
$backupButton.Enabled = $true
|
||||
}
|
||||
})
|
||||
|
||||
# Event: QXP Button Click
|
||||
$qxpButton.Add_Click({
|
||||
$selectedCompany = $companyList.SelectedItem
|
||||
if (-not $selectedCompany) {
|
||||
[System.Windows.Forms.MessageBox]::Show("Please select a company from the list.", "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error)
|
||||
return
|
||||
}
|
||||
|
||||
$selectedFileGroup = $fileDetailsListBox.SelectedItem
|
||||
if (-not $selectedFileGroup) {
|
||||
[System.Windows.Forms.MessageBox]::Show("Please select a file group from the list.", "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error)
|
||||
return
|
||||
}
|
||||
|
||||
$fileName = $selectedFileGroup -replace ".* - ", ""
|
||||
[System.Windows.Forms.MessageBox]::Show("Opening QXP file for ${selectedCompany}: $fileName", "QXP File", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Information)
|
||||
|
||||
# Implement the actual logic for opening the QXP file if needed
|
||||
})
|
||||
|
||||
# Show Form
|
||||
$form.ShowDialog()
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"BackupScriptPath": "X:\\dev\\BOYD\\sentinel\\Modules\\NWABackup.ps1",
|
||||
"CompareScriptPath": "X:\\dev\\BOYD\\sentinel\\Modules\\NWA-Compare.ps1",
|
||||
"OutputPath": "C:\\Users\\$env:USERNAME\\Desktop\\NWABackup\\logs\\compare-output.txt"
|
||||
}
|
||||
Loading…
Reference in New Issue