Fix ROA Windows setup scripts for Oracle XE deployment

Key fixes:
- Add Run.cmd/RunAll.cmd wrappers with ExecutionPolicy Bypass
- Add Get-ListenerHost() to auto-detect listener IP address
- Fix impdp connection using EZConnect format (host:port/service)
- Add parallel=1 for Oracle XE compatibility
- Fix Write-Log to accept empty strings with [AllowEmptyString()]
- Fix Get-SchemaObjectCount regex for Windows line endings (\r\n)
- Fix path comparison for DMP file copy operation
- Add GRANT EXECUTE ON SYS.AUTH_PACK TO PUBLIC for PACK_DREPTURI
- Fix VAUTH_SERII view to use SYN_NOM_PROGRAME (has DENUMIRE column)
- Add sections 10-11 to grants-public.sql for SYS object grants

Tested on VM 302 (10.0.20.130) with Oracle XE 21c.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Marius
2026-01-28 20:56:58 +02:00
parent 75a5daab6f
commit bcb558f1dc
9 changed files with 503 additions and 68 deletions

View File

@@ -17,6 +17,82 @@
# Source logging functions
. "$PSScriptRoot\logging-functions.ps1"
<#
.SYNOPSIS
Get the listener host address.
.DESCRIPTION
Auto-detects the host address from listener configuration.
Returns the IP address the listener is bound to.
.PARAMETER OracleHome
Oracle Home directory.
.OUTPUTS
String. The host address (IP or hostname).
.EXAMPLE
$host = Get-ListenerHost -OracleHome "C:\app\oracle\product\21c\dbhomeXE"
#>
function Get-ListenerHost {
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[string]$OracleHome
)
$oraHome = Get-OracleHome -OracleHome $OracleHome
$lsnrctl = Join-Path $oraHome "bin\lsnrctl.exe"
if (-not (Test-Path $lsnrctl)) {
return "localhost"
}
try {
# Set Oracle environment
$env:ORACLE_HOME = $oraHome
$env:PATH = "$oraHome\bin;$env:PATH"
$output = & $lsnrctl status 2>&1 | Out-String
# Parse HOST from listener output - look for TCP endpoint (not TCPS)
# Format: (PROTOCOL=tcp)(HOST=10.0.20.130)(PORT=1521)
# Use simple IP pattern to avoid regex escaping issues
$tcpMatch = [regex]::Match($output, "PROTOCOL=tcp\).*?HOST=([0-9\.]+)")
if ($tcpMatch.Success) {
$listenerHost = $tcpMatch.Groups[1].Value
# If listener is bound to 0.0.0.0, try to get actual IP
if ($listenerHost -eq "0.0.0.0") {
$ip = (Get-NetIPAddress -AddressFamily IPv4 |
Where-Object { $_.IPAddress -notmatch "^127\." -and $_.PrefixOrigin -ne "WellKnown" } |
Select-Object -First 1).IPAddress
if ($ip) { return $ip }
return "localhost"
}
# If it's a specific IP (not localhost), return it
if ($listenerHost -notmatch "^127\." -and $listenerHost -ne "localhost") {
return $listenerHost
}
}
# Fallback: try any HOST= pattern
$anyHostMatch = [regex]::Match($output, "HOST=([0-9\.]+)")
if ($anyHostMatch.Success) {
$listenerHost = $anyHostMatch.Groups[1].Value
if ($listenerHost -notmatch "^127\." -and $listenerHost -ne "0.0.0.0") {
return $listenerHost
}
}
return "localhost"
}
catch {
return "localhost"
}
}
<#
.SYNOPSIS
Find Oracle Home directory.
@@ -489,14 +565,15 @@ function Invoke-SqlPlus {
throw "SQL*Plus not found at: $sqlplus"
}
# Build connection string (EZConnect format if DbHost is provided)
$sysdba = if ($AsSysdba) { " as sysdba" } else { "" }
if ($DbHost) {
$connString = "$Username/`"$Password`"@${DbHost}:${Port}/${ServiceName}$sysdba"
} else {
$connString = "$Username/`"$Password`"@$ServiceName$sysdba"
# Auto-detect host from listener if not provided
if (-not $DbHost) {
$DbHost = Get-ListenerHost -OracleHome $oraHome
}
# Build connection string (always use EZConnect format for reliability)
$sysdba = if ($AsSysdba) { " as sysdba" } else { "" }
$connString = "$Username/`"$Password`"@${DbHost}:${Port}/${ServiceName}$sysdba"
$tempFile = $null
try {
@@ -973,14 +1050,21 @@ SELECT 'INVALID:' || COUNT(*) FROM dba_objects WHERE owner = UPPER('$SchemaName'
EXIT;
"@
$result = Invoke-SqlPlus -OracleHome $OracleHome -ServiceName $ServiceName `
$oraHome = Get-OracleHome -OracleHome $OracleHome
$result = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $Password -SqlCommand $sql -Silent
$counts = @{}
foreach ($line in $result -split "`n") {
if ($line -match "^([A-Z_ ]+):(\d+)$") {
$counts[$Matches[1].Trim()] = [int]$Matches[2]
# Parse result lines for object type counts
$lines = $result -split "`r?`n"
foreach ($line in $lines) {
$trimmed = $line.Trim()
if ($trimmed.Length -gt 0 -and $trimmed -match "^([A-Z][A-Z_ ]*):(\d+)$") {
$key = $Matches[1].Trim()
$value = [int]$Matches[2]
$counts[$key] = $value
}
}