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