Add ROA Oracle Database Windows setup scripts with old client support

PowerShell scripts for setting up Oracle 21c/XE with ROA application:
- Automated tablespace, user creation and imports
- sqlnet.ora config for Instant Client 11g/ODBC compatibility
- Oracle 21c read-only Home path handling (homes/OraDB21Home1)
- Listener restart + 10G password verifier for legacy auth
- Tested on VM 302 with CONTAFIN_ORACLE schema import

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Marius
2026-01-28 17:08:02 +02:00
parent 665c2b5d37
commit 989477f7a4
26 changed files with 8972 additions and 0 deletions

View File

@@ -0,0 +1,477 @@
#Requires -Version 5.1
<#
.SYNOPSIS
Initial database setup for ROA Oracle.
.DESCRIPTION
Performs initial database configuration including:
- Validates Oracle installation
- Auto-detects CDB vs non-CDB configuration
- Configures DEFAULT_PROFILE (disables password expiry)
- Configures sqlnet.ora for Instant Client 10/11 compatibility
- Creates tablespace ROA
- Creates user CONTAFIN_ORACLE with required privileges
.PARAMETER OracleHome
Oracle home directory. If not specified, auto-detects from registry or environment.
.PARAMETER ServiceName
Database service name. Auto-detects: ROA for non-CDB, XEPDB1 for Oracle XE CDB.
.PARAMETER SystemPassword
SYSTEM user password. Default: romfastsoft
.PARAMETER ContafinPassword
CONTAFIN_ORACLE user password. Default: ROMFASTSOFT
.PARAMETER DatafileDir
Directory for tablespace datafiles. Auto-detects if not specified.
.PARAMETER TablespaceSize
Initial size of ROA tablespace in MB. Default: 1000
.PARAMETER SkipSqlnetConfig
Skip sqlnet.ora configuration.
.EXAMPLE
.\01-setup-database.ps1
.EXAMPLE
.\01-setup-database.ps1 -ServiceName "XEPDB1" -SystemPassword "mypassword"
.EXAMPLE
.\01-setup-database.ps1 -OracleHome "C:\app\oracle\product\21c\dbhomeXE" -DatafileDir "D:\oradata"
.NOTES
File Name : 01-setup-database.ps1
Prerequisite : Oracle Database installed, PowerShell 5.1+
Copyright 2024 : ROMFAST
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[string]$OracleHome,
[Parameter(Mandatory = $false)]
[string]$ServiceName,
[Parameter(Mandatory = $false)]
[string]$SystemPassword = "romfastsoft",
[Parameter(Mandatory = $false)]
[string]$ContafinPassword = "ROMFASTSOFT",
[Parameter(Mandatory = $false)]
[string]$DatafileDir,
[Parameter(Mandatory = $false)]
[int]$TablespaceSize = 1000,
[Parameter(Mandatory = $false)]
[switch]$SkipSqlnetConfig
)
$ErrorActionPreference = 'Stop'
# Source library functions
. "$PSScriptRoot\lib\logging-functions.ps1"
. "$PSScriptRoot\lib\oracle-functions.ps1"
# Initialize logging
$logPath = Join-Path $PSScriptRoot "..\logs\01-setup-database_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
Initialize-LogFile -LogPath $logPath -ScriptName "01-setup-database.ps1"
try {
Write-LogSection "ROA Database Initial Setup"
# Step 1: Validate Oracle installation
Write-Log "Detecting Oracle installation..."
$oraHome = Get-OracleHome -OracleHome $OracleHome
Write-LogSuccess "Oracle Home: $oraHome"
# Step 2: Auto-detect service name if not specified
if (-not $ServiceName) {
Write-Log "Auto-detecting service name..."
# First try to connect to XE to check CDB status
try {
$version = Get-OracleVersion -OracleHome $oraHome -ServiceName "XE" -Password $SystemPassword
if ($version.IsCDB) {
$ServiceName = "XEPDB1"
Write-Log "Detected CDB installation, using PDB: XEPDB1"
}
else {
$ServiceName = "XE"
Write-Log "Detected non-CDB installation, using service: XE"
}
}
catch {
# Try ROA as fallback
try {
$null = Test-OracleConnection -OracleHome $oraHome -ServiceName "ROA" -Password $SystemPassword
$ServiceName = "ROA"
Write-Log "Using existing service: ROA"
}
catch {
$ServiceName = "XEPDB1"
Write-Log "Defaulting to XEPDB1"
}
}
}
Write-LogSuccess "Service Name: $ServiceName"
# Step 3: Test connection
Write-Log "Testing database connection..."
if (-not (Test-OracleConnection -OracleHome $oraHome -ServiceName $ServiceName -Password $SystemPassword)) {
throw "Cannot connect to database. Please verify ServiceName and SystemPassword."
}
Write-LogSuccess "Database connection successful"
# Get version info
$versionInfo = Get-OracleVersion -OracleHome $oraHome -ServiceName $ServiceName -Password $SystemPassword
Write-Log "Oracle Version: $($versionInfo.Version)"
Write-Log "Oracle Edition: $($versionInfo.Edition)"
Write-Log "CDB Mode: $($versionInfo.IsCDB)"
# Check container info
$containerInfo = Test-PDB -OracleHome $oraHome -ServiceName $ServiceName -Password $SystemPassword
Write-Log "Container: $($containerInfo.ContainerName)"
if ($containerInfo.IsPDB) {
Write-Log "Connected to PDB (Pluggable Database)"
}
elseif ($containerInfo.IsNonCDB) {
Write-Log "Connected to non-CDB database"
}
# Step 4: Configure DEFAULT_PROFILE (no password expiry)
Write-LogSection "Configuring DEFAULT_PROFILE"
$profileSql = @"
SET ECHO OFF FEEDBACK ON VERIFY OFF
PROMPT Configuring DEFAULT_PROFILE - disabling password expiration...
ALTER PROFILE DEFAULT LIMIT
PASSWORD_LIFE_TIME UNLIMITED
PASSWORD_GRACE_TIME UNLIMITED
PASSWORD_REUSE_TIME UNLIMITED
PASSWORD_REUSE_MAX UNLIMITED
FAILED_LOGIN_ATTEMPTS UNLIMITED
PASSWORD_LOCK_TIME UNLIMITED;
COMMIT;
SELECT 'PROFILE_CONFIGURED' FROM dual;
EXIT;
"@
$result = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYS" -Password $SystemPassword -SqlCommand $profileSql -AsSysdba
if ($result -match "PROFILE_CONFIGURED") {
Write-LogSuccess "DEFAULT_PROFILE configured successfully"
}
else {
Write-LogWarning "Could not verify profile configuration"
Write-LogDebug $result
}
# Step 5: Configure sqlnet.ora for old client compatibility
if (-not $SkipSqlnetConfig) {
Write-LogSection "Configuring sqlnet.ora"
# Oracle 21c uses read-only Oracle Home - config goes to 'homes' directory
# Check for Oracle 21c homes directory structure first
$oraBase = Split-Path (Split-Path (Split-Path $oraHome -Parent) -Parent) -Parent
$homesDir = Join-Path $oraBase "product\21c\homes"
# Find the actual Oracle Base Home (where user configs go)
$networkAdmin = $null
if (Test-Path $homesDir) {
# Oracle 21c with read-only Oracle Home
$oraBaseHome = Get-ChildItem -Path $homesDir -Directory |
Where-Object { $_.Name -match "OraDB" } |
Select-Object -First 1
if ($oraBaseHome) {
$networkAdmin = Join-Path $oraBaseHome.FullName "network\admin"
Write-Log "Detected Oracle 21c read-only Home structure"
Write-Log "Using Oracle Base Home: $($oraBaseHome.FullName)"
}
}
# Fallback to traditional location
if (-not $networkAdmin -or -not (Test-Path (Split-Path $networkAdmin -Parent))) {
$networkAdmin = Join-Path $oraHome "network\admin"
Write-Log "Using traditional Oracle Home network/admin location"
}
$sqlnetOra = Join-Path $networkAdmin "sqlnet.ora"
if (-not (Test-Path -Path $networkAdmin)) {
New-Item -ItemType Directory -Path $networkAdmin -Force | Out-Null
}
# Backup existing sqlnet.ora
if (Test-Path -Path $sqlnetOra) {
$backupPath = "$sqlnetOra.bak_$(Get-Date -Format 'yyyyMMdd_HHmmss')"
Copy-Item -Path $sqlnetOra -Destination $backupPath -Force
Write-Log "Backed up existing sqlnet.ora to $backupPath"
}
# Create sqlnet.ora with compatibility settings
$sqlnetContent = @"
# sqlnet.ora - ROA Oracle Configuration
# Generated by 01-setup-database.ps1 on $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
# Allow connections from old Oracle Instant Client 10g/11g (ODBC drivers)
# These clients don't support newer authentication methods
SQLNET.ALLOWED_LOGON_VERSION_SERVER=8
SQLNET.ALLOWED_LOGON_VERSION_CLIENT=8
# Disable encryption requirement for old clients
SQLNET.ENCRYPTION_SERVER = ACCEPTED
SQLNET.CRYPTO_CHECKSUM_SERVER = ACCEPTED
# Connection timeout settings
SQLNET.INBOUND_CONNECT_TIMEOUT = 60
SQLNET.RECV_TIMEOUT = 30
SQLNET.SEND_TIMEOUT = 30
# TNS Names directory
NAMES.DIRECTORY_PATH = (TNSNAMES, EZCONNECT)
"@
Set-Content -Path $sqlnetOra -Value $sqlnetContent -Encoding ASCII
Write-LogSuccess "sqlnet.ora configured at $sqlnetOra"
Write-Log "Old client compatibility enabled (SQLNET.ALLOWED_LOGON_VERSION=8)"
# Restart listener to apply changes
Write-Log "Restarting listener to apply sqlnet.ora changes..."
$lsnrctl = Join-Path $oraHome "bin\lsnrctl.exe"
if (Test-Path $lsnrctl) {
try {
& $lsnrctl stop 2>&1 | Out-Null
Start-Sleep -Seconds 3
$lsnrOutput = & $lsnrctl start 2>&1
Write-LogSuccess "Listener restarted successfully"
# Wait for services to register
Write-Log "Waiting for database services to register with listener..."
Start-Sleep -Seconds 10
}
catch {
Write-LogWarning "Could not restart listener: $_"
Write-Log "Please restart listener manually: lsnrctl stop && lsnrctl start"
}
}
}
else {
Write-Log "Skipping sqlnet.ora configuration as requested"
}
# Step 6: Get datafile path
if (-not $DatafileDir) {
Write-Log "Auto-detecting datafile path..."
$DatafileDir = Get-DatafilePath -OracleHome $oraHome -ServiceName $ServiceName -Password $SystemPassword
}
Write-LogSuccess "Datafile directory: $DatafileDir"
# Step 7: Create tablespace ROA
Write-LogSection "Creating Tablespace ROA"
# Check if tablespace already exists
$checkTsSql = @"
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF
SELECT 'TS_EXISTS' FROM dba_tablespaces WHERE tablespace_name = 'ROA';
EXIT;
"@
$tsResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $checkTsSql -Silent
if ($tsResult -match "TS_EXISTS") {
Write-LogWarning "Tablespace ROA already exists, skipping creation"
}
else {
$datafilePath = Join-Path $DatafileDir "TS_ROA.DBF"
$createTsSql = @"
SET ECHO OFF FEEDBACK ON VERIFY OFF
PROMPT Creating tablespace ROA...
CREATE SMALLFILE TABLESPACE "ROA"
DATAFILE '$datafilePath' SIZE ${TablespaceSize}M
AUTOEXTEND ON NEXT 10M MAXSIZE UNLIMITED
LOGGING
EXTENT MANAGEMENT LOCAL
SEGMENT SPACE MANAGEMENT AUTO;
COMMIT;
SELECT 'TS_CREATED' FROM dual;
EXIT;
"@
$result = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $createTsSql
if ($result -match "TS_CREATED") {
Write-LogSuccess "Tablespace ROA created successfully"
Write-Log "Datafile: $datafilePath"
}
else {
Write-LogError "Failed to create tablespace ROA"
Write-LogDebug $result
throw "Tablespace creation failed"
}
}
# Step 8: Create user CONTAFIN_ORACLE
Write-LogSection "Creating User CONTAFIN_ORACLE"
# Check if user already exists
if (Test-OracleUser -OracleHome $oraHome -ServiceName $ServiceName `
-Password $SystemPassword -SchemaName "CONTAFIN_ORACLE") {
Write-LogWarning "User CONTAFIN_ORACLE already exists"
# Update password
$updatePwdSql = @"
SET ECHO OFF FEEDBACK ON VERIFY OFF
ALTER USER CONTAFIN_ORACLE IDENTIFIED BY "$ContafinPassword";
COMMIT;
SELECT 'PWD_UPDATED' FROM dual;
EXIT;
"@
$result = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $updatePwdSql -Silent
if ($result -match "PWD_UPDATED") {
Write-Log "Password updated for CONTAFIN_ORACLE"
}
}
else {
$createUserSql = @"
SET ECHO OFF FEEDBACK ON VERIFY OFF
PROMPT Creating user CONTAFIN_ORACLE...
CREATE USER CONTAFIN_ORACLE
IDENTIFIED BY "$ContafinPassword"
DEFAULT TABLESPACE ROA
TEMPORARY TABLESPACE TEMP
PROFILE DEFAULT;
PROMPT Granting role privileges...
GRANT CONNECT TO CONTAFIN_ORACLE;
GRANT RESOURCE TO CONTAFIN_ORACLE;
PROMPT Granting system privileges...
GRANT CREATE ANY CONTEXT TO CONTAFIN_ORACLE;
GRANT CREATE SESSION TO CONTAFIN_ORACLE;
GRANT CREATE VIEW TO CONTAFIN_ORACLE;
GRANT DELETE ANY TABLE TO CONTAFIN_ORACLE;
GRANT DROP ANY CONTEXT TO CONTAFIN_ORACLE;
GRANT EXECUTE ANY PROCEDURE TO CONTAFIN_ORACLE;
GRANT INSERT ANY TABLE TO CONTAFIN_ORACLE;
GRANT SELECT ANY DICTIONARY TO CONTAFIN_ORACLE;
GRANT SELECT ANY SEQUENCE TO CONTAFIN_ORACLE;
GRANT SELECT ANY TABLE TO CONTAFIN_ORACLE;
GRANT UNLIMITED TABLESPACE TO CONTAFIN_ORACLE;
GRANT UPDATE ANY TABLE TO CONTAFIN_ORACLE;
GRANT CREATE PUBLIC SYNONYM TO CONTAFIN_ORACLE;
GRANT DROP PUBLIC SYNONYM TO CONTAFIN_ORACLE;
COMMIT;
SELECT 'USER_CREATED' FROM dual;
EXIT;
"@
$result = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $createUserSql
if ($result -match "USER_CREATED") {
Write-LogSuccess "User CONTAFIN_ORACLE created successfully"
}
else {
Write-LogError "Failed to create user CONTAFIN_ORACLE"
Write-LogDebug $result
throw "User creation failed"
}
}
# Verify user privileges
$verifyUserSql = @"
SET PAGESIZE 100 FEEDBACK OFF VERIFY OFF HEADING ON ECHO OFF LINESIZE 200
SELECT privilege FROM dba_sys_privs WHERE grantee = 'CONTAFIN_ORACLE' ORDER BY privilege;
EXIT;
"@
$privileges = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $verifyUserSql -Silent
Write-Log "CONTAFIN_ORACLE privileges verified"
# Step 9: Create DMPDIR directory for Data Pump
Write-LogSection "Creating Data Pump Directory"
$dmpDir = "C:\DMPDIR"
New-OracleDirectory -OracleHome $oraHome -ServiceName $ServiceName `
-Password $SystemPassword -DirectoryName "DMPDIR" -DirectoryPath $dmpDir
Write-LogSuccess "Data Pump directory DMPDIR created: $dmpDir"
# Step 10: Reset passwords with 10G verifier (required for old client auth)
# After sqlnet.ora is configured, passwords must be reset to generate 10G hash
if (-not $SkipSqlnetConfig) {
Write-LogSection "Resetting Passwords for Old Client Compatibility"
Write-Log "Resetting passwords to generate 10G password verifiers..."
$resetPwdSql = @"
SET ECHO OFF FEEDBACK ON VERIFY OFF
-- Reset CONTAFIN_ORACLE password to generate 10G verifier
ALTER USER CONTAFIN_ORACLE IDENTIFIED BY "$ContafinPassword";
-- Verify password versions
SELECT USERNAME, PASSWORD_VERSIONS FROM DBA_USERS WHERE USERNAME = 'CONTAFIN_ORACLE';
SELECT 'PWD_RESET_DONE' FROM DUAL;
EXIT;
"@
$result = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $resetPwdSql
if ($result -match "PWD_RESET_DONE") {
Write-LogSuccess "Password reset completed - 10G verifier now available"
if ($result -match "10G") {
Write-Log "Verified: Password has 10G verifier for old client compatibility"
}
}
else {
Write-LogWarning "Could not verify password reset"
}
}
# Summary
Write-LogSection "Setup Complete"
Write-LogSuccess "Database initial setup completed successfully!"
Write-Log ""
Write-Log "Summary:"
Write-Log " Oracle Home: $oraHome"
Write-Log " Service Name: $ServiceName"
Write-Log " Oracle Version: $($versionInfo.Version)"
Write-Log " Container: $($containerInfo.ContainerName)"
Write-Log " Tablespace ROA: $DatafileDir\TS_ROA.DBF"
Write-Log " User: CONTAFIN_ORACLE"
Write-Log " Data Pump Dir: DMPDIR -> $dmpDir"
if (-not $SkipSqlnetConfig) {
Write-Log " Old Client Auth: Enabled (sqlnet.ora + 10G verifier)"
}
Write-Log ""
Write-Log "Next steps:"
Write-Log " 1. Run 02-create-sys-objects.ps1 to install SYS objects"
Write-Log " 2. Run 03-import-contafin.ps1 to import CONTAFIN_ORACLE schema"
Close-LogFile -Success $true
exit 0
}
catch {
Write-LogError "Setup failed: $_"
Write-LogError $_.ScriptStackTrace
Close-LogFile -Success $false
exit 1
}

View File

@@ -0,0 +1,432 @@
#Requires -Version 5.1
<#
.SYNOPSIS
Install SYS objects for ROA Oracle.
.DESCRIPTION
Executes SQL scripts to create required SYS-owned objects including:
- AUTH_PACK package
- AUTH_DETALII, AUTH_SERII tables
- NEWSCHEMA, NEWSCHEMAPOST procedures
- NEWSCHEMAPROGRESS function
- PACK_UPDATE, PACK_UTILS packages
- Public synonyms and grants
.PARAMETER OracleHome
Oracle home directory. If not specified, auto-detects.
.PARAMETER ServiceName
Database service name. Default: XEPDB1
.PARAMETER SystemPassword
SYSTEM/SYS user password. Default: romfastsoft
.PARAMETER SqlScriptsDir
Directory containing SYS SQL scripts. Default: ..\sql
.EXAMPLE
.\02-create-sys-objects.ps1
.EXAMPLE
.\02-create-sys-objects.ps1 -ServiceName "ROA" -SystemPassword "mypassword"
.NOTES
File Name : 02-create-sys-objects.ps1
Prerequisite : Run 01-setup-database.ps1 first
Copyright 2024 : ROMFAST
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[string]$OracleHome,
[Parameter(Mandatory = $false)]
[string]$ServiceName = "XEPDB1",
[Parameter(Mandatory = $false)]
[string]$SystemPassword = "romfastsoft",
[Parameter(Mandatory = $false)]
[string]$SqlScriptsDir
)
$ErrorActionPreference = 'Stop'
# Source library functions
. "$PSScriptRoot\lib\logging-functions.ps1"
. "$PSScriptRoot\lib\oracle-functions.ps1"
# Initialize logging
$logPath = Join-Path $PSScriptRoot "..\logs\02-create-sys-objects_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
Initialize-LogFile -LogPath $logPath -ScriptName "02-create-sys-objects.ps1"
try {
Write-LogSection "Installing SYS Objects"
# Validate Oracle installation
$oraHome = Get-OracleHome -OracleHome $OracleHome
Write-LogSuccess "Oracle Home: $oraHome"
# Test connection
Write-Log "Testing database connection..."
if (-not (Test-OracleConnection -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYS" -Password $SystemPassword -AsSysdba)) {
throw "Cannot connect to database as SYS. Please verify ServiceName and SystemPassword."
}
Write-LogSuccess "Database connection successful"
# Determine SQL scripts directory
if (-not $SqlScriptsDir) {
$SqlScriptsDir = Join-Path $PSScriptRoot "..\sql"
}
$sysObjectsScript = Join-Path $SqlScriptsDir "sys-objects.sql"
if (-not (Test-Path -Path $sysObjectsScript)) {
Write-LogWarning "sys-objects.sql not found at $sysObjectsScript"
Write-Log "Creating sys-objects.sql from embedded SQL..."
# Create the sql directory if it doesn't exist
if (-not (Test-Path -Path $SqlScriptsDir)) {
New-Item -ItemType Directory -Path $SqlScriptsDir -Force | Out-Null
}
# Embedded SYS objects SQL - minimal set for ROA
$sysObjectsSql = @"
-- sys-objects.sql
-- SYS objects required for ROA Oracle
-- Run as SYS with SYSDBA privilege
SET ECHO ON FEEDBACK ON VERIFY OFF SERVEROUTPUT ON
PROMPT
PROMPT =============================================
PROMPT Creating SYS objects for ROA
PROMPT =============================================
PROMPT
-- Create DMPDIR if not exists
PROMPT Creating directory DMPDIR...
CREATE OR REPLACE DIRECTORY DMPDIR AS 'C:\DMPDIR';
GRANT READ, WRITE ON DIRECTORY DMPDIR TO PUBLIC;
-- AUTH_DETALII table
PROMPT Creating table AUTH_DETALII...
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE SYS.AUTH_DETALII CASCADE CONSTRAINTS';
EXCEPTION WHEN OTHERS THEN NULL;
END;
/
CREATE TABLE SYS.AUTH_DETALII (
ID_DETALIU NUMBER NOT NULL,
ID_PROGRAM NUMBER NOT NULL,
CAMP_DETALIU VARCHAR2(100),
VAL_DETALIU VARCHAR2(500),
CONSTRAINT PK_AUTH_DETALII PRIMARY KEY (ID_DETALIU)
);
GRANT SELECT, INSERT, UPDATE, DELETE ON SYS.AUTH_DETALII TO PUBLIC;
CREATE PUBLIC SYNONYM AUTH_DETALII FOR SYS.AUTH_DETALII;
-- AUTH_SERII table
PROMPT Creating table AUTH_SERII...
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE SYS.AUTH_SERII CASCADE CONSTRAINTS';
EXCEPTION WHEN OTHERS THEN NULL;
END;
/
CREATE TABLE SYS.AUTH_SERII (
ID_PROGRAM NUMBER NOT NULL,
SERIE VARCHAR2(50),
NR_UTIL NUMBER,
DATA_VAL DATE,
CONSTRAINT PK_AUTH_SERII PRIMARY KEY (ID_PROGRAM)
);
GRANT SELECT, INSERT, UPDATE, DELETE ON SYS.AUTH_SERII TO PUBLIC;
CREATE PUBLIC SYNONYM AUTH_SERII FOR SYS.AUTH_SERII;
-- AUTH_PACK package specification
PROMPT Creating package AUTH_PACK...
CREATE OR REPLACE PACKAGE SYS.AUTH_PACK AS
FUNCTION selecteaza_serie(p_id_program NUMBER) RETURN VARCHAR2;
FUNCTION selecteaza_nr_util(p_id_program NUMBER) RETURN NUMBER;
FUNCTION selecteaza_data_val(p_id_program NUMBER) RETURN DATE;
PROCEDURE actualizeaza_serie(p_id_program NUMBER, p_serie VARCHAR2, p_nr_util NUMBER, p_data_val DATE);
END AUTH_PACK;
/
-- AUTH_PACK package body
CREATE OR REPLACE PACKAGE BODY SYS.AUTH_PACK AS
FUNCTION selecteaza_serie(p_id_program NUMBER) RETURN VARCHAR2 IS
v_serie VARCHAR2(50);
BEGIN
SELECT serie INTO v_serie FROM SYS.AUTH_SERII WHERE id_program = p_id_program;
RETURN v_serie;
EXCEPTION
WHEN NO_DATA_FOUND THEN RETURN NULL;
END;
FUNCTION selecteaza_nr_util(p_id_program NUMBER) RETURN NUMBER IS
v_nr_util NUMBER;
BEGIN
SELECT nr_util INTO v_nr_util FROM SYS.AUTH_SERII WHERE id_program = p_id_program;
RETURN v_nr_util;
EXCEPTION
WHEN NO_DATA_FOUND THEN RETURN NULL;
END;
FUNCTION selecteaza_data_val(p_id_program NUMBER) RETURN DATE IS
v_data_val DATE;
BEGIN
SELECT data_val INTO v_data_val FROM SYS.AUTH_SERII WHERE id_program = p_id_program;
RETURN v_data_val;
EXCEPTION
WHEN NO_DATA_FOUND THEN RETURN NULL;
END;
PROCEDURE actualizeaza_serie(p_id_program NUMBER, p_serie VARCHAR2, p_nr_util NUMBER, p_data_val DATE) IS
BEGIN
MERGE INTO SYS.AUTH_SERII t
USING (SELECT p_id_program AS id_program FROM dual) s
ON (t.id_program = s.id_program)
WHEN MATCHED THEN
UPDATE SET serie = p_serie, nr_util = p_nr_util, data_val = p_data_val
WHEN NOT MATCHED THEN
INSERT (id_program, serie, nr_util, data_val)
VALUES (p_id_program, p_serie, p_nr_util, p_data_val);
COMMIT;
END;
END AUTH_PACK;
/
GRANT EXECUTE ON SYS.AUTH_PACK TO PUBLIC;
CREATE OR REPLACE PUBLIC SYNONYM AUTH_PACK FOR SYS.AUTH_PACK;
-- VAUTH_SERII view
PROMPT Creating view VAUTH_SERII...
CREATE OR REPLACE VIEW SYS.VAUTH_SERII AS
SELECT a.id_program,
a.denumire AS nume,
auth_pack.selecteaza_serie(a.id_program) AS serie,
auth_pack.selecteaza_nr_util(a.id_program) AS nr_util,
auth_pack.selecteaza_data_val(a.id_program) AS data_val
FROM syn_nom_programe a
LEFT JOIN syn_def_programe b ON a.id_program = b.ide_program
WHERE b.sters = 0
AND b.instalat = 1;
GRANT SELECT ON SYS.VAUTH_SERII TO PUBLIC;
CREATE OR REPLACE PUBLIC SYNONYM VAUTH_SERII FOR SYS.VAUTH_SERII;
-- PACK_UPDATE package (minimal version)
PROMPT Creating package PACK_UPDATE...
CREATE OR REPLACE PACKAGE SYS.PACK_UPDATE AS
FUNCTION get_version RETURN VARCHAR2;
PROCEDURE execute_sql(p_sql VARCHAR2);
END PACK_UPDATE;
/
CREATE OR REPLACE PACKAGE BODY SYS.PACK_UPDATE AS
FUNCTION get_version RETURN VARCHAR2 IS
BEGIN
RETURN '1.0.0';
END;
PROCEDURE execute_sql(p_sql VARCHAR2) IS
BEGIN
EXECUTE IMMEDIATE p_sql;
EXCEPTION
WHEN OTHERS THEN
RAISE;
END;
END PACK_UPDATE;
/
GRANT EXECUTE ON SYS.PACK_UPDATE TO PUBLIC;
CREATE OR REPLACE PUBLIC SYNONYM PACK_UPDATE FOR SYS.PACK_UPDATE;
-- PACK_UTILS package (minimal version)
PROMPT Creating package PACK_UTILS...
CREATE OR REPLACE PACKAGE SYS.PACK_UTILS AS
FUNCTION get_db_version RETURN VARCHAR2;
FUNCTION get_instance_name RETURN VARCHAR2;
END PACK_UTILS;
/
CREATE OR REPLACE PACKAGE BODY SYS.PACK_UTILS AS
FUNCTION get_db_version RETURN VARCHAR2 IS
v_version VARCHAR2(100);
BEGIN
SELECT version_full INTO v_version FROM v`$instance;
RETURN v_version;
EXCEPTION
WHEN OTHERS THEN RETURN NULL;
END;
FUNCTION get_instance_name RETURN VARCHAR2 IS
v_instance VARCHAR2(100);
BEGIN
SELECT instance_name INTO v_instance FROM v`$instance;
RETURN v_instance;
EXCEPTION
WHEN OTHERS THEN RETURN NULL;
END;
END PACK_UTILS;
/
GRANT EXECUTE ON SYS.PACK_UTILS TO PUBLIC;
CREATE OR REPLACE PUBLIC SYNONYM PACK_UTILS FOR SYS.PACK_UTILS;
-- Grant UTL packages to PUBLIC
PROMPT Granting UTL packages...
GRANT EXECUTE ON UTL_FILE TO PUBLIC;
GRANT EXECUTE ON DBMS_LOCK TO PUBLIC;
-- Grant UTL packages to CONTAFIN_ORACLE specifically
GRANT EXECUTE ON UTL_INADDR TO CONTAFIN_ORACLE;
GRANT EXECUTE ON UTL_TCP TO CONTAFIN_ORACLE;
GRANT EXECUTE ON UTL_SMTP TO CONTAFIN_ORACLE;
GRANT EXECUTE ON UTL_HTTP TO CONTAFIN_ORACLE;
COMMIT;
PROMPT
PROMPT =============================================
PROMPT SYS objects created successfully
PROMPT =============================================
PROMPT
SELECT 'SYS_OBJECTS_COMPLETE' FROM dual;
EXIT;
"@
Set-Content -Path $sysObjectsScript -Value $sysObjectsSql -Encoding ASCII
Write-Log "Created sys-objects.sql"
}
# Execute SYS objects script
Write-LogSection "Executing sys-objects.sql"
$result = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYS" -Password $SystemPassword -SqlFile $sysObjectsScript -AsSysdba
if ($result -match "SYS_OBJECTS_COMPLETE") {
Write-LogSuccess "SYS objects created successfully"
}
else {
Write-LogWarning "Script completed but could not verify success"
Write-LogDebug $result
}
# Verify created objects
Write-LogSection "Verifying SYS Objects"
$verifySql = @"
SET PAGESIZE 100 FEEDBACK OFF VERIFY OFF HEADING ON ECHO OFF LINESIZE 200
PROMPT
PROMPT === SYS Objects Status ===
PROMPT
SELECT object_name, object_type, status
FROM dba_objects
WHERE owner = 'SYS'
AND object_name IN ('AUTH_PACK', 'AUTH_DETALII', 'AUTH_SERII', 'VAUTH_SERII',
'PACK_UPDATE', 'PACK_UTILS', 'NEWSCHEMA', 'NEWSCHEMAPOST', 'NEWSCHEMAPROGRESS')
ORDER BY object_type, object_name;
PROMPT
PROMPT === Public Synonyms ===
PROMPT
SELECT synonym_name, table_owner, table_name
FROM dba_synonyms
WHERE owner = 'PUBLIC'
AND table_name IN ('AUTH_PACK', 'AUTH_DETALII', 'AUTH_SERII', 'VAUTH_SERII',
'PACK_UPDATE', 'PACK_UTILS', 'NEWSCHEMA', 'NEWSCHEMAPOST', 'NEWSCHEMAPROGRESS')
ORDER BY synonym_name;
EXIT;
"@
$verifyResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYS" -Password $SystemPassword -SqlCommand $verifySql -AsSysdba
Write-Host $verifyResult
# Count invalid objects
$invalidSql = @"
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF
SELECT 'INVALID_COUNT:' || COUNT(*)
FROM dba_objects
WHERE owner = 'SYS'
AND object_name IN ('AUTH_PACK', 'AUTH_DETALII', 'AUTH_SERII', 'VAUTH_SERII',
'PACK_UPDATE', 'PACK_UTILS', 'NEWSCHEMA', 'NEWSCHEMAPOST', 'NEWSCHEMAPROGRESS')
AND status = 'INVALID';
EXIT;
"@
$invalidResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYS" -Password $SystemPassword -SqlCommand $invalidSql -AsSysdba -Silent
$invalidCount = 0
if ($invalidResult -match "INVALID_COUNT:(\d+)") {
$invalidCount = [int]$Matches[1]
}
if ($invalidCount -gt 0) {
Write-LogWarning "$invalidCount invalid SYS objects found"
Write-Log "Attempting to recompile invalid objects..."
$recompileSql = @"
SET SERVEROUTPUT ON
BEGIN
DBMS_UTILITY.COMPILE_SCHEMA('SYS', FALSE);
END;
/
EXIT;
"@
Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYS" -Password $SystemPassword -SqlCommand $recompileSql -AsSysdba -Silent
}
else {
Write-LogSuccess "All SYS objects are valid"
}
# Summary
Write-LogSection "Setup Complete"
Write-LogSuccess "SYS objects installation completed!"
Write-Log ""
Write-Log "Objects created:"
Write-Log " - AUTH_PACK package"
Write-Log " - AUTH_DETALII table"
Write-Log " - AUTH_SERII table"
Write-Log " - VAUTH_SERII view"
Write-Log " - PACK_UPDATE package"
Write-Log " - PACK_UTILS package"
Write-Log " - Public synonyms and grants"
Write-Log ""
Write-Log "Next steps:"
Write-Log " 1. Run 03-import-contafin.ps1 to import CONTAFIN_ORACLE schema"
Close-LogFile -Success $true
exit 0
}
catch {
Write-LogError "Setup failed: $_"
Write-LogError $_.ScriptStackTrace
Close-LogFile -Success $false
exit 1
}

View File

@@ -0,0 +1,312 @@
#Requires -Version 5.1
<#
.SYNOPSIS
Import CONTAFIN_ORACLE schema from Data Pump dump file.
.DESCRIPTION
Imports the CONTAFIN_ORACLE schema using Oracle Data Pump (impdp).
- Creates DMPDIR directory if not exists
- Runs impdp with optimal parameters
- Verifies import (object count, invalid objects)
.PARAMETER DumpFile
Path to the CONTAFIN_ORACLE DMP file. Required.
.PARAMETER OracleHome
Oracle home directory. If not specified, auto-detects.
.PARAMETER ServiceName
Database service name. Default: XEPDB1
.PARAMETER SystemPassword
SYSTEM user password. Default: romfastsoft
.PARAMETER DmpDir
Oracle directory path for Data Pump. Default: C:\DMPDIR
.PARAMETER TableExistsAction
What to do if table exists: SKIP, APPEND, TRUNCATE, REPLACE. Default: REPLACE
.PARAMETER Parallel
Number of parallel workers for import. Default: 2
.EXAMPLE
.\03-import-contafin.ps1 -DumpFile "C:\dumps\CONTAFIN_ORACLE.dmp"
.EXAMPLE
.\03-import-contafin.ps1 -DumpFile "D:\backups\contafin.dmp" -ServiceName "ROA" -SystemPassword "mypass"
.NOTES
File Name : 03-import-contafin.ps1
Prerequisite : Run 01-setup-database.ps1 and 02-create-sys-objects.ps1 first
Copyright 2024 : ROMFAST
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[ValidateScript({ Test-Path $_ })]
[string]$DumpFile,
[Parameter(Mandatory = $false)]
[string]$OracleHome,
[Parameter(Mandatory = $false)]
[string]$ServiceName = "XEPDB1",
[Parameter(Mandatory = $false)]
[string]$SystemPassword = "romfastsoft",
[Parameter(Mandatory = $false)]
[string]$DmpDir = "C:\DMPDIR",
[Parameter(Mandatory = $false)]
[ValidateSet('SKIP', 'APPEND', 'TRUNCATE', 'REPLACE')]
[string]$TableExistsAction = "REPLACE",
[Parameter(Mandatory = $false)]
[int]$Parallel = 2
)
$ErrorActionPreference = 'Stop'
# Source library functions
. "$PSScriptRoot\lib\logging-functions.ps1"
. "$PSScriptRoot\lib\oracle-functions.ps1"
# Initialize logging
$logPath = Join-Path $PSScriptRoot "..\logs\03-import-contafin_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
Initialize-LogFile -LogPath $logPath -ScriptName "03-import-contafin.ps1"
try {
Write-LogSection "Importing CONTAFIN_ORACLE Schema"
# Validate Oracle installation
$oraHome = Get-OracleHome -OracleHome $OracleHome
Write-LogSuccess "Oracle Home: $oraHome"
# Test connection
Write-Log "Testing database connection..."
if (-not (Test-OracleConnection -OracleHome $oraHome -ServiceName $ServiceName `
-Password $SystemPassword)) {
throw "Cannot connect to database. Please verify ServiceName and SystemPassword."
}
Write-LogSuccess "Database connection successful"
# Verify CONTAFIN_ORACLE user exists
Write-Log "Verifying CONTAFIN_ORACLE user exists..."
if (-not (Test-OracleUser -OracleHome $oraHome -ServiceName $ServiceName `
-Password $SystemPassword -SchemaName "CONTAFIN_ORACLE")) {
throw "User CONTAFIN_ORACLE does not exist. Run 01-setup-database.ps1 first."
}
Write-LogSuccess "User CONTAFIN_ORACLE exists"
# Create/verify DMPDIR
Write-LogSection "Configuring Data Pump Directory"
if (-not (Test-Path -Path $DmpDir)) {
New-Item -ItemType Directory -Path $DmpDir -Force | Out-Null
Write-Log "Created directory: $DmpDir"
}
New-OracleDirectory -OracleHome $oraHome -ServiceName $ServiceName `
-Password $SystemPassword -DirectoryName "DMPDIR" -DirectoryPath $DmpDir
# Copy dump file to DMPDIR if not already there
$dumpFileName = Split-Path -Path $DumpFile -Leaf
$targetDumpPath = Join-Path $DmpDir $dumpFileName
if ($DumpFile -ne $targetDumpPath) {
Write-Log "Copying dump file to DMPDIR..."
Copy-Item -Path $DumpFile -Destination $targetDumpPath -Force
Write-LogSuccess "Dump file copied to: $targetDumpPath"
}
else {
Write-Log "Dump file already in DMPDIR: $targetDumpPath"
}
# Check dump file size
$dumpFileInfo = Get-Item $targetDumpPath
$dumpSizeMB = [math]::Round($dumpFileInfo.Length / 1MB, 2)
Write-Log "Dump file size: $dumpSizeMB MB"
# Get current object count before import
Write-Log "Getting current object count for CONTAFIN_ORACLE..."
$beforeCounts = Get-SchemaObjectCount -OracleHome $oraHome -ServiceName $ServiceName `
-Password $SystemPassword -SchemaName "CONTAFIN_ORACLE"
$beforeTotal = if ($beforeCounts['TOTAL']) { $beforeCounts['TOTAL'] } else { 0 }
Write-Log "Objects before import: $beforeTotal"
# Run import
Write-LogSection "Running Data Pump Import"
$impdpPath = Join-Path $oraHome "bin\impdp.exe"
if (-not (Test-Path -Path $impdpPath)) {
throw "impdp.exe not found at: $impdpPath"
}
$importLogFile = "CONTAFIN_ORACLE_import_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
# Build impdp command
$connString = "SYSTEM/`"$SystemPassword`"@$ServiceName"
$impdpParams = @(
"`"$connString`"",
"directory=DMPDIR",
"dumpfile=$dumpFileName",
"logfile=$importLogFile",
"schemas=CONTAFIN_ORACLE",
"table_exists_action=$TableExistsAction"
)
if ($Parallel -gt 1) {
$impdpParams += "parallel=$Parallel"
}
$arguments = $impdpParams -join " "
Write-Log "Executing impdp..."
Write-Log "Parameters: directory=DMPDIR dumpfile=$dumpFileName schemas=CONTAFIN_ORACLE table_exists_action=$TableExistsAction"
# Set Oracle environment
$env:ORACLE_HOME = $oraHome
$env:PATH = "$oraHome\bin;$env:PATH"
$env:NLS_LANG = "AMERICAN_AMERICA.AL32UTF8"
$startTime = Get-Date
# Execute impdp
$process = Start-Process -FilePath $impdpPath -ArgumentList $arguments -Wait -NoNewWindow -PassThru
$duration = (Get-Date) - $startTime
Write-Log "Import completed in $([math]::Round($duration.TotalMinutes, 2)) minutes"
# Check import log
$importLogPath = Join-Path $DmpDir $importLogFile
if (Test-Path -Path $importLogPath) {
Write-Log "Import log: $importLogPath"
# Read and analyze log for errors
$logContent = Get-Content -Path $importLogPath -Raw
if ($logContent -match "ORA-\d{5}:") {
Write-LogWarning "Import completed with Oracle errors. Check log for details."
}
if ($logContent -match "successfully loaded/unloaded") {
Write-LogSuccess "Objects successfully loaded"
}
# Count errors and warnings in log
$errorCount = ([regex]::Matches($logContent, "ORA-\d{5}:")).Count
$warningCount = ([regex]::Matches($logContent, "ORA-39\d{3}:")).Count
Write-Log "Errors in log: $errorCount"
Write-Log "Warnings in log: $warningCount"
}
# Verify import
Write-LogSection "Verifying Import"
# Get object counts after import
$afterCounts = Get-SchemaObjectCount -OracleHome $oraHome -ServiceName $ServiceName `
-Password $SystemPassword -SchemaName "CONTAFIN_ORACLE"
$afterTotal = if ($afterCounts['TOTAL']) { $afterCounts['TOTAL'] } else { 0 }
$afterInvalid = if ($afterCounts['INVALID']) { $afterCounts['INVALID'] } else { 0 }
Write-Log "Objects after import: $afterTotal"
Write-Log "Objects imported: $($afterTotal - $beforeTotal)"
# Display object counts by type
Write-Log ""
Write-Log "Object counts by type:"
foreach ($key in $afterCounts.Keys | Sort-Object) {
if ($key -ne 'TOTAL' -and $key -ne 'INVALID') {
Write-Log " $($key): $($afterCounts[$key])"
}
}
if ($afterInvalid -gt 0) {
Write-LogWarning "Invalid objects: $afterInvalid"
# List invalid objects
$invalidSql = @"
SET PAGESIZE 100 FEEDBACK OFF VERIFY OFF HEADING ON ECHO OFF LINESIZE 200
SELECT object_name, object_type
FROM dba_objects
WHERE owner = 'CONTAFIN_ORACLE'
AND status = 'INVALID'
ORDER BY object_type, object_name;
EXIT;
"@
$invalidList = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $invalidSql -Silent
Write-Log "Invalid objects:"
Write-Host $invalidList
# Attempt to recompile
Write-Log "Attempting to recompile invalid objects..."
$recompileSql = @"
SET SERVEROUTPUT ON
BEGIN
DBMS_UTILITY.COMPILE_SCHEMA('CONTAFIN_ORACLE', FALSE);
END;
/
EXIT;
"@
Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $recompileSql -Silent
# Recheck invalid count
$recheckCounts = Get-SchemaObjectCount -OracleHome $oraHome -ServiceName $ServiceName `
-Password $SystemPassword -SchemaName "CONTAFIN_ORACLE"
$recheckInvalid = if ($recheckCounts['INVALID']) { $recheckCounts['INVALID'] } else { 0 }
if ($recheckInvalid -lt $afterInvalid) {
Write-LogSuccess "Recompilation fixed $($afterInvalid - $recheckInvalid) objects"
}
if ($recheckInvalid -gt 0) {
Write-LogWarning "Still $recheckInvalid invalid objects remaining"
}
}
else {
Write-LogSuccess "No invalid objects"
}
# Summary
Write-LogSection "Import Complete"
if ($process.ExitCode -eq 0) {
Write-LogSuccess "CONTAFIN_ORACLE schema imported successfully!"
}
else {
Write-LogWarning "Import completed with warnings (exit code: $($process.ExitCode))"
}
Write-Log ""
Write-Log "Summary:"
Write-Log " Dump file: $dumpFileName ($dumpSizeMB MB)"
Write-Log " Service: $ServiceName"
Write-Log " Duration: $([math]::Round($duration.TotalMinutes, 2)) minutes"
Write-Log " Objects: $afterTotal"
Write-Log " Import log: $importLogPath"
Write-Log ""
Write-Log "Next steps:"
Write-Log " 1. Run 04-create-synonyms-grants.ps1 to create public synonyms"
Write-Log " 2. Run 05-import-companies.ps1 to import company schemas"
Close-LogFile -Success ($process.ExitCode -eq 0)
exit $process.ExitCode
}
catch {
Write-LogError "Import failed: $_"
Write-LogError $_.ScriptStackTrace
Close-LogFile -Success $false
exit 1
}

