#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\, si _UPDATE; 08-post-install-config.ps1 face doar _ARHIVE\ (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\, 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 }