feat(oracle): instalare ROA in doua faze, licente, IIS si export zilnic

Adauga FAZA1.cmd/FAZA2.cmd, care despart migrarea in partea care se poate
face in timpul programului (contafin, obiecte SYS, sinonime, licente, IIS)
si partea de seara (schemele de firma). Scripturi noi: 09 pentru licentele
din SYS.AUTH_SERII/AUTH_DETALII, 10 pentru publicarea D:\ROAUPDATE in IIS,
11 pentru exportul zilnic cu backupora.exe, drop-contafin pentru reimport.

backupora.exe si sabloanele sale intra in repo ca sa fie kitul autonom.
Pasul 07 primeste verificarile corespunzatoare pentru licente, IIS si task.

Nerulat inca pe o baza reala - vezi docs/handoff_instalare-doua-faze.md.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SzF1hf4aFS1tmJWpPMiwGp
This commit is contained in:
Marius
2026-08-25 20:57:23 +03:00
parent 7fce925349
commit 5a746990ce
18 changed files with 3446 additions and 854 deletions

View File

@@ -59,7 +59,15 @@ param(
[switch]$Detailed,
[Parameter(Mandatory = $false)]
[string]$OutputFile
[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"
)
$ErrorActionPreference = 'Stop'
@@ -569,6 +577,264 @@ EXIT;
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"
}
# Final Summary
Add-ReportSection "Verification Summary"

View File

