Files
ROMFASTSQL/proxmox/lxc108-oracle/roa-windows-setup/scripts/07-verify-installation.ps1
Marius a5ea8c7ffa fix(oracle): instanta citeste TNS_ADMIN-ul de masina, nu Oracle Home
Continuarea corectiei 3 din ec66377. Aceea rezolva doar jumatatea vizibila a
problemei; jumatatea ascunsa ar fi lovit la primul reboot al serverului, dupa
plecarea de la client. Gasit la VADECO, verificat pe loc.

1. ORA-12514 la toti clientii, cu baza perfect sanatoasa.

   TNS_ADMIN de masina nu decide doar de unde se citeste sqlnet.ora: instanta
   rezolva de acolo si aliasurile din tnsnames.ora. La Oracle XE LOCAL_LISTENER
   e implicit aliasul LISTENER_XE, definit doar in tnsnames.ora din Oracle Home.
   Cand serviciul reporneste dupa ce ROAClient a pus TNS_ADMIN pe folderul
   instantclient-ului, aliasul nu se mai rezolva, instanta nu se mai
   inregistreaza la listener, si atunci: v$instance OPEN, v$pdbs READ WRITE,
   listener pornit pe 0.0.0.0:1521, lsnrctl arata doar CLRExtProc, si absolut
   orice client primeste ORA-12514.

   Capcana e de timp, nu de continut: o instanta pornita inainte ca TNS_ADMIN
   sa existe nu il vede, deci instalarea pare impecabila si cade la primul
   reboot. Reprodus la VADECO cu un simplu Restart-Service OracleServiceXE.

   Pasul 01 scrie acum si tnsnames.ora in TNS_ADMIN (aliasul ROA pentru
   ROAClient - sablonul livrat cu el arata spre HOST=SERVER_ROA, inexistent -
   plus LISTENER_XE pentru instanta) si, mai important, fixeaza LOCAL_LISTENER
   pe adresa literala. Doar asta din urma rezista si daca ROAClient se
   instaleaza dupa kit, sau daca folderul instantclient se muta.

2. ORA-01017 desi parola e corecta.

   Cu SQLNET.ALLOWED_LOGON_VERSION_SERVER=8 serverul autentifica orice client
   pre-12c pe baza verificatorului 10G. Un cont fara 10G in PASSWORD_VERSIONS
   nu se mai poate conecta din Instant Client 10/11, si eroarea nu e ORA-28040,
   ci ORA-01017 - fix cea care trimite pe pista parolei. Dupa o instalare 21c,
   SYSTEM are doar 11G 12C; CONTAFIN_ORACLE scapa doar pentru ca pasul 01 ii
   rescrie parola dupa ce a scris sqlnet.ora. Pasul 01 rescrie acum si parola
   lui SYSTEM, din CDB$ROOT, cu aceeasi valoare.

   Subtilitate: interogat din PDB, PASSWORD_VERSIONS al unui utilizator comun
   ramane cel vechi si dupa reparatie, desi autentificarea foloseste definitia
   din root si functioneaza. Coloana nu e o dovada pentru SYSTEM; conectarea e.

3. Pasul 07 verifica acum ce nu se vede pe hartie.

   Toate cele trei erori trec de verificarile de pana acum: fisierul exista,
   parametrul e setat, contul e OPEN, obiectele sunt valide. Sectiunea noua
   "Conectivitate client vechi (Instant Client)" verifica unde se citeste
   efectiv sqlnet.ora, daca tnsnames.ora din TNS_ADMIN mai e sablonul, daca
   LOCAL_LISTENER e alias sau adresa, ce verificatoare de parola au conturile,
   si - singurul lucru care le prinde pe toate - face o conectare adevarata cu
   Instant Client-ul gasit pe masina. La esec, raportul spune si unde sa te
   uiti. Parametri noi: -ContafinPassword, -InstantClientDir.

4. Get-ServerLanIPv4, in biblioteca.

   Pe serverele la care intram prin Tailscale, un tnsnames.ora cu 100.x nu duce
   nicaieri de pe o statie. Functia alege IP-ul din LAN sarind peste Tailscale
   (100.64.0.0/10) si APIPA, dupa ruta implicita cand sunt mai multe placi.
   Get-ListenerHost o foloseste si el la fallback-ul pe 0.0.0.0, unde inainte
   lua prima adresa nefiltrata.

La VADECO a mai fost nevoie de o corectie manuala, in afara kitului: listener.ora
avea HOST = <nume>.ts.net, deci pornirea listenerului depindea de Tailscale.
Regula generala e in documentatie.

Detaliile, cu dovezi si comenzi de diagnostic: docs/lectii-conectare-client-oracle.md

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SzF1hf4aFS1tmJWpPMiwGp
2026-08-25 22:14:45 +03:00