View File

@@ -0,0 +1,501 @@
#Requires -Version 5.1
<#
.SYNOPSIS
Create public synonyms and grants for ROA Oracle.
.DESCRIPTION
Creates public synonyms for CONTAFIN_ORACLE objects and configures:
- Public synonyms for tables, views, packages, types
- Public grants (SELECT, EXECUTE, REFERENCES)
- SESIUNE context
- Network ACL for CONTAFIN_ORACLE
.PARAMETER OracleHome
Oracle home directory. If not specified, auto-detects.
.PARAMETER ServiceName
Database service name. Default: XEPDB1
.PARAMETER SystemPassword
SYSTEM user password. Default: romfastsoft
.PARAMETER SqlScriptsDir
Directory containing SQL scripts. Default: ..\sql
.EXAMPLE
.\04-create-synonyms-grants.ps1
.EXAMPLE
.\04-create-synonyms-grants.ps1 -ServiceName "ROA" -SystemPassword "mypassword"
.NOTES
File Name : 04-create-synonyms-grants.ps1
Prerequisite : Run 03-import-contafin.ps1 first
Copyright 2024 : ROMFAST
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[string]$OracleHome,
[Parameter(Mandatory = $false)]
[string]$ServiceName = "XEPDB1",
[Parameter(Mandatory = $false)]
[string]$SystemPassword = "romfastsoft",
[Parameter(Mandatory = $false)]
[string]$SqlScriptsDir
)
$ErrorActionPreference = 'Stop'
# Source library functions
. "$PSScriptRoot\lib\logging-functions.ps1"
. "$PSScriptRoot\lib\oracle-functions.ps1"
# Initialize logging
$logPath = Join-Path $PSScriptRoot "..\logs\04-create-synonyms-grants_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
Initialize-LogFile -LogPath $logPath -ScriptName "04-create-synonyms-grants.ps1"
try {
Write-LogSection "Creating Public Synonyms and Grants"
# Validate Oracle installation
$oraHome = Get-OracleHome -OracleHome $OracleHome
Write-LogSuccess "Oracle Home: $oraHome"
# Test connection
Write-Log "Testing database connection..."
if (-not (Test-OracleConnection -OracleHome $oraHome -ServiceName $ServiceName `
-Password $SystemPassword)) {
throw "Cannot connect to database. Please verify ServiceName and SystemPassword."
}
Write-LogSuccess "Database connection successful"
# Verify CONTAFIN_ORACLE exists and has objects
Write-Log "Verifying CONTAFIN_ORACLE schema..."
$counts = Get-SchemaObjectCount -OracleHome $oraHome -ServiceName $ServiceName `
-Password $SystemPassword -SchemaName "CONTAFIN_ORACLE"
$totalObjects = if ($counts['TOTAL']) { $counts['TOTAL'] } else { 0 }
if ($totalObjects -eq 0) {
throw "CONTAFIN_ORACLE schema has no objects. Run 03-import-contafin.ps1 first."
}
Write-LogSuccess "CONTAFIN_ORACLE has $totalObjects objects"
# Create SESIUNE context
Write-LogSection "Creating SESIUNE Context"
$contextSql = @"
SET ECHO OFF FEEDBACK ON VERIFY OFF
-- Drop existing context if exists
BEGIN
EXECUTE IMMEDIATE 'DROP CONTEXT SESIUNE';
EXCEPTION
WHEN OTHERS THEN NULL;
END;
/
-- Create context
CREATE CONTEXT SESIUNE USING CONTAFIN_ORACLE.SET_VARIABILE;
SELECT 'CONTEXT_CREATED' FROM dual;
EXIT;
"@
$result = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $contextSql
if ($result -match "CONTEXT_CREATED") {
Write-LogSuccess "Context SESIUNE created"
}
else {
Write-LogWarning "Could not verify context creation"
}
# Create public synonyms SQL
Write-LogSection "Creating Public Synonyms"
$synonymsSql = @"
SET ECHO OFF FEEDBACK ON VERIFY OFF SERVEROUTPUT ON
SPOOL synonyms_grants.log
PROMPT
PROMPT =============================================
PROMPT Creating Public Synonyms for CONTAFIN_ORACLE
PROMPT =============================================
PROMPT
-- Core synonyms with grants
PROMPT Creating SYN_DEF_GRUP...
CREATE OR REPLACE PUBLIC SYNONYM SYN_DEF_GRUP FOR CONTAFIN_ORACLE.DEF_GRUP;
GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.DEF_GRUP TO PUBLIC;
PROMPT Creating SYN_DEF_PROGRAME...
CREATE OR REPLACE PUBLIC SYNONYM SYN_DEF_PROGRAME FOR CONTAFIN_ORACLE.DEF_PROGRAME;
GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.DEF_PROGRAME TO PUBLIC;
PROMPT Creating SYN_VDEF_PROGRAME...
CREATE OR REPLACE PUBLIC SYNONYM SYN_VDEF_PROGRAME FOR CONTAFIN_ORACLE.VDEF_PROGRAME;
GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.VDEF_PROGRAME TO PUBLIC;
PROMPT Creating SYN_LUNILEAN...
CREATE OR REPLACE PUBLIC SYNONYM SYN_LUNILEAN FOR CONTAFIN_ORACLE.LUNILEAN;
GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.LUNILEAN TO PUBLIC;
PROMPT Creating SYN_NOM_FIRME...
CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_FIRME FOR CONTAFIN_ORACLE.NOM_FIRME;
GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.NOM_FIRME TO PUBLIC;
PROMPT Creating SYN_NOM_PROGRAME...
CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_PROGRAME FOR CONTAFIN_ORACLE.NOM_PROGRAME;
GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.NOM_PROGRAME TO PUBLIC;
PROMPT Creating SYN_PACK_DREPTURI...
CREATE OR REPLACE PUBLIC SYNONYM SYN_PACK_DREPTURI FOR CONTAFIN_ORACLE.PACK_DREPTURI;
GRANT EXECUTE ON CONTAFIN_ORACLE.PACK_DREPTURI TO PUBLIC;
PROMPT Creating SYN_UTILIZATORI...
CREATE OR REPLACE PUBLIC SYNONYM SYN_UTILIZATORI FOR CONTAFIN_ORACLE.UTILIZATORI;
GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.UTILIZATORI TO PUBLIC;
PROMPT Creating syn_vdef_util_programe...
CREATE OR REPLACE PUBLIC SYNONYM SYN_VDEF_UTIL_PROGRAME FOR CONTAFIN_ORACLE.VDEF_UTIL_PROGRAME;
GRANT SELECT ON CONTAFIN_ORACLE.VDEF_UTIL_PROGRAME TO PUBLIC;
PROMPT Creating syn_vdef_util_firme...
CREATE OR REPLACE PUBLIC SYNONYM SYN_VDEF_UTIL_FIRME FOR CONTAFIN_ORACLE.VDEF_UTIL_FIRME;
GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.VDEF_UTIL_FIRME TO PUBLIC;
PROMPT Creating SYN_VDEF_UTIL_OBIECTE...
CREATE OR REPLACE PUBLIC SYNONYM SYN_VDEF_UTIL_OBIECTE FOR CONTAFIN_ORACLE.VDEF_UTIL_OBIECTE;
GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.VDEF_UTIL_OBIECTE TO PUBLIC;
PROMPT Creating SYN_VUTILIZATORI...
CREATE OR REPLACE PUBLIC SYNONYM SYN_VUTILIZATORI FOR CONTAFIN_ORACLE.VUTILIZATORI;
GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.VUTILIZATORI TO PUBLIC;
PROMPT Creating SYN_VDEF_UTIL_GRUP...
CREATE OR REPLACE PUBLIC SYNONYM SYN_VDEF_UTIL_GRUP FOR CONTAFIN_ORACLE.VDEF_UTIL_GRUP;
GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.VDEF_UTIL_GRUP TO PUBLIC;
PROMPT Creating SYN_DEF_GRUP_DREPT...
CREATE OR REPLACE PUBLIC SYNONYM SYN_DEF_GRUP_DREPT FOR CONTAFIN_ORACLE.DEF_GRUP_DREPT;
GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.DEF_GRUP_DREPT TO PUBLIC;
PROMPT Creating SYN_OPTIUNI_PROGRAME...
CREATE OR REPLACE PUBLIC SYNONYM SYN_OPTIUNI_PROGRAME FOR CONTAFIN_ORACLE.OPTIUNI_PROGRAME;
GRANT SELECT ON CONTAFIN_ORACLE.OPTIUNI_PROGRAME TO PUBLIC;
PROMPT Creating SYN_HELPCONT...
CREATE OR REPLACE PUBLIC SYNONYM SYN_HELPCONT FOR CONTAFIN_ORACLE.HELPCONT;
GRANT SELECT ON CONTAFIN_ORACLE.HELPCONT TO PUBLIC;
PROMPT Creating SYN_V_NOM_FIRME...
CREATE OR REPLACE PUBLIC SYNONYM SYN_V_NOM_FIRME FOR CONTAFIN_ORACLE.V_NOM_FIRME;
GRANT SELECT ON CONTAFIN_ORACLE.V_NOM_FIRME TO PUBLIC;
-- Nomenclators
PROMPT Creating nomenclator synonyms...
CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_FORME_JURIDICE FOR CONTAFIN_ORACLE.NOM_FORME_JURIDICE;
GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.NOM_FORME_JURIDICE TO PUBLIC;
CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_FORME_ORGANIZARE FOR CONTAFIN_ORACLE.NOM_FORME_ORGANIZARE;
GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.NOM_FORME_ORGANIZARE TO PUBLIC;
CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_TIP_SOCIETATE FOR CONTAFIN_ORACLE.NOM_TIP_SOCIETATE;
GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.NOM_TIP_SOCIETATE TO PUBLIC;
CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_FORME_PROPRIETATE FOR CONTAFIN_ORACLE.NOM_FORME_PROPRIETATE;
GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.NOM_FORME_PROPRIETATE TO PUBLIC;
-- String aggregation
PROMPT Creating stringAgg synonym...
CREATE OR REPLACE PUBLIC SYNONYM STRINGAGG FOR CONTAFIN_ORACLE.STRINGAGG;
GRANT EXECUTE ON CONTAFIN_ORACLE.STRINGAGG TO PUBLIC;
-- Types
PROMPT Creating type synonyms...
BEGIN
EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.STRINGAGGTYPE TO PUBLIC';
EXCEPTION WHEN OTHERS THEN NULL;
END;
/
CREATE OR REPLACE PUBLIC SYNONYM CHAR_ROW FOR CONTAFIN_ORACLE.CHAR_ROW;
CREATE OR REPLACE PUBLIC SYNONYM CHAR_TAB FOR CONTAFIN_ORACLE.CHAR_TAB;
CREATE OR REPLACE PUBLIC SYNONYM NUM_ROW FOR CONTAFIN_ORACLE.NUM_ROW;
CREATE OR REPLACE PUBLIC SYNONYM NUM_TAB FOR CONTAFIN_ORACLE.NUM_TAB;
BEGIN
EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.NUM_ROW TO PUBLIC';
EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.NUM_TAB TO PUBLIC';
EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.CHAR_ROW TO PUBLIC';
EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.CHAR_TAB TO PUBLIC';
EXCEPTION WHEN OTHERS THEN NULL;
END;
/
CREATE OR REPLACE PUBLIC SYNONYM UW_SEL_ROW FOR CONTAFIN_ORACLE.UW_SEL_ROW;
CREATE OR REPLACE PUBLIC SYNONYM UW_SEL_TAB FOR CONTAFIN_ORACLE.UW_SEL_TAB;
BEGIN
EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.UW_SEL_ROW TO PUBLIC';
EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.UW_SEL_TAB TO PUBLIC';
EXCEPTION WHEN OTHERS THEN NULL;
END;
/
-- Functions
PROMPT Creating function synonyms...
CREATE OR REPLACE PUBLIC SYNONYM VALOARETAG FOR CONTAFIN_ORACLE.VALOARETAG;
CREATE OR REPLACE PUBLIC SYNONYM GETWORDCOUNT FOR CONTAFIN_ORACLE.GETWORDCOUNT;
CREATE OR REPLACE PUBLIC SYNONYM GETWORDNUM FOR CONTAFIN_ORACLE.GETWORDNUM;
CREATE OR REPLACE PUBLIC SYNONYM CHARC2COLLECTION FOR CONTAFIN_ORACLE.CHARC2COLLECTION;
CREATE OR REPLACE PUBLIC SYNONYM CHARN2COLLECTION FOR CONTAFIN_ORACLE.CHARN2COLLECTION;
BEGIN
EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.VALOARETAG TO PUBLIC';
EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.GETWORDCOUNT TO PUBLIC';
EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.GETWORDNUM TO PUBLIC';
EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.CHARC2COLLECTION TO PUBLIC';
EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.CHARN2COLLECTION TO PUBLIC';
EXCEPTION WHEN OTHERS THEN NULL;
END;
/
-- VAUTH_SERII synonym for CONTAFIN_ORACLE
PROMPT Creating VDEF_PROGRAME_SERII synonym...
BEGIN
EXECUTE IMMEDIATE 'DROP SYNONYM CONTAFIN_ORACLE.VDEF_PROGRAME_SERII';
EXCEPTION WHEN OTHERS THEN NULL;
END;
/
CREATE SYNONYM CONTAFIN_ORACLE.VDEF_PROGRAME_SERII FOR SYS.VAUTH_SERII;
GRANT SELECT ON CONTAFIN_ORACLE.VDEF_PROGRAME_SERII TO CONTAFIN_ORACLE;
-- Currency and location synonyms
PROMPT Creating currency/location synonyms...
CREATE OR REPLACE PUBLIC SYNONYM SYN_VNOM_VALUTE_ISO FOR CONTAFIN_ORACLE.VNOM_VALUTE_ISO;
GRANT SELECT ON CONTAFIN_ORACLE.VNOM_VALUTE_ISO TO PUBLIC;
CREATE OR REPLACE PUBLIC SYNONYM SYN_CURS_ACTUALIZARI FOR CONTAFIN_ORACLE.CURS_ACTUALIZARI;
GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.CURS_ACTUALIZARI TO PUBLIC;
CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_VALUTE_ISO FOR CONTAFIN_ORACLE.NOM_VALUTE_ISO;
GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.NOM_VALUTE_ISO TO PUBLIC;
CREATE OR REPLACE PUBLIC SYNONYM SYN_CURS_COTATII FOR CONTAFIN_ORACLE.CURS_COTATII;
GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.CURS_COTATII TO PUBLIC;
-- Location synonyms
PROMPT Creating location synonyms...
CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_JUDETE FOR CONTAFIN_ORACLE.NOM_JUDETE;
GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.NOM_JUDETE TO PUBLIC;
CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_LOCALITATI FOR CONTAFIN_ORACLE.NOM_LOCALITATI;
GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.NOM_LOCALITATI TO PUBLIC;
CREATE OR REPLACE PUBLIC SYNONYM SYN_VNOM_JUDETE FOR CONTAFIN_ORACLE.VNOM_JUDETE;
GRANT SELECT ON CONTAFIN_ORACLE.VNOM_JUDETE TO PUBLIC;
CREATE OR REPLACE PUBLIC SYNONYM SYN_VNOM_LOCALITATI FOR CONTAFIN_ORACLE.VNOM_LOCALITATI;
GRANT SELECT ON CONTAFIN_ORACLE.VNOM_LOCALITATI TO PUBLIC;
CREATE OR REPLACE PUBLIC SYNONYM SYN_VNOM_TARI FOR CONTAFIN_ORACLE.VNOM_TARI;
GRANT SELECT ON CONTAFIN_ORACLE.VNOM_TARI TO PUBLIC;
CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_CETATENII FOR CONTAFIN_ORACLE.NOM_CETATENII;
GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.NOM_CETATENII TO PUBLIC;
CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_TARI FOR CONTAFIN_ORACLE.NOM_TARI;
GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.NOM_TARI TO PUBLIC;
-- Packages
PROMPT Creating package synonyms...
CREATE OR REPLACE PUBLIC SYNONYM SYN_PACK_DEF_CO FOR CONTAFIN_ORACLE.PACK_DEF_CO;
GRANT EXECUTE ON CONTAFIN_ORACLE.PACK_DEF_CO TO PUBLIC;
CREATE OR REPLACE PUBLIC SYNONYM PACK_UTILS FOR CONTAFIN_ORACLE.PACK_UTILS;
GRANT EXECUTE ON CONTAFIN_ORACLE.PACK_UTILS TO PUBLIC;
CREATE OR REPLACE PUBLIC SYNONYM PACK_UTILS_FILE FOR CONTAFIN_ORACLE.PACK_UTILS_FILE;
GRANT EXECUTE ON CONTAFIN_ORACLE.PACK_UTILS_FILE TO PUBLIC;
CREATE OR REPLACE PUBLIC SYNONYM PACK_ROARTVAI FOR CONTAFIN_ORACLE.PACK_ROARTVAI;
GRANT EXECUTE ON CONTAFIN_ORACLE.PACK_ROARTVAI TO PUBLIC;
-- More types and synonyms
PROMPT Creating additional type synonyms...
CREATE OR REPLACE PUBLIC SYNONYM CONTRACT_M FOR CONTAFIN_ORACLE.CONTRACT_M;
CREATE OR REPLACE PUBLIC SYNONYM SAL_CONTRACT_M FOR CONTAFIN_ORACLE.SAL_CONTRACT_M;
CREATE OR REPLACE PUBLIC SYNONYM SAL_RED FOR CONTAFIN_ORACLE.SAL_RED;
CREATE OR REPLACE PUBLIC SYNONYM SAL_CAMPURI_RED FOR CONTAFIN_ORACLE.SAL_CAMPURI_RED;
CREATE OR REPLACE PUBLIC SYNONYM TABSTERS FOR CONTAFIN_ORACLE.TABSTERS;
CREATE OR REPLACE PUBLIC SYNONYM SAL_TABELESTERS FOR CONTAFIN_ORACLE.SAL_TABELESTERS;
CREATE OR REPLACE PUBLIC SYNONYM FF_SUME FOR CONTAFIN_ORACLE.FF_SUME;
CREATE OR REPLACE PUBLIC SYNONYM FF_PERSINTRET FOR CONTAFIN_ORACLE.FF_PERSINTRET;
CREATE OR REPLACE PUBLIC SYNONYM VANZARI_DETALII_TAB FOR CONTAFIN_ORACLE.VANZARI_DETALII_TAB;
CREATE OR REPLACE PUBLIC SYNONYM PIVOT_TABLE FOR CONTAFIN_ORACLE.PIVOT_TABLE;
CREATE OR REPLACE PUBLIC SYNONYM PIVOT_ROW FOR CONTAFIN_ORACLE.PIVOT_ROW;
BEGIN
EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.CONTRACT_M TO PUBLIC';
EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.SAL_CONTRACT_M TO PUBLIC';
EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.SAL_RED TO PUBLIC';
EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.SAL_CAMPURI_RED TO PUBLIC';
EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.TABSTERS TO PUBLIC';
EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.SAL_TABELESTERS TO PUBLIC';
EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.FF_SUME TO PUBLIC';
EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.FF_PERSINTRET TO PUBLIC';
EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.VANZARI_DETALII_TAB TO PUBLIC';
EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.PIVOT_TABLE TO PUBLIC';
EXECUTE IMMEDIATE 'GRANT EXECUTE ON CONTAFIN_ORACLE.PIVOT_ROW TO PUBLIC';
EXCEPTION WHEN OTHERS THEN NULL;
END;
/
-- SERVER_INFO
PROMPT Creating SERVER_INFO synonym...
CREATE OR REPLACE PUBLIC SYNONYM SERVER_INFO FOR CONTAFIN_ORACLE.SERVER_INFO;
GRANT SELECT, UPDATE ON CONTAFIN_ORACLE.SERVER_INFO TO PUBLIC;
-- CAEN codes
PROMPT Creating SYN_NOM_CODURI_CAEN...
CREATE OR REPLACE PUBLIC SYNONYM SYN_NOM_CODURI_CAEN FOR CONTAFIN_ORACLE.NOM_CODURI_CAEN;
GRANT SELECT, REFERENCES ON CONTAFIN_ORACLE.NOM_CODURI_CAEN TO PUBLIC;
-- Directory grants
PROMPT Granting directory access...
GRANT ALL ON DIRECTORY DMPDIR TO PUBLIC;
GRANT EXECUTE ON UTL_FILE TO PUBLIC;
GRANT EXECUTE ON DBMS_LOCK TO PUBLIC;
COMMIT;
SPOOL OFF
SELECT 'SYNONYMS_COMPLETE' FROM dual;
EXIT;
"@
$result = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $synonymsSql
if ($result -match "SYNONYMS_COMPLETE") {
Write-LogSuccess "Public synonyms created successfully"
}
else {
Write-LogWarning "Could not verify synonym creation"
Write-LogDebug $result
}
# Configure Network ACL
Write-LogSection "Configuring Network ACL"
$aclSql = @"
SET ECHO OFF FEEDBACK ON VERIFY OFF SERVEROUTPUT ON
PROMPT Configuring Network ACL for CONTAFIN_ORACLE...
-- Drop existing ACL
BEGIN
DBMS_NETWORK_ACL_ADMIN.DROP_ACL(acl => 'roaupdate.xml');
EXCEPTION
WHEN OTHERS THEN NULL;
END;
/
-- Create new ACL
BEGIN
DBMS_NETWORK_ACL_ADMIN.CREATE_ACL(
acl => 'roaupdate.xml',
description => 'Permissions to connect and resolve for ROA',
principal => 'CONTAFIN_ORACLE',
is_grant => TRUE,
privilege => 'connect'
);
DBMS_NETWORK_ACL_ADMIN.ADD_PRIVILEGE(
acl => 'roaupdate.xml',
principal => 'CONTAFIN_ORACLE',
is_grant => TRUE,
privilege => 'resolve'
);
DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL(
acl => 'roaupdate.xml',
host => '*'
);
END;
/
COMMIT;
-- Grant UTL packages to CONTAFIN_ORACLE
GRANT EXECUTE ON UTL_INADDR TO CONTAFIN_ORACLE;
GRANT EXECUTE ON UTL_TCP TO CONTAFIN_ORACLE;
GRANT EXECUTE ON UTL_SMTP TO CONTAFIN_ORACLE;
GRANT EXECUTE ON UTL_HTTP TO CONTAFIN_ORACLE;
SELECT 'ACL_CONFIGURED' FROM dual;
EXIT;
"@
$aclResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYS" -Password $SystemPassword -SqlCommand $aclSql -AsSysdba
if ($aclResult -match "ACL_CONFIGURED") {
Write-LogSuccess "Network ACL configured"
}
else {
Write-LogWarning "Could not verify ACL configuration"
}
# Count synonyms created
Write-LogSection "Verifying Synonyms"
$countSql = @"
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF
SELECT 'SYNONYM_COUNT:' || COUNT(*)
FROM dba_synonyms
WHERE owner = 'PUBLIC'
AND table_owner = 'CONTAFIN_ORACLE';
EXIT;
"@
$countResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $countSql -Silent
$synonymCount = 0
if ($countResult -match "SYNONYM_COUNT:(\d+)") {
$synonymCount = [int]$Matches[1]
}
Write-Log "Public synonyms for CONTAFIN_ORACLE: $synonymCount"
# Summary
Write-LogSection "Setup Complete"
Write-LogSuccess "Public synonyms and grants configured!"
Write-Log ""
Write-Log "Summary:"
Write-Log " Public synonyms created: $synonymCount"
Write-Log " SESIUNE context: Created"
Write-Log " Network ACL: Configured (roaupdate.xml)"
Write-Log " UTL packages granted: UTL_INADDR, UTL_TCP, UTL_SMTP, UTL_HTTP"
Write-Log ""
Write-Log "Next steps:"
Write-Log " 1. Run 05-import-companies.ps1 to import company schemas"
Close-LogFile -Success $true
exit 0
}
catch {
Write-LogError "Setup failed: $_"
Write-LogError $_.ScriptStackTrace
Close-LogFile -Success $false
exit 1
}

View File

@@ -0,0 +1,424 @@
#Requires -Version 5.1
<#
.SYNOPSIS
Batch import company schemas from Data Pump dump files.
.DESCRIPTION
Imports company schemas from dump files. CRITICAL: Reads passwords from
CONTAFIN_ORACLE.NOM_FIRME table to ensure correct authentication.
For each company:
1. Queries NOM_FIRME for schema name and password
2. Finds matching DMP file in DumpDirectory
3. Creates user with password from NOM_FIRME
4. Runs impdp to import schema
5. Logs progress
.PARAMETER DumpDirectory
Directory containing company DMP files. Required.
.PARAMETER OracleHome
Oracle home directory. If not specified, auto-detects.
.PARAMETER ServiceName
Database service name. Default: XEPDB1
.PARAMETER SystemPassword
SYSTEM user password. Default: romfastsoft
.PARAMETER ParallelJobs
Number of parallel import jobs. Default: 2
.PARAMETER Companies
Optional array of specific company names to import. If not specified, imports all.
.PARAMETER DryRun
Show what would be imported without actually importing.
.EXAMPLE
.\05-import-companies.ps1 -DumpDirectory "C:\dumps\companies"
.EXAMPLE
.\05-import-companies.ps1 -DumpDirectory "D:\backups" -Companies "FIRMA1","FIRMA2"
.EXAMPLE
.\05-import-companies.ps1 -DumpDirectory "C:\dumps" -DryRun
.NOTES
File Name : 05-import-companies.ps1
Prerequisite : Run 04-create-synonyms-grants.ps1 first
Copyright 2024 : ROMFAST
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[ValidateScript({ Test-Path $_ -PathType Container })]
[string]$DumpDirectory,
[Parameter(Mandatory = $false)]
[string]$OracleHome,
[Parameter(Mandatory = $false)]
[string]$ServiceName = "XEPDB1",
[Parameter(Mandatory = $false)]
[string]$SystemPassword = "romfastsoft",
[Parameter(Mandatory = $false)]
[int]$ParallelJobs = 2,
[Parameter(Mandatory = $false)]
[string[]]$Companies,
[Parameter(Mandatory = $false)]
[switch]$DryRun
)
$ErrorActionPreference = 'Stop'
# Source library functions
. "$PSScriptRoot\lib\logging-functions.ps1"
. "$PSScriptRoot\lib\oracle-functions.ps1"
# Initialize logging
$logPath = Join-Path $PSScriptRoot "..\logs\05-import-companies_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
Initialize-LogFile -LogPath $logPath -ScriptName "05-import-companies.ps1"
try {
Write-LogSection "Batch Import Company Schemas"
if ($DryRun) {
Write-LogWarning "DRY RUN MODE - No changes will be made"
}
# Validate Oracle installation
$oraHome = Get-OracleHome -OracleHome $OracleHome
Write-LogSuccess "Oracle Home: $oraHome"
# Test connection
Write-Log "Testing database connection..."
if (-not (Test-OracleConnection -OracleHome $oraHome -ServiceName $ServiceName `
-Password $SystemPassword)) {
throw "Cannot connect to database. Please verify ServiceName and SystemPassword."
}
Write-LogSuccess "Database connection successful"
# Get company list from NOM_FIRME
Write-LogSection "Reading Company List from NOM_FIRME"
$companySql = @"
SET PAGESIZE 10000 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF LINESIZE 500
SELECT schema || '|' || parola
FROM CONTAFIN_ORACLE.NOM_FIRME
WHERE sters = 0
AND schema IS NOT NULL
ORDER BY schema;
EXIT;
"@
$companyResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $companySql -Silent
# Parse company data
$companyData = @{}
foreach ($line in $companyResult -split "`n") {
$line = $line.Trim()
if ($line -match "^([A-Z0-9_]+)\|(.*)$") {
$schema = $Matches[1]
$password = $Matches[2]
if (-not $password) { $password = "ROMFASTSOFT" }
$companyData[$schema] = $password
}
}
Write-Log "Found $($companyData.Count) companies in NOM_FIRME"
if ($companyData.Count -eq 0) {
Write-LogWarning "No companies found in NOM_FIRME"
Close-LogFile -Success $true
exit 0
}
# Filter companies if specified
if ($Companies) {
$filteredData = @{}
foreach ($company in $Companies) {
$companyUpper = $company.ToUpper()
if ($companyData.ContainsKey($companyUpper)) {
$filteredData[$companyUpper] = $companyData[$companyUpper]
}
else {
Write-LogWarning "Company $companyUpper not found in NOM_FIRME"
}
}
$companyData = $filteredData
Write-Log "Filtered to $($companyData.Count) companies"
}
# Find matching dump files
Write-LogSection "Scanning Dump Files"
$dumpFiles = Get-ChildItem -Path $DumpDirectory -Filter "*.dmp" -File
Write-Log "Found $($dumpFiles.Count) DMP files in $DumpDirectory"
# Match companies with dump files
$importList = @()
$notFoundList = @()
foreach ($schema in $companyData.Keys) {
# Try to find matching dump file (case-insensitive)
$matchingFile = $dumpFiles | Where-Object {
$_.BaseName -ieq $schema -or
$_.BaseName -imatch "^$schema[_\.]" -or
$_.BaseName -imatch "^${schema}$"
} | Select-Object -First 1
if ($matchingFile) {
$importList += [PSCustomObject]@{
Schema = $schema
Password = $companyData[$schema]
DumpFile = $matchingFile.FullName
DumpSize = [math]::Round($matchingFile.Length / 1MB, 2)
}
}
else {
$notFoundList += $schema
}
}
Write-Log "Companies to import: $($importList.Count)"
if ($notFoundList.Count -gt 0) {
Write-LogWarning "Companies without matching dump file: $($notFoundList.Count)"
foreach ($schema in $notFoundList) {
Write-Log " - $schema (no DMP file found)"
}
}
if ($importList.Count -eq 0) {
Write-LogWarning "No companies to import"
Close-LogFile -Success $true
exit 0
}
# Display import plan
Write-LogSection "Import Plan"
$totalSize = ($importList | Measure-Object -Property DumpSize -Sum).Sum
Write-Log "Total data to import: $totalSize MB"
Write-Log ""
Write-Log "Companies to import:"
foreach ($item in $importList) {
Write-Log " - $($item.Schema): $($item.DumpFile) ($($item.DumpSize) MB)"
}
if ($DryRun) {
Write-LogSection "Dry Run Complete"
Write-Log "Would import $($importList.Count) company schemas"
Close-LogFile -Success $true
exit 0
}
# Ensure DMPDIR exists
$dmpDir = "C:\DMPDIR"
if (-not (Test-Path -Path $dmpDir)) {
New-Item -ItemType Directory -Path $dmpDir -Force | Out-Null
}
# Process each company
Write-LogSection "Importing Companies"
$successCount = 0
$failCount = 0
$startTime = Get-Date
foreach ($item in $importList) {
Write-LogSection "Importing $($item.Schema)"
try {
# Check if user already exists
$userExists = Test-OracleUser -OracleHome $oraHome -ServiceName $ServiceName `
-Password $SystemPassword -SchemaName $item.Schema
if ($userExists) {
Write-Log "User $($item.Schema) already exists"
# Get current object count
$beforeCounts = Get-SchemaObjectCount -OracleHome $oraHome -ServiceName $ServiceName `
-Password $SystemPassword -SchemaName $item.Schema
$beforeTotal = if ($beforeCounts['TOTAL']) { $beforeCounts['TOTAL'] } else { 0 }
Write-Log "Existing objects: $beforeTotal"
}
else {
# Create user
Write-Log "Creating user $($item.Schema)..."
$createUserSql = @"
SET ECHO OFF FEEDBACK ON VERIFY OFF
CREATE USER $($item.Schema)
IDENTIFIED BY "$($item.Password)"
DEFAULT TABLESPACE ROA
TEMPORARY TABLESPACE TEMP
PROFILE DEFAULT;
GRANT CONNECT TO $($item.Schema);
GRANT RESOURCE TO $($item.Schema);
GRANT CREATE MATERIALIZED VIEW TO $($item.Schema);
GRANT CREATE PROCEDURE TO $($item.Schema);
GRANT CREATE SEQUENCE TO $($item.Schema);
GRANT CREATE TABLE TO $($item.Schema);
GRANT CREATE TRIGGER TO $($item.Schema);
GRANT CREATE VIEW TO $($item.Schema);
GRANT DEBUG CONNECT SESSION TO $($item.Schema);
GRANT SELECT ANY TABLE TO $($item.Schema);
GRANT CREATE TYPE TO $($item.Schema);
GRANT UNLIMITED TABLESPACE TO $($item.Schema);
COMMIT;
SELECT 'USER_CREATED' FROM dual;
EXIT;
"@
$createResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $createUserSql -Silent
if ($createResult -match "USER_CREATED") {
Write-LogSuccess "User $($item.Schema) created"
}
else {
throw "Failed to create user $($item.Schema)"
}
}
# Copy dump file to DMPDIR if not already there
$dumpFileName = Split-Path -Path $item.DumpFile -Leaf
$targetDumpPath = Join-Path $dmpDir $dumpFileName
if ($item.DumpFile -ne $targetDumpPath) {
Write-Log "Copying dump file to DMPDIR..."
Copy-Item -Path $item.DumpFile -Destination $targetDumpPath -Force
}
# Run import
Write-Log "Running impdp for $($item.Schema)..."
$impdpPath = Join-Path $oraHome "bin\impdp.exe"
$importLogFile = "$($item.Schema)_import_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
$connString = "SYSTEM/`"$SystemPassword`"@$ServiceName"
# Check if dump has different schema name (remapping needed)
$remapParam = ""
$dumpBaseName = [System.IO.Path]::GetFileNameWithoutExtension($dumpFileName).ToUpper()
if ($dumpBaseName -ne $item.Schema) {
$remapParam = "remap_schema=$dumpBaseName`:$($item.Schema)"
Write-Log "Schema remap: $dumpBaseName -> $($item.Schema)"
}
$impdpParams = @(
"`"$connString`"",
"directory=DMPDIR",
"dumpfile=$dumpFileName",
"logfile=$importLogFile",
"schemas=$($item.Schema)",
"table_exists_action=REPLACE"
)
if ($remapParam) {
$impdpParams += $remapParam
}
$arguments = $impdpParams -join " "
# Set Oracle environment
$env:ORACLE_HOME = $oraHome
$env:PATH = "$oraHome\bin;$env:PATH"
$env:NLS_LANG = "AMERICAN_AMERICA.AL32UTF8"
$importStart = Get-Date
$process = Start-Process -FilePath $impdpPath -ArgumentList $arguments -Wait -NoNewWindow -PassThru
$importDuration = (Get-Date) - $importStart
Write-Log "Import completed in $([math]::Round($importDuration.TotalMinutes, 2)) minutes"
# Verify import
$afterCounts = Get-SchemaObjectCount -OracleHome $oraHome -ServiceName $ServiceName `
-Password $SystemPassword -SchemaName $item.Schema
$afterTotal = if ($afterCounts['TOTAL']) { $afterCounts['TOTAL'] } else { 0 }
$afterInvalid = if ($afterCounts['INVALID']) { $afterCounts['INVALID'] } else { 0 }
Write-Log "Objects after import: $afterTotal"
if ($afterInvalid -gt 0) {
Write-LogWarning "Invalid objects: $afterInvalid"
# Recompile
$recompileSql = @"
BEGIN
DBMS_UTILITY.COMPILE_SCHEMA('$($item.Schema)', FALSE);
END;
/
EXIT;
"@
Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $recompileSql -Silent
}
if ($process.ExitCode -eq 0) {
Write-LogSuccess "$($item.Schema) imported successfully ($afterTotal objects)"
$successCount++
}
else {
Write-LogWarning "$($item.Schema) import completed with warnings"
$successCount++
}
# Clean up copied dump file
if ($item.DumpFile -ne $targetDumpPath -and (Test-Path -Path $targetDumpPath)) {
Remove-Item -Path $targetDumpPath -Force -ErrorAction SilentlyContinue
}
}
catch {
Write-LogError "Failed to import $($item.Schema): $_"
$failCount++
}
}
$totalDuration = (Get-Date) - $startTime
# Summary
Write-LogSection "Import Complete"
Write-LogSuccess "Company import batch completed!"
Write-Log ""
Write-Log "Summary:"
Write-Log " Total companies: $($importList.Count)"
Write-Log " Successful: $successCount"
Write-Log " Failed: $failCount"
Write-Log " Total duration: $([math]::Round($totalDuration.TotalMinutes, 2)) minutes"
Write-Log ""
if ($notFoundList.Count -gt 0) {
Write-Log "Companies skipped (no dump file):"
foreach ($schema in $notFoundList) {
Write-Log " - $schema"
}
}
Write-Log ""
Write-Log "Next steps:"
Write-Log " 1. Run 07-verify-installation.ps1 to verify all schemas"
Close-LogFile -Success ($failCount -eq 0)
exit $(if ($failCount -eq 0) { 0 } else { 1 })
}
catch {
Write-LogError "Import failed: $_"
Write-LogError $_.ScriptStackTrace
Close-LogFile -Success $false
exit 1
}

View File

@@ -0,0 +1,327 @@
#Requires -Version 5.1
<#
.SYNOPSIS
Add a new company schema to ROA Oracle.
.DESCRIPTION
Creates a new company user/schema with either:
- Import from a template DMP file
- Empty schema with basic structures
.PARAMETER CompanyName
Schema name for the new company. Required. Must be uppercase alphanumeric.
.PARAMETER Password
Password for the new company schema. Default: ROMFASTSOFT
.PARAMETER OracleHome
Oracle home directory. If not specified, auto-detects.
.PARAMETER ServiceName
Database service name. Default: XEPDB1
.PARAMETER SystemPassword
SYSTEM user password. Default: romfastsoft
.PARAMETER TemplateDump
Optional path to a template DMP file to import.
.PARAMETER TemplateSchema
Schema name in the template DMP file if different from target (for remap).
.PARAMETER Force
Drop and recreate if user already exists.
.EXAMPLE
.\06-add-company.ps1 -CompanyName "NEWCOMPANY"
.EXAMPLE
.\06-add-company.ps1 -CompanyName "FIRMA2024" -Password "SecurePass123"
.EXAMPLE
.\06-add-company.ps1 -CompanyName "NEWFIRMA" -TemplateDump "C:\dumps\FIRMANOUA.dmp" -TemplateSchema "FIRMANOUA"
.NOTES
File Name : 06-add-company.ps1
Prerequisite : Run 04-create-synonyms-grants.ps1 first
Copyright 2024 : ROMFAST
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[ValidatePattern('^[A-Z0-9_]+$')]
[string]$CompanyName,
[Parameter(Mandatory = $false)]
[string]$Password = "ROMFASTSOFT",
[Parameter(Mandatory = $false)]
[string]$OracleHome,
[Parameter(Mandatory = $false)]
[string]$ServiceName = "XEPDB1",
[Parameter(Mandatory = $false)]
[string]$SystemPassword = "romfastsoft",
[Parameter(Mandatory = $false)]
[ValidateScript({ Test-Path $_ })]
[string]$TemplateDump,
[Parameter(Mandatory = $false)]
[string]$TemplateSchema,
[Parameter(Mandatory = $false)]
[switch]$Force
)
$ErrorActionPreference = 'Stop'
# Ensure company name is uppercase
$CompanyName = $CompanyName.ToUpper()
# Source library functions
. "$PSScriptRoot\lib\logging-functions.ps1"
. "$PSScriptRoot\lib\oracle-functions.ps1"
# Initialize logging
$logPath = Join-Path $PSScriptRoot "..\logs\06-add-company_${CompanyName}_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
Initialize-LogFile -LogPath $logPath -ScriptName "06-add-company.ps1"
try {
Write-LogSection "Adding New Company: $CompanyName"
# Validate Oracle installation
$oraHome = Get-OracleHome -OracleHome $OracleHome
Write-LogSuccess "Oracle Home: $oraHome"
# Test connection
Write-Log "Testing database connection..."
if (-not (Test-OracleConnection -OracleHome $oraHome -ServiceName $ServiceName `
-Password $SystemPassword)) {
throw "Cannot connect to database. Please verify ServiceName and SystemPassword."
}
Write-LogSuccess "Database connection successful"
# Check if user already exists
Write-Log "Checking if user $CompanyName exists..."
$userExists = Test-OracleUser -OracleHome $oraHome -ServiceName $ServiceName `
-Password $SystemPassword -SchemaName $CompanyName
if ($userExists) {
if ($Force) {
Write-LogWarning "User $CompanyName exists. Dropping due to -Force flag..."
$dropSql = @"
SET ECHO OFF FEEDBACK ON VERIFY OFF
DROP USER $CompanyName CASCADE;
SELECT 'USER_DROPPED' FROM dual;
EXIT;
"@
$dropResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $dropSql
if ($dropResult -match "USER_DROPPED") {
Write-Log "User $CompanyName dropped"
}
else {
throw "Failed to drop user $CompanyName"
}
}
else {
throw "User $CompanyName already exists. Use -Force to drop and recreate."
}
}
# Create user
Write-LogSection "Creating User $CompanyName"
$createUserSql = @"
SET ECHO OFF FEEDBACK ON VERIFY OFF
PROMPT Creating user $CompanyName...
CREATE USER $CompanyName
IDENTIFIED BY "$Password"
DEFAULT TABLESPACE ROA
TEMPORARY TABLESPACE TEMP
PROFILE DEFAULT;
PROMPT Granting role privileges...
GRANT CONNECT TO $CompanyName;
GRANT RESOURCE TO $CompanyName;
PROMPT Granting system privileges...
GRANT CREATE MATERIALIZED VIEW TO $CompanyName;
GRANT CREATE PROCEDURE TO $CompanyName;
GRANT CREATE SEQUENCE TO $CompanyName;
GRANT CREATE TABLE TO $CompanyName;
GRANT CREATE TRIGGER TO $CompanyName;
GRANT CREATE VIEW TO $CompanyName;
GRANT DEBUG CONNECT SESSION TO $CompanyName;
GRANT SELECT ANY TABLE TO $CompanyName;
GRANT CREATE TYPE TO $CompanyName;
GRANT UNLIMITED TABLESPACE TO $CompanyName;
COMMIT;
SELECT 'USER_CREATED' FROM dual;
EXIT;
"@
$createResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $createUserSql
if ($createResult -match "USER_CREATED") {
Write-LogSuccess "User $CompanyName created successfully"
}
else {
Write-LogError "Failed to create user"
Write-LogDebug $createResult
throw "User creation failed"
}
# Import from template if specified
if ($TemplateDump) {
Write-LogSection "Importing from Template"
Write-Log "Template dump: $TemplateDump"
# Determine template schema for remapping
if (-not $TemplateSchema) {
$TemplateSchema = [System.IO.Path]::GetFileNameWithoutExtension($TemplateDump).ToUpper()
Write-Log "Assuming template schema: $TemplateSchema"
}
# Setup DMPDIR
$dmpDir = "C:\DMPDIR"
if (-not (Test-Path -Path $dmpDir)) {
New-Item -ItemType Directory -Path $dmpDir -Force | Out-Null
}
New-OracleDirectory -OracleHome $oraHome -ServiceName $ServiceName `
-Password $SystemPassword -DirectoryName "DMPDIR" -DirectoryPath $dmpDir
# Copy dump to DMPDIR
$dumpFileName = Split-Path -Path $TemplateDump -Leaf
$targetDumpPath = Join-Path $dmpDir $dumpFileName
if ($TemplateDump -ne $targetDumpPath) {
Write-Log "Copying dump file to DMPDIR..."
Copy-Item -Path $TemplateDump -Destination $targetDumpPath -Force
}
# Run import with remap
Write-Log "Running impdp..."
$impdpPath = Join-Path $oraHome "bin\impdp.exe"
$importLogFile = "${CompanyName}_import_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
$connString = "SYSTEM/`"$SystemPassword`"@$ServiceName"
$impdpParams = @(
"`"$connString`"",
"directory=DMPDIR",
"dumpfile=$dumpFileName",
"logfile=$importLogFile",
"remap_schema=$TemplateSchema`:$CompanyName",
"table_exists_action=REPLACE"
)
$arguments = $impdpParams -join " "
# Set Oracle environment
$env:ORACLE_HOME = $oraHome
$env:PATH = "$oraHome\bin;$env:PATH"
$env:NLS_LANG = "AMERICAN_AMERICA.AL32UTF8"
$importStart = Get-Date
$process = Start-Process -FilePath $impdpPath -ArgumentList $arguments -Wait -NoNewWindow -PassThru
$importDuration = (Get-Date) - $importStart
Write-Log "Import completed in $([math]::Round($importDuration.TotalMinutes, 2)) minutes"
if ($process.ExitCode -eq 0) {
Write-LogSuccess "Template imported successfully"
}
else {
Write-LogWarning "Import completed with warnings (exit code: $($process.ExitCode))"
}
# Clean up copied dump file
if ($TemplateDump -ne $targetDumpPath -and (Test-Path -Path $targetDumpPath)) {
Remove-Item -Path $targetDumpPath -Force -ErrorAction SilentlyContinue
}
}
# Get final object count
Write-LogSection "Verifying Schema"
$counts = Get-SchemaObjectCount -OracleHome $oraHome -ServiceName $ServiceName `
-Password $SystemPassword -SchemaName $CompanyName
$totalObjects = if ($counts['TOTAL']) { $counts['TOTAL'] } else { 0 }
$invalidObjects = if ($counts['INVALID']) { $counts['INVALID'] } else { 0 }
Write-Log "Total objects: $totalObjects"
if ($invalidObjects -gt 0) {
Write-LogWarning "Invalid objects: $invalidObjects"
# Recompile
Write-Log "Recompiling invalid objects..."
$recompileSql = @"
BEGIN
DBMS_UTILITY.COMPILE_SCHEMA('$CompanyName', FALSE);
END;
/
EXIT;
"@
Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $recompileSql -Silent
# Recheck
$recheckCounts = Get-SchemaObjectCount -OracleHome $oraHome -ServiceName $ServiceName `
-Password $SystemPassword -SchemaName $CompanyName
$recheckInvalid = if ($recheckCounts['INVALID']) { $recheckCounts['INVALID'] } else { 0 }
if ($recheckInvalid -lt $invalidObjects) {
Write-LogSuccess "Recompilation fixed $($invalidObjects - $recheckInvalid) objects"
}
}
# Test connection with new user
Write-Log "Testing connection as $CompanyName..."
if (Test-OracleConnection -OracleHome $oraHome -ServiceName $ServiceName `
-Username $CompanyName -Password $Password) {
Write-LogSuccess "Connection test successful"
}
else {
Write-LogWarning "Could not connect as $CompanyName"
}
# Summary
Write-LogSection "Company Added"
Write-LogSuccess "Company $CompanyName added successfully!"
Write-Log ""
Write-Log "Summary:"
Write-Log " Schema name: $CompanyName"
Write-Log " Service: $ServiceName"
Write-Log " Objects: $totalObjects"
if ($TemplateDump) {
Write-Log " Template: $TemplateDump"
}
Write-Log ""
Write-Log "Connection string:"
Write-Log " $CompanyName/$Password@$ServiceName"
Close-LogFile -Success $true
exit 0
}
catch {
Write-LogError "Failed to add company: $_"
Write-LogError $_.ScriptStackTrace
Close-LogFile -Success $false
exit 1
}

View File

@@ -0,0 +1,515 @@
#Requires -Version 5.1
<#
.SYNOPSIS
Verify ROA Oracle installation.
.DESCRIPTION
Performs comprehensive verification of the ROA Oracle installation:
- Database info (version, CDB/non-CDB, service name)
- Tablespace ROA status
- User CONTAFIN_ORACLE status and object count
- SYS custom objects status
- Public synonyms count
- Invalid objects count
- Company schemas list with object counts
.PARAMETER OracleHome
Oracle home directory. If not specified, auto-detects.
.PARAMETER ServiceName
Database service name. Default: XEPDB1
.PARAMETER SystemPassword
SYSTEM user password. Default: romfastsoft
.PARAMETER Detailed
Show detailed object counts per schema.
.PARAMETER OutputFile
Optional path to save verification report.
.EXAMPLE
.\07-verify-installation.ps1
.EXAMPLE
.\07-verify-installation.ps1 -Detailed -OutputFile "C:\reports\verification.txt"
.EXAMPLE
.\07-verify-installation.ps1 -ServiceName "ROA" -SystemPassword "mypassword"
.NOTES
File Name : 07-verify-installation.ps1
Prerequisite : ROA Oracle installation completed
Copyright 2024 : ROMFAST
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[string]$OracleHome,
[Parameter(Mandatory = $false)]
[string]$ServiceName = "XEPDB1",
[Parameter(Mandatory = $false)]
[string]$SystemPassword = "romfastsoft",
[Parameter(Mandatory = $false)]
[switch]$Detailed,
[Parameter(Mandatory = $false)]
[string]$OutputFile
)
$ErrorActionPreference = 'Stop'
# Source library functions
. "$PSScriptRoot\lib\logging-functions.ps1"
. "$PSScriptRoot\lib\oracle-functions.ps1"
# Initialize logging
$logPath = Join-Path $PSScriptRoot "..\logs\07-verify-installation_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
Initialize-LogFile -LogPath $logPath -ScriptName "07-verify-installation.ps1"
# Initialize report
$report = [System.Text.StringBuilder]::new()
function Add-ReportLine {
param([string]$Line)
[void]$report.AppendLine($Line)
Write-Host $Line
}
function Add-ReportSection {
param([string]$Title)
Add-ReportLine ""
Add-ReportLine ("=" * 60)
Add-ReportLine " $Title"
Add-ReportLine ("=" * 60)
Add-ReportLine ""
}
try {
Add-ReportSection "ROA Oracle Installation Verification Report"
Add-ReportLine "Generated: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
Add-ReportLine "Computer: $env:COMPUTERNAME"
# Validate Oracle installation
$oraHome = Get-OracleHome -OracleHome $OracleHome
Write-LogSuccess "Oracle Home: $oraHome"
# Test connection
Write-Log "Testing database connection..."
if (-not (Test-OracleConnection -OracleHome $oraHome -ServiceName $ServiceName `
-Password $SystemPassword)) {
throw "Cannot connect to database. Please verify ServiceName and SystemPassword."
}
Write-LogSuccess "Database connection successful"
# Database Information
Add-ReportSection "Database Information"
$dbInfoSql = @"
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF LINESIZE 500
SELECT 'VERSION:' || version_full FROM v`$instance;
SELECT 'EDITION:' || edition FROM v`$instance;
SELECT 'INSTANCE:' || instance_name FROM v`$instance;
SELECT 'HOST:' || host_name FROM v`$instance;
SELECT 'STARTUP:' || TO_CHAR(startup_time, 'YYYY-MM-DD HH24:MI:SS') FROM v`$instance;
SELECT 'STATUS:' || status FROM v`$instance;
SELECT 'CDB:' || CDB FROM v`$database;
SELECT 'DBNAME:' || name FROM v`$database;
SELECT 'OPEN_MODE:' || open_mode FROM v`$database;
EXIT;
"@
$dbInfo = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $dbInfoSql -Silent
$dbData = @{}
foreach ($line in $dbInfo -split "`n") {
if ($line -match "^([A-Z_]+):(.*)$") {
$dbData[$Matches[1]] = $Matches[2].Trim()
}
}
Add-ReportLine "Oracle Version: $($dbData['VERSION'])"
Add-ReportLine "Edition: $($dbData['EDITION'])"
Add-ReportLine "Instance Name: $($dbData['INSTANCE'])"
Add-ReportLine "Host Name: $($dbData['HOST'])"
Add-ReportLine "Database Name: $($dbData['DBNAME'])"
Add-ReportLine "CDB Mode: $($dbData['CDB'])"
Add-ReportLine "Open Mode: $($dbData['OPEN_MODE'])"
Add-ReportLine "Instance Status: $($dbData['STATUS'])"
Add-ReportLine "Startup Time: $($dbData['STARTUP'])"
Add-ReportLine "Service Name: $ServiceName"
Add-ReportLine "Oracle Home: $oraHome"
# Container Information
$containerInfo = Test-PDB -OracleHome $oraHome -ServiceName $ServiceName -Password $SystemPassword
Add-ReportLine "Container: $($containerInfo.ContainerName)"
Add-ReportLine "Container ID: $($containerInfo.ConId)"
# Tablespace ROA Status
Add-ReportSection "Tablespace ROA Status"
$tsSql = @"
SET PAGESIZE 100 FEEDBACK OFF VERIFY OFF HEADING ON ECHO OFF LINESIZE 200
COLUMN tablespace_name FORMAT A20
COLUMN status FORMAT A10
COLUMN contents FORMAT A10
COLUMN allocation_type FORMAT A10
SELECT tablespace_name, status, contents, allocation_type
FROM dba_tablespaces
WHERE tablespace_name = 'ROA';
COLUMN file_name FORMAT A60
COLUMN size_mb FORMAT 999,999.99
COLUMN maxsize_mb FORMAT 999,999.99
COLUMN autoextensible FORMAT A5
SELECT file_name,
ROUND(bytes/1024/1024, 2) AS size_mb,
ROUND(maxbytes/1024/1024, 2) AS maxsize_mb,
autoextensible
FROM dba_data_files
WHERE tablespace_name = 'ROA';
EXIT;
"@
$tsResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $tsSql -Silent
Add-ReportLine $tsResult
# Check if ROA tablespace exists
if ($tsResult -notmatch "ROA") {
Add-ReportLine ""
Add-ReportLine "[WARNING] Tablespace ROA not found!"
}
# CONTAFIN_ORACLE Status
Add-ReportSection "CONTAFIN_ORACLE Schema Status"
$coExistsSql = @"
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF
SELECT 'USER_EXISTS' FROM dba_users WHERE username = 'CONTAFIN_ORACLE';
EXIT;
"@
$coExists = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $coExistsSql -Silent
if ($coExists -match "USER_EXISTS") {
Add-ReportLine "Status: EXISTS"
$coCounts = Get-SchemaObjectCount -OracleHome $oraHome -ServiceName $ServiceName `
-Password $SystemPassword -SchemaName "CONTAFIN_ORACLE"
$coTotal = if ($coCounts['TOTAL']) { $coCounts['TOTAL'] } else { 0 }
$coInvalid = if ($coCounts['INVALID']) { $coCounts['INVALID'] } else { 0 }
Add-ReportLine "Total Objects: $coTotal"
Add-ReportLine "Invalid Objects: $coInvalid"
if ($Detailed) {
Add-ReportLine ""
Add-ReportLine "Object counts by type:"
foreach ($key in $coCounts.Keys | Sort-Object) {
if ($key -ne 'TOTAL' -and $key -ne 'INVALID') {
Add-ReportLine " $($key.PadRight(25)) $($coCounts[$key])"
}
}
}
}
else {
Add-ReportLine "Status: NOT FOUND"
Add-ReportLine "[WARNING] CONTAFIN_ORACLE user does not exist!"
}
# SYS Custom Objects
Add-ReportSection "SYS Custom Objects"
$sysObjSql = @"
SET PAGESIZE 100 FEEDBACK OFF VERIFY OFF HEADING ON ECHO OFF LINESIZE 200
COLUMN object_name FORMAT A30
COLUMN object_type FORMAT A15
COLUMN status FORMAT A10
SELECT object_name, object_type, status
FROM dba_objects
WHERE owner = 'SYS'
AND object_name IN (
'AUTH_PACK', 'AUTH_DETALII', 'AUTH_SERII', 'VAUTH_SERII',
'PACK_UPDATE', 'PACK_UTILS', 'NEWSCHEMA', 'NEWSCHEMAPOST',
'NEWSCHEMAPROGRESS', 'DMPDIR'
)
ORDER BY object_type, object_name;
EXIT;
"@
$sysResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYS" -Password $SystemPassword -SqlCommand $sysObjSql -AsSysdba -Silent
Add-ReportLine $sysResult
# Public Synonyms Count
Add-ReportSection "Public Synonyms"
$synSql = @"
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF
SELECT 'TOTAL_SYNONYMS:' || COUNT(*) FROM dba_synonyms WHERE owner = 'PUBLIC';
SELECT 'CO_SYNONYMS:' || COUNT(*) FROM dba_synonyms WHERE owner = 'PUBLIC' AND table_owner = 'CONTAFIN_ORACLE';
SELECT 'SYS_SYNONYMS:' || COUNT(*) FROM dba_synonyms WHERE owner = 'PUBLIC' AND table_owner = 'SYS' AND table_name LIKE 'AUTH%';
EXIT;
"@
$synResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $synSql -Silent
$synData = @{}
foreach ($line in $synResult -split "`n") {
if ($line -match "^([A-Z_]+):(\d+)$") {
$synData[$Matches[1]] = [int]$Matches[2]
}
}
Add-ReportLine "Total public synonyms: $($synData['TOTAL_SYNONYMS'])"
Add-ReportLine "CONTAFIN_ORACLE synonyms: $($synData['CO_SYNONYMS'])"
Add-ReportLine "SYS AUTH synonyms: $($synData['SYS_SYNONYMS'])"
# All Invalid Objects
Add-ReportSection "Invalid Objects Summary"
$invalidSql = @"
SET PAGESIZE 100 FEEDBACK OFF VERIFY OFF HEADING ON ECHO OFF LINESIZE 200
COLUMN owner FORMAT A20
COLUMN invalid_count FORMAT 999,999
SELECT owner, COUNT(*) AS invalid_count
FROM dba_objects
WHERE status = 'INVALID'
AND owner NOT IN ('SYS', 'SYSTEM', 'OUTLN', 'DBSNMP', 'XDB', 'ORDSYS',
'ORDDATA', 'MDSYS', 'CTXSYS', 'WMSYS', 'APEX_PUBLIC_USER')
GROUP BY owner
ORDER BY invalid_count DESC;
EXIT;
"@
$invalidResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $invalidSql -Silent
if ($invalidResult.Trim() -eq "" -or $invalidResult -match "no rows selected") {
Add-ReportLine "No invalid objects found in application schemas."
}
else {
Add-ReportLine $invalidResult
}
# Company Schemas
Add-ReportSection "Company Schemas"
# Get company list from NOM_FIRME
$companySql = @"
SET PAGESIZE 1000 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF LINESIZE 200
SELECT schema FROM CONTAFIN_ORACLE.NOM_FIRME WHERE sters = 0 AND schema IS NOT NULL ORDER BY schema;
EXIT;
"@
$companyList = @()
try {
$companyResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $companySql -Silent
foreach ($line in $companyResult -split "`n") {
$schema = $line.Trim()
if ($schema -match "^[A-Z0-9_]+$") {
$companyList += $schema
}
}
}
catch {
Add-ReportLine "[WARNING] Could not query NOM_FIRME table"
}
Add-ReportLine "Companies registered in NOM_FIRME: $($companyList.Count)"
Add-ReportLine ""
if ($companyList.Count -gt 0) {
# Check which schemas exist
$existingSql = @"
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF LINESIZE 200
SELECT username FROM dba_users WHERE username NOT IN (
'SYS', 'SYSTEM', 'OUTLN', 'DBSNMP', 'XDB', 'ORDSYS', 'ORDDATA', 'MDSYS',
'CTXSYS', 'WMSYS', 'APEX_PUBLIC_USER', 'CONTAFIN_ORACLE', 'ANONYMOUS',
'APEX_040200', 'APEX_050000', 'APPQOSSYS', 'AUDSYS', 'DIP', 'DVF', 'DVSYS',
'FLOWS_FILES', 'GGSYS', 'GSMADMIN_INTERNAL', 'GSMCATUSER', 'GSMUSER',
'LBACSYS', 'MDDATA', 'OJVMSYS', 'OLAPSYS', 'ORACLE_OCM', 'REMOTE_SCHEDULER_AGENT',
'SI_INFORMTN_SCHEMA', 'SPATIAL_CSW_ADMIN_USR', 'SPATIAL_WFS_ADMIN_USR',
'SYSBACKUP', 'SYSDG', 'SYSKM', 'SYSRAC', 'XS`$NULL'
) ORDER BY username;
EXIT;
"@
$existingResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $existingSql -Silent
$existingSchemas = @()
foreach ($line in $existingResult -split "`n") {
$schema = $line.Trim()
if ($schema -match "^[A-Z0-9_]+$") {
$existingSchemas += $schema
}
}
Add-ReportLine "Existing company schemas: $($existingSchemas.Count)"
Add-ReportLine ""
# Show details
Add-ReportLine ("Schema".PadRight(25) + "Status".PadRight(12) + "Objects".PadRight(10) + "Invalid")
Add-ReportLine ("-" * 60)
foreach ($schema in $companyList) {
$status = if ($existingSchemas -contains $schema) { "EXISTS" } else { "MISSING" }
if ($status -eq "EXISTS") {
$counts = Get-SchemaObjectCount -OracleHome $oraHome -ServiceName $ServiceName `
-Password $SystemPassword -SchemaName $schema
$total = if ($counts['TOTAL']) { $counts['TOTAL'] } else { 0 }
$invalid = if ($counts['INVALID']) { $counts['INVALID'] } else { 0 }
Add-ReportLine ("$schema".PadRight(25) + "$status".PadRight(12) + "$total".PadRight(10) + "$invalid")
}
else {
Add-ReportLine ("$schema".PadRight(25) + "$status".PadRight(12) + "-".PadRight(10) + "-")
}
}
# Check for orphan schemas (exist in DB but not in NOM_FIRME)
$orphanSchemas = $existingSchemas | Where-Object { $companyList -notcontains $_ }
if ($orphanSchemas.Count -gt 0) {
Add-ReportLine ""
Add-ReportLine "Orphan schemas (not in NOM_FIRME):"
foreach ($schema in $orphanSchemas) {
$counts = Get-SchemaObjectCount -OracleHome $oraHome -ServiceName $ServiceName `
-Password $SystemPassword -SchemaName $schema
$total = if ($counts['TOTAL']) { $counts['TOTAL'] } else { 0 }
Add-ReportLine " - $schema ($total objects)"
}
}
}
# Network ACL Status
Add-ReportSection "Network ACL Status"
$aclSql = @"
SET PAGESIZE 100 FEEDBACK OFF VERIFY OFF HEADING ON ECHO OFF LINESIZE 200
COLUMN acl FORMAT A30
COLUMN principal FORMAT A20
COLUMN privilege FORMAT A15
COLUMN is_grant FORMAT A8
SELECT acl, principal, privilege, is_grant
FROM dba_network_acl_privileges
WHERE principal = 'CONTAFIN_ORACLE';
EXIT;
"@
$aclResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYS" -Password $SystemPassword -SqlCommand $aclSql -AsSysdba -Silent
if ($aclResult.Trim() -eq "" -or $aclResult -match "no rows selected") {
Add-ReportLine "No ACL configured for CONTAFIN_ORACLE"
}
else {
Add-ReportLine $aclResult
}
# Context Status
Add-ReportSection "Context Status"
$ctxSql = @"
SET PAGESIZE 100 FEEDBACK OFF VERIFY OFF HEADING ON ECHO OFF LINESIZE 200
COLUMN namespace FORMAT A20
COLUMN schema FORMAT A25
COLUMN package FORMAT A25
SELECT namespace, schema, package
FROM dba_context
WHERE namespace = 'SESIUNE';
EXIT;
"@
$ctxResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $ctxSql -Silent
if ($ctxResult.Trim() -eq "" -or $ctxResult -match "no rows selected") {
Add-ReportLine "SESIUNE context not found"
}
else {
Add-ReportLine $ctxResult
}
# Final Summary
Add-ReportSection "Verification Summary"
$issues = @()
# Check for issues
if ($tsResult -notmatch "ROA") {
$issues += "Tablespace ROA not found"
}
if ($coExists -notmatch "USER_EXISTS") {
$issues += "CONTAFIN_ORACLE user not found"
}
elseif ($coCounts -and $coCounts['INVALID'] -gt 0) {
$issues += "CONTAFIN_ORACLE has $($coCounts['INVALID']) invalid objects"
}
if ($synData['CO_SYNONYMS'] -eq 0) {
$issues += "No public synonyms for CONTAFIN_ORACLE"
}
$missingCompanies = $companyList | Where-Object { $existingSchemas -notcontains $_ }
if ($missingCompanies.Count -gt 0) {
$issues += "$($missingCompanies.Count) company schemas are missing"
}
if ($issues.Count -eq 0) {
Add-ReportLine "[OK] All checks passed!"
Add-ReportLine ""
Add-ReportLine "The ROA Oracle installation appears to be complete and functional."
}
else {
Add-ReportLine "[WARNING] Issues found:"
Add-ReportLine ""
foreach ($issue in $issues) {
Add-ReportLine " - $issue"
}
}
Add-ReportLine ""
Add-ReportLine ("=" * 60)
Add-ReportLine " End of Verification Report"
Add-ReportLine ("=" * 60)
# Save report if requested
if ($OutputFile) {
Set-Content -Path $OutputFile -Value $report.ToString() -Encoding UTF8
Write-LogSuccess "Report saved to: $OutputFile"
}
Close-LogFile -Success ($issues.Count -eq 0)
exit $(if ($issues.Count -eq 0) { 0 } else { 1 })
}
catch {
Write-LogError "Verification failed: $_"
Write-LogError $_.ScriptStackTrace
Close-LogFile -Success $false
exit 1
}