@@ -0,0 +1,387 @@
#Requires -Version 5.1
<#
.SYNOPSIS
Copiaza licentele ROA (SYS.AUTH_SERII + SYS.AUTH_DETALII) de pe serverul
vechi pe cel nou.
.DESCRIPTION
Fara acest pas, un client migrat ramane fara licente: sys-objects.sql
creeaza tabelele goale, iar 08-post-install-config.ps1 scrie doar
AUTH_DETALII (Customer ID). Seriile propriu-zise din AUTH_SERII, pe care
AUTH_PACK le decripteaza ca sa afle ce module si cate firme sunt permise,
nu se creeaza nicaieri.
Doua moduri:
1. Prin retea. Se conecteaza cu SQL*Plus la serverul VECHI (parametrii
-OldHost / -OldPort / -OldService / -OldSysPassword), ruleaza
sql\export-licente.sql si captureaza INSERT-urile generate.
Serverul vechi nu e modificat - se face doar SELECT.
2. Din fisier (-FromFile). Cand serverul vechi nu e accesibil din cel
nou, rulezi manual pe el:
sqlplus -S "sys/PAROLA@GAZDA:1521/SERVICIU as sysdba" @export-licente.sql > licente.sql
si aduci licente.sql la client.
Inainte de a scrie ceva, salveaza starea curenta a licentelor de pe
serverul NOU in logs\licente-backup-server-nou_<data>.sql, in acelasi
format. Daca ceva merge prost, ala e drumul inapoi.
Dupa import, recreeaza SYS.SEQ_AUTH_SERII peste MAX(ID_SERIE)+1, altfel
prima licenta adaugata ulterior din aplicatie ar incalca PK_AUTH_SERII.
.PARAMETER OldHost
Gazda serverului VECHI. Prezenta ei porneste modul prin retea.
.PARAMETER OldPort
Portul listener-ului de pe serverul vechi. Implicit 1521.
.PARAMETER OldService
Numele serviciului de pe serverul vechi (ex. XE, ORCL, XEPDB1).
Implicit XE - bazele vechi de client sunt de regula non-CDB.
.PARAMETER OldSysPassword
Parola SYS de pe serverul vechi. Obligatorie in modul prin retea.
.PARAMETER FromFile
Fisierul .sql produs de export-licente.sql. Ocoleste conexiunea la
serverul vechi.
.PARAMETER OracleHome
Oracle home local. Autodetectat daca lipseste.
.PARAMETER ServiceName
Serviciul bazei NOI. Implicit XEPDB1.
.PARAMETER SystemPassword
Parola SYS de pe serverul NOU. Implicit romfastsoft.
.PARAMETER Replace
Sterge licentele existente de pe serverul nou inainte de import.
Fara el, scriptul refuza sa scrie peste licente deja prezente.
.PARAMETER ExportOnly
Doar scoate licentele de pe serverul vechi intr-un fisier, fara sa
importe nimic. Util cand pregatesti kitul de pe alta statie.
.EXAMPLE
.\09-copy-licenses.ps1 -OldHost 192.168.1.10 -OldSysPassword "parolaveche"
Ia licentele prin retea si le importa.
.EXAMPLE
.\09-copy-licenses.ps1 -OldHost 192.168.1.10 -OldService ORCL -OldSysPassword "x" -ExportOnly
Doar salveaza licentele in logs\, pentru import ulterior.
.EXAMPLE
.\09-copy-licenses.ps1 -FromFile "C:\kit\licente.sql" -Replace
Importa dintr-un fisier adus manual, peste licentele existente.
.NOTES
File Name : 09-copy-licenses.ps1
Prerequisite : 02-create-sys-objects.ps1 (tabelele AUTH_* trebuie sa existe)
Copyright 2026 : ROMFAST
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[string]$OldHost,
[Parameter(Mandatory = $false)]
[int]$OldPort = 1521,
[Parameter(Mandatory = $false)]
[string]$OldService = "XE",
[Parameter(Mandatory = $false)]
[string]$OldSysPassword,
[Parameter(Mandatory = $false)]
[string]$FromFile,
[Parameter(Mandatory = $false)]
[string]$OracleHome,
[Parameter(Mandatory = $false)]
[string]$ServiceName = "XEPDB1",
[Parameter(Mandatory = $false)]
[string]$SystemPassword = "romfastsoft",
[Parameter(Mandatory = $false)]
[switch]$Replace,
[Parameter(Mandatory = $false)]
[switch]$ExportOnly
)
$ErrorActionPreference = "Stop"
. (Join-Path $PSScriptRoot "lib\logging-functions.ps1")
. (Join-Path $PSScriptRoot "lib\oracle-functions.ps1")
$configFile = Join-Path $PSScriptRoot "..\config.ps1"
if (Test-Path $configFile) {
. $configFile
if (-not $PSBoundParameters.ContainsKey('OracleHome') -and $Config.OracleHome) { $OracleHome = $Config.OracleHome }
if (-not $PSBoundParameters.ContainsKey('ServiceName') -and $Config.ServiceName) { $ServiceName = $Config.ServiceName }
if (-not $PSBoundParameters.ContainsKey('SystemPassword') -and $Config.SystemPassword) { $SystemPassword = $Config.SystemPassword }
}
$stamp = Get-Date -Format 'yyyyMMdd_HHmmss'
$logDir = Join-Path $PSScriptRoot "..\logs"
if (-not (Test-Path $logDir)) { New-Item -ItemType Directory -Path $logDir -Force | Out-Null }
Initialize-LogFile -LogPath (Join-Path $logDir "09-copy-licenses_$stamp.log") -ScriptName "09-copy-licenses.ps1"
$MarkerStart = '-- ROA-LICENTE-EXPORT v1'
$MarkerEnd = '-- ROA-LICENTE-SFARSIT'
function Test-LicenseDump {
param([string]$Path)
if (-not (Test-Path $Path)) { throw "Fisierul de licente nu exista: $Path" }
$text = Get-Content -Path $Path -Raw
if ($null -eq $text) { $text = "" }
if ($text -notmatch [regex]::Escape($MarkerStart)) {
throw "Fisierul $Path nu contine marcajul '$MarkerStart'. Nu e o iesire valida a lui export-licente.sql."
}
if ($text -notmatch [regex]::Escape($MarkerEnd)) {
throw "Fisierul $Path nu contine marcajul de final '$MarkerEnd'. Exportul s-a intrerupt la mijloc - nu il import."
}
if ($text -match 'ORA-\d{5}:|SP2-\d{4}:') {
throw "Fisierul $Path contine erori Oracle. Corecteaza exportul inainte de import."
}
$nextval = 1
if ($text -match '-- ROA-LICENTE-NEXTVAL=(\d+)') { $nextval = [int]$Matches[1] }
return [PSCustomObject]@{
Serii = ([regex]::Matches($text, 'INSERT INTO SYS\.AUTH_SERII')).Count
Detalii = ([regex]::Matches($text, 'INSERT INTO SYS\.AUTH_DETALII')).Count
NextVal = $nextval
}
}
try {
Write-LogSection "Copiere licente ROA (AUTH_SERII + AUTH_DETALII)"
$oraHome = Get-OracleHome -OracleHome $OracleHome
Write-LogSuccess "Oracle Home: $oraHome"
$exportSql = Join-Path $PSScriptRoot "..\sql\export-licente.sql"
if (-not (Test-Path $exportSql)) {
throw "Lipseste sql\export-licente.sql din kit."
}
# ------------------------------------------------------------------
# Sursa licentelor: retea sau fisier
# ------------------------------------------------------------------
$dumpFile = $null
if ($FromFile) {
Write-LogSection "Sursa: fisier"
$dumpFile = (Resolve-Path $FromFile).Path
Write-Log "Fisier: $dumpFile"
}
elseif ($OldHost) {
Write-LogSection "Sursa: serverul vechi, prin retea"
if (-not $OldSysPassword) {
throw "-OldSysPassword e obligatoriu cand dai -OldHost."
}
Write-Log "Server vechi: ${OldHost}:${OldPort}/${OldService}"
Write-Log "Se testeaza conexiunea..."
$reachable = $false
try {
$reachable = Test-OracleConnection -OracleHome $oraHome -ServiceName $OldService `
-DbHost $OldHost -Port $OldPort -Password $OldSysPassword
}
catch {
Write-LogDebug $_.Exception.Message
}
if (-not $reachable) {
Write-LogError "Nu ma pot conecta la ${OldHost}:${OldPort}/${OldService}."
Write-LogError "Verifica: listener-ul pornit, firewall-ul, numele serviciului, parola SYS."
Write-LogError ""
Write-LogError "Varianta manuala - ruleaza PE SERVERUL VECHI:"
Write-LogError " sqlplus -S ""sys/PAROLA@localhost:$OldPort/$OldService as sysdba"" @export-licente.sql > licente.sql"
Write-LogError "apoi adu licente.sql aici si ruleaza:"
Write-LogError " .\09-copy-licenses.ps1 -FromFile licente.sql -Replace"
throw "Serverul vechi nu e accesibil."
}
Write-LogSuccess "Conexiune la serverul vechi: OK"
Write-Log "Se extrag licentele (doar SELECT, serverul vechi nu se modifica)..."
$raw = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $OldService `
-DbHost $OldHost -Port $OldPort `
-Username "sys" -Password $OldSysPassword -AsSysdba `
-SqlFile $exportSql -Silent
$dumpFile = Join-Path $logDir "licente-de-pe-server-vechi_$stamp.sql"
Set-Content -Path $dumpFile -Value $raw -Encoding ASCII
Write-LogSuccess "Salvat: $dumpFile"
}
else {
throw "Da fie -OldHost (+ -OldSysPassword), fie -FromFile. Vezi 'Get-Help .\09-copy-licenses.ps1 -Full'."
}
$info = Test-LicenseDump -Path $dumpFile
Write-LogSuccess "Export valid: $($info.Serii) serii, $($info.Detalii) inregistrari AUTH_DETALII"
Write-Log "SEQ_AUTH_SERII va porni de la $($info.NextVal)"
if ($info.Serii -eq 0) {
Write-LogWarning "Serverul vechi nu are nicio serie in AUTH_SERII."
Write-LogWarning "Ori clientul chiar nu are licente, ori te-ai conectat la baza gresita."
}
if ($ExportOnly) {
Write-LogSection "Gata (ExportOnly)"
Write-Log "Fisierul de licente: $dumpFile"
Write-Log "Il importi mai tarziu cu:"
Write-Log " .\09-copy-licenses.ps1 -FromFile ""$dumpFile"" -Replace"
Close-LogFile
exit 0
}
# ------------------------------------------------------------------
# Serverul nou: verificari si backup
# ------------------------------------------------------------------
Write-LogSection "Serverul nou"
if (-not (Test-OracleConnection -OracleHome $oraHome -ServiceName $ServiceName -Password $SystemPassword)) {
throw "Nu ma pot conecta la baza noua ($ServiceName)."
}
Write-LogSuccess "Conexiune: OK"
$check = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "sys" -Password $SystemPassword -AsSysdba -Silent -SqlCommand @"
SET PAGESIZE 0 FEEDBACK OFF HEADING OFF VERIFY OFF
SELECT 'TABELE=' || COUNT(*) FROM dba_tables
WHERE owner = 'SYS' AND table_name IN ('AUTH_SERII','AUTH_DETALII');
SELECT 'SERII=' || COUNT(*) FROM sys.auth_serii;
EXIT
"@
if ($check -notmatch 'TABELE=2') {
throw "SYS.AUTH_SERII / SYS.AUTH_DETALII nu exista pe serverul nou. Ruleaza intai 02-create-sys-objects.ps1."
}
$seriiExistente = 0
if ($check -match 'SERII=(\d+)') { $seriiExistente = [int]$Matches[1] }
Write-Log "Licente deja prezente pe serverul nou: $seriiExistente serii"
if ($seriiExistente -gt 0 -and -not $Replace) {
Write-LogError "Serverul nou are deja $seriiExistente serii de licenta."
Write-LogError "Ruleaza din nou cu -Replace daca vrei sa le inlocuiesti cu cele de pe serverul vechi."
throw "Import oprit ca sa nu dublez licentele."
}
# Backup in acelasi format, ca sa poata fi re-importat cu -FromFile.
$backupFile = Join-Path $logDir "licente-backup-server-nou_$stamp.sql"
Write-Log "Salvez licentele curente in $backupFile ..."
$backupRaw = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "sys" -Password $SystemPassword -AsSysdba `
-SqlFile $exportSql -Silent
Set-Content -Path $backupFile -Value $backupRaw -Encoding ASCII
Write-LogSuccess "Backup salvat."
Write-Log "Drumul inapoi: .\09-copy-licenses.ps1 -FromFile ""$backupFile"" -Replace"
# ------------------------------------------------------------------
# Import
# ------------------------------------------------------------------
Write-LogSection "Import licente"
$inserts = @(Get-Content -Path $dumpFile | Where-Object { $_ -match '^\s*INSERT INTO SYS\.AUTH_' })
$seqBlock = @"
DECLARE
v_next NUMBER := $($info.NextVal);
BEGIN
BEGIN
EXECUTE IMMEDIATE 'DROP SEQUENCE SYS.SEQ_AUTH_SERII';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -2289 THEN RAISE; END IF; -- -2289 = secventa nu exista
END;
EXECUTE IMMEDIATE 'CREATE SEQUENCE SYS.SEQ_AUTH_SERII ' ||
'MINVALUE 1 MAXVALUE 99999999999999999 INCREMENT BY 1 ' ||
'START WITH ' || v_next || ' NOCACHE NOORDER NOCYCLE';
DBMS_OUTPUT.PUT_LINE(' SEQ_AUTH_SERII recreata, START WITH ' || v_next);
END;
/
"@
$importLines = @()
$importLines += "SET FEEDBACK ON SERVEROUTPUT ON VERIFY OFF"
$importLines += "WHENEVER SQLERROR EXIT FAILURE ROLLBACK"
$importLines += "DELETE FROM sys.auth_serii;"
$importLines += "DELETE FROM sys.auth_detalii;"
$importLines += $inserts
$importLines += "COMMIT;"
$importLines += $seqBlock
$importLines += "SET PAGESIZE 0 HEADING OFF FEEDBACK OFF"
$importLines += "SELECT 'IMPORTAT_SERII=' || COUNT(*) FROM sys.auth_serii;"
$importLines += "SELECT 'IMPORTAT_DETALII=' || COUNT(*) FROM sys.auth_detalii;"
$importLines += "EXIT"
$importFile = Join-Path $logDir "licente-import_$stamp.sql"
Set-Content -Path $importFile -Value ($importLines -join "`r`n") -Encoding ASCII
$result = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "sys" -Password $SystemPassword -AsSysdba -SqlFile $importFile
Write-LogDebug $result
if ($result -match 'ORA-\d{5}:') {
Write-LogError "Importul a returnat erori Oracle. Vezi $importFile."
throw "Import esuat - tranzactia a fost anulata (ROLLBACK)."
}
$importateSerii = -1
if ($result -match 'IMPORTAT_SERII=(\d+)') { $importateSerii = [int]$Matches[1] }
if ($importateSerii -ne $info.Serii) {
Write-LogError "Am importat $importateSerii serii, dar exportul avea $($info.Serii)."
throw "Numarul de licente nu se potriveste."
}
Write-LogSuccess "$importateSerii serii de licenta importate"
# ------------------------------------------------------------------
# Verificare finala: ce vede AUTH_PACK prin VAUTH_SERII
# ------------------------------------------------------------------
Write-LogSection "Licente active"
$lista = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "sys" -Password $SystemPassword -AsSysdba -Silent -SqlCommand @"
SET PAGESIZE 200 LINESIZE 200 FEEDBACK OFF VERIFY OFF
COLUMN nume FORMAT A25
SELECT nume, nr_util, TO_CHAR(data_val,'YYYY-MM-DD') AS data_val
FROM sys.vauth_serii
ORDER BY nume;
EXIT
"@
Write-Host $lista
Write-LogSection "Gata"
Write-Log "Backup inainte de import: $backupFile"
Write-Log "Sursa importata: $dumpFile"
Close-LogFile
exit 0
}
catch {
Write-LogError $_.Exception.Message
Write-LogDebug $_.ScriptStackTrace
Close-LogFile
exit 1
}

View File

@@ -0,0 +1,411 @@
#Requires -Version 5.1
<#
.SYNOPSIS
Pregateste D:\ROAUPDATE ca oglinda locala de update si o publica in IIS
la http://localhost/roaupdate/.
.DESCRIPTION
Mecanismul de actualizare ROA are doua etaje:
1. Serverul clientului trage modulele de la ROMFAST. Jobul
CONTAFIN_ORACLE.UPDATEROA_ZILNIC apeleaza PACK_UPDATE.UPDATEROA,
care descarca de la SERVER_INFO.UPD_URL_APP (https://update.romfast.ro/roa/)
in D:\ROAUPDATE.
2. Statiile de lucru iau modulele de la serverul clientului, prin HTTP.
Pentru asta D:\ROAUPDATE trebuie publicat in IIS. Fara pasul asta,
etajul 1 functioneaza si nu se vede nimic - statiile raman pe
versiunile vechi la nesfarsit.
Ce face scriptul:
- creeaza D:\ROAUPDATE, _ARHIVE\<MODUL>, <MODUL> si _UPDATE;
08-post-install-config.ps1 face doar _ARHIVE\<MODUL> (pentru
obiectele Oracle DIRECTORY), aici se adauga directoarele de modul de
la nivelul de sus, in care ajung binarele curente;
- instaleaza rolul IIS daca lipseste (Windows Server sau Windows Pro);
- creeaza aplicatia /roaupdate in Default Web Site, catre D:\ROAUPDATE;
- activeaza directory browsing si se asigura ca .zip si .xml se servesc;
- da drept de citire lui IIS_IUSRS pe D:\ROAUPDATE;
- verifica la final ca http://localhost/roaupdate/ raspunde 200.
.PARAMETER RoaUpdatePath
Radacina oglinzii de update. Implicit D:\ROAUPDATE.
Trebuie sa fie aceeasi valoare ca la 08-post-install-config.ps1, altfel
obiectele Oracle DIRECTORY arata in alta parte decat IIS.
.PARAMETER SiteName
Site-ul IIS in care se creeaza aplicatia. Implicit "Default Web Site".
.PARAMETER AppName
Numele aplicatiei (segmentul din URL). Implicit "roaupdate".
.PARAMETER SkipIisInstall
Nu instala rolul IIS. Daca lipseste, scriptul se opreste cu instructiuni.
Foloseste-l pe servere unde nu ai voie sa adaugi roluri.
.PARAMETER SkipDirectories
Nu crea directoarele fizice, doar configureaza IIS.
.PARAMETER Modules
Lista modulelor pentru care se creeaza directoare. Implicit lista
standard ROA (aceeasi ca in 08-post-install-config.ps1).
.EXAMPLE
.\10-setup-roaupdate-iis.ps1
Varianta obisnuita: D:\ROAUPDATE publicat la http://localhost/roaupdate/.
.EXAMPLE
.\10-setup-roaupdate-iis.ps1 -RoaUpdatePath "E:\ROAUPDATE" -SkipIisInstall
Alta litera de disc, pe un server unde IIS e deja instalat de altcineva.
.NOTES
File Name : 10-setup-roaupdate-iis.ps1
Prerequisite : drepturi de administrator; instalarea rolului IIS poate cere restart
Copyright 2026 : ROMFAST
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[string]$RoaUpdatePath = "D:\ROAUPDATE",
[Parameter(Mandatory = $false)]
[string]$SiteName = "Default Web Site",
[Parameter(Mandatory = $false)]
[string]$AppName = "roaupdate",
[Parameter(Mandatory = $false)]
[switch]$SkipIisInstall,
[Parameter(Mandatory = $false)]
[switch]$SkipDirectories,
[Parameter(Mandatory = $false)]
[string[]]$Modules
)
$ErrorActionPreference = "Stop"
. (Join-Path $PSScriptRoot "lib\logging-functions.ps1")
$configFile = Join-Path $PSScriptRoot "..\config.ps1"
if (Test-Path $configFile) {
. $configFile
if (-not $PSBoundParameters.ContainsKey('RoaUpdatePath') -and $Config.RoaUpdatePath) {
$RoaUpdatePath = $Config.RoaUpdatePath
}
}
$stamp = Get-Date -Format 'yyyyMMdd_HHmmss'
$logDir = Join-Path $PSScriptRoot "..\logs"
if (-not (Test-Path $logDir)) { New-Item -ItemType Directory -Path $logDir -Force | Out-Null }
Initialize-LogFile -LogPath (Join-Path $logDir "10-setup-roaupdate-iis_$stamp.log") -ScriptName "10-setup-roaupdate-iis.ps1"
# Aceeasi lista ca in 08-post-install-config.ps1. Daca adaugi un modul,
# adauga-l in ambele locuri - 08 face obiectele Oracle DIRECTORY pe
# _ARHIVE\<MODUL>, scriptul asta face directoarele fizice de modul.
if (-not $Modules -or $Modules.Count -eq 0) {
$Modules = @(
"COMUNROA", "USERREPORTS",
"ROAAPROV", "ROAAUTO", "ROABAVERT", "ROACASA", "ROACOMENZI",
"ROACONIMPORT", "ROACONSTRUCTII", "ROACONT", "ROACONTRACTE",
"ROADECL", "ROADEF", "ROADEFSALARII", "ROADEPOZIT", "ROADEVIZE",
"ROAFACTURARE", "ROAFURNIZORI",
"ROAGEN", "ROAGEST",
"ROAGRESTAURANT", "ROAHOTEL", "ROAHOTELCONFIG",
"ROAIMOB", "ROAINCHIDSAL",
"ROALUCRARI", "ROAMANAGER", "ROAMASINI",
"ROANOR", "ROANORFRUVIMED", "ROANORRENAV", "ROANORUTMIDIA",
"ROAOBINV", "ROAOFERTARE", "ROAPRETURI",
"ROAPRINT", "ROAPRINT_INITIALIZARI",
"ROAPRODAGR", "ROAPRODUCTIE",
"ROAREGISTRATURA", "ROAREPARTIZSAL",
"ROARES", "ROARESTAURANT", "ROARETAIL", "ROARETAILMON",
"ROASAL", "ROASALSPEC",
"ROASITFIN", "ROASITOP",
"ROASTART", "ROASUPORT",
"ROATELCOMM", "ROATELMON",
"ROAVIN"
)
}
function Test-Administrator {
$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = New-Object Security.Principal.WindowsPrincipal($identity)
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
function Get-WindowsKind {
# 1 = Workstation (Win 10/11), 2 = Domain Controller, 3 = Server
$osInfo = Get-CimInstance -ClassName Win32_OperatingSystem
if ($osInfo.ProductType -eq 1) { return "Client" } else { return "Server" }
}
function Test-IisInstalled {
return (Test-Path "$env:SystemRoot\System32\inetsrv\appcmd.exe")
}
try {
Write-LogSection "Oglinda de update ROA + publicare in IIS"
if (-not (Test-Administrator)) {
throw "Scriptul are nevoie de drepturi de administrator (instaleaza roluri Windows si scrie in configul IIS)."
}
Write-Log "Radacina: $RoaUpdatePath"
Write-Log "Site IIS: $SiteName"
Write-Log "Aplicatie: /$AppName"
# ------------------------------------------------------------------
# 1. Directoare fizice
# ------------------------------------------------------------------
if (-not $SkipDirectories) {
Write-LogSection "Directoare"
$drive = Split-Path -Qualifier $RoaUpdatePath
if ($drive -and -not (Test-Path $drive)) {
throw "Discul $drive nu exista. Da alta cale cu -RoaUpdatePath (si aceeasi la 08-post-install-config.ps1)."
}
$creat = 0
$exista = 0
foreach ($dir in @($RoaUpdatePath,
(Join-Path $RoaUpdatePath "_ARHIVE"),
(Join-Path $RoaUpdatePath "_UPDATE"))) {
if (-not (Test-Path $dir)) {
New-Item -ItemType Directory -Path $dir -Force | Out-Null
Write-Log "Creat: $dir"
$creat++
} else { $exista++ }
}
foreach ($modul in $Modules) {
# Directorul de modul de la nivelul de sus - aici stau binarele
# curente pe care le vad statiile.
$caleModul = Join-Path $RoaUpdatePath $modul
if (-not (Test-Path $caleModul)) {
New-Item -ItemType Directory -Path $caleModul -Force | Out-Null
$creat++
} else { $exista++ }
# Arhiva de versiuni; 08 creeaza si obiectul Oracle DIRECTORY
# care arata aici. O facem si noi, ca scriptul sa poata rula
# independent de ordinea pasilor.
$caleArhiva = Join-Path (Join-Path $RoaUpdatePath "_ARHIVE") $modul
if (-not (Test-Path $caleArhiva)) {
New-Item -ItemType Directory -Path $caleArhiva -Force | Out-Null
$creat++
} else { $exista++ }
}
Write-LogSuccess "$creat directoare create, $exista existau deja ($($Modules.Count) module)"
}
else {
Write-Log "Sar peste crearea directoarelor (-SkipDirectories)"
}
if (-not (Test-Path $RoaUpdatePath)) {
throw "$RoaUpdatePath nu exista. Ruleaza fara -SkipDirectories sau creeaza-l manual."
}
# ------------------------------------------------------------------
# 2. IIS
# ------------------------------------------------------------------
Write-LogSection "IIS"
if (-not (Test-IisInstalled)) {
if ($SkipIisInstall) {
Write-LogError "IIS nu e instalat si mi-ai cerut sa nu il instalez (-SkipIisInstall)."
Write-LogError "Instaleaza-l manual:"
if ((Get-WindowsKind) -eq "Server") {
Write-LogError " Install-WindowsFeature -Name Web-Server -IncludeManagementTools"
} else {
Write-LogError " Enable-WindowsOptionalFeature -Online -FeatureName IIS-WebServerRole, IIS-WebServer, IIS-StaticContent, IIS-DirectoryBrowsing, IIS-DefaultDocument, IIS-HttpErrors, IIS-ManagementConsole -All"
}
throw "IIS lipseste."
}
$kind = Get-WindowsKind
Write-Log "IIS nu e instalat. Sistem detectat: Windows $kind. Il instalez..."
if ($kind -eq "Server") {
Import-Module ServerManager -ErrorAction Stop
$res = Install-WindowsFeature -Name Web-Server -IncludeManagementTools
Write-Log "Install-WindowsFeature: Success=$($res.Success) ExitCode=$($res.ExitCode)"
if ($res.RestartNeeded -eq 'Yes') {
Write-LogWarning "Windows cere restart pentru a finaliza instalarea IIS."
Write-LogWarning "Reporneste serverul si ruleaza din nou scriptul asta."
}
if (-not $res.Success) {
throw "Instalarea rolului Web-Server a esuat."
}
}
else {
$features = @(
'IIS-WebServerRole', 'IIS-WebServer', 'IIS-CommonHttpFeatures',
'IIS-StaticContent', 'IIS-DefaultDocument', 'IIS-DirectoryBrowsing',
'IIS-HttpErrors', 'IIS-RequestFiltering', 'IIS-HttpLogging',
'IIS-WebServerManagementTools', 'IIS-ManagementConsole'
)
foreach ($f in $features) {
try {
$state = (Get-WindowsOptionalFeature -Online -FeatureName $f -ErrorAction Stop).State
if ($state -ne 'Enabled') {
Enable-WindowsOptionalFeature -Online -FeatureName $f -All -NoRestart -ErrorAction Stop | Out-Null
Write-Log "Activat: $f"
}
}
catch {
Write-LogWarning "Nu am putut activa $f : $($_.Exception.Message)"
}
}
}
if (-not (Test-IisInstalled)) {
throw "IIS tot nu e disponibil dupa instalare. Probabil e nevoie de restart - reporneste si reia scriptul."
}
Write-LogSuccess "IIS instalat"
}
else {
Write-LogSuccess "IIS e deja instalat"
}
Import-Module WebAdministration -ErrorAction Stop
Write-LogSuccess "Modulul WebAdministration incarcat"
# Site-ul gazda
if (-not (Test-Path "IIS:\Sites\$SiteName")) {
Write-LogError "Site-ul IIS '$SiteName' nu exista. Site-uri disponibile:"
Get-ChildItem "IIS:\Sites" | ForEach-Object { Write-LogError " - $($_.Name)" }
throw "Da numele corect cu -SiteName."
}
$siteState = (Get-Website -Name $SiteName).State
if ($siteState -ne 'Started') {
Write-Log "Site-ul '$SiteName' e $siteState; il pornesc..."
Start-Website -Name $SiteName
}
# ------------------------------------------------------------------
# 3. Aplicatia /roaupdate
# ------------------------------------------------------------------
Write-LogSection "Aplicatia /$AppName"
$appPath = "IIS:\Sites\$SiteName\$AppName"
if (Test-Path $appPath) {
$existing = (Get-WebApplication -Site $SiteName -Name $AppName).PhysicalPath
if ($existing -eq $RoaUpdatePath) {
Write-LogSuccess "Aplicatia exista deja si arata corect catre $RoaUpdatePath"
}
else {
Write-LogWarning "Aplicatia exista dar arata catre '$existing'. O reorientez catre $RoaUpdatePath."
Set-ItemProperty -Path $appPath -Name physicalPath -Value $RoaUpdatePath
Write-LogSuccess "Cale actualizata"
}
}
else {
New-WebApplication -Site $SiteName -Name $AppName -PhysicalPath $RoaUpdatePath -Force | Out-Null
Write-LogSuccess "Aplicatie creata: /$AppName -> $RoaUpdatePath"
}
$appLocation = "$SiteName/$AppName"
# Directory browsing: statiile si omul de la suport trebuie sa poata
# vedea ce ZIP-uri exista fara sa ghiceasca numele.
Set-WebConfigurationProperty -Filter "/system.webServer/directoryBrowse" `
-Name enabled -Value $true -PSPath "IIS:\" -Location $appLocation
Write-LogSuccess "Directory browsing activat"
# ZIP-urile si XML-urile trebuie servite ca fisiere, nu blocate.
foreach ($ext in @('.zip', '.xml', '.dbf', '.fpt', '.cdx')) {
try {
$existing = Get-WebConfiguration -Filter "/system.webServer/staticContent/mimeMap[@fileExtension='$ext']" `
-PSPath "IIS:\" -Location $appLocation
if (-not $existing) {
$type = switch ($ext) {
'.zip' { 'application/zip' }
'.xml' { 'text/xml' }
default { 'application/octet-stream' }
}
Add-WebConfigurationProperty -Filter "/system.webServer/staticContent" -Name "." `
-Value @{ fileExtension = $ext; mimeType = $type } `
-PSPath "IIS:\" -Location $appLocation
Write-Log "MIME adaugat: $ext -> $type"
}
}
catch {
Write-LogDebug "MIME $ext : $($_.Exception.Message)"
}
}
# Request filtering blocheaza implicit unele extensii; ne asiguram ca
# limita de dimensiune nu taie ZIP-urile mari la download (maxAllowedContentLength
# afecteaza uploadul, dar il ridicam oricum pentru simetrie cu serverul ROMFAST).
try {
Set-WebConfigurationProperty -Filter "/system.webServer/security/requestFiltering/requestLimits" `
-Name maxAllowedContentLength -Value 4294967295 -PSPath "IIS:\" -Location $appLocation
}
catch {
Write-LogDebug "requestLimits: $($_.Exception.Message)"
}
# ------------------------------------------------------------------
# 4. Permisiuni NTFS
# ------------------------------------------------------------------
Write-LogSection "Permisiuni"
foreach ($cont in @('IIS_IUSRS', 'IUSR')) {
$null = & icacls.exe $RoaUpdatePath /grant "${cont}:(OI)(CI)RX" /T /Q 2>&1
if ($LASTEXITCODE -eq 0) {
Write-LogSuccess "Drept de citire pentru $cont pe $RoaUpdatePath"
} else {
Write-LogWarning "icacls pentru $cont a returnat codul $LASTEXITCODE"
}
}
# ------------------------------------------------------------------
# 5. Verificare
# ------------------------------------------------------------------
Write-LogSection "Verificare"
$url = "http://localhost/$AppName/"
Write-Log "Cer $url ..."
try {
$resp = Invoke-WebRequest -Uri $url -UseBasicParsing -TimeoutSec 20
if ($resp.StatusCode -eq 200) {
Write-LogSuccess "$url raspunde 200 OK"
}
else {
Write-LogWarning "$url a raspuns cu codul $($resp.StatusCode)"
}
}
catch {
Write-LogError "$url nu raspunde: $($_.Exception.Message)"
Write-LogError "Verifica: serviciul W3SVC pornit, portul 80 liber (netstat -ano | findstr :80),"
Write-LogError "si ca site-ul '$SiteName' are un binding pe portul 80."
throw "Publicarea in IIS nu s-a putut verifica."
}
Write-LogSection "Gata"
Write-Log "Oglinda de update: $RoaUpdatePath"
Write-Log "URL local: $url"
Write-Log ""
Write-Log "Statiile de lucru se configureaza catre $url"
Write-Log "Serverul trage modulele de la SERVER_INFO.UPD_URL_APP prin"
Write-Log "jobul CONTAFIN_ORACLE.UPDATEROA_ZILNIC (creat de pasul 08, dezactivat implicit)."
Close-LogFile
exit 0
}
catch {
Write-LogError $_.Exception.Message
Write-LogDebug $_.ScriptStackTrace
Close-LogFile
exit 1
}

View File

@@ -0,0 +1,528 @@
#Requires -Version 5.1
<#
.SYNOPSIS
Pregateste exportul zilnic al bazei: D:\ROA\EXPORT_ORADMP cu backupora.exe,
setari.ini, schema.txt si task-ul zilnic din Windows Task Scheduler.
.DESCRIPTION
Ce face, in ordine:
1. Creeaza D:\ROA\EXPORT_ORADMP (+ subdirectorul LOG).
2. Copiaza backupora.exe si config.fpw din kit (backup\).
3. Genereaza setari.ini din backup\setari.ini.template, inlocuind
marcajele {{...}} cu valorile reale ale instalarii.
4. Genereaza schema.txt cu schemele de exportat, in formatul cerut de
backupora.exe: SCHEMA;PAROLA@SERVICIU, cate una pe linie.
CONTAFIN_ORACLE + firmele active din CONTAFIN_ORACLE.NOM_FIRME
(parolele se citesc din NOM_FIRME.parola).
Alternativ, il copiaza de pe serverul vechi (-SchemaFromPath).
5. Creeaza obiectul Oracle DIRECTORY BACKUP_ORACLE catre acelasi
director, ca Data Pump sa poata scrie acolo, si da drepturi
serviciului Oracle pe folder.
6. Inregistreaza un task zilnic in Windows Task Scheduler.
Formatul lui setari.ini NU e cimentat in cod: sablonul e un fisier de
date, iar scriptul doar substituie marcajele.
ATENTIE la doua capcane ale lui backupora.exe, verificate in sursa lui
(main.prg):
- programul SCRIE in ini-ul implicit cheia "delete_backups_olther_xdays"
(cu typo) dar CITESTE "delete_backups_older_xdays". Sablonul o are pe
cea corecta. Nu o "corecta" inapoi.
- alege intre exportul clasic si Data Pump dupa NUMELE executabilului din
oracleexpfile. Ca sa foloseasca expdp, fisierul trebuie sa se cheme
"expdp.exe"; de aceea aratam catre <OracleHome>\bin\expdp.exe.
Dump-urile ajung in <BackupPath>\<AAAALLZZ>\ - backupora.exe creeaza singur
subdirectorul pe zi.
.PARAMETER ExportPath
Directorul in care sta backupora.exe. Implicit D:\ROA\EXPORT_ORADMP.
.PARAMETER BackupPath
Unde ajung dump-urile. Implicit acelasi cu ExportPath, deci
D:\ROA\EXPORT_ORADMP\<AAAALLZZ>\. Pe instalarile mai vechi de la clienti
valoarea uzuala e C:\BACKUP_ORACLE - daca vrei sa pastrezi conventia aia,
da-o explicit.
.PARAMETER ContafinPassword
Parola CONTAFIN_ORACLE, pentru linia lui din schema.txt.
Implicit ROMFASTSOFT.
.PARAMETER OracleHome
Oracle home. Autodetectat daca lipseste.
.PARAMETER ServiceName
Serviciul bazei. Implicit XEPDB1.
.PARAMETER SystemPassword
Parola SYSTEM/SYS. Implicit romfastsoft.
.PARAMETER SchemaFromPath
Cale (locala sau UNC) catre un schema.txt existent, de regula de pe
serverul vechi: \\server-vechi\d$\ROA\EXPORT_ORADMP\schema.txt
Daca e dat si fisierul e citibil, se copiaza in loc sa se genereze.
.PARAMETER RetentionDays
Cate zile se pastreaza dump-urile. Ajunge in setari.ini. Implicit 7.
.PARAMETER TaskTime
Ora rularii zilnice, format HH:mm. Implicit 22:30.
.PARAMETER TaskName
Numele task-ului din Task Scheduler. Implicit "ROA Export Oracle".
.PARAMETER TaskUser
Contul sub care ruleaza task-ul. Implicit SYSTEM.
.PARAMETER SkipTask
Nu crea task-ul zilnic; doar directorul, fisierele si obiectul DIRECTORY.
.PARAMETER SkipSchema
Nu genera si nu copia schema.txt (il completezi manual dupa).
.PARAMETER SchemaOnly
Regenereaza doar schema.txt si iese. Nu atinge setari.ini, backupora.exe
sau task-ul. Asa se reia pasul dupa faza 2, cand firmele exista in
NOM_FIRME, fara sa pierzi corecturile facute manual in setari.ini.
.EXAMPLE
.\11-setup-backup-export.ps1
Varianta obisnuita, cu schema.txt generat din NOM_FIRME.
.EXAMPLE
.\11-setup-backup-export.ps1 -SchemaFromPath "\\10.0.0.5\d$\ROA\EXPORT_ORADMP\schema.txt"
Preia schema.txt de pe serverul vechi, exact cum era acolo.
.EXAMPLE
.\11-setup-backup-export.ps1 -TaskTime "23:00" -RetentionDays 14
Alta ora si alta retentie.
.NOTES
File Name : 11-setup-backup-export.ps1
Prerequisite : drepturi de administrator; backup\backupora.exe prezent in kit
Copyright 2026 : ROMFAST
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[string]$ExportPath = "D:\ROA\EXPORT_ORADMP",
[Parameter(Mandatory = $false)]
[string]$BackupPath,
[Parameter(Mandatory = $false)]
[string]$ContafinPassword = "ROMFASTSOFT",
[Parameter(Mandatory = $false)]
[string]$OracleHome,
[Parameter(Mandatory = $false)]
[string]$ServiceName = "XEPDB1",
[Parameter(Mandatory = $false)]
[string]$SystemPassword = "romfastsoft",
[Parameter(Mandatory = $false)]
[string]$SchemaFromPath,
[Parameter(Mandatory = $false)]
[int]$RetentionDays = 7,
[Parameter(Mandatory = $false)]
[ValidatePattern('^\d{1,2}:\d{2}$')]
[string]$TaskTime = "22:30",
[Parameter(Mandatory = $false)]
[string]$TaskName = "ROA Export Oracle",
[Parameter(Mandatory = $false)]
[string]$TaskUser = "SYSTEM",
[Parameter(Mandatory = $false)]
[switch]$SkipTask,
[Parameter(Mandatory = $false)]
[switch]$SkipSchema,
[Parameter(Mandatory = $false)]
[switch]$SchemaOnly
)
$ErrorActionPreference = "Stop"
. (Join-Path $PSScriptRoot "lib\logging-functions.ps1")
. (Join-Path $PSScriptRoot "lib\oracle-functions.ps1")
$configFile = Join-Path $PSScriptRoot "..\config.ps1"
if (Test-Path $configFile) {
. $configFile
if (-not $PSBoundParameters.ContainsKey('OracleHome') -and $Config.OracleHome) { $OracleHome = $Config.OracleHome }
if (-not $PSBoundParameters.ContainsKey('ServiceName') -and $Config.ServiceName) { $ServiceName = $Config.ServiceName }
if (-not $PSBoundParameters.ContainsKey('SystemPassword') -and $Config.SystemPassword) { $SystemPassword = $Config.SystemPassword }
}
$stamp = Get-Date -Format 'yyyyMMdd_HHmmss'
$logDir = Join-Path $PSScriptRoot "..\logs"
if (-not (Test-Path $logDir)) { New-Item -ItemType Directory -Path $logDir -Force | Out-Null }
Initialize-LogFile -LogPath (Join-Path $logDir "11-setup-backup-export_$stamp.log") -ScriptName "11-setup-backup-export.ps1"
$kitBackupDir = Join-Path $PSScriptRoot "..\backup"
function Test-Administrator {
$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = New-Object Security.Principal.WindowsPrincipal($identity)
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
<#
Scrie schema.txt: lista schemelor pe care le exporta backupora.exe.
Fie copiaza fisierul de pe serverul vechi, fie il genereaza din
CONTAFIN_ORACLE.NOM_FIRME. Se apeleaza si din fluxul complet, si din
-SchemaOnly (reluarea de dupa faza 2, cand firmele exista).
#>
function New-SchemaFile {
param(
[string]$SchemaFile,
[string]$SourcePath,
[string]$OraHome,
[string]$Service,
[string]$Password,
[string]$ContafinPwd
)
Write-LogSection "schema.txt"
if ($SourcePath) {
if (Test-Path $SourcePath) {
Copy-Item -Path $SourcePath -Destination $SchemaFile -Force
$n = @(Get-Content $SchemaFile | Where-Object { $_.Trim() -ne '' }).Count
Write-LogSuccess "Copiat de pe serverul vechi: $n linii"
Write-LogWarning "Verifica-l: parolele si numele serviciului din el sunt cele de pe"
Write-LogWarning "serverul VECHI. Daca difera, corecteaza-le sau regenereaza cu -SchemaOnly."
return
}
Write-LogWarning "Nu pot citi $SourcePath. Generez schema.txt din NOM_FIRME."
}
Write-Log "Citesc schemele si parolele din CONTAFIN_ORACLE.NOM_FIRME..."
# Formatul cerut de backupora.exe (vezi schema.tmpl):
# SCHEMA;PAROLA@SERVICIU
# Delimitatorul e ';', nu '|' - alegem alt separator la SELECT ca sa nu se
# confunde daca o parola ar contine ';'.
$sql = @"
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
"@
$rez = Invoke-SqlPlus -OracleHome $OraHome -ServiceName $Service `
-Username "SYSTEM" -Password $Password -SqlCommand $sql -Silent
$firme = @()
foreach ($linie in ($rez -split "`n")) {
$linie = $linie.Trim()
if ($linie -match '^([A-Z0-9_]+)~(.*)$') {
$schema = $Matches[1]
$parola = $Matches[2].Trim()
if (-not $parola) { $parola = "ROMFASTSOFT" }
$firme += "$schema;$parola@$Service"
}
}
# CONTAFIN_ORACLE nu e in NOM_FIRME, dar trebuie exportat primul: fara el,
# dump-urile de firma nu se pot reimporta (NOM_FIRME tine parolele si
# maparea firma -> schema).
$linii = @("CONTAFIN_ORACLE;$ContafinPwd@$Service") + ($firme | Sort-Object -Unique)
Set-Content -Path $SchemaFile -Value ($linii -join "`r`n") -Encoding ASCII
Write-LogSuccess "Generat: $SchemaFile (CONTAFIN_ORACLE + $($firme.Count) firme)"
Write-LogWarning "Fisierul contine parole in clar - asa il cere backupora.exe."
Write-LogWarning "Nu il copia in afara serverului si nu il pune in kit."
if ($firme.Count -eq 0) {
Write-LogWarning "NOM_FIRME nu are nicio firma activa."
Write-LogWarning "In faza 1 e normal - reia cu -SchemaOnly dupa faza 2."
}
}
try {
Write-LogSection "Export zilnic Oracle (EXPORT_ORADMP)"
# -SchemaOnly nu scrie in Task Scheduler, deci nu cere administrator.
if (-not $SchemaOnly -and -not (Test-Administrator)) {
throw "Scriptul are nevoie de drepturi de administrator (creeaza un task in Task Scheduler)."
}
$oraHome = Get-OracleHome -OracleHome $OracleHome
Write-LogSuccess "Oracle Home: $oraHome"
if (-not $BackupPath) { $BackupPath = $ExportPath }
Write-Log "Director program: $ExportPath"
Write-Log "Dump-uri in: $BackupPath\<AAAALLZZ>\"
# ------------------------------------------------------------------
# Reluare doar pentru schema.txt (dupa faza 2, cand firmele exista).
# Nu atinge setari.ini, backupora.exe sau task-ul.
# ------------------------------------------------------------------
if ($SchemaOnly) {
if (-not (Test-Path $ExportPath)) {
throw "$ExportPath nu exista. Ruleaza intai scriptul fara -SchemaOnly."
}
New-SchemaFile -SchemaFile (Join-Path $ExportPath "schema.txt") -SourcePath $SchemaFromPath `
-OraHome $oraHome -Service $ServiceName -Password $SystemPassword `
-ContafinPwd $ContafinPassword
Write-LogSection "Gata (SchemaOnly)"
Close-LogFile
exit 0
}
# ------------------------------------------------------------------
# 1. Directoare
# ------------------------------------------------------------------
Write-LogSection "Directoare"
$drive = Split-Path -Qualifier $ExportPath
if ($drive -and -not (Test-Path $drive)) {
throw "Discul $drive nu exista. Da alta cale cu -ExportPath."
}
$logSubDir = Join-Path $ExportPath "LOG"
foreach ($d in @($ExportPath, $logSubDir, $BackupPath)) {
if (-not (Test-Path $d)) {
New-Item -ItemType Directory -Path $d -Force | Out-Null
Write-LogSuccess "Creat: $d"
} else {
Write-Log "Exista: $d"
}
}
# Data Pump scrie cu contul serviciului Oracle, nu cu al tau. Fara
# dreptul asta, expdp da ORA-39002 la deschiderea fisierului.
$oracleServices = @(Get-Service -Name "Oracle*XE*" -ErrorAction SilentlyContinue |
Where-Object { $_.Name -like "OracleService*" })
foreach ($svc in $oracleServices) {
$cont = "NT SERVICE\$($svc.Name)"
foreach ($tinta in (@($ExportPath, $BackupPath) | Select-Object -Unique)) {
$null = & icacls.exe $tinta /grant "${cont}:(OI)(CI)F" /T /Q 2>&1
if ($LASTEXITCODE -eq 0) {
Write-LogSuccess "Drepturi depline pentru $cont pe $tinta"
} else {
Write-LogWarning "icacls pentru $cont pe $tinta a returnat codul $LASTEXITCODE"
}
}
}
if ($oracleServices.Count -eq 0) {
Write-LogWarning "Nu am gasit niciun serviciu OracleService*. Verifica manual drepturile pe $ExportPath."
}
# ------------------------------------------------------------------
# 2. backupora.exe + config.fpw
# ------------------------------------------------------------------
# config.fpw e configul runtime VFP (SCREEN=OFF, RESOURCE=OFF). Fara el,
# backupora.exe ar deschide o fereastra si ar astepta - inacceptabil
# pentru un task programat care ruleaza fara sesiune interactiva.
Write-LogSection "backupora.exe"
$tintaExe = Join-Path $ExportPath "backupora.exe"
foreach ($fis in @('backupora.exe', 'config.fpw', 'setari.ini.tmpl', 'schema.tmpl', 'changelog_backupora.txt')) {
$sursa = Join-Path $kitBackupDir $fis
$tinta = Join-Path $ExportPath $fis
if (Test-Path $sursa) {
Copy-Item -Path $sursa -Destination $tinta -Force
$dim = [math]::Round((Get-Item $tinta).Length / 1KB, 1)
Write-LogSuccess "Copiat: $fis ($dim KB)"
}
elseif ($fis -eq 'backupora.exe') {
if (Test-Path $tinta) {
Write-LogWarning "backup\backupora.exe lipseste din kit, dar exista deja $tinta. Il las cum e."
}
else {
Write-LogError "Lipseste backup\backupora.exe din kit SI din $ExportPath."
Write-LogError "Fara el, task-ul zilnic nu are ce rula."
Write-LogError "Pune backupora.exe in kit, in directorul backup\, si reconstruieste kitul."
throw "backupora.exe lipseste."
}
}
else {
Write-LogDebug "backup\$fis lipseste din kit - optional, se continua."
}
}
# ------------------------------------------------------------------
# 3. setari.ini
# ------------------------------------------------------------------
Write-LogSection "setari.ini"
$sablon = Join-Path $kitBackupDir "setari.ini.template"
$tintaIni = Join-Path $ExportPath "setari.ini"
if (-not (Test-Path $sablon)) {
throw "Lipseste backup\setari.ini.template din kit."
}
if (Test-Path $tintaIni) {
$backupIni = Join-Path $ExportPath "setari.ini.bak_$stamp"
Copy-Item -Path $tintaIni -Destination $backupIni -Force
Write-LogWarning "setari.ini exista deja; l-am salvat ca $(Split-Path -Leaf $backupIni) inainte sa il rescriu."
}
# backupora.exe alege exp vs expdp dupa numele executabilului, deci
# aratam direct catre expdp.exe din Oracle home. Stub-ul de 0 octeti din
# directorul programului (asa apare pe instalarile vechi) nu ar exporta nimic.
$expdpExe = Join-Path $oraHome "bin\expdp.exe"
if (-not (Test-Path $expdpExe)) {
Write-LogWarning "Nu gasesc $expdpExe. Verifica manual cheia oracleexpfile din setari.ini."
}
# Calea fizica a directorului Oracle DMPDIR, pentru cheile datapumpdir*.
$dmpDirPath = "C:\DMPDIR"
$dmpDirName = "DMPDIR"
try {
$r = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "sys" -Password $SystemPassword -AsSysdba -Silent -SqlCommand @"
SET PAGESIZE 0 FEEDBACK OFF HEADING OFF VERIFY OFF
SELECT 'DMPDIR=' || directory_path FROM dba_directories WHERE directory_name = 'DMPDIR';
EXIT
"@
if ($r -match 'DMPDIR=(.+)') { $dmpDirPath = $Matches[1].Trim() }
}
catch {
Write-LogDebug "Nu am putut citi DMPDIR: $($_.Exception.Message)"
}
$schemaFile = Join-Path $ExportPath "schema.txt"
$inlocuiri = @{
'{{ORACLE_HOME}}' = $oraHome
'{{DB_SERVICE}}' = $ServiceName
'{{EXPORT_DIR}}' = $ExportPath
'{{BACKUP_PATH}}' = $BackupPath
'{{SCHEMA_FILE}}' = $schemaFile
'{{RETENTION_DAYS}}' = "$RetentionDays"
'{{EXPDP_EXE}}' = $expdpExe
'{{DMPDIR_PATH}}' = $dmpDirPath
'{{DMPDIR_NAME}}' = $dmpDirName
'{{DATA_GENERARII}}' = (Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
}
$continut = Get-Content -Path $sablon -Raw
foreach ($cheie in $inlocuiri.Keys) {
$continut = $continut.Replace($cheie, $inlocuiri[$cheie])
}
Set-Content -Path $tintaIni -Value $continut -Encoding ASCII
Write-LogSuccess "Generat: $tintaIni"
$ramase = [regex]::Matches($continut, '\{\{[A-Z_]+\}\}')
if ($ramase.Count -gt 0) {
$lista = ($ramase | ForEach-Object { $_.Value } | Select-Object -Unique) -join ", "
Write-LogWarning "Marcaje nesubstituite in setari.ini: $lista"
Write-LogWarning "Completeaza-le manual sau adauga-le in tabelul de inlocuiri din scriptul asta."
}
# ------------------------------------------------------------------
# 4. schema.txt
# ------------------------------------------------------------------
if (-not $SkipSchema) {
New-SchemaFile -SchemaFile $schemaFile -SourcePath $SchemaFromPath `
-OraHome $oraHome -Service $ServiceName -Password $SystemPassword `
-ContafinPwd $ContafinPassword
}
else {
Write-Log "Sar peste schema.txt (-SkipSchema). Completeaza-l manual in $ExportPath."
}
# ------------------------------------------------------------------
# 5. Obiectul Oracle DIRECTORY
# ------------------------------------------------------------------
Write-LogSection "Obiectul DIRECTORY BACKUP_ORACLE"
$dirSql = @"
SET FEEDBACK ON SERVEROUTPUT ON VERIFY OFF
CREATE OR REPLACE DIRECTORY BACKUP_ORACLE AS '$ExportPath';
GRANT READ, WRITE ON DIRECTORY BACKUP_ORACLE TO SYSTEM;
GRANT READ, WRITE ON DIRECTORY BACKUP_ORACLE TO CONTAFIN_ORACLE;
SET PAGESIZE 0 HEADING OFF FEEDBACK OFF
SELECT 'DIRECTORY=' || directory_path FROM dba_directories WHERE directory_name = 'BACKUP_ORACLE';
EXIT
"@
$rezDir = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "sys" -Password $SystemPassword -AsSysdba -SqlCommand $dirSql
if ($rezDir -match "DIRECTORY=(.+)") {
Write-LogSuccess "BACKUP_ORACLE -> $($Matches[1].Trim())"
} else {
Write-LogWarning "Nu am putut confirma obiectul DIRECTORY BACKUP_ORACLE."
Write-LogDebug $rezDir
}
# ------------------------------------------------------------------
# 6. Task zilnic
# ------------------------------------------------------------------
if (-not $SkipTask) {
Write-LogSection "Task zilnic in Windows Task Scheduler"
$existent = $null
try { $existent = Get-ScheduledTask -TaskName $TaskName -ErrorAction Stop } catch { }
if ($existent) {
Write-LogWarning "Task-ul '$TaskName' exista deja; il inlocuiesc."
Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false
}
$actiune = New-ScheduledTaskAction -Execute $tintaExe -WorkingDirectory $ExportPath
$declansator = New-ScheduledTaskTrigger -Daily -At $TaskTime
$principal = New-ScheduledTaskPrincipal -UserId $TaskUser -LogonType ServiceAccount -RunLevel Highest
$setari = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries `
-StartWhenAvailable -ExecutionTimeLimit (New-TimeSpan -Hours 6)
Register-ScheduledTask -TaskName $TaskName -Action $actiune -Trigger $declansator `
-Principal $principal -Settings $setari `
-Description "Export zilnic al schemelor ROA in $ExportPath (backupora.exe)" | Out-Null
Write-LogSuccess "Task '$TaskName' creat, zilnic la $TaskTime, sub contul $TaskUser"
Write-Log "Rulare de proba: Start-ScheduledTask -TaskName ""$TaskName"""
Write-Log "Stare: Get-ScheduledTaskInfo -TaskName ""$TaskName"""
}
else {
Write-Log "Sar peste task-ul zilnic (-SkipTask)"
}
# ------------------------------------------------------------------
Write-LogSection "Gata"
Write-Log "Director program: $ExportPath"
Write-Log "Executabil: $tintaExe"
Write-Log "Config: $tintaIni"
if (-not $SkipSchema) { Write-Log "Scheme: $schemaFile" }
Write-Log "Dump-uri in: $BackupPath\<AAAALLZZ>\"
Write-Log "DIRECTORY: BACKUP_ORACLE"
if (-not $SkipTask) { Write-Log "Task zilnic: $TaskName la $TaskTime" }
Write-Log ""
Write-LogWarning "Verifica manual prima rulare inainte sa pleci de la client:"
Write-LogWarning " Start-ScheduledTask -TaskName ""$TaskName"""
Write-LogWarning "apoi uita-te in $logSubDir si vezi ca s-au scris dump-urile."
Close-LogFile
exit 0
}
catch {
Write-LogError $_.Exception.Message
Write-LogDebug $_.ScriptStackTrace
Close-LogFile
exit 1
}

View File

@@ -0,0 +1,203 @@
#Requires -Version 5.1
<#
.SYNOPSIS
Sterge schema CONTAFIN_ORACLE, pentru reimportul din faza 2.
.DESCRIPTION
DROP USER CONTAFIN_ORACLE CASCADE. Se foloseste doar in FAZA2.cmd cu
/reimportcontafin, inainte de a recrea userul (01) si a importa contafin-ul
real al clientului (03).
Nu e un pas numerotat pentru ca nu face parte din instalare - e o operatie
distructiva, apelata explicit.
Ce se pierde odata cu schema, si trebuie refacut dupa:
- tabela SERVER_INFO -> se reface la reluarea pasului 08;
- joburile UPDATEROA_ZILNIC / UPDATERTVAI_ZILNIC -> tot pasul 08;
- sinonimele publice catre obiectele ei -> pasul 04.
FAZA2.cmd le ruleaza pe toate in ordinea corecta.
Ce NU se pierde: licentele (SYS.AUTH_SERII, SYS.AUTH_DETALII) si restul
obiectelor SYS traiesc in alta schema.
Inainte de drop, raporteaza sesiunile deschise ale userului. Daca exista,
dropul esueaza cu ORA-01940 si scriptul spune exact ce sa faci.
.PARAMETER OracleHome
Oracle home. Autodetectat daca lipseste.
.PARAMETER ServiceName
Serviciul bazei. Implicit XEPDB1.
.PARAMETER SystemPassword
Parola SYS. Implicit romfastsoft.
.PARAMETER KillSessions
Inchide fortat sesiunile CONTAFIN_ORACLE inainte de drop.
.PARAMETER Force
Nu cere confirmare. Obligatoriu cand rulezi neinteractiv (FAZA2.cmd il da).
.EXAMPLE
.\drop-contafin.ps1 -Force
.EXAMPLE
.\drop-contafin.ps1 -Force -KillSessions
Cand mai sunt utilizatori conectati si nu ai timp sa ii cauti.
.NOTES
File Name : drop-contafin.ps1
Copyright 2026 : ROMFAST
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[string]$OracleHome,
[Parameter(Mandatory = $false)]
[string]$ServiceName = "XEPDB1",
[Parameter(Mandatory = $false)]
[string]$SystemPassword = "romfastsoft",
[Parameter(Mandatory = $false)]
[switch]$KillSessions,
[Parameter(Mandatory = $false)]
[switch]$Force
)
$ErrorActionPreference = "Stop"
. (Join-Path $PSScriptRoot "lib\logging-functions.ps1")
. (Join-Path $PSScriptRoot "lib\oracle-functions.ps1")
$configFile = Join-Path $PSScriptRoot "..\config.ps1"
if (Test-Path $configFile) {
. $configFile
if (-not $PSBoundParameters.ContainsKey('OracleHome') -and $Config.OracleHome) { $OracleHome = $Config.OracleHome }
if (-not $PSBoundParameters.ContainsKey('ServiceName') -and $Config.ServiceName) { $ServiceName = $Config.ServiceName }
if (-not $PSBoundParameters.ContainsKey('SystemPassword') -and $Config.SystemPassword) { $SystemPassword = $Config.SystemPassword }
}
$stamp = Get-Date -Format 'yyyyMMdd_HHmmss'
$logDir = Join-Path $PSScriptRoot "..\logs"
if (-not (Test-Path $logDir)) { New-Item -ItemType Directory -Path $logDir -Force | Out-Null }
Initialize-LogFile -LogPath (Join-Path $logDir "drop-contafin_$stamp.log") -ScriptName "drop-contafin.ps1"
try {
Write-LogSection "Stergere CONTAFIN_ORACLE"
$oraHome = Get-OracleHome -OracleHome $OracleHome
Write-LogSuccess "Oracle Home: $oraHome"
if (-not (Test-OracleConnection -OracleHome $oraHome -ServiceName $ServiceName -Password $SystemPassword)) {
throw "Nu ma pot conecta la baza ($ServiceName)."
}
if (-not (Test-OracleUser -OracleHome $oraHome -ServiceName $ServiceName -Password $SystemPassword -SchemaName "CONTAFIN_ORACLE")) {
Write-LogSuccess "CONTAFIN_ORACLE nu exista. Nimic de sters."
Close-LogFile
exit 0
}
# Cate obiecte pierdem - util in log, daca ceva merge prost.
$stare = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "sys" -Password $SystemPassword -AsSysdba -Silent -SqlCommand @"
SET PAGESIZE 0 FEEDBACK OFF HEADING OFF VERIFY OFF
SELECT 'OBIECTE=' || COUNT(*) FROM dba_objects WHERE owner = 'CONTAFIN_ORACLE';
SELECT 'SESIUNI=' || COUNT(*) FROM v`$session WHERE username = 'CONTAFIN_ORACLE';
EXIT
"@
$obiecte = 0
$sesiuni = 0
if ($stare -match 'OBIECTE=(\d+)') { $obiecte = [int]$Matches[1] }
if ($stare -match 'SESIUNI=(\d+)') { $sesiuni = [int]$Matches[1] }
Write-Log "Obiecte in schema: $obiecte"
Write-Log "Sesiuni deschise: $sesiuni"
if ($sesiuni -gt 0) {
if ($KillSessions) {
Write-LogWarning "Inchid fortat cele $sesiuni sesiuni..."
$kill = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "sys" -Password $SystemPassword -AsSysdba -SqlCommand @"
SET SERVEROUTPUT ON FEEDBACK OFF VERIFY OFF
BEGIN
FOR s IN (SELECT sid, serial# FROM v`$session WHERE username = 'CONTAFIN_ORACLE') LOOP
BEGIN
EXECUTE IMMEDIATE 'ALTER SYSTEM KILL SESSION ''' || s.sid || ',' || s.serial# || ''' IMMEDIATE';
DBMS_OUTPUT.PUT_LINE(' Sesiune inchisa: ' || s.sid);
EXCEPTION
WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE(' Nu am putut inchide ' || s.sid || ': ' || SQLERRM);
END;
END LOOP;
END;
/
EXIT
"@
Write-LogDebug $kill
}
else {
Write-LogWarning "CONTAFIN_ORACLE are $sesiuni sesiuni deschise. Dropul va esua cu ORA-01940."
Write-LogWarning "Ori opresti aplicatiile, ori reiei cu -KillSessions."
}
}
if (-not $Force) {
Write-Host ""
Write-Host " Se sterge schema CONTAFIN_ORACLE cu tot cu cele $obiecte obiecte." -ForegroundColor Yellow
$raspuns = Read-Host " Scrie DA ca sa continui"
if ($raspuns -ne "DA") {
Write-Log "Anulat de utilizator."
Close-LogFile
exit 2
}
}
Write-Log "DROP USER CONTAFIN_ORACLE CASCADE ..."
$rez = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
-Username "sys" -Password $SystemPassword -AsSysdba -SqlCommand @"
SET FEEDBACK ON VERIFY OFF
DROP USER CONTAFIN_ORACLE CASCADE;
EXIT
"@
if ($rez -match 'ORA-01918') {
Write-LogSuccess "Userul nu exista (ORA-01918). Nimic de facut."
Close-LogFile
exit 0
}
if ($rez -match 'ORA-01940') {
Write-LogError "ORA-01940: userul are sesiuni conectate. Reia cu -KillSessions."
throw "Drop esuat: sesiuni active."
}
if ($rez -match 'ORA-(\d{5})') {
Write-LogError "Drop esuat cu ORA-$($Matches[1])."
Write-LogDebug $rez
throw "Drop esuat."
}
if (Test-OracleUser -OracleHome $oraHome -ServiceName $ServiceName -Password $SystemPassword -SchemaName "CONTAFIN_ORACLE") {
throw "Comanda a trecut, dar userul CONTAFIN_ORACLE inca exista."
}
Write-LogSuccess "CONTAFIN_ORACLE sters ($obiecte obiecte)"
Write-Log ""
Write-Log "Urmeaza, in ordine: 01 (recreare user) -> 03 (import) -> 04 (sinonime) -> 08 (SERVER_INFO, joburi)."
Close-LogFile
exit 0
}
catch {
Write-LogError $_.Exception.Message
Write-LogDebug $_.ScriptStackTrace
Close-LogFile
exit 1
}