From 1e8e52454abb41f8586c4d4def25b5f58950c412 Mon Sep 17 00:00:00 2001 From: tigattack <10629864+tigattack@users.noreply.github.com> Date: Sat, 13 Dec 2025 15:09:44 +0000 Subject: [PATCH 1/7] fix(installer): update manual unblock command --- Installer.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Installer.ps1 b/Installer.ps1 index bb1c680..df6d8ab 100644 --- a/Installer.ps1 +++ b/Installer.ps1 @@ -465,7 +465,7 @@ function Install-DownloadedProject { } catch { Write-Warning 'Failed to unblock downloaded files. You will need to run the following commands manually once installation is complete:' - Write-Host "Get-ChildItem -Path $InstallParentPath -Filter *.ps* -Recurse | Unblock-File" + Write-Host "gci $InstallParentPath -Recurse | ?{$_.Name -match '\.(ps\w*|dll)$'} | Unblock-File" } # Extract release to destination path From 20bbae9bc8c2760518921b652d75662492029ff6 Mon Sep 17 00:00:00 2001 From: tigattack <10629864+tigattack@users.noreply.github.com> Date: Sat, 13 Dec 2025 16:29:23 +0000 Subject: [PATCH 2/7] fix(installer): allow `InstallParentPath` without other params --- Installer.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/Installer.ps1 b/Installer.ps1 index df6d8ab..c8ffc4a 100644 --- a/Installer.ps1 +++ b/Installer.ps1 @@ -43,6 +43,7 @@ [CmdletBinding(DefaultParameterSetName = 'None')] param( + [Parameter(ParameterSetName = 'None', Position = 0)] [Parameter(ParameterSetName = 'Version', Position = 0)] [Parameter(ParameterSetName = 'Release', Position = 0)] [Parameter(ParameterSetName = 'Branch', Position = 0)] From 8daa11a8d45b1f279778f955badf2eaa52eebd83 Mon Sep 17 00:00:00 2001 From: tigattack <10629864+tigattack@users.noreply.github.com> Date: Sat, 13 Dec 2025 17:49:12 +0000 Subject: [PATCH 3/7] fix(installer): unblock executable files Fixes #129 --- Installer.ps1 | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/Installer.ps1 b/Installer.ps1 index c8ffc4a..ad427e9 100644 --- a/Installer.ps1 +++ b/Installer.ps1 @@ -460,14 +460,8 @@ function Install-DownloadedProject { } # Unblock downloaded ZIP - try { - Write-Host 'Unblocking ZIP...' - Unblock-File -Path $downloadPath - } - catch { - Write-Warning 'Failed to unblock downloaded files. You will need to run the following commands manually once installation is complete:' - Write-Host "gci $InstallParentPath -Recurse | ?{$_.Name -match '\.(ps\w*|dll)$'} | Unblock-File" - } + Write-Host 'Unblocking ZIP...' + Unblock-File -Path $downloadPath -ErrorAction Continue # Extract release to destination path Write-Host "Extracting files to '$InstallParentPath'..." @@ -491,6 +485,20 @@ function Install-DownloadedProject { })[0] | Rename-Item -NewName "$Project" } + # Unblock PS and DLL files in installation directory + Write-Host 'Unblocking executable files in installation directory...' + $srcFiles = Get-ChildItem -Path "$InstallParentPath\$Project" -Recurse | Where-Object { + $_.Name -match '\.(ps\w*|dll)$' + } + + try { + $srcFiles | Unblock-File + } + catch { + Write-Warning 'Failed to unblock downloaded files. You will need to run the following command manually once installation is complete:' + Write-Host "gci $InstallParentPath -Recurse | ?{$_.Name -match '\.(ps\w*|dll)$'} | Unblock-File" + } + # Clean up temp files Remove-Item -Path $downloadPath } From 5bc48ea2dc3dce41ec8d8b3e50c3a1c1db43b3cf Mon Sep 17 00:00:00 2001 From: tigattack <10629864+tigattack@users.noreply.github.com> Date: Sat, 13 Dec 2025 17:54:33 +0000 Subject: [PATCH 4/7] refactor(installer): create function for yes/no prompts --- Installer.ps1 | 137 +++++++++++++++++++++++++++++--------------------- 1 file changed, 81 insertions(+), 56 deletions(-) diff --git a/Installer.ps1 b/Installer.ps1 index ad427e9..eb441fc 100644 --- a/Installer.ps1 +++ b/Installer.ps1 @@ -230,23 +230,25 @@ function Get-InstallationSource { $downloadQuery_opts += New-Object System.Management.Automation.Host.ChoiceDescription '&Branch', '[TESTING ONLY] Download a branch.' $downloadQuery_opts += New-Object System.Management.Automation.Host.ChoiceDescription '&PullRequest', '[TESTING ONLY] Download a pull request.' $downloadQuery_result = $host.UI.PromptForChoice( - 'Download type', - "Please select how you would like to download $Project.", + 'Download Source', + "Please select a download source for $Project", $downloadQuery_opts, 0 ) } else { - $branchQuery_yes = New-Object System.Management.Automation.Host.ChoiceDescription '&Yes', 'Install from a branch.' - $branchQuery_no = New-Object System.Management.Automation.Host.ChoiceDescription '&No', 'Cancel installation.' - $host.UI.PromptForChoice( - 'Would you like to install from a branch?', - "There are currently no releases or prereleases available for $Project.", - @($branchQuery_yes, $branchQuery_no), - 0 - ) | ForEach-Object { - if ($_ -eq 0) { $downloadQuery_result = 2 } - else { exit } + $installFromBranchPrompt = @{ + Title = 'Would you like to install from a branch?' + Description = "There are currently no releases or prereleases available for $Project." + Default = 'Yes' + OptionATitle = 'Install from Branch' + OptionBTitle = 'Exit Installer' + } + if (YesNoPrompt @installFromBranchPrompt) { + $downloadQuery_result = 2 + } + else { + exit } } @@ -257,41 +259,35 @@ function Get-InstallationSource { if ($latestStable -and $latestPrerelease) { # Query release stream $releasePrompt = $true - # Query release stream - $versionQuery_stable = New-Object System.Management.Automation.Host.ChoiceDescription 'Latest &stable', "Latest stable: $latestStable." - $versionQuery_prerelease = New-Object System.Management.Automation.Host.ChoiceDescription 'Latest &prerelease', "Latest prelease: $latestPrerelease." - $versionQuery_result = $host.UI.PromptForChoice( - 'Release Selection', - "Which release type would you like to install?`nEnter '?' to see versions.", - @( - $versionQuery_stable, - $versionQuery_prerelease), - 0 - ) - - switch ($versionQuery_result) { - 0 { - $Latest = 'Release' - } - 1 { - $Latest = 'Prerelease' - } + $releaseTypePrompt = @{ + Title = 'Release Selection' + Description = "Which release type would you like to install?`nLatest stable: $latestStable`nLatest prerelease: $latestPrerelease" + Default = 'Yes' + OptionAKey = 'Stable' ; OptionATitle = 'Install Latest Stable' + OptionBKey = 'Prerelease' ; OptionBTitle = 'Install Latest Prerelease' + } + if (YesNoPrompt @releaseTypePrompt) { + $Latest = 'Release' + } + else { + $Latest = 'Prerelease' } } elseif ($latestStable) { $Latest = 'Release' } elseif ($latestPrerelease) { - $prereleaseQuery_yes = New-Object System.Management.Automation.Host.ChoiceDescription '&Yes', 'Install the latest prerelease.' - $prereleaseQuery_no = New-Object System.Management.Automation.Host.ChoiceDescription '&No', 'Cancel installation.' - $host.UI.PromptForChoice( - 'Do you wish to install the latest prerelease?', - 'You chose release, but the only available releases are prereleases.', - @($prereleaseQuery_yes, $prereleaseQuery_no), - 0 - ) | ForEach-Object { - if ($_ -eq 0) { $Latest = 'Prerelease' } - else { exit } + $installPrereleasePrompt = @{ + Title = 'Do you wish to install the latest prerelease?' + Description = 'You chose release, but the only available releases are prereleases.' + OptionATitle = 'Install Prerelease' + OptionBTitle = 'Exit Installer' + } + if (YesNoPrompt @installPrereleasePrompt) { + $Latest = 'Prerelease' + } + else { + exit } } } @@ -699,22 +695,51 @@ function Invoke-DeploymentTool { ) # Query for configuration deployment script. - $configPrompt_yes = New-Object System.Management.Automation.Host.ChoiceDescription '&Yes', 'Execute configuration deployment tool.' - $configPrompt_no = New-Object System.Management.Automation.Host.ChoiceDescription '&No', 'Skip configuration deployment tool.' - $host.UI.PromptForChoice( - 'Configuration Deployment Tool', - "Would you like to to run the VeeamNotify configuration deployment tool?`nNone of your job configurations will be modified without confirmation.", - @( - $configPrompt_yes, - $configPrompt_no - ), - 0 - ) | ForEach-Object { - if ($_ -eq 0) { - Write-Host "`nRunning configuration deployment script...`n" - & "$InstallParentPath\$Project\resources\DeployVeeamConfiguration.ps1" -InstallParentPath $InstallParentPath - } + $runDeploymentToolPrompt = @{ + Title = 'Configuration Deployment Tool' + Description = "Would you like to to run the VeeamNotify configuration deployment tool?`nNone of your job configurations will be modified without confirmation." + Default = 'Yes' + OptionATitle = 'Run Deployment Tool' + OptionBTitle = 'Skip Deployment Tool' } + if (YesNoPrompt @runDeploymentToolPrompt) { + Write-Host "`nRunning configuration deployment script...`n" + & "$InstallParentPath\$Project\resources\DeployVeeamConfiguration.ps1" -InstallParentPath $InstallParentPath + } +} + +function YesNoPrompt { + [CmdletBinding()] + [OutputType([bool])] + param ( + [Parameter(Mandatory)] + [string]$Title, + [Parameter(Mandatory)] + [string]$Description, + [Parameter()] + [string]$Default = 'No', + [Parameter()] + [string]$OptionAKey = 'Yes', + [Parameter()] + [string]$OptionATitle = 'Yes', + [Parameter()] + [string]$OptionBKey = 'No', + [Parameter()] + [string]$OptionBTitle = 'No' + ) + + $defaultChoice = if ($Default -eq 'Yes') { 0 } else { 1 } + + $yesChoice = New-Object System.Management.Automation.Host.ChoiceDescription "&$OptionAKey", $OptionATitle + $noChoice = New-Object System.Management.Automation.Host.ChoiceDescription "&$OptionBKey", $OptionBTitle + $result = $host.UI.PromptForChoice( + $Title, + $Description, + @($yesChoice, $noChoice), + $defaultChoice + ) + + return $result -eq 0 } #endregion Functions From 853b6302f9b5b78a0c84541cd1655d301361f06b Mon Sep 17 00:00:00 2001 From: tigattack <10629864+tigattack@users.noreply.github.com> Date: Sat, 13 Dec 2025 17:54:51 +0000 Subject: [PATCH 5/7] fix(installer): remove errant tilde --- Installer.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Installer.ps1 b/Installer.ps1 index eb441fc..76caeef 100644 --- a/Installer.ps1 +++ b/Installer.ps1 @@ -771,7 +771,7 @@ Install-DownloadedProject -Project $project ` -InstallParentPath $InstallParentPath ` -DownloadUrl $downloadProperties.DownloadUrl ` -OutFile $downloadProperties.OutFile ` - -ReleaseName $downloadProperties.ReleaseName ` + -ReleaseName $downloadProperties.ReleaseName # Configure the installation if not running in non-interactive mode if (-not $NonInteractive) { From 497f130c4ba88845dcd2d6e27320f3d629003dbd Mon Sep 17 00:00:00 2001 From: tigattack <10629864+tigattack@users.noreply.github.com> Date: Sat, 13 Dec 2025 17:55:23 +0000 Subject: [PATCH 6/7] feat(installer): make config flow optional --- Installer.ps1 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Installer.ps1 b/Installer.ps1 index 76caeef..81bd5dd 100644 --- a/Installer.ps1 +++ b/Installer.ps1 @@ -775,7 +775,12 @@ Install-DownloadedProject -Project $project ` # Configure the installation if not running in non-interactive mode if (-not $NonInteractive) { - $configPath = Set-ProjectConfiguration -Project $project -InstallParentPath $InstallParentPath + if (-not (YesNoPrompt -Title "$Project Configuration" -Description 'Would you like to configure the installation now?')) { + Write-Host "`nYou can configure VeeamNotify later by editing the config file located at:`n$InstallParentPath\$project\config\conf.json" + } + else { + Set-ProjectConfiguration -Project $project -InstallParentPath $InstallParentPath | Out-Null + } } else { $configPath = Join-Path -Path $InstallParentPath -ChildPath $project | Join-Path -ChildPath 'config\conf.json' From 3e5a6df57eaddf98c20ec3963d7b9bd90a9f552e Mon Sep 17 00:00:00 2001 From: tigattack <10629864+tigattack@users.noreply.github.com> Date: Sat, 13 Dec 2025 18:10:52 +0000 Subject: [PATCH 7/7] style(installer): fmt --- Installer.ps1 | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Installer.ps1 b/Installer.ps1 index 81bd5dd..0f7ff8f 100644 --- a/Installer.ps1 +++ b/Installer.ps1 @@ -238,9 +238,9 @@ function Get-InstallationSource { } else { $installFromBranchPrompt = @{ - Title = 'Would you like to install from a branch?' - Description = "There are currently no releases or prereleases available for $Project." - Default = 'Yes' + Title = 'Would you like to install from a branch?' + Description = "There are currently no releases or prereleases available for $Project." + Default = 'Yes' OptionATitle = 'Install from Branch' OptionBTitle = 'Exit Installer' } @@ -278,8 +278,8 @@ function Get-InstallationSource { } elseif ($latestPrerelease) { $installPrereleasePrompt = @{ - Title = 'Do you wish to install the latest prerelease?' - Description = 'You chose release, but the only available releases are prereleases.' + Title = 'Do you wish to install the latest prerelease?' + Description = 'You chose release, but the only available releases are prereleases.' OptionATitle = 'Install Prerelease' OptionBTitle = 'Exit Installer' } @@ -696,9 +696,9 @@ function Invoke-DeploymentTool { # Query for configuration deployment script. $runDeploymentToolPrompt = @{ - Title = 'Configuration Deployment Tool' - Description = "Would you like to to run the VeeamNotify configuration deployment tool?`nNone of your job configurations will be modified without confirmation." - Default = 'Yes' + Title = 'Configuration Deployment Tool' + Description = "Would you like to to run the VeeamNotify configuration deployment tool?`nNone of your job configurations will be modified without confirmation." + Default = 'Yes' OptionATitle = 'Run Deployment Tool' OptionBTitle = 'Skip Deployment Tool' }