From 6dba2de28450608f549cc84df66466cb0f56f7dd Mon Sep 17 00:00:00 2001 From: tigattack <10629864+tigattack@users.noreply.github.com> Date: Tue, 2 Apr 2024 16:44:48 +0100 Subject: [PATCH 1/2] refactor(deployveeamconfig): rework script * Extract logic into functions * Simplify user choice prompts * Improve/fix support for configuring different job types * Improve error handling & output (fix/improve output for user, pre-fill more information in GitHub issue, etc) * Add `-nonInteractive` switches for job configuration functions (so-far unused, possible future functionality) * Other misc. changes --- resources/DeployVeeamConfiguration.ps1 | 488 +++++++++++++------------ 1 file changed, 254 insertions(+), 234 deletions(-) diff --git a/resources/DeployVeeamConfiguration.ps1 b/resources/DeployVeeamConfiguration.ps1 index 15e9dca..f2a8d01 100644 --- a/resources/DeployVeeamConfiguration.ps1 +++ b/resources/DeployVeeamConfiguration.ps1 @@ -2,273 +2,195 @@ param( [String]$InstallParentPath = 'C:\VeeamScripts' ) -# Function to be used when an error is encountered -function DeploymentError { - $issues = 'https://github.com/tigattack/VeeamNotify/issues' - - Write-Output "An error occured $($_.ScriptStackTrace.Split("`n")[0]): $($_.Exception.Message)" - Write-Output "`nPlease raise an issue at $issues" - - $launchIssuesPrompt_yes = New-Object System.Management.Automation.Host.ChoiceDescription '&Yes', 'Open a new issue' - $launchIssuesPrompt_no = New-Object System.Management.Automation.Host.ChoiceDescription '&No', 'Do nothing' - $launchIssuesPrompt_opts = [System.Management.Automation.Host.ChoiceDescription[]]($launchIssuesPrompt_Yes, $launchIssuesPrompt_No) - $launchIssuesPrompt_result = $host.UI.PromptForChoice('Open a new issue', 'Do you wish to open the new issue page in your browser?', $launchIssuesPrompt_opts, -1) - - If ($launchIssuesPrompt_result -eq 1) { - Start-Process "$issues/new?assignees=tigattack&labels=bug&template=bug_report.yml&title=[BUG]+Veeam%20configuration%20deployment%20error" - } +$issuesUrl = 'https://github.com/tigattack/VeeamNotify/issues' + +#region Prompt definitions TODO: move these somewhere else? +$backupChoiceParams = @{ + caption = 'Create a Veeam Configuration Backup?' + message = 'This script can create a Veeam configuration backup for you before making any changes.' + choices = [System.Management.Automation.Host.ChoiceDescription[]]( + [System.Management.Automation.Host.ChoiceDescription]::new('&Yes', 'Create a Veeam configuration backup.'), + [System.Management.Automation.Host.ChoiceDescription]::new('&No', 'Do not create a Veeam configuration backup.') + ) + defaultChoice = 0 } -# Post-job script for VeeamNotify -# Get PowerShell path -try { - $powershellExePath = (Get-Command -Name 'powershell.exe' -ErrorAction Stop).Path -} -catch { - DeploymentError +$backupErrorParams = @{ + caption = 'Backup Failed' + message = 'Do you want to continue anyway?' + choices = [System.Management.Automation.Host.ChoiceDescription[]]( + [System.Management.Automation.Host.ChoiceDescription]::new('&Yes', 'Continue anyway.'), + [System.Management.Automation.Host.ChoiceDescription]::new('&No', 'Exit now.') + ) + defaultChoice = -1 } -$newPostScriptCmd = "$powershellExePath -ExecutionPolicy Bypass -File $(Join-Path -Path "$InstallParentPath" -ChildPath 'VeeamNotify\Bootstrap.ps1')" +$configChoiceParams = @{ + caption = 'Job Configuration Selection' + message = 'Do you wish to configure all supported jobs, make a decision for each job, or configure none?' + choices = [System.Management.Automation.Host.ChoiceDescription[]]( + [System.Management.Automation.Host.ChoiceDescription]::new('&All', 'Configure all supported jobs automatically.'), + [System.Management.Automation.Host.ChoiceDescription]::new('&Decide', 'Make a decision for each job.'), + [System.Management.Automation.Host.ChoiceDescription]::new('&None', 'Do not configure any jobs.') + ) + defaultChoice = 0 +} -# Import Veeam module -Import-Module Veeam.Backup.PowerShell -DisableNameChecking +$launchIssuesPromptParams = @{ + caption = "Please raise an issue at ${issuesUrl}" + message = 'Do you wish to open the new issue page in your browser?' + choices = [System.Management.Automation.Host.ChoiceDescription[]]( + [System.Management.Automation.Host.ChoiceDescription]::new('&Yes', 'Open a new issue'), + [System.Management.Automation.Host.ChoiceDescription]::new('&No', 'Do nothing') + ) + defaultChoice = -1 +} -# Get all supported jobs -$backupJobs = Get-VBRJob -WarningAction SilentlyContinue | Where-Object { - $_.JobType -in 'Backup', 'Replica', 'EpAgentBackup' -} | Sort-Object -Property Name, Type +$overwriteCurrentCmdParams = @{ + caption = 'Overwrite Job Configuration' + message = 'Do you wish to overwrite the existing post-job script?' + choices = [System.Management.Automation.Host.ChoiceDescription[]]( + [System.Management.Automation.Host.ChoiceDescription]::new('&Yes', 'Overwrite the current post-job script.'), + [System.Management.Automation.Host.ChoiceDescription]::new('&No', 'Skip configuration of this job, leaving it as-is.') + ) + defaultChoice = -1 +} -# Make sure we found some jobs -if ($backupJobs.Count -eq 0) { - Write-Output 'No supported jobs found; Exiting.' - Start-Sleep 10 - exit +$setNewPostScriptParams = @{ + caption = 'Send notifications for this job?' + message = '' + choices = [System.Management.Automation.Host.ChoiceDescription[]]( + [System.Management.Automation.Host.ChoiceDescription]::new('&Yes', 'Configure this job to send notifications.'), + [System.Management.Automation.Host.ChoiceDescription]::new('&No', 'Skip configuration of this job, leaving it as-is.') + ) + defaultChoice = -1 } -else { - Write-Output "Found $($backupJobs.count) supported jobs:" - $backupJobs | Format-Table -Property Name, @{Name = 'Type'; Expression = { $_.TypeToString } } -AutoSize +#endregion + +#region Functions +function DoPrompt ($params) { + return $host.UI.PromptForChoice($params.caption, $params.message, $params.choices, $params.defaultChoice) } -# Query config backup -$backupChoice_yes = New-Object System.Management.Automation.Host.ChoiceDescription '&Yes', 'Create a Veeam configuration backup.' -$backupChoice_no = New-Object System.Management.Automation.Host.ChoiceDescription '&No', 'Do not create a Veeam configuration backup.' -$backupChoice_opts = [System.Management.Automation.Host.ChoiceDescription[]]($backupChoice_yes, $backupChoice_no) -$backupChoice_message = 'This script can create a Veeam configuration backup for you before making any changes. Do you want to create a backup now?' -$backupChoice_result = $host.UI.PromptForChoice('Veeam Configuration Backup', $backupChoice_message, $backupChoice_opts, 0) +function DeploymentError { + $errorPosition = $_.InvocationInfo.PSCommandPath, $_.InvocationInfo.ScriptLineNumber, $_.InvocationInfo.OffsetInLine -join ':' + $errorFunction = $_.InvocationInfo.MyCommand + $errorException = $_.Exception.Message -If ($backupChoice_result -eq 0) { - # Run backup - Write-Output "`nCreating backup, please wait..." - ($backupResult = Start-VBRConfigurationBackupJob) | Out-Null - if ($backupResult.Result -ne 'Failed') { - Write-Output 'Backup completed successfully.' + if ($errorFunction) { + Write-Output "An error occurred in ${errorFunction} at ${errorPosition}: ${errorException}" | Out-Host } else { - $continueChoice_yes = New-Object System.Management.Automation.Host.ChoiceDescription '&Yes', 'Continue anyway.' - $continueChoice_no = New-Object System.Management.Automation.Host.ChoiceDescription '&No', 'Exit now.' - $continueChoice_opts = [System.Management.Automation.Host.ChoiceDescription[]]($continueChoice_yes, $continueChoice_no) - $continueChoice_result = $host.UI.PromptForChoice('Backup Failed', 'Do you want to continue anyway', $continueChoice_opts, -1) + Write-Output "An error occurred at ${errorPosition}: ${errorException}" | Out-Host + } - if ($continueChoice_result -eq 1) { - Write-Output 'Exiting.' - Start-Sleep 10 - exit - } - else { - Write-Output 'Continuing anyway.' - } + $launchIssuesPromptResp = DoPrompt($launchIssuesPromptParams) + if ($launchIssuesPromptResp -eq 0) { + Add-Type -AssemblyName System.Web + $title = [System.Web.HttpUtility]::UrlEncode('[BUG] Veeam configuration deployment error') + + $formatString = 'Exception: +```ps1 +{0} : {1} +{2} + + CategoryInfo : {3} + + FullyQualifiedErrorId : {4} +```' + $fields = $_.InvocationInfo.MyCommand.Name, $_.Exception.Message, $_.InvocationInfo.PositionMessage, $_.CategoryInfo.ToString(), $_.FullyQualifiedErrorId + $errorString = [System.Web.HttpUtility]::UrlEncode($formatString -f $fields) + + $veeamBuild = (Get-Item 'C:\Program Files\Veeam\Backup and Replication\Backup\Packages\VeeamDeploymentDll.dll').VersionInfo.ProductVersion + + Start-Process "$issuesUrl/new?labels=bug&template=bug_report.yml&title=${title}&veeam_version=${veeamBuild}&logs=${errorString}" } + Write-Output "`nExiting." | Out-Host + Start-Sleep 3 + exit } -# Query configure all or selected jobs -$configChoice_all = New-Object System.Management.Automation.Host.ChoiceDescription '&All', 'Configure all supported jobs automatically.' -$configChoice_decide = New-Object System.Management.Automation.Host.ChoiceDescription '&Decide', 'Make a decision for each job.' -$configChoice_none = New-Object System.Management.Automation.Host.ChoiceDescription '&None', 'Do not configure any jobs.' -$configChoice_opts = [System.Management.Automation.Host.ChoiceDescription[]]($configChoice_all, $configChoice_decide, $configChoice_none) -$configChoice_message = 'Do you wish to configure all supported jobs, make a decision for each job, or configure none?' -$configChoice_result = $host.UI.PromptForChoice('Job Configuration Selection', $configChoice_message, $configChoice_opts, 0) - -If ($configChoice_result -eq 1) { - # Run foreach loop for all found backup jobs - foreach ($job in $backupJobs) { - # Set name string - $jobName = "`"$($job.Name)`"" - - # Get post-job script options for job - $jobOptions = $job.GetOptions() - $postScriptEnabled = $jobOptions.JobScriptCommand.PostScriptEnabled - $postScriptCmd = $jobOptions.JobScriptCommand.PostScriptCommandLine - - # Check if job is already configured for VeeamNotify - if ($postScriptCmd.EndsWith('\Bootstrap.ps1') -or $postScriptCmd.EndsWith("\Bootstrap.ps1'")) { - - # Check if job has full PowerShell.exe path - if ($postScriptCmd.StartsWith('powershell.exe', 'CurrentCultureIgnoreCase')) { - Write-Output "`n$($jobName) is already configured for VeeamNotify, but does not have a full path to Powershell. Updating..." - try { - # Replace Powershell.exe with full path in a new variable for update. - $PostScriptFullPSPath = $postScriptCmd -replace 'Powershell.exe', 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' - # Set job to use modified post script path - $jobOptions.JobScriptCommand.PostScriptCommandLine = $PostScriptFullPSPath - Set-VBRJobOptions -Job $job -Options $jobOptions | Out-Null - - Write-Output "$($jobName) is now updated." - Continue - } - catch { - DeploymentError - } +function GetJobScriptOptions ($job) { + switch ($job.GetType().Name) { + 'CBackupJob' { + $opts = $job.GetOptions() + return @{ + 'jobOptions' = $opts; + 'PostScriptEnabled' = $opts.JobScriptCommand.PostScriptEnabled; + 'PostScriptCommandLine' = $opts.JobScriptCommand.PostScriptCommandLine } - - # skip if all correct - else { - Write-Output "`n$($jobName) is already configured for VeeamNotify; Skipping." - Continue + } + 'VBRComputerBackupJob' { + $opts = $job.ScriptOptions + return @{ + 'jobOptions' = $opts; + 'PostScriptEnabled' = $opts.PostScriptEnabled; + 'PostScriptCommandLine' = $opts.PostCommand } } + } +} - # Different actions whether post-job script is already enabled. If yes we ask to modify it, if not we ask to enable & set it. - if ($postScriptEnabled) { - Write-Output "`n$($jobName) has an existing post-job script.`nScript: $postScriptCmd" - Write-Output "`nIf you wish to receive notifications for this job, you must overwrite the existing post-job script." - - $overwriteCurrentCmd_yes = New-Object System.Management.Automation.Host.ChoiceDescription '&yes', 'Overwrite the current post-job script.' - $overwriteCurrentCmd_no = New-Object System.Management.Automation.Host.ChoiceDescription '&no', 'Skip configuration of this job, leaving it as-is.' - $overwriteCurrentCmd_opts = [System.Management.Automation.Host.ChoiceDescription[]]($overwriteCurrentCmd_yes, $overwriteCurrentCmd_no) - $overwriteCurrentCmd_result = $host.UI.PromptForChoice('Overwrite Job Configuration', 'Do you wish to overwrite the existing post-job script?', $overwriteCurrentCmd_opts, -1) - - switch ($overWriteCurrentCmd_result) { - # Overwrite current post-job script - 0 { - try { - # Check to see if the script has even changed - if ($postScriptCmd -ne $newPostScriptCmd) { - - # Script is not the same. Update the script command line. - $jobOptions.JobScriptCommand.PostScriptCommandLine = $newPostScriptCmd - Set-VBRJobOptions -Job $job -Options $jobOptions | Out-Null - - Write-Output "Updated post-job script for job $($jobName).`nOld: $postScriptCmd`nNew: $newPostScriptCmd" - Write-Output "$($jobName) is now configured for VeeamNotify." - } - else { - # Script hasn't changed. Notify user of this and continue. - Write-Output "$($jobName) is already configured for VeeamNotify; Skipping." - } - } - catch { - DeploymentError - } - } - # Skip configuration of this job - 1 { Write-Output "`nSkipping job $($jobName)`n" } - # Default action will be to skip the job. - default { Write-Output "`nSkipping job $($jobName)`n" } - } +function PatchJobScriptOptions ($job, $newPostScriptCmd, $jobOptions) { + switch ($job.GetType().Name) { + 'CBackupJob' { + $jobOptions.JobScriptCommand.PostScriptEnabled = $true + $jobOptions.JobScriptCommand.PostScriptCommandLine = $newPostScriptCmd + return Set-VBRJobOptions -Job $job -Options $jobOptions } - else { - $setNewPostScript_yes = New-Object System.Management.Automation.Host.ChoiceDescription '&Yes', 'Configure this job to send notifications.' - $setNewPostScript_no = New-Object System.Management.Automation.Host.ChoiceDescription '&No', 'Skip configuration of this job, leaving it as-is.' - $setNewPostScript_opts = [System.Management.Automation.Host.ChoiceDescription[]]($setNewPostScript_yes, $setNewPostScript_no) - $setNewPostScript_message = "Do you wish to receive notifications for $($jobName) ($($job.TypeToString))?" - $setNewPostScript_result = $host.UI.PromptForChoice('Configure Job', $setNewPostScript_message, $setNewPostScript_opts, -1) - - Switch ($setNewPostScript_result) { - # Overwrite current post-job script - 0 { - try { - # Sets post-job script to Enabled and sets the command line to full command including path. - $jobOptions.JobScriptCommand.PostScriptEnabled = $true - $jobOptions.JobScriptCommand.PostScriptCommandLine = $newPostScriptCmd - Set-VBRJobOptions -Job $job -Options $jobOptions | Out-Null - - Write-Output "`n$($jobName) is now configured for VeeamNotify." - } - catch { - DeploymentError - } - } - # Skip configuration of this job - 1 { Write-Output "`nSkipping job $($jobName)`n" } - # Default action will be to skip the job. - default { Write-Output "`nSkipping job $($jobName)`n" } - } + 'VBRComputerBackupJob' { + $newScriptOptions = Set-VBRJobScriptOptions -JobScriptOptions $job.ScriptOptions -PostScriptEnabled -PostCommand $newPostScriptCmd + return Set-VBRComputerBackupJob -Job $job -ScriptOptions $newScriptOptions } } } -elseif ($configChoice_result -eq 0) { - # Run foreach loop for all found backup jobs - foreach ($job in $backupJobs) { - # Set name string - $jobName = "`"$($job.Name)`"" - - # Get post-job script options for job - $jobOptions = $job.GetOptions() - $postScriptEnabled = $jobOptions.JobScriptCommand.PostScriptEnabled - $postScriptCmd = $jobOptions.JobScriptCommand.PostScriptCommandLine - - # Check if job is already configured for VeeamNotify - if ($postScriptCmd.EndsWith('\Bootstrap.ps1') -or $postScriptCmd.EndsWith("\Bootstrap.ps1'")) { - - # Check if job has full PowerShell.exe path - if ($postScriptCmd.StartsWith('powershell.exe', 'CurrentCultureIgnoreCase')) { - Write-Output "`n$($jobName) is already configured for VeeamNotify, but does not have a full path to Powershell. Updating..." - try { - # Replace Powershell.exe with full path in a new variable for update. - $PostScriptFullPSPath = $postScriptCmd -replace 'Powershell.exe', 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' - # Set job to use modified post script path - $jobOptions.JobScriptCommand.PostScriptCommandLine = $PostScriptFullPSPath - Set-VBRJobOptions -Job $job -Options $jobOptions | Out-Null - - Write-Output "$($jobName) is now updated." - Continue - } - catch { - DeploymentError - } - } +function ConfigureJob ($job, [string]$newPostScriptCmd, [switch]$nonInteractive) { + # Get post-job script options for job + $opts = GetJobScriptOptions -job $job + $jobOptions = $opts.jobOptions + $postScriptEnabled = $opts.PostScriptEnabled + $postScriptCmd = $opts.PostScriptCommandLine + + # Check if job is already configured for VeeamNotify + if ($postScriptCmd -eq $newPostScriptCmd) { + Write-Output "$($job.Name) is already configured for VeeamNotify; Skipping." + return + } - # skip if all correct - else { - Write-Output "`n$($jobName) is already configured for VeeamNotify; Skipping." - Continue - } - } + elseif ($postScriptEnabled) { + Write-Output "`n$($job.Name) has an existing post-job script.`nScript: $postScriptCmd" - # Different actions whether post-job script is already enabled. If yes we ask to modify it, if not we ask to enable & set it. - if ($postScriptEnabled) { - Write-Output "`n$($jobName) has an existing post-job script.`nScript: $postScriptCmd" + if (-not $nonInteractive) { Write-Output "`nIf you wish to receive notifications for this job, you must overwrite the existing post-job script." + $overwriteCurrentCmdResp = DoPrompt($overwriteCurrentCmdParams) + if ($overwriteCurrentCmdResp -eq 1) { + Write-Output "`nSkipping job $($job.Name)`n" + } + } + if ($nonInteractive -or $overwriteCurrentCmdResp -eq 0) { try { - # Check to see if the script has even changed - if ($postScriptCmd -ne $newPostScriptCmd) { - - # Script is not the same. Update the script command line. - $jobOptions.JobScriptCommand.PostScriptCommandLine = $newPostScriptCmd - Set-VBRJobOptions -Job $job -Options $jobOptions | Out-Null - - Write-Output "Updated post-job script for job $($jobName).`nOld: $postScriptCmd`nNew: $newPostScriptCmd" - Write-Output "$($jobName) is now configured for VeeamNotify." - } - else { - # Script hasn't changed. Notify user of this and continue. - Write-Output "$($jobName) is already configured for VeeamNotify; Skipping." - } + PatchJobScriptOptions -job $job -newPostScriptCmd $newPostScriptCmd -jobOptions $jobOptions | Out-Null + Write-Output "Updated post-job script for job $($job.Name).`nOld: $postScriptCmd`nNew: $newPostScriptCmd" + Write-Output "$($job.Name) is now configured for VeeamNotify." } catch { DeploymentError } } - else { - try { - # Sets post-job script to Enabled and sets the command line to full command including path. - $jobOptions.JobScriptCommand.PostScriptEnabled = $true - $jobOptions.JobScriptCommand.PostScriptCommandLine = $newPostScriptCmd - Set-VBRJobOptions -Job $job -Options $jobOptions | Out-Null + } - Write-Output "`n$($jobName) is now configured for VeeamNotify." + else { + if (-not $nonInteractive) { + $setNewPostScriptResp = DoPrompt($setNewPostScriptParams) + if ($setNewPostScriptResp -eq 1) { + Write-Output "`nSkipping job $($job.Name)`n" + } + } + + if ($nonInteractive -or $setNewPostScriptResp -eq 0) { + try { + PatchJobScriptOptions -job $job -newPostScriptCmd $newPostScriptCmd -jobOptions $jobOptions | Out-Null + Write-Output "`n$($job.Name) is now configured for VeeamNotify." } catch { DeploymentError @@ -277,13 +199,111 @@ elseif ($configChoice_result -eq 0) { } } -elseif ($configChoice_result -eq 2) { - Write-Output 'Skipping VeeamNotify configuration deployment for all jobs.' +function ConfigureJobs ([array]$backupJobs, [string]$newPostScriptCmd, [switch]$nonInteractive) { + foreach ($job in $backupJobs) { + Write-Output "`nChecking job '$($job.Name)'..." + ConfigureJob -job $job -newPostScriptCmd $newPostScriptCmd -nonInteractive:$nonInteractive + } +} + +function GetJobs { + $jobs = @() + try { + $jobs += Get-VBRJob | Where-Object { + $_.JobType -in 'Backup', 'Replica' + } + $jobs += Get-VBRComputerBackupJob | Where-Object { + $_.Mode -eq 'ManagedByBackupServer' + } + return ($jobs | Sort-Object -Property Name) + } + catch { + DeploymentError + } +} +#endregion + +# Get PowerShell path +try { + $powershellExePath = (Get-Command -Name 'powershell.exe' -ErrorAction Stop).Path +} +catch { + DeploymentError +} + +$newPostScriptCmd = "$powershellExePath -ExecutionPolicy Bypass -File $(Join-Path -Path "$InstallParentPath" -ChildPath 'VeeamNotify\Bootstrap.ps1')" + +# Import Veeam module +Import-Module Veeam.Backup.PowerShell -DisableNameChecking + +if ($MyInvocation.ScriptName -notlike '*Installer.ps1') { + Write-Output " +__ __ _ _ _ _ __ +\ \ / /__ ___ __ _ _ __ ___ | \ | | ___ | |_(_)/ _|_ _ + \ \ / / _ \/ _ \/ _` | '_ ` _ \| \| |/ _ \| __| | |_| | | | + \ V / __/ __/ (_| | | | | | | |\ | (_) | |_| | _| |_| | + \_/ \___|\___|\__,_|_| |_| |_|_| \_|\___/ \__|_|_| \__, | + |___/ +" +} + +# Get all supported jobs +Write-Output 'Discovering supported jobs...' +$backupJobs = GetJobs + +if ($backupJobs.Count -gt 0) { + Write-Output "Found $($backupJobs.count) supported jobs:" + $type = if ($backupJobs[0].JobType -eq 'Backup') { 'Backup' } elseif ($backupJobs[0].JobType -eq 'Replica') { 'Replication' } + + $backupJobs | Format-Table -AutoSize -Property Name, @{Name = 'Type'; Expression = { + if ($_.Mode -eq 'ManagedByBackupServer') { 'Agent' } + elseif ($_.JobType -eq 'Backup') { 'VM Backup' } + elseif ($_.JobType -eq 'Replica') { 'VM Replication' } + else { 'Unknown' } + } + } +} +else { + Write-Output 'No supported jobs found; Exiting.' + Start-Sleep 3 + exit +} + +# Do config backup if user wishes +$backupChoiceResp = DoPrompt($backupChoiceParams) +if ($backupChoiceResp -eq 0) { + # Run backup + Write-Output "`nCreating backup, please wait..." + ($backupResult = Start-VBRConfigurationBackupJob) | Out-Null + + if ($backupResult.Result -ne 'Failed') { + Write-Output 'Backup completed successfully.' + } + + # Backup failed, exit/continue depending on user's wish + else { + $backupErrorResp = DoPrompt($backupErrorParams) + if ($backupChoiceResp -eq 1) { + Write-Output 'Exiting.' + Start-Sleep 3 + exit + } + else { + Write-Output 'Continuing anyway.' + } + } +} + +# Query configure all or selected jobs +switch (DoPrompt($configChoiceParams)) { + 0 { ConfigureJobs -backupJobs $backupJobs -newPostScriptCmd $newPostScriptCmd -nonInteractive } + 1 { ConfigureJobs -backupJobs $backupJobs -newPostScriptCmd $newPostScriptCmd } + 2 { Write-Output 'Skipping VeeamNotify configuration deployment for all jobs.' } } -If ($MyInvocation.ScriptName -notlike '*Installer.ps1') { +if ($MyInvocation.ScriptName -notlike '*Installer.ps1') { Write-Output "`n`Finished. Exiting." - Start-Sleep 10 + Start-Sleep 3 } exit From 33fa21dc016ef7685ae2d87e47261630c4a8cb2f Mon Sep 17 00:00:00 2001 From: tigattack <10629864+tigattack@users.noreply.github.com> Date: Tue, 2 Apr 2024 16:47:54 +0100 Subject: [PATCH 2/2] style(installer): replace VeeamNotify header in script output --- Installer.ps1 | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Installer.ps1 b/Installer.ps1 index 9276d32..0548322 100644 --- a/Installer.ps1 +++ b/Installer.ps1 @@ -66,13 +66,14 @@ param( $project = 'VeeamNotify' $ErrorActionPreference = 'Stop' -Write-Output @' -####################################### -# # -# VeeamNotify Installer # -# # -####################################### -'@ +Write-Output " +__ __ _ _ _ _ __ +\ \ / /__ ___ __ _ _ __ ___ | \ | | ___ | |_(_)/ _|_ _ + \ \ / / _ \/ _ \/ _` | '_ ` _ \| \| |/ _ \| __| | |_| | | | + \ V / __/ __/ (_| | | | | | | |\ | (_) | |_| | _| |_| | + \_/ \___|\___|\__,_|_| |_| |_|_| \_|\___/ \__|_|_| \__, | + |___/ +" # Check if this project is already installed and if so, exit if (Test-Path "$InstallParentPath\$project\resources\version.txt") {