Files
ROMFASTSQL/proxmox/lxc108-oracle/roa-windows-setup/scripts/lib/oracle-functions.ps1
Marius 498025160e Fix PowerShell $Host reserved variable conflict in ROA setup scripts
- Rename $Host parameter to $DbHost in oracle-functions.ps1 (Invoke-SqlPlus,
  Test-OracleConnection, Get-OracleVersion, Test-PDB, Get-ServiceName)
- Update all function calls in 01-setup-database.ps1 to use -DbHost instead of -Host
- Fix ${Host} -> ${DbHost} in log message (line 147)
- Fix Write-Log "" -> Write-Host "" to avoid empty string parameter error
- Add DbHost/Port parameters and config.ps1 support to setup script
- Update sys-updates/README.md to clarify folder is for future patches only

Tested successfully on ROACENTRAL (10.0.20.130) with Oracle XE 21c.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 18:30:31 +02:00

992 lines
26 KiB
PowerShell

#Requires -Version 5.1
<#
.SYNOPSIS
Oracle connectivity and operations functions for ROA setup scripts.
.DESCRIPTION
Provides functions for Oracle database connectivity, SQL*Plus execution,
version detection, and Data Pump operations.
.NOTES
File Name : oracle-functions.ps1
Prerequisite : PowerShell 5.1 or higher, Oracle Client installed
Copyright 2024 : ROMFAST
#>
# Source logging functions
. "$PSScriptRoot\logging-functions.ps1"
<#
.SYNOPSIS
Find Oracle Home directory.
.DESCRIPTION
Auto-detects Oracle Home from registry, environment variable, or common paths.
.PARAMETER OracleHome
Optional explicit Oracle Home path. If not specified, auto-detects.
.OUTPUTS
String. The Oracle Home path.
.EXAMPLE
$oracleHome = Get-OracleHome
#>
function Get-OracleHome {
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[string]$OracleHome
)
# If explicitly provided, validate and return
if ($OracleHome) {
if (Test-Path -Path "$OracleHome\bin\sqlplus.exe") {
return $OracleHome
}
throw "Invalid Oracle Home: sqlplus.exe not found at $OracleHome\bin\sqlplus.exe"
}
# Try ORACLE_HOME environment variable
if ($env:ORACLE_HOME -and (Test-Path -Path "$env:ORACLE_HOME\bin\sqlplus.exe")) {
return $env:ORACLE_HOME
}
# Try registry for Oracle XE
$regPaths = @(
'HKLM:\SOFTWARE\Oracle\KEY_OraDB21Home1',
'HKLM:\SOFTWARE\Oracle\KEY_OraDB18Home1',
'HKLM:\SOFTWARE\Oracle\KEY_XE',
'HKLM:\SOFTWARE\Wow6432Node\Oracle\KEY_OraDB21Home1',
'HKLM:\SOFTWARE\Wow6432Node\Oracle\KEY_OraDB18Home1'
)
foreach ($regPath in $regPaths) {
if (Test-Path -Path $regPath) {
$oraHome = (Get-ItemProperty -Path $regPath -ErrorAction SilentlyContinue).ORACLE_HOME
if ($oraHome -and (Test-Path -Path "$oraHome\bin\sqlplus.exe")) {
return $oraHome
}
}
}
# Try common installation paths (including user-specific paths)
$currentUser = $env:USERNAME
$commonPaths = @(
"C:\app\$currentUser\product\21c\dbhomeXE",
"C:\app\$currentUser\product\21c\dbhome_1",
"C:\app\$currentUser\product\18c\dbhomeXE",
'C:\app\oracle\product\21c\dbhomeXE',
'C:\app\oracle\product\21c\dbhome_1',
'C:\app\oracle\product\18c\dbhomeXE',
'C:\app\romfast\product\21c\dbhomeXE',
'C:\app\romfast\product\21c\dbhome_1',
'C:\oraclexe\app\oracle\product\11.2.0\server',
"D:\app\$currentUser\product\21c\dbhomeXE",
'D:\app\oracle\product\21c\dbhomeXE',
'D:\app\oracle\product\18c\dbhomeXE'
)
foreach ($path in $commonPaths) {
if (Test-Path -Path "$path\bin\sqlplus.exe") {
return $path
}
}
throw "Oracle Home not found. Please specify -OracleHome parameter or set ORACLE_HOME environment variable."
}
<#
.SYNOPSIS
Get Oracle version information.
.DESCRIPTION
Detects Oracle version (XE vs SE), edition, and whether it's a Container Database (CDB).
.PARAMETER OracleHome
Oracle Home directory.
.PARAMETER ServiceName
Database service name.
.PARAMETER Username
Username for connection (default: SYSTEM).
.PARAMETER Password
Password for connection.
.OUTPUTS
PSCustomObject with Version, Edition, IsCDB, IsXE properties.
.EXAMPLE
$version = Get-OracleVersion -ServiceName "XE" -Password "oracle"
#>
function Get-OracleVersion {
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[string]$OracleHome,
[Parameter(Mandatory = $true)]
[string]$ServiceName,
[Parameter(Mandatory = $false)]
[string]$DbHost,
[Parameter(Mandatory = $false)]
[int]$Port = 1521,
[Parameter(Mandatory = $false)]
[string]$Username = "SYSTEM",
[Parameter(Mandatory = $true)]
[string]$Password
)
$oraHome = Get-OracleHome -OracleHome $OracleHome
$sql = @"
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF
SELECT 'VERSION:' || version_full FROM v`$instance;
SELECT 'EDITION:' || edition FROM v`$instance;
SELECT 'CDB:' || CDB FROM v`$database;
EXIT;
"@
$result = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-DbHost $DbHost -Port $Port `
-Username $Username -Password $Password -SqlCommand $sql -Silent
$versionInfo = [PSCustomObject]@{
Version = ""
Edition = ""
IsCDB = $false
IsXE = $false
FullInfo = $result
}
foreach ($line in $result -split "`n") {
if ($line -match "^VERSION:(.+)$") {
$versionInfo.Version = $Matches[1].Trim()
}
elseif ($line -match "^EDITION:(.+)$") {
$versionInfo.Edition = $Matches[1].Trim()
$versionInfo.IsXE = $versionInfo.Edition -match "XE|Express"
}
elseif ($line -match "^CDB:(.+)$") {
$versionInfo.IsCDB = $Matches[1].Trim() -eq "YES"
}
}
return $versionInfo
}
<#
.SYNOPSIS
Get the default service name based on Oracle configuration.
.DESCRIPTION
Auto-detects the appropriate service name. Returns XEPDB1 for Oracle XE CDB,
or ROA for traditional non-CDB installations.
.PARAMETER OracleHome
Oracle Home directory.
.PARAMETER SystemPassword
SYSTEM user password.
.OUTPUTS
String. The service name.
.EXAMPLE
$serviceName = Get-ServiceName -SystemPassword "oracle"
#>
function Get-ServiceName {
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[string]$OracleHome,
[Parameter(Mandatory = $false)]
[string]$DbHost,
[Parameter(Mandatory = $false)]
[int]$Port = 1521,
[Parameter(Mandatory = $true)]
[string]$SystemPassword
)
$oraHome = Get-OracleHome -OracleHome $OracleHome
# First try to connect to XE and check if it's CDB
try {
$version = Get-OracleVersion -OracleHome $oraHome -ServiceName "XE" `
-DbHost $DbHost -Port $Port `
-Password $SystemPassword -ErrorAction Stop
if ($version.IsCDB) {
# For CDB, use XEPDB1 (the default pluggable database)
return "XEPDB1"
}
else {
return "XE"
}
}
catch {
# Try ROA as service name
try {
$null = Test-OracleConnection -OracleHome $oraHome -ServiceName "ROA" `
-DbHost $DbHost -Port $Port `
-Username "SYSTEM" -Password $SystemPassword -ErrorAction Stop
return "ROA"
}
catch {
# Default to XEPDB1 for modern XE installations
return "XEPDB1"
}
}
}
<#
.SYNOPSIS
Test Oracle database connection.
.DESCRIPTION
Attempts to connect to Oracle and verifies the connection is successful.
.PARAMETER OracleHome
Oracle Home directory.
.PARAMETER ServiceName
Database service name.
.PARAMETER Username
Username for connection.
.PARAMETER Password
Password for connection.
.OUTPUTS
Boolean. True if connection successful.
.EXAMPLE
if (Test-OracleConnection -ServiceName "XEPDB1" -Username "SYSTEM" -Password "oracle") {
Write-Host "Connected!"
}
#>
function Test-OracleConnection {
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[string]$OracleHome,
[Parameter(Mandatory = $true)]
[string]$ServiceName,
[Parameter(Mandatory = $false)]
[string]$DbHost,
[Parameter(Mandatory = $false)]
[int]$Port = 1521,
[Parameter(Mandatory = $false)]
[string]$Username = "SYSTEM",
[Parameter(Mandatory = $true)]
[string]$Password,
[Parameter(Mandatory = $false)]
[switch]$AsSysdba
)
$oraHome = Get-OracleHome -OracleHome $OracleHome
$sql = "SELECT 'CONNECTED' FROM dual; EXIT;"
try {
$result = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-DbHost $DbHost -Port $Port `
-Username $Username -Password $Password -SqlCommand $sql -AsSysdba:$AsSysdba -Silent
return $result -match "CONNECTED"
}
catch {
return $false
}
}
<#
.SYNOPSIS
Test if connected to a PDB or non-CDB.
.DESCRIPTION
Checks the current container type to determine if connected to a PDB,
the CDB root, or a non-CDB database.
.PARAMETER OracleHome
Oracle Home directory.
.PARAMETER ServiceName
Database service name.
.PARAMETER Username
Username for connection.
.PARAMETER Password
Password for connection.
.OUTPUTS
PSCustomObject with ContainerName, IsPDB, IsCDBRoot, IsNonCDB properties.
.EXAMPLE
$containerInfo = Test-PDB -ServiceName "XEPDB1" -Password "oracle"
#>
function Test-PDB {
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[string]$OracleHome,
[Parameter(Mandatory = $true)]
[string]$ServiceName,
[Parameter(Mandatory = $false)]
[string]$DbHost,
[Parameter(Mandatory = $false)]
[int]$Port = 1521,
[Parameter(Mandatory = $false)]
[string]$Username = "SYSTEM",
[Parameter(Mandatory = $true)]
[string]$Password
)
$oraHome = Get-OracleHome -OracleHome $OracleHome
$sql = @"
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF
SELECT 'CONTAINER:' || SYS_CONTEXT('USERENV', 'CON_NAME') FROM dual;
SELECT 'CON_ID:' || SYS_CONTEXT('USERENV', 'CON_ID') FROM dual;
EXIT;
"@
$result = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-DbHost $DbHost -Port $Port `
-Username $Username -Password $Password -SqlCommand $sql -Silent
$containerInfo = [PSCustomObject]@{
ContainerName = ""
ConId = 0
IsPDB = $false
IsCDBRoot = $false
IsNonCDB = $false
}
foreach ($line in $result -split "`n") {
if ($line -match "^CONTAINER:(.+)$") {
$containerInfo.ContainerName = $Matches[1].Trim()
}
elseif ($line -match "^CON_ID:(.+)$") {
$containerInfo.ConId = [int]$Matches[1].Trim()
}
}
if ($containerInfo.ConId -eq 0) {
$containerInfo.IsNonCDB = $true
}
elseif ($containerInfo.ConId -eq 1) {
$containerInfo.IsCDBRoot = $true
}
else {
$containerInfo.IsPDB = $true
}
return $containerInfo
}
<#
.SYNOPSIS
Execute SQL via SQL*Plus.
.DESCRIPTION
Runs a SQL command or file using SQL*Plus and returns the output.
.PARAMETER OracleHome
Oracle Home directory.
.PARAMETER ServiceName
Database service name.
.PARAMETER Username
Username for connection.
.PARAMETER Password
Password for connection.
.PARAMETER SqlCommand
SQL command(s) to execute.
.PARAMETER SqlFile
Path to SQL file to execute.
.PARAMETER AsSysdba
Connect as SYSDBA.
.PARAMETER Silent
Suppress console output.
.OUTPUTS
String. The SQL*Plus output.
.EXAMPLE
Invoke-SqlPlus -ServiceName "XEPDB1" -Username "SYSTEM" -Password "oracle" -SqlCommand "SELECT * FROM dual;"
.EXAMPLE
Invoke-SqlPlus -ServiceName "XEPDB1" -Username "SYS" -Password "oracle" -SqlFile "C:\scripts\setup.sql" -AsSysdba
#>
function Invoke-SqlPlus {
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[string]$OracleHome,
[Parameter(Mandatory = $true)]
[string]$ServiceName,
[Parameter(Mandatory = $false)]
[string]$DbHost,
[Parameter(Mandatory = $false)]
[int]$Port = 1521,
[Parameter(Mandatory = $false)]
[string]$Username = "SYSTEM",
[Parameter(Mandatory = $true)]
[string]$Password,
[Parameter(Mandatory = $false)]
[string]$SqlCommand,
[Parameter(Mandatory = $false)]
[string]$SqlFile,
[Parameter(Mandatory = $false)]
[switch]$AsSysdba,
[Parameter(Mandatory = $false)]
[switch]$Silent
)
$oraHome = Get-OracleHome -OracleHome $OracleHome
$sqlplus = Join-Path $oraHome "bin\sqlplus.exe"
if (-not (Test-Path -Path $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"
}
$tempFile = $null
try {
if ($SqlFile) {
# Execute SQL file
if (-not (Test-Path -Path $SqlFile)) {
throw "SQL file not found: $SqlFile"
}
$arguments = "-S `"$connString`" @`"$SqlFile`""
}
else {
# Create temp file for SQL command
$tempFile = [System.IO.Path]::GetTempFileName()
$tempFile = [System.IO.Path]::ChangeExtension($tempFile, ".sql")
Set-Content -Path $tempFile -Value $SqlCommand -Encoding ASCII
$arguments = "-S `"$connString`" @`"$tempFile`""
}
# Set Oracle environment
$env:ORACLE_HOME = $oraHome
$env:PATH = "$oraHome\bin;$env:PATH"
$env:NLS_LANG = "AMERICAN_AMERICA.AL32UTF8"
# Execute SQL*Plus
$processInfo = New-Object System.Diagnostics.ProcessStartInfo
$processInfo.FileName = $sqlplus
$processInfo.Arguments = "-S `"$connString`""
$processInfo.RedirectStandardInput = $true
$processInfo.RedirectStandardOutput = $true
$processInfo.RedirectStandardError = $true
$processInfo.UseShellExecute = $false
$processInfo.CreateNoWindow = $true
$process = New-Object System.Diagnostics.Process
$process.StartInfo = $processInfo
$process.Start() | Out-Null
# Send SQL
if ($SqlFile) {
$process.StandardInput.WriteLine("@`"$SqlFile`"")
}
else {
$process.StandardInput.WriteLine($SqlCommand)
}
$process.StandardInput.Close()
$output = $process.StandardOutput.ReadToEnd()
$errorOutput = $process.StandardError.ReadToEnd()
$process.WaitForExit()
if ($errorOutput) {
$output += "`n$errorOutput"
}
# Check for Oracle errors
if ($output -match "ORA-\d{5}:|SP2-\d{4}:") {
if (-not $Silent) {
Write-LogWarning "SQL*Plus returned errors:"
Write-Host $output -ForegroundColor Yellow
}
}
return $output
}
finally {
if ($tempFile -and (Test-Path -Path $tempFile)) {
Remove-Item -Path $tempFile -Force -ErrorAction SilentlyContinue
}
}
}
<#
.SYNOPSIS
Create Oracle directory object for Data Pump.
.DESCRIPTION
Creates a directory object in Oracle for Data Pump operations if it doesn't exist.
.PARAMETER OracleHome
Oracle Home directory.
.PARAMETER ServiceName
Database service name.
.PARAMETER Password
SYS or SYSTEM password.
.PARAMETER DirectoryName
Oracle directory object name (default: DMPDIR).
.PARAMETER DirectoryPath
File system path for the directory (default: C:\DMPDIR).
.EXAMPLE
New-OracleDirectory -ServiceName "XEPDB1" -Password "oracle" -DirectoryPath "D:\Dumps"
#>
function New-OracleDirectory {
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[string]$OracleHome,
[Parameter(Mandatory = $true)]
[string]$ServiceName,
[Parameter(Mandatory = $true)]
[string]$Password,
[Parameter(Mandatory = $false)]
[string]$DirectoryName = "DMPDIR",
[Parameter(Mandatory = $false)]
[string]$DirectoryPath = "C:\DMPDIR"
)
# Create physical directory if it doesn't exist
if (-not (Test-Path -Path $DirectoryPath)) {
New-Item -ItemType Directory -Path $DirectoryPath -Force | Out-Null
Write-Log "Created directory: $DirectoryPath"
}
$sql = @"
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF
CREATE OR REPLACE DIRECTORY $DirectoryName AS '$DirectoryPath';
GRANT READ, WRITE ON DIRECTORY $DirectoryName TO PUBLIC;
COMMIT;
SELECT 'DIRECTORY_CREATED' FROM dual;
EXIT;
"@
$result = Invoke-SqlPlus -OracleHome $OracleHome -ServiceName $ServiceName `
-Username "SYS" -Password $Password -SqlCommand $sql -AsSysdba -Silent
if ($result -match "DIRECTORY_CREATED") {
Write-Log "Oracle directory $DirectoryName created pointing to $DirectoryPath"
return $true
}
else {
Write-LogWarning "Could not verify directory creation"
return $false
}
}
<#
.SYNOPSIS
Get the default datafile path based on Oracle installation.
.DESCRIPTION
Determines the appropriate datafile location based on Oracle Home and version.
.PARAMETER OracleHome
Oracle Home directory.
.PARAMETER ServiceName
Database service name.
.PARAMETER Password
SYSTEM password.
.OUTPUTS
String. The datafile directory path.
.EXAMPLE
$datafilePath = Get-DatafilePath -ServiceName "XEPDB1" -Password "oracle"
#>
function Get-DatafilePath {
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[string]$OracleHome,
[Parameter(Mandatory = $true)]
[string]$ServiceName,
[Parameter(Mandatory = $true)]
[string]$Password
)
$oraHome = Get-OracleHome -OracleHome $OracleHome
# Query Oracle for default datafile location
$sql = @"
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF LINESIZE 500
SELECT 'DATAFILE_PATH:' || SUBSTR(file_name, 1, INSTR(file_name, '\', -1))
FROM dba_data_files
WHERE tablespace_name = 'SYSTEM'
AND ROWNUM = 1;
EXIT;
"@
$result = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $Password -SqlCommand $sql -Silent
foreach ($line in $result -split "`n") {
if ($line -match "^DATAFILE_PATH:(.+)$") {
$path = $Matches[1].Trim()
# Remove trailing backslash if present
return $path.TrimEnd('\')
}
}
# Fallback to common paths based on Oracle Home
$version = Get-OracleVersion -OracleHome $oraHome -ServiceName $ServiceName -Password $Password
if ($version.IsXE) {
if ($version.Version -match "^21") {
return "C:\app\oracle\oradata\XE\XEPDB1"
}
elseif ($version.Version -match "^18") {
return "C:\app\oracle\oradata\XE"
}
}
# Default fallback
return "C:\app\oracle\oradata"
}
<#
.SYNOPSIS
Execute Data Pump import.
.DESCRIPTION
Runs impdp with specified parameters.
.PARAMETER OracleHome
Oracle Home directory.
.PARAMETER ServiceName
Database service name.
.PARAMETER Username
Username for connection (default: SYSTEM).
.PARAMETER Password
Password for connection.
.PARAMETER DumpFile
Name of the dump file (in DMPDIR).
.PARAMETER LogFile
Name of the log file.
.PARAMETER Schemas
Schema(s) to import.
.PARAMETER RemapSchema
Remap schema mapping (e.g., "OLD_SCHEMA:NEW_SCHEMA").
.PARAMETER DirectoryName
Oracle directory object name (default: DMPDIR).
.PARAMETER TableExists
Table exists action: SKIP, APPEND, TRUNCATE, REPLACE (default: REPLACE).
.PARAMETER AdditionalParams
Additional impdp parameters.
.OUTPUTS
PSCustomObject with Success, LogContent, ErrorMessage properties.
.EXAMPLE
Invoke-DataPumpImport -ServiceName "XEPDB1" -Password "oracle" -DumpFile "CONTAFIN_ORACLE.dmp" -Schemas "CONTAFIN_ORACLE"
#>
function Invoke-DataPumpImport {
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[string]$OracleHome,
[Parameter(Mandatory = $true)]
[string]$ServiceName,
[Parameter(Mandatory = $false)]
[string]$Username = "SYSTEM",
[Parameter(Mandatory = $true)]
[string]$Password,
[Parameter(Mandatory = $true)]
[string]$DumpFile,
[Parameter(Mandatory = $false)]
[string]$LogFile,
[Parameter(Mandatory = $false)]
[string[]]$Schemas,
[Parameter(Mandatory = $false)]
[string]$RemapSchema,
[Parameter(Mandatory = $false)]
[string]$DirectoryName = "DMPDIR",
[Parameter(Mandatory = $false)]
[ValidateSet('SKIP', 'APPEND', 'TRUNCATE', 'REPLACE')]
[string]$TableExists = "REPLACE",
[Parameter(Mandatory = $false)]
[string]$AdditionalParams
)
$oraHome = Get-OracleHome -OracleHome $OracleHome
$impdp = Join-Path $oraHome "bin\impdp.exe"
if (-not (Test-Path -Path $impdp)) {
throw "impdp not found at: $impdp"
}
# Build impdp command
if (-not $LogFile) {
$LogFile = [System.IO.Path]::GetFileNameWithoutExtension($DumpFile) + "_import.log"
}
$connString = "$Username/`"$Password`"@$ServiceName"
$params = @(
"`"$connString`"",
"directory=$DirectoryName",
"dumpfile=$DumpFile",
"logfile=$LogFile",
"table_exists_action=$TableExists"
)
if ($Schemas) {
$params += "schemas=$($Schemas -join ',')"
}
if ($RemapSchema) {
$params += "remap_schema=$RemapSchema"
}
if ($AdditionalParams) {
$params += $AdditionalParams
}
$arguments = $params -join " "
Write-Log "Executing: impdp $($params -join ' ' -replace $Password, '****')"
# Set Oracle environment
$env:ORACLE_HOME = $oraHome
$env:PATH = "$oraHome\bin;$env:PATH"
$env:NLS_LANG = "AMERICAN_AMERICA.AL32UTF8"
# Execute impdp
$process = Start-Process -FilePath $impdp -ArgumentList $arguments -Wait -NoNewWindow -PassThru `
-RedirectStandardOutput "$env:TEMP\impdp_out.txt" -RedirectStandardError "$env:TEMP\impdp_err.txt"
$stdout = Get-Content -Path "$env:TEMP\impdp_out.txt" -Raw -ErrorAction SilentlyContinue
$stderr = Get-Content -Path "$env:TEMP\impdp_err.txt" -Raw -ErrorAction SilentlyContinue
$result = [PSCustomObject]@{
Success = $process.ExitCode -eq 0
ExitCode = $process.ExitCode
Output = $stdout
ErrorOutput = $stderr
LogFile = $LogFile
}
# Clean up temp files
Remove-Item -Path "$env:TEMP\impdp_out.txt" -Force -ErrorAction SilentlyContinue
Remove-Item -Path "$env:TEMP\impdp_err.txt" -Force -ErrorAction SilentlyContinue
return $result
}
<#
.SYNOPSIS
Check if a user/schema exists in the database.
.DESCRIPTION
Queries DBA_USERS to check if a user exists.
.PARAMETER OracleHome
Oracle Home directory.
.PARAMETER ServiceName
Database service name.
.PARAMETER Password
SYSTEM password.
.PARAMETER SchemaName
Name of the schema/user to check.
.OUTPUTS
Boolean. True if user exists.
.EXAMPLE
if (Test-OracleUser -ServiceName "XEPDB1" -Password "oracle" -SchemaName "CONTAFIN_ORACLE") {
Write-Host "User exists"
}
#>
function Test-OracleUser {
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[string]$OracleHome,
[Parameter(Mandatory = $true)]
[string]$ServiceName,
[Parameter(Mandatory = $true)]
[string]$Password,
[Parameter(Mandatory = $true)]
[string]$SchemaName
)
$sql = @"
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF
SELECT 'USER_EXISTS' FROM dba_users WHERE username = UPPER('$SchemaName');
EXIT;
"@
$result = Invoke-SqlPlus -OracleHome $OracleHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $Password -SqlCommand $sql -Silent
return $result -match "USER_EXISTS"
}
<#
.SYNOPSIS
Get object count for a schema.
.DESCRIPTION
Counts objects in a schema grouped by type.
.PARAMETER OracleHome
Oracle Home directory.
.PARAMETER ServiceName
Database service name.
.PARAMETER Password
SYSTEM password.
.PARAMETER SchemaName
Name of the schema.
.OUTPUTS
Hashtable with object types and counts.
.EXAMPLE
$counts = Get-SchemaObjectCount -ServiceName "XEPDB1" -Password "oracle" -SchemaName "CONTAFIN_ORACLE"
#>
function Get-SchemaObjectCount {
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[string]$OracleHome,
[Parameter(Mandatory = $true)]
[string]$ServiceName,
[Parameter(Mandatory = $true)]
[string]$Password,
[Parameter(Mandatory = $true)]
[string]$SchemaName
)
$sql = @"
SET PAGESIZE 1000 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF LINESIZE 200
SELECT object_type || ':' || COUNT(*)
FROM dba_objects
WHERE owner = UPPER('$SchemaName')
GROUP BY object_type
ORDER BY object_type;
SELECT 'TOTAL:' || COUNT(*) FROM dba_objects WHERE owner = UPPER('$SchemaName');
SELECT 'INVALID:' || COUNT(*) FROM dba_objects WHERE owner = UPPER('$SchemaName') AND status = 'INVALID';
EXIT;
"@
$result = Invoke-SqlPlus -OracleHome $OracleHome -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]
}
}
return $counts
}
# Note: Functions are available when dot-sourced (. .\oracle-functions.ps1)
# Do NOT use Export-ModuleMember - it only works inside .psm1 modules