From d169226ce35f08caced02f2f62e7bcfc14917dc1 Mon Sep 17 00:00:00 2001 From: Zach Boogher <129975920+AlrightLad@users.noreply.github.com> Date: Wed, 21 Jan 2026 16:19:10 -0500 Subject: [PATCH] Ps7 64bit Bootstrap added What changed: 1. Added a $varsToPass hashtable capturing all NinjaRMM variables 2. Builds a variable declaration block that gets prepended to the PS7 script 3. Uses a marker (# === MAIN SCRIPT START ===) to identify where the real script begins 4. Writes a temp script file with variables injected, runs it in PS7, then cleans up 5. Properly passes through the exit code back to NinjaRMM --- bdr-veeam/veeam-add-backup-repo.ps1 | 153 +++++++++++++++++++--------- 1 file changed, 107 insertions(+), 46 deletions(-) diff --git a/bdr-veeam/veeam-add-backup-repo.ps1 b/bdr-veeam/veeam-add-backup-repo.ps1 index 55edab8..f82f3a4 100644 --- a/bdr-veeam/veeam-add-backup-repo.ps1 +++ b/bdr-veeam/veeam-add-backup-repo.ps1 @@ -1,39 +1,115 @@ ## Please note this script can only support the following backup repository types ## -# S3 Compabitble & Local. Both are forced. +# S3 Compatible & Local. Both are forced. -Start-Transcript -Path $env:WINDIR\logs\veeam-add-backup-repo.log +# =========================================== +# PowerShell 7 x64 Check, Install, and Bootstrap +# =========================================== -Write-Host "Checking if we are running from a RMM or not." +# MUST use x64 path - Veeam modules are 64-bit only +$ps7Path = "C:\Program Files\PowerShell\7\pwsh.exe" -# if ($rmm -ne 1) { - # Set the repository details - # $repositoryType = "Please enter the repository type (1 S3 Compatible; 2 Windows Local; 3 Both)" - # $moveBackups = "Enter 1 if you wish to move your local backups" - # $description = Read-Host "Please enter the ticket # or project ticket # related to this configuration" - # $immutabilityPeriod = Read-Host "Enter how many days every object is immutable for" - # $repositoryName = Read-Host "Enter the repository name" | Out-String - # $accessKey = Read-Host "Enter the access key" - # $secretKey = Read-Host "Enter the secret key" - # $endpoint = Read-Host "Enter the S3 endpoint url" - # $regionId = Read-Host "Enter the region ID" - # $bucketName = Read-Host "Enter the bucket name" +if ($PSVersionTable.PSVersion.Major -lt 7) { + + Write-Host "Running in PowerShell $($PSVersionTable.PSVersion.Major) - checking for PS7 x64..." + + # Check if PS7 x64 is installed + if (-not (Test-Path $ps7Path)) { + Write-Host "PowerShell 7 x64 not found. Installing..." + + try { + $msiUrl = "https://github.com/PowerShell/PowerShell/releases/download/v7.4.7/PowerShell-7.4.7-win-x64.msi" + $msiPath = "$env:TEMP\PS7-x64.msi" + + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + Invoke-WebRequest -Uri $msiUrl -OutFile $msiPath -UseBasicParsing + + Write-Host "Downloaded PS7 installer. Running silent install..." + Start-Process msiexec.exe -ArgumentList "/i `"$msiPath`" /qn REGISTER_MANIFEST=1" -Wait -NoNewWindow + + Remove-Item $msiPath -Force -ErrorAction SilentlyContinue + + if (-not (Test-Path $ps7Path)) { + Write-Error "PowerShell 7 x64 installation failed" + exit 1 + } + Write-Host "PowerShell 7 x64 installed successfully" + } + catch { + Write-Error "Failed to download/install PowerShell 7: $_" + exit 1 + } + } + + # =========================================== + # Capture NinjaRMM variables to pass to PS7 + # =========================================== + Write-Host "Capturing RMM variables for PS7 session..." + + # Build parameter string for PS7 relaunch + $scriptBlock = @" +`$repositoryType = '$repositoryType' +`$moveBackups = '$moveBackups' +`$description = '$description' +`$immutabilityPeriod = '$immutabilityPeriod' +`$accessKey = '$accessKey' +`$secretKey = '$secretKey' +`$endpoint = '$endpoint' +`$regionId = '$regionId' +`$bucketName = '$bucketName' +`$driveLetters = '$driveLetters' +`$folderName = '$folderName' +`$moveListedBackups = '$moveListedBackups' + +"@ + + # Read main script content (everything after the marker) + $scriptContent = Get-Content -Path $MyInvocation.MyCommand.Path -Raw + $marker = "# === MAIN SCRIPT START ===" + $markerIndex = $scriptContent.IndexOf($marker) + + if ($markerIndex -gt 0) { + $mainScript = $scriptContent.Substring($markerIndex + $marker.Length) + $fullScript = $scriptBlock + $mainScript + + # Write temp script and execute in PS7 x64 + $tempScript = "$env:TEMP\veeam-repo-ps7-$(Get-Random).ps1" + $fullScript | Out-File -FilePath $tempScript -Encoding UTF8 -Force + + Write-Host "Relaunching in PowerShell 7 x64: $ps7Path" + & $ps7Path -NoProfile -ExecutionPolicy Bypass -File $tempScript + $exitCode = $LASTEXITCODE + + Remove-Item $tempScript -Force -ErrorAction SilentlyContinue + exit $exitCode + } + else { + Write-Error "Could not find main script marker" + exit 1 + } +} + +# === MAIN SCRIPT START === +# =========================================== +# Running in PS7 x64 - Execute Veeam commands +# =========================================== -# } +Write-Host "Running in PowerShell $($PSVersionTable.PSVersion) x64 - Proceeding with Veeam configuration" -Write-Host "The varialbes are now set." +Start-Transcript -Path $env:WINDIR\logs\veeam-add-backup-repo-ps7.log -Force + +Write-Host "The variables are now set." Write-Host "Repository type: $repositoryType" Write-Host "Move backups: $moveBackups" Write-Host "Description: $description" Write-Host "Immutability period: $immutabilityPeriod" Write-Host "Access key: $accessKey" -Write-Host "Secret key: **redacted for sensativity**" +Write-Host "Secret key: **redacted for sensitivity**" Write-Host "S3 Endpoint: $endpoint" Write-Host "S3 Region ID: $regionId" Write-Host "S3 Bucket Name: $bucketName" Write-Host "Automatic volume letter to create WinLocal repo: " Write-Host "Drive letters to create WinLocal Repos: $driveLetters" - # Make sure PSModulePath includes Veeam Console Write-Host "Installing Veeam PowerShell Module if not installed already." $MyModulePath = "C:\Program Files\Veeam\Backup and Replication\Console\" @@ -41,20 +117,14 @@ $env:PSModulePath = $env:PSModulePath + "$([System.IO.Path]::PathSeparator)$MyMo if ($Modules = Get-Module -ListAvailable -Name Veeam.Backup.PowerShell) { try { $Modules | Import-Module -WarningAction SilentlyContinue - } - catch { - throw "Failed to load Veeam Modules" - } - } - -# Set Timestamp -# Write-Host "Getting timestamp for repository names." -# $timeStamp = [int](Get-Date -UFormat %s -Millisecond 0) -# REMOVED TO MAKE FOLDERNAME LOCATION GUID $folderName = $timeStamp - + } + catch { + throw "Failed to load Veeam Modules" + } +} if ($repositoryType -eq 1 -Or $repositoryType -eq 3) { - Write-Host "Creating S3 Repository: S3 $FolderName" + Write-Host "Creating S3 Repository: S3 $folderName" # Add the S3 Account $account = Add-VBRAmazonAccount -AccessKey $accessKey -SecretKey $secretKey -Description "$description $bucketName" @@ -73,7 +143,7 @@ if ($repositoryType -eq 1 -Or $repositoryType -eq 3) { Add-VBRAmazonS3CompatibleRepository ` -AmazonS3Folder $folder ` -Connection $connect ` - -Name "S3 $FolderName" ` + -Name "S3 $folderName" ` -EnableBackupImmutability ` -ImmutabilityPeriod $immutabilityPeriod ` -Description "$description $bucketName" ` @@ -82,7 +152,7 @@ if ($repositoryType -eq 1 -Or $repositoryType -eq 3) { Add-VBRAmazonS3CompatibleRepository ` -AmazonS3Folder $folder ` -Connection $connect ` - -Name "S3 $FolderName" ` + -Name "S3 $folderName" ` -EnableBackupImmutability ` -ImmutabilityPeriod $immutabilityPeriod ` -Description "$description $bucketName" @@ -92,37 +162,32 @@ if ($repositoryType -eq 1 -Or $repositoryType -eq 3) { $repository } - if ($repositoryType -eq 2 -Or $repositoryType -eq 3){ - Write-Host "Creating local repository Local $FolderName" + Write-Host "Creating local repository Local $folderName" # Get all logical drives on the system $drives = Get-WmiObject -Class Win32_LogicalDisk | Where-Object { $_.DriveType -eq 3 } # Find the drive with the largest total capacity if ($drives.Count -gt 1){ $filteredDrives = $drives | Where-Object { $_.DeviceId -ne 'C:' } - } else { $filteredDrives = $drives } # Create the local repository $filteredDrives | ForEach-Object { - # $timeStamp = [int](Get-Date -UFormat %s -Millisecond 0) - $repositoryPath = Join-Path -Path $_.DeviceID -ChildPath "\veeam\$FolderName" - $repositoryName = "Local $FolderName" + $repositoryPath = Join-Path -Path $_.DeviceID -ChildPath "\veeam\$folderName" + $repositoryName = "Local $folderName" Write-Host "Repository name: $repositoryName" Write-Host "Repository path: $repositoryPath" $repository = Add-VBRBackupRepository -Type WinLocal -Name "$repositoryName" -Folder $repositoryPath -Description "$description" - # Display the added repository details + # Display the added repository details $repository $localRepository = $repository Start-Sleep -Seconds 1 } } - - # Move all local backups if ($moveBackups -eq 1){ $backups = Get-VBRBackup | Where -Property TypeToString -ne "Backup Copy" @@ -141,10 +206,6 @@ if ($moveListedBackups){ $moveListedBackups | ForEach-Object { Move-VBRBackup -Repository $localRepository -Backup $_ -RunAsync } - } -# Move local/scale out repo to new repo - - Stop-Transcript