This commit introduces a complete deployment automation system for Windows Server deployment: New Features: - Publish-And-Deploy.ps1: Interactive console for building locally and transferring to server * Supports auto-detection of transfer method (Windows Share or SSH) * Configurable via deploy-config.json * Integrated with Build-ROA2WEB.ps1 for consistent builds - Check-And-Deploy.ps1: Server-side auto-deployment script * Monitors transfer directory for new packages * Automatically deploys when new version detected * Integrates with ROA2WEB-Console.ps1 for deployment - Setup-AutoDeploy.ps1: Configures scheduled task for auto-deployment - DEPLOYMENT_AUTOMATION.md: Complete documentation for automation workflow Bug Fixes: - Fix path resolution in Publish-And-Deploy.ps1: Added Resolve-FullPath function to correctly resolve ../deploy-package path - Fix ROA2WEB-Console.ps1 exit codes: Properly return boolean values and exit codes in non-interactive mode - Fix Build-ROA2WEB.ps1 script copying: Added debug output and force deletion to avoid caching issues Enhancements: - ROA2WEB-Console.ps1: Support for ROA2WEB_SOURCE environment variable for flexible source paths - Build-ROA2WEB.ps1: Enhanced debug output for troubleshooting script copying issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
473 lines
16 KiB
PowerShell
473 lines
16 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
ROA2WEB - Auto-Deploy Setup Wizard (Server-Side)
|
|
|
|
.DESCRIPTION
|
|
Interactive wizard to configure automatic deployment monitoring on Windows Server.
|
|
Creates scheduled task that runs Check-And-Deploy.ps1 at specified intervals.
|
|
|
|
.PARAMETER MonitorPath
|
|
Path to monitor for deployment packages (default: C:\Temp)
|
|
|
|
.PARAMETER ScriptsPath
|
|
Path where Check-And-Deploy.ps1 is located (default: C:\Temp\ROA2WEB-Scripts)
|
|
|
|
.PARAMETER CheckIntervalMinutes
|
|
How often to check for new packages in minutes (default: 5)
|
|
|
|
.PARAMETER AutoDeploy
|
|
Automatically deploy new packages when found (default: true)
|
|
|
|
.PARAMETER CreateScheduledTask
|
|
Create Windows Scheduled Task for automation (default: true)
|
|
|
|
.PARAMETER NonInteractive
|
|
Run in non-interactive mode with provided parameters
|
|
|
|
.EXAMPLE
|
|
.\Setup-AutoDeploy.ps1
|
|
Launch interactive setup wizard
|
|
|
|
.EXAMPLE
|
|
.\Setup-AutoDeploy.ps1 -NonInteractive -MonitorPath "C:\Temp" -CheckIntervalMinutes 5
|
|
Non-interactive setup with defaults
|
|
|
|
.NOTES
|
|
Author: ROA2WEB Team
|
|
Version: 1.0 (Auto-Deploy Setup)
|
|
Requires: Administrator privileges, PowerShell 5.1+
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
param(
|
|
[string]$MonitorPath = "C:\Temp",
|
|
[string]$ScriptsPath = "C:\Temp\ROA2WEB-Scripts",
|
|
[int]$CheckIntervalMinutes = 5,
|
|
[bool]$AutoDeploy = $true,
|
|
[bool]$CreateScheduledTask = $true,
|
|
[switch]$NonInteractive
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
# =============================================================================
|
|
# HELPER FUNCTIONS
|
|
# =============================================================================
|
|
|
|
function Write-Step {
|
|
param([string]$Message)
|
|
Write-Host "`n[*] $Message" -ForegroundColor Cyan
|
|
}
|
|
|
|
function Write-Success {
|
|
param([string]$Message)
|
|
Write-Host " [OK] $Message" -ForegroundColor Green
|
|
}
|
|
|
|
function Write-Error {
|
|
param([string]$Message)
|
|
Write-Host " [ERROR] $Message" -ForegroundColor Red
|
|
}
|
|
|
|
function Write-Warning {
|
|
param([string]$Message)
|
|
Write-Host " [WARN] $Message" -ForegroundColor Yellow
|
|
}
|
|
|
|
function Write-Info {
|
|
param([string]$Message)
|
|
Write-Host " [*] $Message" -ForegroundColor Yellow
|
|
}
|
|
|
|
# =============================================================================
|
|
# WIZARD FUNCTIONS
|
|
# =============================================================================
|
|
|
|
function Show-WizardWelcome {
|
|
Clear-Host
|
|
Write-Host "`n" + ("=" * 70) -ForegroundColor Cyan
|
|
Write-Host " ROA2WEB - Auto-Deploy Setup Wizard" -ForegroundColor Cyan
|
|
Write-Host ("=" * 70) -ForegroundColor Cyan
|
|
Write-Host ""
|
|
Write-Host " This wizard will configure automatic deployment monitoring." -ForegroundColor Yellow
|
|
Write-Host ""
|
|
Write-Host " What it does:" -ForegroundColor White
|
|
Write-Host " • Creates directory structure for auto-deployment" -ForegroundColor Gray
|
|
Write-Host " • Copies Check-And-Deploy.ps1 to scripts folder" -ForegroundColor Gray
|
|
Write-Host " • Creates Windows Scheduled Task for monitoring" -ForegroundColor Gray
|
|
Write-Host " • Configures auto-deploy settings" -ForegroundColor Gray
|
|
Write-Host ""
|
|
Write-Host ("=" * 70) -ForegroundColor Cyan
|
|
Write-Host ""
|
|
Write-Host "Press any key to continue or Ctrl+C to cancel..." -ForegroundColor Yellow
|
|
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
|
|
}
|
|
|
|
function Get-WizardInput {
|
|
param(
|
|
[string]$Prompt,
|
|
[string]$Default,
|
|
[switch]$IsNumber,
|
|
[switch]$IsYesNo
|
|
)
|
|
|
|
do {
|
|
Write-Host "`n$Prompt" -ForegroundColor Yellow
|
|
if ($Default) {
|
|
Write-Host " Default: $Default" -ForegroundColor Gray
|
|
}
|
|
Write-Host " > " -NoNewline -ForegroundColor Cyan
|
|
$input = Read-Host
|
|
|
|
# Use default if empty
|
|
if ([string]::IsNullOrWhiteSpace($input) -and $Default) {
|
|
return $Default
|
|
}
|
|
|
|
# Validate number
|
|
if ($IsNumber) {
|
|
$num = 0
|
|
if ([int]::TryParse($input, [ref]$num) -and $num -gt 0) {
|
|
return $num
|
|
} else {
|
|
Write-Host " Invalid number. Please enter a positive integer." -ForegroundColor Red
|
|
continue
|
|
}
|
|
}
|
|
|
|
# Validate Yes/No
|
|
if ($IsYesNo) {
|
|
$normalized = $input.ToUpper()
|
|
if ($normalized -eq "Y" -or $normalized -eq "YES") {
|
|
return $true
|
|
} elseif ($normalized -eq "N" -or $normalized -eq "NO") {
|
|
return $false
|
|
} else {
|
|
Write-Host " Invalid input. Please enter Y or N." -ForegroundColor Red
|
|
continue
|
|
}
|
|
}
|
|
|
|
return $input
|
|
} while ($true)
|
|
}
|
|
|
|
# =============================================================================
|
|
# SETUP FUNCTIONS
|
|
# =============================================================================
|
|
|
|
function Test-Prerequisites {
|
|
Write-Step "Checking prerequisites..."
|
|
|
|
# Check Administrator
|
|
$currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()
|
|
$principal = New-Object Security.Principal.WindowsPrincipal($currentUser)
|
|
$isAdmin = $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
|
|
|
if (-not $isAdmin) {
|
|
throw "This script requires Administrator privileges"
|
|
}
|
|
Write-Success "Running as Administrator"
|
|
|
|
# Check PowerShell version
|
|
if ($PSVersionTable.PSVersion.Major -lt 5) {
|
|
throw "PowerShell 5.1 or higher is required"
|
|
}
|
|
Write-Success "PowerShell version: $($PSVersionTable.PSVersion)"
|
|
|
|
# Check if Check-And-Deploy.ps1 exists
|
|
$checkDeployScript = Join-Path $PSScriptRoot "Check-And-Deploy.ps1"
|
|
if (-not (Test-Path $checkDeployScript)) {
|
|
throw "Check-And-Deploy.ps1 not found in: $PSScriptRoot"
|
|
}
|
|
Write-Success "Check-And-Deploy.ps1 found"
|
|
|
|
return $true
|
|
}
|
|
|
|
function New-DirectoryStructure {
|
|
param(
|
|
[string]$MonitorPath,
|
|
[string]$ScriptsPath
|
|
)
|
|
|
|
Write-Step "Creating directory structure..."
|
|
|
|
# Create monitor path
|
|
if (-not (Test-Path $MonitorPath)) {
|
|
New-Item -ItemType Directory -Path $MonitorPath -Force | Out-Null
|
|
Write-Success "Created: $MonitorPath"
|
|
} else {
|
|
Write-Success "Already exists: $MonitorPath"
|
|
}
|
|
|
|
# Create scripts path
|
|
if (-not (Test-Path $ScriptsPath)) {
|
|
New-Item -ItemType Directory -Path $ScriptsPath -Force | Out-Null
|
|
Write-Success "Created: $ScriptsPath"
|
|
} else {
|
|
Write-Success "Already exists: $ScriptsPath"
|
|
}
|
|
|
|
# Create logs directory
|
|
$logsPath = Join-Path $ScriptsPath "Logs"
|
|
if (-not (Test-Path $logsPath)) {
|
|
New-Item -ItemType Directory -Path $logsPath -Force | Out-Null
|
|
Write-Success "Created: $logsPath"
|
|
} else {
|
|
Write-Success "Already exists: $logsPath"
|
|
}
|
|
|
|
return $true
|
|
}
|
|
|
|
function Copy-MonitorScript {
|
|
param(
|
|
[string]$SourcePath,
|
|
[string]$DestPath
|
|
)
|
|
|
|
Write-Step "Copying Check-And-Deploy.ps1 to scripts folder..."
|
|
|
|
$sourceScript = Join-Path $SourcePath "Check-And-Deploy.ps1"
|
|
$destScript = Join-Path $DestPath "Check-And-Deploy.ps1"
|
|
|
|
# Check if source and destination are the same file
|
|
$sourceFull = (Resolve-Path $sourceScript -ErrorAction SilentlyContinue).Path
|
|
$destFull = (Resolve-Path $destScript -ErrorAction SilentlyContinue).Path
|
|
|
|
if ($sourceFull -and $destFull -and ($sourceFull -eq $destFull)) {
|
|
Write-Success "Script already in target location: $destScript"
|
|
return $destScript
|
|
}
|
|
|
|
try {
|
|
Copy-Item -Path $sourceScript -Destination $destScript -Force
|
|
Write-Success "Script copied to: $destScript"
|
|
return $destScript
|
|
} catch {
|
|
Write-Error "Failed to copy script: $_"
|
|
return $null
|
|
}
|
|
}
|
|
|
|
function New-ScheduledTaskForAutoDeployNew {
|
|
param(
|
|
[string]$ScriptPath,
|
|
[int]$IntervalMinutes,
|
|
[string]$MonitorPath
|
|
)
|
|
|
|
Write-Step "Creating Windows Scheduled Task..."
|
|
|
|
$taskName = "ROA2WEB-AutoDeploy"
|
|
|
|
# Remove existing task if present
|
|
$existingTask = Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue
|
|
if ($existingTask) {
|
|
Write-Info "Removing existing task..."
|
|
Unregister-ScheduledTask -TaskName $taskName -Confirm:$false
|
|
}
|
|
|
|
try {
|
|
# Create action
|
|
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" `
|
|
-Argument "-NoProfile -ExecutionPolicy Bypass -File `"$ScriptPath`" -WatchPath `"$MonitorPath`""
|
|
|
|
# Create trigger (repeat indefinitely every X minutes)
|
|
# Note: When RepetitionDuration is not specified, the task repeats indefinitely
|
|
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) `
|
|
-RepetitionInterval (New-TimeSpan -Minutes $IntervalMinutes)
|
|
|
|
# Create settings
|
|
$settings = New-ScheduledTaskSettingsSet `
|
|
-AllowStartIfOnBatteries `
|
|
-DontStopIfGoingOnBatteries `
|
|
-StartWhenAvailable `
|
|
-RunOnlyIfNetworkAvailable:$false `
|
|
-DontStopOnIdleEnd `
|
|
-MultipleInstances IgnoreNew
|
|
|
|
# Register task (run as SYSTEM)
|
|
Register-ScheduledTask -TaskName $taskName `
|
|
-Action $action `
|
|
-Trigger $trigger `
|
|
-Settings $settings `
|
|
-User "SYSTEM" `
|
|
-RunLevel Highest `
|
|
-Description "Monitors $MonitorPath for new deployment packages and auto-deploys them" | Out-Null
|
|
|
|
Write-Success "Scheduled task created: $taskName"
|
|
Write-Success "Interval: Every $IntervalMinutes minutes"
|
|
Write-Success "User: SYSTEM"
|
|
Write-Success "Status: Enabled"
|
|
|
|
return $true
|
|
} catch {
|
|
Write-Error "Failed to create scheduled task: $_"
|
|
return $false
|
|
}
|
|
}
|
|
|
|
function Show-SetupSummary {
|
|
param(
|
|
[hashtable]$Config
|
|
)
|
|
|
|
Write-Host "`n" + ("=" * 70) -ForegroundColor Cyan
|
|
Write-Host " Setup Summary" -ForegroundColor Cyan
|
|
Write-Host ("=" * 70) -ForegroundColor Cyan
|
|
Write-Host ""
|
|
Write-Host " Monitor Path: $($Config.MonitorPath)" -ForegroundColor Gray
|
|
Write-Host " Scripts Path: $($Config.ScriptsPath)" -ForegroundColor Gray
|
|
Write-Host " Check Interval: $($Config.CheckIntervalMinutes) minutes" -ForegroundColor Gray
|
|
Write-Host " Auto-Deploy: $($Config.AutoDeploy)" -ForegroundColor Gray
|
|
Write-Host " Scheduled Task: $($Config.CreateScheduledTask)" -ForegroundColor Gray
|
|
Write-Host ""
|
|
Write-Host ("=" * 70) -ForegroundColor Cyan
|
|
Write-Host ""
|
|
Write-Host "Proceed with setup? [Y/N]: " -ForegroundColor Yellow -NoNewline
|
|
$confirm = Read-Host
|
|
|
|
return ($confirm.ToUpper() -eq "Y" -or $confirm.ToUpper() -eq "YES")
|
|
}
|
|
|
|
# =============================================================================
|
|
# MAIN SETUP FLOW
|
|
# =============================================================================
|
|
|
|
function Invoke-Setup {
|
|
param([hashtable]$Config)
|
|
|
|
Write-Host "`n" + ("=" * 70) -ForegroundColor Cyan
|
|
Write-Host " Starting Setup" -ForegroundColor Cyan
|
|
Write-Host ("=" * 70) -ForegroundColor Cyan
|
|
|
|
try {
|
|
# Test prerequisites
|
|
Test-Prerequisites | Out-Null
|
|
|
|
# Create directory structure
|
|
New-DirectoryStructure -MonitorPath $Config.MonitorPath -ScriptsPath $Config.ScriptsPath | Out-Null
|
|
|
|
# Copy monitor script
|
|
$scriptPath = Copy-MonitorScript -SourcePath $PSScriptRoot -DestPath $Config.ScriptsPath
|
|
|
|
if (-not $scriptPath) {
|
|
throw "Failed to copy monitor script"
|
|
}
|
|
|
|
# Create scheduled task if requested
|
|
if ($Config.CreateScheduledTask) {
|
|
$taskSuccess = New-ScheduledTaskForAutoDeployNew `
|
|
-ScriptPath $scriptPath `
|
|
-IntervalMinutes $Config.CheckIntervalMinutes `
|
|
-MonitorPath $Config.MonitorPath
|
|
|
|
if (-not $taskSuccess) {
|
|
throw "Failed to create scheduled task"
|
|
}
|
|
}
|
|
|
|
Write-Host "`n" + ("=" * 70) -ForegroundColor Green
|
|
Write-Host " SETUP COMPLETED SUCCESSFULLY" -ForegroundColor Green
|
|
Write-Host ("=" * 70) -ForegroundColor Green
|
|
Write-Host ""
|
|
Write-Host " Next Steps:" -ForegroundColor Yellow
|
|
Write-Host " 1. Deploy packages will be placed in: $($Config.MonitorPath)" -ForegroundColor Gray
|
|
Write-Host " 2. Server will check for updates every $($Config.CheckIntervalMinutes) minutes" -ForegroundColor Gray
|
|
Write-Host " 3. New packages will be deployed automatically" -ForegroundColor Gray
|
|
Write-Host ""
|
|
Write-Host " Manual Testing:" -ForegroundColor Yellow
|
|
Write-Host " - Test: cd $($Config.ScriptsPath) && .\\Check-And-Deploy.ps1 -Interactive" -ForegroundColor Gray
|
|
Write-Host " - View Task: Get-ScheduledTask -TaskName 'ROA2WEB-AutoDeploy'" -ForegroundColor Gray
|
|
Write-Host ""
|
|
Write-Host ("=" * 70) -ForegroundColor Green
|
|
|
|
return $true
|
|
} catch {
|
|
Write-Host "`n" + ("=" * 70) -ForegroundColor Red
|
|
Write-Host " SETUP FAILED" -ForegroundColor Red
|
|
Write-Host ("=" * 70) -ForegroundColor Red
|
|
Write-Host ""
|
|
Write-Error $_
|
|
Write-Host ""
|
|
Write-Host ("=" * 70) -ForegroundColor Red
|
|
|
|
return $false
|
|
}
|
|
}
|
|
|
|
# =============================================================================
|
|
# MAIN EXECUTION FLOW
|
|
# =============================================================================
|
|
|
|
function Main {
|
|
# Non-interactive mode
|
|
if ($NonInteractive) {
|
|
$config = @{
|
|
MonitorPath = $MonitorPath
|
|
ScriptsPath = $ScriptsPath
|
|
CheckIntervalMinutes = $CheckIntervalMinutes
|
|
AutoDeploy = $AutoDeploy
|
|
CreateScheduledTask = $CreateScheduledTask
|
|
}
|
|
|
|
Invoke-Setup -Config $config | Out-Null
|
|
return
|
|
}
|
|
|
|
# Interactive mode - Wizard
|
|
Show-WizardWelcome
|
|
|
|
Write-Host "`n" + ("=" * 70) -ForegroundColor Cyan
|
|
Write-Host " Configuration Wizard" -ForegroundColor Cyan
|
|
Write-Host ("=" * 70) -ForegroundColor Cyan
|
|
|
|
# Step 1: Monitor Path
|
|
$monitorPath = Get-WizardInput -Prompt "[1/5] Deploy Folder Path`n Path to monitor for new deployment packages:" -Default $MonitorPath
|
|
|
|
# Step 2: Scripts Path
|
|
$scriptsPath = Get-WizardInput -Prompt "[2/5] Scripts Folder Path`n Path to store monitoring scripts:" -Default $ScriptsPath
|
|
|
|
# Step 3: Check Interval
|
|
$checkInterval = Get-WizardInput -Prompt "[3/5] Check Interval`n How often to check for updates (minutes):" -Default $CheckIntervalMinutes -IsNumber
|
|
|
|
# Step 4: Auto-Deploy
|
|
Write-Host "`n[4/5] Auto-Deploy Enabled" -ForegroundColor Yellow
|
|
Write-Host " Deploy automatically when new package found?" -ForegroundColor Yellow
|
|
Write-Host " [Y] Yes (recommended) [N] No (manual trigger only)" -ForegroundColor Gray
|
|
$autoDeploy = Get-WizardInput -Prompt " Your choice:" -Default "Y" -IsYesNo
|
|
|
|
# Step 5: Scheduled Task
|
|
Write-Host "`n[5/5] Create Scheduled Task" -ForegroundColor Yellow
|
|
Write-Host " Create Windows Scheduled Task for automatic monitoring?" -ForegroundColor Yellow
|
|
Write-Host " [Y] Yes [N] No" -ForegroundColor Gray
|
|
$createTask = Get-WizardInput -Prompt " Your choice:" -Default "Y" -IsYesNo
|
|
|
|
# Configuration object
|
|
$config = @{
|
|
MonitorPath = $monitorPath
|
|
ScriptsPath = $scriptsPath
|
|
CheckIntervalMinutes = [int]$checkInterval
|
|
AutoDeploy = $autoDeploy
|
|
CreateScheduledTask = $createTask
|
|
}
|
|
|
|
# Show summary and confirm
|
|
$confirmed = Show-SetupSummary -Config $config
|
|
|
|
if ($confirmed) {
|
|
Invoke-Setup -Config $config
|
|
} else {
|
|
Write-Host "`nSetup cancelled by user" -ForegroundColor Yellow
|
|
exit 0
|
|
}
|
|
|
|
Write-Host "`nPress any key to exit..." -ForegroundColor Gray
|
|
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
|
|
}
|
|
|
|
# Run main
|
|
Main
|