#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 }