1130 lines
45 KiB
PowerShell

#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,
# Folosite doar ca valoare de rezerva: caile reale se citesc din
# SERVER_INFO.ROAUPDATEPATH si din obiectul DIRECTORY BACKUP_ORACLE.
[Parameter(Mandatory = $false)]
[string]$RoaUpdatePath = "D:\ROAUPDATE",
[Parameter(Mandatory = $false)]
[string]$ExportPath = "D:\ROA\EXPORT_ORADMP",
# Parola CONTAFIN_ORACLE, folosita pentru proba de conectare cu Instant
# Client-ul vechi. Daca e gresita, proba raporteaza esec - nu instalarea.
[Parameter(Mandatory = $false)]
[string]$ContafinPassword = "ROMFASTSOFT",
# Folderul Instant Client-ului vechi (cel al ROAClient). Implicit se
# deduce din TNS_ADMIN sau se cauta sub D:\ROA si C:\ROA.
[Parameter(Mandatory = $false)]
[string]$InstantClientDir
)
$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
# Dictionary Grants required by PACK_DIAG_SPATIU
Add-ReportSection "Dictionary Grants (PACK_DIAG_SPATIU)"
$dictSql = @"
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF LINESIZE 200
SELECT 'GRANTED:' || table_name
FROM dba_tab_privs
WHERE grantee = 'CONTAFIN_ORACLE'
AND grantor = 'SYS'
AND privilege = 'SELECT'
ORDER BY table_name;
EXIT;
"@
$dictResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $dictSql -Silent
$granted = @()
foreach ($line in $dictResult -split "`n") {
if ($line -match "^GRANTED:(.+)$") { $granted += $Matches[1].Trim() }
}
# Lista din sql\sys-grants.sql, sectiunea [5/5]
$expectedDict = @(
'DBA_DATA_FILES', 'DBA_FREE_SPACE', 'DBA_TEMP_FILES', 'DBA_SEGMENTS',
'DBA_TAB_STATS_HISTORY', 'DBA_SCHEDULER_JOB_RUN_DETAILS', 'DBA_RECYCLEBIN',
'V_$INSTANCE', 'V_$DATABASE', 'V_$PARAMETER', 'V_$TRANSACTION',
'V_$TEMP_SPACE_HEADER', 'V_$FLASH_RECOVERY_AREA_USAGE',
'DBA_TABLESPACES', 'V_$VERSION',
'DBA_LOBS', 'DBA_LOB_PARTITIONS', 'DBA_INDEXES'
)
$missingDict = $expectedDict | Where-Object { $granted -notcontains $_ }
Add-ReportLine "Expected grants: $($expectedDict.Count)"
Add-ReportLine "Present grants: $($expectedDict.Count - $missingDict.Count)"
if ($missingDict.Count -eq 0) {
Add-ReportLine "Status: OK"
}
else {
Add-ReportLine "Status: INCOMPLETE"
Add-ReportLine ""
Add-ReportLine "Missing:"
foreach ($m in $missingDict) { Add-ReportLine " - $m" }
Add-ReportLine ""
Add-ReportLine "[WARNING] CONTAFIN_ORACLE.PACK_DIAG_SPATIU va ramane INVALID."
Add-ReportLine " Rolul DBA nu se aplica in pachetele cu drepturi de definitor."
Add-ReportLine " Rezolvare: sqlplus sys/<parola>@$ServiceName as sysdba @sql\sys-grants.sql"
}
# 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+)\s*$") {
$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)"
}
}
}
# Company Template + SMTP
# ------------------------------------------------------------------------
# SYS.NEWSCHEMA (si 06-add-company.ps1) creeaza o firma noua importand
# sablonul FIRMANOUA.dmp din directorul Oracle DMPDIR. Daca fisierul nu e
# acolo, adaugarea de firme noi pica in DBMS_DATAPUMP.ADD_FILE - dar abia
# peste luni, cand clientul chiar adauga o firma. Il verificam la instalare.
Add-ReportSection "Company Template + SMTP"
# Lipsa sablonului e un defect real (blocheaza adaugarea de firme), deci
# intra in $issues si in codul de iesire. SMTP nesetat ramane doar o nota:
# nu toti clientii folosesc notificarile pe email.
$extraIssues = @()
$tmplSql = @"
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF LINESIZE 200
SELECT 'DMPDIR_PATH:' || directory_path FROM dba_directories WHERE directory_name = 'DMPDIR';
SELECT 'SMTP_OUT:' || NVL(value, '<nesetat>') FROM v`$parameter WHERE name = 'smtp_out_server';
EXIT;
"@
$tmplResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYS" -Password $SystemPassword -SqlCommand $tmplSql -AsSysdba -Silent
$dmpDirPath = $null
$smtpOut = $null
foreach ($line in $tmplResult -split "`n") {
$line = $line.Trim()
if ($line -match "^DMPDIR_PATH:(.+)$") { $dmpDirPath = $Matches[1].Trim() }
if ($line -match "^SMTP_OUT:(.+)$") { $smtpOut = $Matches[1].Trim() }
}
if (-not $dmpDirPath) {
Add-ReportLine "[WARNING] Directorul Oracle DMPDIR nu exista."
$extraIssues += "Oracle directory DMPDIR missing"
}
else {
Add-ReportLine "DMPDIR: $dmpDirPath"
$tmplPath = Join-Path $dmpDirPath "FIRMANOUA.dmp"
if (Test-Path $tmplPath) {
$sizeMb = [math]::Round((Get-Item $tmplPath).Length / 1MB, 1)
Add-ReportLine "FIRMANOUA.dmp: OK ($sizeMb MB)"
}
else {
Add-ReportLine "FIRMANOUA.dmp: LIPSA"
Add-ReportLine ""
Add-ReportLine "[WARNING] Fara sablonul FIRMANOUA.dmp in DMPDIR, adaugarea unei firme"
Add-ReportLine " noi (SYS.NEWSCHEMA / 06-add-company.ps1) va esua la"
Add-ReportLine " DBMS_DATAPUMP.ADD_FILE. Copiaza-l in $dmpDirPath."
Add-ReportLine " Sursa: LXC 108, container oracle-xe,"
Add-ReportLine " /tmp/oracle-import-roa2/firmanoua.dmp"
$extraIssues += "FIRMANOUA.dmp missing from DMPDIR (adding new companies will fail)"
}
}
Add-ReportLine ""
if ($smtpOut -and $smtpOut -ne '<nesetat>') {
Add-ReportLine "SMTP_OUT_SERVER: $smtpOut"
}
else {
Add-ReportLine "SMTP_OUT_SERVER: NESETAT"
Add-ReportLine "[NOTA] UTL_MAIL.SEND va da ORA-29278/29279 pana cand e setat."
Add-ReportLine " Ruleaza 08-post-install-config.ps1 -EmailSmtp <server>."
}
# 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
}
# ------------------------------------------------------------------------
# Licente
# ------------------------------------------------------------------------
# AUTH_DETALII tine Id-ul de client, AUTH_SERII seriile propriu-zise pe
# care AUTH_PACK le decripteaza. Pasul 08 scrie doar Id-ul; seriile vin
# de pe serverul vechi prin 09-copy-licenses.ps1. O baza cu Id de client
# dar fara serii e cazul tipic de migrare facuta pe jumatate: aplicatia
# porneste si apoi refuza fiecare modul.
Add-ReportSection "Licente"
$licSql = @"
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF LINESIZE 300
SELECT 'SERII:' || COUNT(*) FROM sys.auth_serii;
SELECT 'SERII_ACTIVE:' || COUNT(*) FROM sys.auth_serii WHERE sters = 0;
SELECT 'IDCLIENT:' || NVL(MAX(detalii), '<nesetat>') FROM sys.auth_detalii;
SELECT 'EXPIRA:' || nume || '|' || TO_CHAR(data_val, 'YYYY-MM-DD')
FROM sys.vauth_serii
WHERE data_val IS NOT NULL AND data_val < SYSDATE + 60
ORDER BY data_val;
EXIT;
"@
$licResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYS" -Password $SystemPassword -SqlCommand $licSql -AsSysdba -Silent
$nrSerii = 0
$nrSeriiActive = 0
$idClient = '<nesetat>'
$expiraCurand = @()
foreach ($line in $licResult -split "`n") {
$line = $line.Trim()
if ($line -match "^SERII:(\d+)$") { $nrSerii = [int]$Matches[1] }
if ($line -match "^SERII_ACTIVE:(\d+)$") { $nrSeriiActive = [int]$Matches[1] }
if ($line -match "^IDCLIENT:(.+)$") { $idClient = $Matches[1].Trim() }
if ($line -match "^EXPIRA:(.+)\|(.+)$") { $expiraCurand += "$($Matches[1].Trim()) expira la $($Matches[2].Trim())" }
}
Add-ReportLine "Id client (AUTH_DETALII): $idClient"
Add-ReportLine "Serii de licenta: $nrSerii ($nrSeriiActive active)"
if ($nrSeriiActive -eq 0) {
Add-ReportLine ""
Add-ReportLine "[WARNING] Nicio serie activa in SYS.AUTH_SERII."
Add-ReportLine " La un client NOU e normal - licentele se adauga ulterior."
Add-ReportLine " La o MIGRARE inseamna ca pasul 09 nu a rulat sau a esuat:"
Add-ReportLine " Run.cmd 09-copy-licenses.ps1 -OldHost <gazda> -OldSysPassword <parola> -Replace"
$extraIssues += "No active license series in SYS.AUTH_SERII"
}
if ($expiraCurand.Count -gt 0) {
Add-ReportLine ""
Add-ReportLine "[NOTA] Licente care expira in urmatoarele 60 de zile:"
foreach ($e in $expiraCurand) { Add-ReportLine " - $e" }
}
# ------------------------------------------------------------------------
# Oglinda de update + IIS
# ------------------------------------------------------------------------
# Doua etaje: serverul trage modulele de la ROMFAST in ROAUPDATE (jobul
# UPDATEROA_ZILNIC), statiile le iau de la serverul clientului prin IIS.
# Daca al doilea etaj lipseste, primul merge si nu se vede nimic - statiile
# raman pe versiunile vechi la nesfarsit.
Add-ReportSection "Actualizarea aplicatiilor"
$caleRoaUpdate = $RoaUpdatePath
$siSql = @"
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF LINESIZE 300
SELECT 'ROAUPDATEPATH:' || value FROM contafin_oracle.server_info WHERE name = 'ROAUPDATEPATH';
SELECT 'UPD_URL_APP:' || value FROM contafin_oracle.server_info WHERE name = 'UPD_URL_APP';
EXIT;
"@
$siResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $siSql -Silent
$urlApp = $null
foreach ($line in $siResult -split "`n") {
$line = $line.Trim()
if ($line -match "^ROAUPDATEPATH:(.+)$") { $caleRoaUpdate = $Matches[1].Trim() }
if ($line -match "^UPD_URL_APP:(.+)$") { $urlApp = $Matches[1].Trim() }
}
Add-ReportLine "SERVER_INFO.ROAUPDATEPATH: $caleRoaUpdate"
Add-ReportLine "SERVER_INFO.UPD_URL_APP: $(if ($urlApp) { $urlApp } else { '<nesetat>' })"
if (-not $urlApp) {
$extraIssues += "SERVER_INFO.UPD_URL_APP not set (server cannot pull updates)"
}
if (-not (Test-Path $caleRoaUpdate)) {
Add-ReportLine "Directorul fizic: LIPSA"
Add-ReportLine "[WARNING] $caleRoaUpdate nu exista. Ruleaza 10-setup-roaupdate-iis.ps1."
$extraIssues += "ROAUPDATE directory missing: $caleRoaUpdate"
}
else {
$caleArhiva = Join-Path $caleRoaUpdate "_ARHIVE"
$dirModule = @(Get-ChildItem -Path $caleRoaUpdate -Directory -ErrorAction SilentlyContinue |
Where-Object { $_.Name -notlike "_*" })
$dirArhiva = @(Get-ChildItem -Path $caleArhiva -Directory -ErrorAction SilentlyContinue)
Add-ReportLine "Directorul fizic: OK"
Add-ReportLine "Directoare de modul: $($dirModule.Count)"
Add-ReportLine "Directoare _ARHIVE: $($dirArhiva.Count)"
if ($dirModule.Count -eq 0) {
Add-ReportLine "[WARNING] Nu exista directoare de modul in $caleRoaUpdate."
Add-ReportLine " Ruleaza 10-setup-roaupdate-iis.ps1."
$extraIssues += "No module directories under $caleRoaUpdate"
}
# Cate module au macar un ZIP si cat de proaspata e oglinda. Asta e
# masura practica a "aplicatiile sunt actualizate": daca nu s-a
# descarcat nimic, sau ce e acolo e vechi de luni, actualizarea nu
# merge indiferent ce spune jobul.
$moduleCuZip = 0
$celMaiNou = $null
foreach ($d in $dirArhiva) {
$zips = @(Get-ChildItem -Path $d.FullName -Filter "*.zip" -File -ErrorAction SilentlyContinue)
if ($zips.Count -gt 0) {
$moduleCuZip++
$max = ($zips | Sort-Object LastWriteTime -Descending | Select-Object -First 1).LastWriteTime
if (-not $celMaiNou -or $max -gt $celMaiNou) { $celMaiNou = $max }
}
}
Add-ReportLine "Module cu ZIP-uri in arhiva: $moduleCuZip"
if ($celMaiNou) {
$zile = [math]::Round(((Get-Date) - $celMaiNou).TotalDays)
Add-ReportLine "Cel mai recent ZIP: $($celMaiNou.ToString('yyyy-MM-dd')) (acum $zile zile)"
if ($zile -gt 30) {
Add-ReportLine "[NOTA] Oglinda nu s-a mai improspatat de peste 30 de zile."
Add-ReportLine " Verifica jobul UPDATEROA_ZILNIC si accesul la $urlApp."
}
}
else {
Add-ReportLine "Cel mai recent ZIP: niciunul"
Add-ReportLine "[NOTA] Oglinda e goala. La o instalare noua e normal - se umple"
Add-ReportLine " la prima rulare a jobului UPDATEROA_ZILNIC."
}
}
# Publicarea in IIS
$urlLocal = "http://localhost/roaupdate/"
try {
$respIis = Invoke-WebRequest -Uri $urlLocal -UseBasicParsing -TimeoutSec 10
Add-ReportLine "IIS $($urlLocal): OK ($($respIis.StatusCode))"
}
catch {
Add-ReportLine "IIS $($urlLocal): NU RASPUNDE"
Add-ReportLine "[WARNING] Statiile de lucru nu pot lua actualizari de la serverul asta."
Add-ReportLine " Ruleaza 10-setup-roaupdate-iis.ps1."
$extraIssues += "IIS mirror at $urlLocal not responding"
}
# Joburile de actualizare
$jobSql = @"
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF LINESIZE 300
SELECT 'JOB:' || job_name || '|' || enabled || '|' || state ||
'|' || NVL(TO_CHAR(last_start_date, 'YYYY-MM-DD HH24:MI'), 'niciodata')
FROM dba_scheduler_jobs
WHERE owner = 'CONTAFIN_ORACLE'
AND job_name IN ('UPDATEROA_ZILNIC', 'UPDATERTVAI_ZILNIC')
ORDER BY job_name;
EXIT;
"@
$jobResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYS" -Password $SystemPassword -SqlCommand $jobSql -AsSysdba -Silent
Add-ReportLine ""
$joburiGasite = 0
foreach ($line in $jobResult -split "`n") {
if ($line.Trim() -match "^JOB:([^|]+)\|([^|]+)\|([^|]+)\|(.+)$") {
$joburiGasite++
Add-ReportLine ("{0,-20} activat={1,-6} stare={2,-10} ultima rulare: {3}" -f `
$Matches[1].Trim(), $Matches[2].Trim(), $Matches[3].Trim(), $Matches[4].Trim())
}
}
if ($joburiGasite -eq 0) {
Add-ReportLine "Joburile de actualizare: LIPSA"
Add-ReportLine "[WARNING] Ruleaza 08-post-install-config.ps1."
$extraIssues += "Update scheduler jobs missing"
}
# ------------------------------------------------------------------------
# Exportul zilnic
# ------------------------------------------------------------------------
Add-ReportSection "Export zilnic (EXPORT_ORADMP)"
$expSql = @"
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF LINESIZE 300
SELECT 'BACKUPDIR:' || directory_path FROM dba_directories WHERE directory_name = 'BACKUP_ORACLE';
EXIT;
"@
$expResult = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYS" -Password $SystemPassword -SqlCommand $expSql -AsSysdba -Silent
$caleExport = $ExportPath
if ($expResult -match "BACKUPDIR:(.+)") { $caleExport = $Matches[1].Trim() }
Add-ReportLine "DIRECTORY BACKUP_ORACLE: $(if ($expResult -match 'BACKUPDIR:') { $caleExport } else { 'LIPSA' })"
if ($expResult -notmatch "BACKUPDIR:") {
$extraIssues += "Oracle directory BACKUP_ORACLE missing"
}
if (-not (Test-Path $caleExport)) {
Add-ReportLine "Directorul fizic: LIPSA ($caleExport)"
Add-ReportLine "[WARNING] Ruleaza 11-setup-backup-export.ps1."
$extraIssues += "Export directory missing: $caleExport"
}
else {
Add-ReportLine "Directorul fizic: OK"
foreach ($f in @('backupora.exe', 'setari.ini', 'schema.txt')) {
$cale = Join-Path $caleExport $f
if (Test-Path $cale) {
if ($f -eq 'schema.txt') {
$nrScheme = @(Get-Content $cale | Where-Object { $_.Trim() -ne '' }).Count
Add-ReportLine ("{0,-28} OK ({1} scheme)" -f "${f}:", $nrScheme)
} else {
Add-ReportLine ("{0,-28} OK" -f "${f}:")
}
}
else {
Add-ReportLine ("{0,-28} LIPSA" -f "${f}:")
$extraIssues += "$f missing from $caleExport"
}
}
$dumpuri = @(Get-ChildItem -Path $caleExport -Filter "*.dmp" -File -ErrorAction SilentlyContinue)
if ($dumpuri.Count -gt 0) {
$celMaiNouDmp = ($dumpuri | Sort-Object LastWriteTime -Descending | Select-Object -First 1)
$zileDmp = [math]::Round(((Get-Date) - $celMaiNouDmp.LastWriteTime).TotalDays)
Add-ReportLine "Dump-uri prezente: $($dumpuri.Count), cel mai recent acum $zileDmp zile"
if ($zileDmp -gt 2) {
Add-ReportLine "[NOTA] Ultimul export e vechi de $zileDmp zile. Verifica task-ul."
}
}
else {
Add-ReportLine "Dump-uri prezente: niciunul (exportul nu a rulat inca)"
}
}
# Task-ul din Windows
$task = $null
try { $task = Get-ScheduledTask -TaskName "ROA Export Oracle" -ErrorAction Stop } catch { }
if ($task) {
$info = Get-ScheduledTaskInfo -TaskName "ROA Export Oracle"
$ultima = if ($info.LastRunTime -and $info.LastRunTime.Year -gt 1999) {
$info.LastRunTime.ToString('yyyy-MM-dd HH:mm')
} else { 'niciodata' }
Add-ReportLine "Task 'ROA Export Oracle': $($task.State), ultima rulare: $ultima (cod $($info.LastTaskResult))"
}
else {
Add-ReportLine "Task 'ROA Export Oracle': LIPSA"
Add-ReportLine "[WARNING] Nu exista task zilnic de export. Ruleaza 11-setup-backup-export.ps1."
$extraIssues += "Scheduled task 'ROA Export Oracle' missing"
}
# ------------------------------------------------------------------------
# Conectivitate pentru clientii vechi (Instant Client 10/11)
# ------------------------------------------------------------------------
# Sectiunea asta exista pentru ca toate esecurile de aici arata, la prima
# vedere, ca altceva: ORA-01017 pare parola gresita, ORA-12514 pare baza
# oprita. Vezi docs/lectii-conectare-client-oracle.md.
Add-ReportSection "Conectivitate client vechi (Instant Client)"
# --- unde se citeste, de fapt, sqlnet.ora
$oraBaseRoot = Split-Path (Split-Path (Split-Path $oraHome -Parent) -Parent) -Parent
$homesRoot = Join-Path $oraBaseRoot "product\21c\homes"
$adminOh = $null
if (Test-Path $homesRoot) {
$bh = Get-ChildItem -Path $homesRoot -Directory -ErrorAction SilentlyContinue |
Where-Object { $_.Name -match "OraDB" } | Select-Object -First 1
if ($bh) { $adminOh = Join-Path $bh.FullName "network\admin" }
}
if (-not $adminOh) { $adminOh = Join-Path $oraHome "network\admin" }
$sqlnetOh = Join-Path $adminOh "sqlnet.ora"
if (Test-Path $sqlnetOh) {
$continutOh = Get-Content $sqlnetOh -Raw
$verOh = if ($continutOh -match '(?im)^\s*SQLNET\.ALLOWED_LOGON_VERSION_SERVER\s*=\s*(\d+)') { $Matches[1] } else { $null }
Add-ReportLine "sqlnet.ora (Oracle Home): $sqlnetOh"
if ($verOh) {
Add-ReportLine " ALLOWED_LOGON_VERSION_SERVER = $verOh"
if ([int]$verOh -gt 11) {
Add-ReportLine "[WARNING] Valoare peste 11: clientii 10/11 vor primi ORA-28040."
$extraIssues += "ALLOWED_LOGON_VERSION_SERVER=$verOh in $sqlnetOh"
}
}
else {
Add-ReportLine "[WARNING] Nu contine ALLOWED_LOGON_VERSION_SERVER."
$extraIssues += "ALLOWED_LOGON_VERSION_SERVER missing from $sqlnetOh"
}
}
else {
Add-ReportLine "sqlnet.ora (Oracle Home): LIPSA ($sqlnetOh)"
$extraIssues += "sqlnet.ora missing from $adminOh"
}
# --- TNS_ADMIN de masina: castiga in fata Oracle Home, si pentru clienti,
# si pentru instanta - dar abia de la urmatoarea pornire a serviciului.
$tnsAdminM = [Environment]::GetEnvironmentVariable('TNS_ADMIN', 'Machine')
Add-ReportLine ""
if ($tnsAdminM) {
$tnsAdminM = [IO.Path]::GetFullPath($tnsAdminM.TrimEnd('\'))
Add-ReportLine "TNS_ADMIN (masina): $tnsAdminM"
if ($tnsAdminM -ne [IO.Path]::GetFullPath($adminOh.TrimEnd('\'))) {
$sqlnetTns = Join-Path $tnsAdminM "sqlnet.ora"
if (Test-Path $sqlnetTns) {
Add-ReportLine " sqlnet.ora acolo: OK"
}
else {
Add-ReportLine " sqlnet.ora acolo: LIPSA"
Add-ReportLine "[WARNING] Instanta citeste TNS_ADMIN-ul de masina de la urmatorul restart."
Add-ReportLine " Fara sqlnet.ora acolo, dupa primul reboot toti clientii vechi"
Add-ReportLine " iau ORA-28040. Ruleaza din nou 01-setup-database.ps1."
$extraIssues += "sqlnet.ora missing from TNS_ADMIN ($tnsAdminM)"
}
$tnsFile = Join-Path $tnsAdminM "tnsnames.ora"
if (Test-Path $tnsFile) {
$tnsTxt = Get-Content $tnsFile -Raw
$areRoa = $tnsTxt -match '(?im)^\s*ROA\s*='
$areLsn = $tnsTxt -match '(?im)^\s*LISTENER_XE\s*='
$areSablon = $tnsTxt -match 'SERVER_ROA'
Add-ReportLine (" tnsnames.ora acolo: alias ROA={0}, LISTENER_XE={1}" -f `
$(if ($areRoa) { 'da' } else { 'NU' }), $(if ($areLsn) { 'da' } else { 'NU' }))
if ($areSablon) {
Add-ReportLine "[WARNING] tnsnames.ora e inca sablonul (HOST=SERVER_ROA). Statiile nu se pot conecta."
$extraIssues += "tnsnames.ora still template (SERVER_ROA) in $tnsAdminM"
}
elseif (-not $areRoa) {
Add-ReportLine "[WARNING] Lipseste aliasul ROA. ROAClient nu stie unde e baza."
$extraIssues += "TNS alias ROA missing from $tnsFile"
}
}
else {
Add-ReportLine " tnsnames.ora acolo: LIPSA"
$extraIssues += "tnsnames.ora missing from TNS_ADMIN ($tnsAdminM)"
}
}
else {
Add-ReportLine " (coincide cu Oracle Home - nimic de dublat)"
}
}
else {
Add-ReportLine "TNS_ADMIN (masina): nesetat (se citeste din Oracle Home)"
Add-ReportLine "[NOTA] Daca se instaleaza ROAClient dupa asta, TNS_ADMIN va aparea si"
Add-ReportLine " va trebui rulat din nou 01-setup-database.ps1."
}
# --- LOCAL_LISTENER: alias sau adresa literala
$llSql = @"
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF LINESIZE 300
SELECT 'LL:' || value FROM v`$parameter WHERE name = 'local_listener';
EXIT;
"@
$llOut = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $llSql -Silent
Add-ReportLine ""
if ($llOut -match 'LL:(.*)') {
$llVal = $Matches[1].Trim()
Add-ReportLine "LOCAL_LISTENER: $(if ($llVal) { $llVal } else { '(gol - implicit)' })"
if ($llVal -and $llVal -notmatch '\(ADDRESS') {
Add-ReportLine "[WARNING] LOCAL_LISTENER e un alias ($llVal), deci depinde de tnsnames.ora."
Add-ReportLine " Daca aliasul nu se rezolva la urmatoarea pornire a instantei, aceasta"
Add-ReportLine " nu se mai inregistreaza la listener si toti clientii iau ORA-12514."
Add-ReportLine " Ruleaza din nou 01-setup-database.ps1 ca sa il fixeze pe adresa literala."
$extraIssues += "LOCAL_LISTENER is an alias ($llVal), not a literal address"
}
}
# --- verificatoare de parola: fara 10G, clientii vechi iau ORA-01017
# SYSTEM lipseste intentionat din lista: fiind utilizator comun, randul lui
# din DBA_USERS al PDB-ului ramane cu vechile PASSWORD_VERSIONS chiar dupa
# ce parola a fost rescrisa din root, iar autentificarea foloseste oricum
# definitia din root. Verificarea care conteaza pentru el e proba de
# conectare de mai jos, nu coloana asta.
$pvSql = @"
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF LINESIZE 300
SELECT 'PV:' || username || '|' || password_versions
FROM dba_users
WHERE username = 'CONTAFIN_ORACLE'
OR username IN (SELECT UPPER(schema) FROM CONTAFIN_ORACLE.NOM_FIRME
WHERE sters = 0 AND schema IS NOT NULL)
ORDER BY username;
EXIT;
"@
$pvOut = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $pvSql -Silent
Add-ReportLine ""
Add-ReportLine "Verificatoare de parola (10G e obligatoriu pentru Instant Client 10/11):"
$fara10G = @()
foreach ($line in $pvOut -split "`n") {
if ($line -match '^PV:([^|]+)\|(.*)$') {
$u = $Matches[1].Trim(); $v = $Matches[2].Trim()
$are = $v -match '10G'
Add-ReportLine (" {0,-24} {1,-16} {2}" -f $u, $v, $(if ($are) { 'OK' } else { 'FARA 10G' }))
if (-not $are) { $fara10G += $u }
}
}
if ($fara10G.Count -gt 0) {
Add-ReportLine "[WARNING] Conturi fara verificator 10G: $($fara10G -join ', ')"
Add-ReportLine " Din Instant Client 10/11 vor da ORA-01017, care pare parola gresita."
Add-ReportLine " Se repara rescriind aceeasi parola: ALTER USER <nume> IDENTIFIED BY <parola>;"
$extraIssues += "Accounts without 10G password verifier: $($fara10G -join ', ')"
}
# --- proba adevarata: o conectare cu Instant Client-ul vechi
Add-ReportLine ""
$icDir = $InstantClientDir
if (-not $icDir -and $tnsAdminM -and (Test-Path (Join-Path $tnsAdminM "sqlplus.exe"))) {
$icDir = $tnsAdminM
}
if (-not $icDir) {
foreach ($radacina in @('D:\ROA', 'C:\ROA', 'D:\', 'C:\')) {
if (-not (Test-Path $radacina)) { continue }
$g = Get-ChildItem -Path $radacina -Directory -Filter 'instantclient*' -ErrorAction SilentlyContinue |
Where-Object { Test-Path (Join-Path $_.FullName 'sqlplus.exe') } | Select-Object -First 1
if ($g) { $icDir = $g.FullName; break }
}
}
if (-not $icDir) {
Add-ReportLine "Proba de conectare: nu am gasit Instant Client pe masina (sarita)"
Add-ReportLine "[NOTA] Fara ROAClient instalat aici, proba se face de pe o statie."
}
else {
$icSqlplus = Join-Path $icDir "sqlplus.exe"
Add-ReportLine "Instant Client: $icSqlplus"
$probaSql = Join-Path $env:TEMP "roa_proba_client.sql"
Set-Content -Path $probaSql -Encoding ASCII -Value @(
'SET FEEDBACK OFF PAGESIZE 0 LINESIZE 200',
"SELECT 'PROBA_OK ' || USER FROM DUAL;",
'EXIT')
$ipLan = Get-ServerLanIPv4
$tinte = @()
$areAliasRoa = $tnsAdminM -and (Test-Path (Join-Path $tnsAdminM 'tnsnames.ora')) -and
((Get-Content (Join-Path $tnsAdminM 'tnsnames.ora') -Raw) -match '(?im)^\s*ROA\s*=')
if ($areAliasRoa) {
$tinte += @{ Nume = 'CONTAFIN_ORACLE / alias ROA'; Sir = "CONTAFIN_ORACLE/$ContafinPassword@ROA" }
}
if ($ipLan) {
$tinte += @{ Nume = "CONTAFIN_ORACLE / $ipLan"; Sir = "CONTAFIN_ORACLE/$ContafinPassword@//${ipLan}:1521/$ServiceName" }
}
if ($tinte.Count -eq 0) {
$tinte += @{ Nume = 'CONTAFIN_ORACLE / localhost'; Sir = "CONTAFIN_ORACLE/$ContafinPassword@//localhost:1521/$ServiceName" }
}
# SYSTEM: singura verificare valida a verificatorului lui de parola.
$gazdaSys = if ($ipLan) { $ipLan } else { 'localhost' }
$tinte += @{ Nume = "SYSTEM / $gazdaSys"; Sir = "SYSTEM/$SystemPassword@//${gazdaSys}:1521/$ServiceName" }
foreach ($t in $tinte) {
$iesire = (& $icSqlplus -S -L $t.Sir "@$probaSql" 2>&1 | Where-Object { $_ -match '\S' }) -join ' '
if ($iesire -match 'PROBA_OK') {
Add-ReportLine (" {0,-32} OK" -f $t.Nume)
}
else {
$eroare = if ($iesire -match '(ORA-\d+|TNS-\d+|SP2-\d+)') { $Matches[1] } else { 'esec' }
Add-ReportLine (" {0,-32} ESEC ({1})" -f $t.Nume, $eroare)
Add-ReportLine " $iesire"
switch ($eroare) {
'ORA-01017' { Add-ReportLine " Verifica intai verificatorul 10G, nu parola: ALTER USER ... IDENTIFIED BY <aceeasi parola>;" }
'ORA-28040' { Add-ReportLine " sqlnet.ora nu e citit de unde crezi. Verifica TNS_ADMIN de mai sus." }
'ORA-12514' { Add-ReportLine " Instanta nu e inregistrata la listener. Verifica LOCAL_LISTENER de mai sus." }
}
$extraIssues += "Instant Client connect test failed via $($t.Nume): $eroare"
}
}
Remove-Item $probaSql -Force -ErrorAction SilentlyContinue
}
# 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 ($extraIssues.Count -gt 0) {
$issues += $extraIssues
}
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
}