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