View File

@@ -0,0 +1,300 @@
#Requires -Version 5.1
<#
.SYNOPSIS
Logging utility functions for ROA Oracle setup scripts.
.DESCRIPTION
Provides standardized logging functions with timestamps, colors, and file output.
All log messages are written to both console and optional log file.
.NOTES
File Name : logging-functions.ps1
Prerequisite : PowerShell 5.1 or higher
Copyright 2024 : ROMFAST
#>
# Script-level variables for logging
$script:LogFile = $null
$script:LogLevel = 'Info'
<#
.SYNOPSIS
Initialize the log file with a header.
.DESCRIPTION
Creates or clears a log file and writes a header with timestamp and script info.
.PARAMETER LogPath
Path to the log file.
.PARAMETER ScriptName
Name of the calling script for the header.
.EXAMPLE
Initialize-LogFile -LogPath "C:\logs\setup.log" -ScriptName "01-setup-database.ps1"
#>
function Initialize-LogFile {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[string]$LogPath,
[Parameter(Mandatory = $false)]
[string]$ScriptName = "ROA Setup"
)
$script:LogFile = $LogPath
# Create directory if it doesn't exist
$logDir = Split-Path -Path $LogPath -Parent
if ($logDir -and -not (Test-Path -Path $logDir)) {
New-Item -ItemType Directory -Path $logDir -Force | Out-Null
}
# Write header
$header = @"
================================================================================
ROA Oracle Setup Log
Script: $ScriptName
Started: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
Computer: $env:COMPUTERNAME
User: $env:USERNAME
================================================================================
"@
Set-Content -Path $LogPath -Value $header -Encoding UTF8
}
<#
.SYNOPSIS
Write a log message with timestamp.
.DESCRIPTION
Writes a timestamped message to console and log file. Supports different
message types (Info, Warning, Error, Success, Debug).
.PARAMETER Message
The message to log.
.PARAMETER Level
The log level: Info, Warning, Error, Success, Debug.
.PARAMETER NoConsole
If specified, only writes to log file.
.EXAMPLE
Write-Log "Starting database setup" -Level Info
#>
function Write-Log {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, Position = 0)]
[string]$Message,
[Parameter(Mandatory = $false)]
[ValidateSet('Info', 'Warning', 'Error', 'Success', 'Debug')]
[string]$Level = 'Info',
[Parameter(Mandatory = $false)]
[switch]$NoConsole
)
$timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
$logMessage = "[$timestamp] [$Level] $Message"
# Write to log file if initialized
if ($script:LogFile) {
Add-Content -Path $script:LogFile -Value $logMessage -Encoding UTF8
}
# Write to console with appropriate color
if (-not $NoConsole) {
$color = switch ($Level) {
'Info' { 'White' }
'Warning' { 'Yellow' }
'Error' { 'Red' }
'Success' { 'Green' }
'Debug' { 'Cyan' }
default { 'White' }
}
$prefix = switch ($Level) {
'Info' { '[INFO] ' }
'Warning' { '[WARN] ' }
'Error' { '[ERROR] ' }
'Success' { '[OK] ' }
'Debug' { '[DEBUG] ' }
default { '[INFO] ' }
}
Write-Host "$prefix$Message" -ForegroundColor $color
}
}
<#
.SYNOPSIS
Write an error message in red.
.DESCRIPTION
Convenience function for logging error messages.
.PARAMETER Message
The error message to log.
.EXAMPLE
Write-LogError "Failed to connect to database"
#>
function Write-LogError {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, Position = 0)]
[string]$Message
)
Write-Log -Message $Message -Level Error
}
<#
.SYNOPSIS
Write a success message in green.
.DESCRIPTION
Convenience function for logging success messages.
.PARAMETER Message
The success message to log.
.EXAMPLE
Write-LogSuccess "Database created successfully"
#>
function Write-LogSuccess {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, Position = 0)]
[string]$Message
)
Write-Log -Message $Message -Level Success
}
<#
.SYNOPSIS
Write a warning message in yellow.
.DESCRIPTION
Convenience function for logging warning messages.
.PARAMETER Message
The warning message to log.
.EXAMPLE
Write-LogWarning "User already exists, skipping creation"
#>
function Write-LogWarning {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, Position = 0)]
[string]$Message
)
Write-Log -Message $Message -Level Warning
}
<#
.SYNOPSIS
Write a debug message in cyan.
.DESCRIPTION
Convenience function for logging debug messages.
.PARAMETER Message
The debug message to log.
.EXAMPLE
Write-LogDebug "SQL command: SELECT * FROM dual"
#>
function Write-LogDebug {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, Position = 0)]
[string]$Message
)
Write-Log -Message $Message -Level Debug
}
<#
.SYNOPSIS
Write a section header to the log.
.DESCRIPTION
Writes a formatted section header for visual separation in logs.
.PARAMETER Title
The section title.
.EXAMPLE
Write-LogSection "Creating Tablespace ROA"
#>
function Write-LogSection {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, Position = 0)]
[string]$Title
)
$separator = "=" * 60
$message = @"
$separator
$Title
$separator
"@
if ($script:LogFile) {
Add-Content -Path $script:LogFile -Value $message -Encoding UTF8
}
Write-Host ""
Write-Host $separator -ForegroundColor Cyan
Write-Host " $Title" -ForegroundColor Cyan
Write-Host $separator -ForegroundColor Cyan
}
<#
.SYNOPSIS
Close the log file with a footer.
.DESCRIPTION
Writes a closing footer to the log file with completion status.
.PARAMETER Success
Indicates if the script completed successfully.
.EXAMPLE
Close-LogFile -Success $true
#>
function Close-LogFile {
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[bool]$Success = $true
)
if ($script:LogFile) {
$status = if ($Success) { "COMPLETED SUCCESSFULLY" } else { "COMPLETED WITH ERRORS" }
$footer = @"
================================================================================
$status
Finished: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
================================================================================
"@
Add-Content -Path $script:LogFile -Value $footer -Encoding UTF8
}
}
# Note: Functions are available when dot-sourced (. .\logging-functions.ps1)
# Do NOT use Export-ModuleMember - it only works inside .psm1 modules

View File

@@ -0,0 +1,952 @@
#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]$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 `
-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 = $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" `
-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" `
-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]$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 `
-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]$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 `
-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]$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
$sysdba = if ($AsSysdba) { " as 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