AcuInstallerHelper_Functions.ps1
function Get-AcuVersionPath { param( [Parameter(Mandatory = $true)] [string] $versionNbr ) return Join-Path (Get-AcuDir) (Get-AcuVersionDir) $versionNbr } function Get-AcuConfigurationExe { param( [Parameter(Mandatory = $true)] [string] $versionNbr ) return Join-Path (Get-AcuVersionPath -versionNbr $versionNbr) "Data\ac.exe" } function Test-AcuVersionPath { param( [Parameter(Mandatory = $true)] [string] $versionNbr ) return Test-Path (Get-AcuConfigurationExe -versionNbr $versionNbr) } function Test-VersionFormat { param ( [Parameter(Mandatory = $true)] [string] $version ) Write-AcuDebug "Validating version format: $version" if ($version -notmatch '^\d{2}\.\d{3}\.\d{4}$') { Write-AcuError "Invalid version format: $version" throw "Version '$version' is invalid. Expected format is ##.###.####" } Write-AcuDebug "Version format is valid" } function PromptYesNo { param( [Parameter(Mandatory = $true)] [string] $message ) do { Write-AcuPrompt -Message $message $response = Read-Host if ($response -match '^[YyNn]$') { $result = $response -match '^[Yy]$' Write-AcuDebug "User response: $(if ($result) { 'Yes' } else { 'No' })" return $result } Write-AcuWarning "Invalid input. Please enter Y or N" } while ($true) } function Invoke-AcuExe { param ( [Parameter(Mandatory = $true)] [string[]] $arguments, [Parameter(Mandatory = $true)] [string] $version ) if (Get-Command Write-AcuDebug -ErrorAction SilentlyContinue) { Write-AcuDebug "Preparing to execute Acumatica configuration utility" } # Verify admin rights $isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]"Administrator") if (!$isAdmin) { if (Get-Command Write-AcuError -ErrorAction SilentlyContinue) { Write-AcuError "Administrator privileges required" } throw "This script must be run as Administrator" } if (Get-Command Write-AcuDebug -ErrorAction SilentlyContinue) { Write-AcuDebug "Administrator privileges confirmed" } # Get ac.exe path $acExePath = Get-AcuConfigurationExe -versionNbr $version if (!(Test-Path $acExePath)) { if (Get-Command Write-AcuError -ErrorAction SilentlyContinue) { Write-AcuError "Configuration utility not found at: $acExePath" } throw "ac.exe not found at $acExePath" } if (Get-Command Write-AcuDebug -ErrorAction SilentlyContinue) { Write-AcuDebug "Configuration utility found at: $acExePath" Write-AcuDebug "Arguments: $($arguments -join ' ')" } if (Get-Command Write-AcuStep -ErrorAction SilentlyContinue) { Write-AcuStep "Executing Acumatica configuration utility" } try { # Execute with proper error handling $process = Start-Process -FilePath $acExePath -ArgumentList $arguments -Wait -PassThru -NoNewWindow -RedirectStandardOutput $env:TEMP\acu_output.txt -RedirectStandardError $env:TEMP\acu_error.txt # Read output files $output = if (Test-Path "$env:TEMP\acu_output.txt") { Get-Content "$env:TEMP\acu_output.txt" -Raw } else { "" } $errorOutput = if (Test-Path "$env:TEMP\acu_error.txt") { Get-Content "$env:TEMP\acu_error.txt" -Raw } else { "" } # Clean up temp files Remove-Item "$env:TEMP\acu_output.txt" -ErrorAction SilentlyContinue Remove-Item "$env:TEMP\acu_error.txt" -ErrorAction SilentlyContinue if ($process.ExitCode -ne 0) { if (Get-Command Write-AcuError -ErrorAction SilentlyContinue) { Write-AcuError "Configuration utility failed with exit code: $($process.ExitCode)" Write-AcuError "Error output: $errorOutput" Write-AcuError "Standard output: $output" } throw "Acumatica configuration failed with exit code $($process.ExitCode)`nError: $errorOutput`nOutput: $output" } if (Get-Command Write-AcuSuccess -ErrorAction SilentlyContinue) { Write-AcuSuccess "Configuration utility executed successfully" } if (Get-Command Write-AcuDebug -ErrorAction SilentlyContinue) { Write-AcuDebug "Process output: $output" } return $output } catch { if (Get-Command Write-AcuError -ErrorAction SilentlyContinue) { Write-AcuError "Failed to execute configuration utility: $_" } throw } } function Read-SitePathFromRegistryEntry { param( [Parameter(Mandatory = $true)] [string] $siteName ) $registryPath = "HKLM:\SOFTWARE\Acumatica ERP\$siteName" Write-AcuDebug "Looking for site registry entry: $registryPath" if (!(Test-Path $registryPath)) { Write-AcuError "No registry entry found for site: $siteName" throw "No registry key found for site '$siteName'" } try { $path = Get-ItemPropertyValue -Path $registryPath -Name "Path" Write-AcuDebug "Site path found in registry: $path" return $path } catch { Write-AcuError "Failed to read site path from registry" throw "Failed to read site path from registry: $_" } } function Get-AcuSiteVersion { param( [string] $sitePath, [string] $siteName ) Write-AcuDebug "Retrieving site version information" # Validate parameters if ([string]::IsNullOrWhiteSpace($sitePath) -and [string]::IsNullOrWhiteSpace($siteName)) { Write-AcuError "Missing required parameters" throw "Either SitePath or SiteName must be provided" } # Get site path from registry if not provided if ([string]::IsNullOrWhiteSpace($sitePath)) { Write-AcuDebug "Site path not provided, reading from registry" $sitePath = Read-SitePathFromRegistryEntry $siteName } # Read version from web.config $webConfigPath = Join-Path $sitePath "web.config" Write-AcuDebug "Checking web.config at: $webConfigPath" if (!(Test-Path $webConfigPath)) { Write-AcuError "web.config not found at: $webConfigPath" throw "web.config not found at $webConfigPath" } try { [xml]$webConfig = Get-Content $webConfigPath $versionNode = $webConfig.configuration.appSettings.add | Where-Object { $_.key -eq 'Version' } if (!$versionNode) { Write-AcuError "Version key not found in web.config" throw "Version key not found in web.config" } $version = $versionNode.value Write-AcuDebug "Version found in web.config: $version" return $version } catch { Write-AcuError "Failed to parse web.config" throw "Failed to read version from web.config: $_" } } function Build-AcuExeArgs { param ( [Parameter(Mandatory = $true)] [string] $siteName, [string] $newClient, [string] $sitePath, [Alias("p")] [bool] $portal, [Alias("u")] [switch] $upgrade, [Alias("n")] [switch] $newInstance, [Alias("d")] [switch] $delete, [Alias("r")] [switch] $rename ) Write-AcuDebug "Building configuration utility arguments" # Validate exactly one operation $operations = @($upgrade, $newInstance, $delete, $rename) $selectedOps = $operations | Where-Object { $_ } if ($selectedOps.Count -ne 1) { Write-AcuError "Invalid operation selection" throw "Specify exactly one operation: -upgrade, -newInstance, -delete, or -rename" } # Portal only valid for new instances if ($portal -and !$newInstance) { Write-AcuError "Portal configuration only valid for new instances" throw "Portal sites can only be created as new instances (use -portal with -newInstance)" } $virtDir = if ($portal) { "${siteName}Portal" } else { $siteName } Write-AcuDebug "Virtual directory name: $virtDir" # Build arguments based on operation switch ($true) { $newInstance { Write-AcuDebug "Building arguments for new instance creation" $exeArgs = @( "-configmode:`"NewInstance`"", "-dbsrvname:`"(local)`"", "-dbname:`"$siteName`"", "-output:Forced", "-iname:`"$virtDir`"", "-company:`"CompanyID=1;CompanyType=;LoginName=;`"", "-company:`"CompanyID=2;CompanyType=SalesDemo;ParentID=1;Visible=Yes;LoginName=Company;`"", "-ipath:`"$sitePath`"", "-swebsite:`"Default Web Site`"", "-svirtdir:`"$virtDir`"", "-spool:`"DefaultAppPool`"" ) if ($portal) { Write-AcuDebug "Adding portal-specific arguments" $exeArgs += "-portal:`"Yes`"", "-dbnew:`"No`"" } return $exeArgs } $upgrade { Write-AcuDebug "Building arguments for site upgrade" return @( "-configmode:`"UpgradeSite`"", "-output:Forced", "-iname:`"$virtDir`"" ) } $delete { Write-AcuDebug "Building arguments for site deletion" return @( "-configmode:`"DeleteSite`"", "-output:Forced", "-iname:`"$virtDir`"" ) } $rename { Write-AcuDebug "Building arguments for site rename" if ([string]::IsNullOrWhiteSpace($newClient)) { Write-AcuError "NewClient parameter required for rename operation" throw "NewClient parameter required for rename operation" } return @( "-configmode:`"RenameSite`"", "-output:Forced", "-iname:`"$newClient`"", "-ioldname:`"$virtDir`"" ) } } } function Test-Url { param ( [Parameter(Mandatory = $true)] [string] $Url ) Write-AcuDebug "Testing URL accessibility: $Url" try { $response = Invoke-WebRequest -Uri $Url -UseBasicParsing -TimeoutSec 10 -Method Head $isAccessible = $response.StatusCode -eq 200 Write-AcuDebug "URL test result: $(if ($isAccessible) { 'Accessible' } else { 'Not accessible' })" return $isAccessible } catch { Write-AcuDebug "URL test failed: $_" return $false } } |