fix(oracle): instanta citeste TNS_ADMIN-ul de masina, nu Oracle Home
Continuarea corectiei 3 din ec66377. Aceea rezolva doar jumatatea vizibila a
problemei; jumatatea ascunsa ar fi lovit la primul reboot al serverului, dupa
plecarea de la client. Gasit la VADECO, verificat pe loc.
1. ORA-12514 la toti clientii, cu baza perfect sanatoasa.
TNS_ADMIN de masina nu decide doar de unde se citeste sqlnet.ora: instanta
rezolva de acolo si aliasurile din tnsnames.ora. La Oracle XE LOCAL_LISTENER
e implicit aliasul LISTENER_XE, definit doar in tnsnames.ora din Oracle Home.
Cand serviciul reporneste dupa ce ROAClient a pus TNS_ADMIN pe folderul
instantclient-ului, aliasul nu se mai rezolva, instanta nu se mai
inregistreaza la listener, si atunci: v$instance OPEN, v$pdbs READ WRITE,
listener pornit pe 0.0.0.0:1521, lsnrctl arata doar CLRExtProc, si absolut
orice client primeste ORA-12514.
Capcana e de timp, nu de continut: o instanta pornita inainte ca TNS_ADMIN
sa existe nu il vede, deci instalarea pare impecabila si cade la primul
reboot. Reprodus la VADECO cu un simplu Restart-Service OracleServiceXE.
Pasul 01 scrie acum si tnsnames.ora in TNS_ADMIN (aliasul ROA pentru
ROAClient - sablonul livrat cu el arata spre HOST=SERVER_ROA, inexistent -
plus LISTENER_XE pentru instanta) si, mai important, fixeaza LOCAL_LISTENER
pe adresa literala. Doar asta din urma rezista si daca ROAClient se
instaleaza dupa kit, sau daca folderul instantclient se muta.
2. ORA-01017 desi parola e corecta.
Cu SQLNET.ALLOWED_LOGON_VERSION_SERVER=8 serverul autentifica orice client
pre-12c pe baza verificatorului 10G. Un cont fara 10G in PASSWORD_VERSIONS
nu se mai poate conecta din Instant Client 10/11, si eroarea nu e ORA-28040,
ci ORA-01017 - fix cea care trimite pe pista parolei. Dupa o instalare 21c,
SYSTEM are doar 11G 12C; CONTAFIN_ORACLE scapa doar pentru ca pasul 01 ii
rescrie parola dupa ce a scris sqlnet.ora. Pasul 01 rescrie acum si parola
lui SYSTEM, din CDB$ROOT, cu aceeasi valoare.
Subtilitate: interogat din PDB, PASSWORD_VERSIONS al unui utilizator comun
ramane cel vechi si dupa reparatie, desi autentificarea foloseste definitia
din root si functioneaza. Coloana nu e o dovada pentru SYSTEM; conectarea e.
3. Pasul 07 verifica acum ce nu se vede pe hartie.
Toate cele trei erori trec de verificarile de pana acum: fisierul exista,
parametrul e setat, contul e OPEN, obiectele sunt valide. Sectiunea noua
"Conectivitate client vechi (Instant Client)" verifica unde se citeste
efectiv sqlnet.ora, daca tnsnames.ora din TNS_ADMIN mai e sablonul, daca
LOCAL_LISTENER e alias sau adresa, ce verificatoare de parola au conturile,
si - singurul lucru care le prinde pe toate - face o conectare adevarata cu
Instant Client-ul gasit pe masina. La esec, raportul spune si unde sa te
uiti. Parametri noi: -ContafinPassword, -InstantClientDir.
4. Get-ServerLanIPv4, in biblioteca.
Pe serverele la care intram prin Tailscale, un tnsnames.ora cu 100.x nu duce
nicaieri de pe o statie. Functia alege IP-ul din LAN sarind peste Tailscale
(100.64.0.0/10) si APIPA, dupa ruta implicita cand sunt mai multe placi.
Get-ListenerHost o foloseste si el la fallback-ul pe 0.0.0.0, unde inainte
lua prima adresa nefiltrata.
La VADECO a mai fost nevoie de o corectie manuala, in afara kitului: listener.ora
avea HOST = <nume>.ts.net, deci pornirea listenerului depindea de Tailscale.
Regula generala e in documentatie.
Detaliile, cu dovezi si comenzi de diagnostic: docs/lectii-conectare-client-oracle.md
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SzF1hf4aFS1tmJWpPMiwGp
This commit is contained in:
@@ -47,6 +47,7 @@ input/ # Oracle DMP files for import
|
|||||||
- **Disaster recovery**: `proxmox/vm109-windows-dr/README.md`
|
- **Disaster recovery**: `proxmox/vm109-windows-dr/README.md`
|
||||||
- **Instalare/migrare Oracle — care director se folosește**: `proxmox/lxc108-oracle/docs/instalare-si-migrare-oracle.md`
|
- **Instalare/migrare Oracle — care director se folosește**: `proxmox/lxc108-oracle/docs/instalare-si-migrare-oracle.md`
|
||||||
- **ROA Windows setup scripts (XE/SE 21c)**: `proxmox/lxc108-oracle/roa-windows-setup/README.md`
|
- **ROA Windows setup scripts (XE/SE 21c)**: `proxmox/lxc108-oracle/roa-windows-setup/README.md`
|
||||||
|
- **Conectarea clienților vechi (Instant Client 10/11) la 21c — ORA-28040 / ORA-01017 / ORA-12514**: `docs/lectii-conectare-client-oracle.md`
|
||||||
- **Kit de instalare pentru client (DMP-uri șablon + scripturi, gata de dus la client)**: `proxmox/lxc108-oracle/scripts/build-client-kit.ps1`
|
- **Kit de instalare pentru client (DMP-uri șablon + scripturi, gata de dus la client)**: `proxmox/lxc108-oracle/scripts/build-client-kit.ps1`
|
||||||
- **VM 302 test environment for ROA setup**: `proxmox/vm302-oracle-test/README.md`
|
- **VM 302 test environment for ROA setup**: `proxmox/vm302-oracle-test/README.md`
|
||||||
- **Diagnostic spațiu Oracle la clienți (job zilnic + emailuri)**: `docs/diagnostic-spatiu-clienti.md`
|
- **Diagnostic spațiu Oracle la clienți (job zilnic + emailuri)**: `docs/diagnostic-spatiu-clienti.md`
|
||||||
|
|||||||
247
docs/lectii-conectare-client-oracle.md
Normal file
247
docs/lectii-conectare-client-oracle.md
Normal file
@@ -0,0 +1,247 @@
|
|||||||
|
# Lecții — conectarea clienților vechi (Instant Client 10/11) la Oracle 21c
|
||||||
|
|
||||||
|
Scris pe 2026-08-25, după migrarea VADECO pe server nou. Toate lucrurile de mai
|
||||||
|
jos au fost **observate direct**, nu deduse din documentație, iar fiecare a fost
|
||||||
|
verificat pe serverul clientului (`WIN-16COB435C1E`, `192.168.101.111`,
|
||||||
|
Oracle XE 21.3, CDB `XE` + PDB `XEPDB1`).
|
||||||
|
|
||||||
|
Numitorul comun al tuturor: **niciuna dintre erori nu arată spre cauza ei.**
|
||||||
|
`ORA-01017` pare parolă greșită, `ORA-12514` pare baza oprită, `ORA-28040` pare o
|
||||||
|
problemă de client. De aceea au ajuns aici, într-un fișier separat.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. `TNS_ADMIN` de mașină bate Oracle Home — și pentru instanță, nu doar pentru clienți
|
||||||
|
|
||||||
|
ROAClient își pune `TNS_ADMIN` de mașină pe folderul propriului Instant Client
|
||||||
|
(la VADECO: `d:\roa\instantclient_11_2_0_2`). Variabila nu e citită doar de
|
||||||
|
`sqlplus`-ul din folderul acela: **serviciul Oracle o moștenește la pornire**,
|
||||||
|
iar procesele bazei citesc de acolo și `sqlnet.ora`, și `tnsnames.ora`.
|
||||||
|
|
||||||
|
Capcana e de timp, nu de conținut. O instanță pornită **înainte** ca `TNS_ADMIN`
|
||||||
|
să existe nu o vede, deci continuă să citească din Oracle Home și totul pare în
|
||||||
|
regulă. Efectul apare **abia la primul restart al serviciului** — adică la primul
|
||||||
|
reboot al serverului, de obicei după ce am plecat de la client.
|
||||||
|
|
||||||
|
### 1a. Fără `sqlnet.ora` acolo → `ORA-28040` la toți clienții vechi
|
||||||
|
|
||||||
|
`SQLNET.ALLOWED_LOGON_VERSION_SERVER=8` scris frumos în
|
||||||
|
`ORACLE_BASE_HOME\network\admin\sqlnet.ora` devine irelevant: instanța citește din
|
||||||
|
`TNS_ADMIN`, nu găsește nimic, cade pe implicitul 21c (`12`) și refuză orice
|
||||||
|
client pre-12c.
|
||||||
|
|
||||||
|
### 1b. Fără `tnsnames.ora` acolo → `ORA-12514` la **toți** clienții
|
||||||
|
|
||||||
|
Asta e cea gravă, și e cea pe care am prins-o efectiv. La Oracle XE,
|
||||||
|
`LOCAL_LISTENER` e implicit **aliasul** `LISTENER_XE`, definit numai în
|
||||||
|
`tnsnames.ora` din Oracle Home. După restart, instanța încearcă să rezolve
|
||||||
|
aliasul din `TNS_ADMIN`-ul nou, nu-l găsește, **nu se mai înregistrează la
|
||||||
|
listener** — și atunci:
|
||||||
|
|
||||||
|
- baza e sus (`v$instance` = `OPEN`, `v$pdbs` = `READ WRITE`);
|
||||||
|
- serviciul Windows e `Running`;
|
||||||
|
- listenerul e `Running` și ascultă pe `0.0.0.0:1521`;
|
||||||
|
- `lsnrctl status` arată **doar** `CLRExtProc`;
|
||||||
|
- **absolut orice** client primește `ORA-12514`.
|
||||||
|
|
||||||
|
Adică: server aparent perfect, aplicație complet moartă. Exact ce s-ar fi
|
||||||
|
întâmplat la VADECO la primul reboot.
|
||||||
|
|
||||||
|
### Reparația
|
||||||
|
|
||||||
|
Trei lucruri, toate făcute acum de `01-setup-database.ps1`:
|
||||||
|
|
||||||
|
1. `sqlnet.ora` scris **și** în `TNS_ADMIN`, identic cu cel din Oracle Home;
|
||||||
|
2. `tnsnames.ora` scris în `TNS_ADMIN`, cu aliasul `ROA` (pentru ROAClient) **și**
|
||||||
|
`LISTENER_XE` (pentru instanță);
|
||||||
|
3. `LOCAL_LISTENER` fixat pe **adresă literală**, ca să nu mai depindă de niciun
|
||||||
|
fișier de rețea:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
ALTER SYSTEM SET LOCAL_LISTENER='(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.101.111)(PORT=1521))' SCOPE=BOTH;
|
||||||
|
ALTER SYSTEM REGISTER;
|
||||||
|
```
|
||||||
|
|
||||||
|
Punctul 3 e singurul care rezistă și dacă ROAClient se instalează **după** kit,
|
||||||
|
sau dacă cineva mută folderul Instant Client. Punctele 1 și 2 rămân necesare
|
||||||
|
pentru `sqlnet.ora` și pentru aliasul `ROA`, dar au aceeași fragilitate: sunt
|
||||||
|
corecte doar față de valoarea lui `TNS_ADMIN` din momentul rulării. De asta pasul
|
||||||
|
07 le reverifică.
|
||||||
|
|
||||||
|
### Diagnostic rapid
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
[Environment]::GetEnvironmentVariable('TNS_ADMIN','Machine')
|
||||||
|
Test-Path "$([Environment]::GetEnvironmentVariable('TNS_ADMIN','Machine'))\sqlnet.ora"
|
||||||
|
& "$env:ORACLE_HOME\bin\lsnrctl.exe" status | Select-String 'Service "'
|
||||||
|
```
|
||||||
|
|
||||||
|
Dacă `lsnrctl status` nu listează serviciul PDB-ului dar baza e `OPEN`, e exact
|
||||||
|
cazul 1b. Confirmarea:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT value FROM v$parameter WHERE name = 'local_listener';
|
||||||
|
```
|
||||||
|
|
||||||
|
Un alias (`LISTENER_XE`) în loc de un `(ADDRESS=...)` = bombă cu ceas.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. `ALLOWED_LOGON_VERSION_SERVER=8` cere verificator **10G**, altfel `ORA-01017`
|
||||||
|
|
||||||
|
Cu setarea asta, serverul autentifică orice client pre-12c pe baza
|
||||||
|
verificatorului **10G**. Un cont care nu are `10G` în `PASSWORD_VERSIONS` nu se
|
||||||
|
mai poate conecta din Instant Client 10/11 — și eroarea **nu** e `ORA-28040`, e:
|
||||||
|
|
||||||
|
```
|
||||||
|
ORA-01017: invalid username/password; logon denied
|
||||||
|
```
|
||||||
|
|
||||||
|
Adică fix eroarea care te trimite să verifici parola. Parola e corectă: același
|
||||||
|
cont, aceeași parolă, se conectează perfect din `sqlplus`-ul 21c de pe server.
|
||||||
|
|
||||||
|
După o instalare curată de 21c, `SYSTEM` are doar `11G 12C`. `CONTAFIN_ORACLE`
|
||||||
|
are `10G 11G 12C` **doar pentru că** pasul 01 îi rescrie parola *după* ce a scris
|
||||||
|
`sqlnet.ora` — verificatoarele se generează după setarea activă în momentul
|
||||||
|
`CREATE`/`ALTER USER`, nu retroactiv.
|
||||||
|
|
||||||
|
### Reparația
|
||||||
|
|
||||||
|
Rescrierea **aceleiași** parole. Nu se schimbă nimic pentru nimeni, doar se
|
||||||
|
regenerează verificatoarele:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- utilizator local (schemele de firmă, CONTAFIN_ORACLE) — din PDB
|
||||||
|
ALTER USER CONTAFIN_ORACLE IDENTIFIED BY "ROMFASTSOFT";
|
||||||
|
|
||||||
|
-- utilizator comun (SYSTEM) — obligatoriu din CDB$ROOT
|
||||||
|
ALTER USER SYSTEM IDENTIFIED BY "romfastsoft" CONTAINER=ALL;
|
||||||
|
```
|
||||||
|
|
||||||
|
Pasul 01 face acum ambele.
|
||||||
|
|
||||||
|
### Sub-capcană: `PASSWORD_VERSIONS` minte pentru utilizatorii comuni
|
||||||
|
|
||||||
|
Interogat **din PDB**, `DBA_USERS.PASSWORD_VERSIONS` pentru `SYSTEM` rămâne
|
||||||
|
`11G 12C` și după `ALTER USER ... CONTAINER=ALL` din root. Rândul local nu se
|
||||||
|
împrospătează, dar autentificarea folosește definiția din root — și funcționează.
|
||||||
|
|
||||||
|
Măsurat la VADECO, în aceeași secundă:
|
||||||
|
|
||||||
|
| | `PASSWORD_VERSIONS` |
|
||||||
|
|---|---|
|
||||||
|
| `CDB$ROOT` | `10G 11G 12C` |
|
||||||
|
| `XEPDB1` | `11G 12C` |
|
||||||
|
| conectare reală din Instant Client 11.2 | **merge** |
|
||||||
|
|
||||||
|
Concluzie: pentru utilizatorii comuni, coloana nu e o dovadă. Singura verificare
|
||||||
|
validă e o conectare adevărată. De asta pasul 07 nu se mai uită la coloană pentru
|
||||||
|
`SYSTEM`, ci îl probează.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. `listener.ora` legat de un nume care depinde de Tailscale
|
||||||
|
|
||||||
|
Instalarea de Oracle a pus în `listener.ora` și `tnsnames.ora`:
|
||||||
|
|
||||||
|
```
|
||||||
|
(ADDRESS = (PROTOCOL = TCP)(HOST = vadeco-server.tailf7372d.ts.net)(PORT = 1521))
|
||||||
|
```
|
||||||
|
|
||||||
|
Adică numele MagicDNS al mașinii în tailnet. Ascultarea în sine e corectă
|
||||||
|
(listenerul se leagă tot pe `0.0.0.0:1521`, deci LAN-ul e servit), dar **pornirea
|
||||||
|
listenerului ajunge să depindă de Tailscale**: la boot, dacă `tailscaled` nu a
|
||||||
|
ridicat încă resolverul, numele nu se rezolvă.
|
||||||
|
|
||||||
|
Înlocuit cu numele mașinii, care se rezolvă local întotdeauna:
|
||||||
|
|
||||||
|
```
|
||||||
|
(ADDRESS = (PROTOCOL = TCP)(HOST = WIN-16COB435C1E)(PORT = 1521))
|
||||||
|
```
|
||||||
|
|
||||||
|
Verificat după restartul listenerului: tot `0.0.0.0:1521`, toate serviciile
|
||||||
|
înregistrate, clienții se conectează.
|
||||||
|
|
||||||
|
**Regulă:** pe serverele la care intrăm prin Tailscale, niciun fișier de
|
||||||
|
configurare Oracle nu are voie să conțină un nume `*.ts.net` sau o adresă
|
||||||
|
`100.64.0.0/10`. Din același motiv, `Get-ServerLanIPv4` (în
|
||||||
|
`scripts/lib/oracle-functions.ps1`) sare peste intervalul Tailscale când alege
|
||||||
|
IP-ul pentru `tnsnames.ora` și `LOCAL_LISTENER` — un `tnsnames.ora` cu `100.x`
|
||||||
|
copiat pe o stație nu duce nicăieri, stația nu e în tailnet.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Proba de conectare cu clientul vechi e obligatorie
|
||||||
|
|
||||||
|
Toate cele trei probleme de mai sus trec de verificările „pe hârtie": fișierul
|
||||||
|
există, parametrul e setat, contul e `OPEN`, obiectele sunt valide. Singurul
|
||||||
|
lucru care le prinde pe toate e o conectare adevărată, cu **clientul vechi**, nu
|
||||||
|
cu `sqlplus`-ul 21c de pe server.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$ic = 'D:\ROA\instantclient_11_2_0_2'
|
||||||
|
'select ''PROBA_OK '' || user from dual;' , 'exit' | Set-Content -Encoding ascii C:\Windows\Temp\t.sql
|
||||||
|
|
||||||
|
# prin aliasul din tnsnames.ora — asa se conecteaza ROAClient
|
||||||
|
& "$ic\sqlplus.exe" -S -L "CONTAFIN_ORACLE/ROMFASTSOFT@ROA" '@C:\Windows\Temp\t.sql'
|
||||||
|
|
||||||
|
# prin EZConnect, pe IP-ul din LAN — ocoleste tnsnames.ora, izoleaza cauza
|
||||||
|
& "$ic\sqlplus.exe" -S -L "CONTAFIN_ORACLE/ROMFASTSOFT@//192.168.101.111:1521/XEPDB1" '@C:\Windows\Temp\t.sql'
|
||||||
|
```
|
||||||
|
|
||||||
|
`-L` (o singură încercare) nu e opțional: fără el, la o parolă refuzată `sqlplus`
|
||||||
|
cere parola de la tastatură și **agață** o sesiune neinteractivă până la timeout.
|
||||||
|
|
||||||
|
Diferența dintre cele două forme e utilă la diagnostic: dacă EZConnect merge și
|
||||||
|
aliasul nu, problema e în `tnsnames.ora`; dacă niciuna nu merge, problema e la
|
||||||
|
server (verificator de parolă, `sqlnet.ora` sau înregistrarea la listener).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Ce verifică acum pasul 07
|
||||||
|
|
||||||
|
`07-verify-installation.ps1` a primit secțiunea **„Conectivitate client vechi
|
||||||
|
(Instant Client)"**, care acoperă toate lecțiile de mai sus:
|
||||||
|
|
||||||
|
| Verificare | Prinde |
|
||||||
|
|---|---|
|
||||||
|
| `ALLOWED_LOGON_VERSION_SERVER` din `sqlnet.ora` de Oracle Home | valoare > 11 |
|
||||||
|
| `sqlnet.ora` există în `TNS_ADMIN` de mașină | 1a — `ORA-28040` la primul reboot |
|
||||||
|
| `tnsnames.ora` din `TNS_ADMIN`: alias `ROA`, `LISTENER_XE`, urme de șablon (`SERVER_ROA`) | 1b — `ORA-12514` la primul reboot; stații care nu găsesc baza |
|
||||||
|
| `LOCAL_LISTENER` e adresă literală, nu alias | 1b, cazul de fond |
|
||||||
|
| `PASSWORD_VERSIONS` conține `10G` pentru `CONTAFIN_ORACLE` și schemele de firmă | 2 — `ORA-01017` |
|
||||||
|
| conectare reală cu Instant Client-ul găsit pe mașină: `CONTAFIN_ORACLE` prin alias și prin EZConnect, `SYSTEM` prin EZConnect | tot ce a scăpat |
|
||||||
|
|
||||||
|
La eșec, raportul spune și unde să te uiți: `ORA-01017` → verificatorul 10G,
|
||||||
|
`ORA-28040` → `TNS_ADMIN`, `ORA-12514` → `LOCAL_LISTENER`.
|
||||||
|
|
||||||
|
Parametri noi: `-ContafinPassword` (implicit `ROMFASTSOFT`) și
|
||||||
|
`-InstantClientDir` (implicit: din `TNS_ADMIN`, altfel căutat sub `D:\ROA`,
|
||||||
|
`C:\ROA`, `D:\`, `C:\`). Dacă nu există Instant Client pe server, proba se
|
||||||
|
raportează ca sărită, nu ca eșec.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Capcane de mediu, plătite deja
|
||||||
|
|
||||||
|
- **`powershell -Command -` prin SSH trunchiază scriptul.** Un script cu blocuri
|
||||||
|
pe mai multe linii trimis pe stdin se execută parțial: comenzile de după primul
|
||||||
|
bloc multi-linie pur și simplu nu rulează, fără nicio eroare. Se pierde timp
|
||||||
|
crezând că o comandă a eșuat. Soluția: `scp` fișierul `.ps1` și
|
||||||
|
`ssh ... powershell -NoProfile -ExecutionPolicy Bypass -File C:\Windows\Temp\x.ps1`.
|
||||||
|
- **`sqlplus / as sysdba` nu merge într-o sesiune SSH** pe serverul ăsta
|
||||||
|
(`ORA-01017`) — autentificarea pe sistem de operare nu primește token-ul de
|
||||||
|
grup. Se folosește `sys/<parola>@//localhost:1521/XE as sysdba`, sau bequeath
|
||||||
|
cu `ORACLE_SID` setat și parolă explicită.
|
||||||
|
- **Un `Restart-Service OracleServiceXE` durează 2–4 minute** (oprire + pornire +
|
||||||
|
înregistrare). Comenzile de la distanță au nevoie de timeout pe măsură;
|
||||||
|
altfel timeout-ul taie sesiunea în mijlocul unui restart.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Legături
|
||||||
|
|
||||||
|
- Kit și flux complet: `proxmox/lxc108-oracle/roa-windows-setup/README.md`
|
||||||
|
- Migrarea VADECO: `docs/handoff_vadeco-migrare.md` (nu intră în git)
|
||||||
|
- Capcana cu discul `C:` de pe același server: aceeași migrare, secțiune separată
|
||||||
|
în handoff — procesul Oracle nu ajunge la nicio cale de pe `C:`
|
||||||
@@ -61,7 +61,7 @@ Ce se întâmplă, în ordine:
|
|||||||
| Pas | Script | Ce face |
|
| Pas | Script | Ce face |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| 1 | — | copiază DMP-urile în `C:\DMPDIR` + drepturi pentru serviciul Oracle |
|
| 1 | — | copiază DMP-urile în `C:\DMPDIR` + drepturi pentru serviciul Oracle |
|
||||||
| 2 | `01-setup-database.ps1` | tablespace `ROA`, profil, user `CONTAFIN_ORACLE`, `sqlnet.ora` |
|
| 2 | `01-setup-database.ps1` | tablespace `ROA`, profil, user `CONTAFIN_ORACLE`, `sqlnet.ora` + `tnsnames.ora` în `TNS_ADMIN`, `LOCAL_LISTENER` literal |
|
||||||
| 3 | `02-create-sys-objects.ps1` | obiectele SYS: `AUTH_PACK`, `NEWSCHEMA`, `INFO`, `AUTH_SERII`… |
|
| 3 | `02-create-sys-objects.ps1` | obiectele SYS: `AUTH_PACK`, `NEWSCHEMA`, `INFO`, `AUTH_SERII`… |
|
||||||
| 4 | `03-import-contafin.ps1` | importă `CONTAFIN_ORACLE` **al clientului** |
|
| 4 | `03-import-contafin.ps1` | importă `CONTAFIN_ORACLE` **al clientului** |
|
||||||
| 5 | `04-create-synonyms-grants.ps1` | sinonime publice, granturi, `sys-grants.sql` |
|
| 5 | `04-create-synonyms-grants.ps1` | sinonime publice, granturi, `sys-grants.sql` |
|
||||||
@@ -175,13 +175,13 @@ Run.cmd 11-setup-backup-export.ps1
|
|||||||
|
|
||||||
| Script | Ce face | Când |
|
| Script | Ce face | Când |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `01-setup-database.ps1` | tablespace `ROA`, profil, user `CONTAFIN_ORACLE`, `sqlnet.ora` | mereu |
|
| `01-setup-database.ps1` | tablespace `ROA`, profil, user `CONTAFIN_ORACLE`, configurarea de rețea pentru clienți vechi | mereu |
|
||||||
| `02-create-sys-objects.ps1` | `AUTH_PACK`, `NEWSCHEMA`, `EXECUTESCRIPTOS`, `INFO`, `UTL_MAIL` | mereu |
|
| `02-create-sys-objects.ps1` | `AUTH_PACK`, `NEWSCHEMA`, `EXECUTESCRIPTOS`, `INFO`, `UTL_MAIL` | mereu |
|
||||||
| `03-import-contafin.ps1` | import `CONTAFIN_ORACLE` din DMP | mereu |
|
| `03-import-contafin.ps1` | import `CONTAFIN_ORACLE` din DMP | mereu |
|
||||||
| `04-create-synonyms-grants.ps1` | sinonime publice, granturi, `sys-grants.sql` | mereu |
|
| `04-create-synonyms-grants.ps1` | sinonime publice, granturi, `sys-grants.sql` | mereu |
|
||||||
| `05-import-companies.ps1` | schemele de firmă, citind parolele din `NOM_FIRME` | migrare |
|
| `05-import-companies.ps1` | schemele de firmă, citind parolele din `NOM_FIRME` | migrare |
|
||||||
| `06-add-company.ps1` | adaugă o firmă pe un server deja instalat | ocazional |
|
| `06-add-company.ps1` | adaugă o firmă pe un server deja instalat | ocazional |
|
||||||
| `07-verify-installation.ps1` | verificare completă; cod 0 = instalare bună | mereu |
|
| `07-verify-installation.ps1` | verificare completă, inclusiv **probă de conectare cu Instant Client-ul vechi**; cod 0 = instalare bună | mereu |
|
||||||
| `08-post-install-config.ps1` | `ROAUPDATE`, `SERVER_INFO`, joburi, SMTP, Id client | mereu |
|
| `08-post-install-config.ps1` | `ROAUPDATE`, `SERVER_INFO`, joburi, SMTP, Id client | mereu |
|
||||||
| `09-copy-licenses.ps1` | `AUTH_SERII` + `AUTH_DETALII` de pe serverul vechi | migrare |
|
| `09-copy-licenses.ps1` | `AUTH_SERII` + `AUTH_DETALII` de pe serverul vechi | migrare |
|
||||||
| `10-setup-roaupdate-iis.ps1` | directoare de modul + publicare `/roaupdate` în IIS | mereu |
|
| `10-setup-roaupdate-iis.ps1` | directoare de modul + publicare `/roaupdate` în IIS | mereu |
|
||||||
@@ -507,39 +507,71 @@ $f = "C:\app\romfast\product\21c\homes\OraDB21Home1\network\admin\sqlnet.ora"
|
|||||||
Importul care „a eșuat" nu trebuie refăcut dacă logul spune `completed`; rulează
|
Importul care „a eșuat" nu trebuie refăcut dacă logul spune `completed`; rulează
|
||||||
doar `07-verify-installation.ps1`.
|
doar `07-verify-installation.ps1`.
|
||||||
|
|
||||||
### ORA-28040: No matching authentication protocol
|
### ORA-28040 / ORA-01017 / ORA-12514 — cele trei erori de conectare
|
||||||
|
|
||||||
Clienții vechi (Instant Client 10/11) nu se pot conecta la 21c.
|
Toate trei au fost întâlnite la VADECO și **niciuna nu arată spre cauza ei**.
|
||||||
|
Ghidul complet, cu dovezile: [`../../../docs/lectii-conectare-client-oracle.md`](../../../docs/lectii-conectare-client-oracle.md).
|
||||||
|
Rezumatul:
|
||||||
|
|
||||||
|
**Verifică întâi unde se citește `sqlnet.ora`.** Dacă `TNS_ADMIN` de mașină e
|
||||||
|
setat (ROAClient îl pune pe folderul propriului Instant Client), acela câștigă —
|
||||||
|
și pentru clienți, și pentru procesele bazei, de la următoarea pornire a
|
||||||
|
serviciului Oracle. Fișierul din Oracle Home devine irelevant.
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
Copy-Item config\sqlnet.ora $env:ORACLE_HOME\network\admin\sqlnet.ora
|
[Environment]::GetEnvironmentVariable('TNS_ADMIN','Machine')
|
||||||
lsnrctl reload
|
```
|
||||||
|
|
||||||
|
### ORA-28040: No matching authentication protocol
|
||||||
|
|
||||||
|
`sqlnet.ora` lipsește din locul de unde citește instanța, deci
|
||||||
|
`ALLOWED_LOGON_VERSION_SERVER` cade pe implicitul 21c (`12`).
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\scripts\01-setup-database.ps1 # scrie sqlnet.ora in ambele locuri
|
||||||
```
|
```
|
||||||
|
|
||||||
### ORA-01017: invalid username/password
|
### ORA-01017: invalid username/password
|
||||||
|
|
||||||
După configurarea lui `sqlnet.ora` pentru clienți vechi, parolele trebuie rescrise
|
Cu `ALLOWED_LOGON_VERSION_SERVER=8`, serverul autentifică orice client pre-12c pe
|
||||||
ca să se genereze verificatorul vechi:
|
baza verificatorului **10G**. Un cont fără `10G` în `PASSWORD_VERSIONS` primește
|
||||||
|
`ORA-01017` — **parola e corectă**, lipsește verificatorul. Se repară rescriind
|
||||||
|
aceeași parolă:
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
ALTER USER CONTAFIN_ORACLE IDENTIFIED BY ROMFASTSOFT;
|
-- utilizatori locali (din PDB)
|
||||||
ALTER USER <FIRMA> IDENTIFIED BY <parola>;
|
ALTER USER CONTAFIN_ORACLE IDENTIFIED BY "ROMFASTSOFT";
|
||||||
|
ALTER USER <FIRMA> IDENTIFIED BY "<parola>";
|
||||||
|
|
||||||
|
-- utilizatori comuni (din CDB$ROOT)
|
||||||
|
ALTER USER SYSTEM IDENTIFIED BY "romfastsoft" CONTAINER=ALL;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Pentru `SYSTEM`, `PASSWORD_VERSIONS` citit din PDB rămâne `11G 12C` chiar și după
|
||||||
|
reparație — rândul local nu se împrospătează. Singura verificare validă e o
|
||||||
|
conectare adevărată.
|
||||||
|
|
||||||
### ORA-12514: listener does not know of service
|
### ORA-12514: listener does not know of service
|
||||||
|
|
||||||
```powershell
|
Întâi PDB-ul — pentru XE trebuie deschis și starea salvată:
|
||||||
lsnrctl status
|
|
||||||
lsnrctl services
|
|
||||||
```
|
|
||||||
|
|
||||||
Pentru XE, PDB-ul trebuie deschis:
|
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
ALTER PLUGGABLE DATABASE XEPDB1 OPEN;
|
ALTER PLUGGABLE DATABASE XEPDB1 OPEN;
|
||||||
ALTER PLUGGABLE DATABASE XEPDB1 SAVE STATE;
|
ALTER PLUGGABLE DATABASE XEPDB1 SAVE STATE;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Dacă baza e `OPEN`, listenerul e pornit și totuși `lsnrctl status` arată doar
|
||||||
|
`CLRExtProc`, atunci **instanța nu s-a înregistrat**. La XE, `LOCAL_LISTENER` e
|
||||||
|
implicit aliasul `LISTENER_XE`, care se rezolvă din `tnsnames.ora` — deci depinde
|
||||||
|
de `TNS_ADMIN`. După un restart cu alt `TNS_ADMIN`, aliasul nu se mai rezolvă și
|
||||||
|
**toți** clienții primesc `ORA-12514`.
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT value FROM v$parameter WHERE name = 'local_listener'; -- alias = fragil
|
||||||
|
ALTER SYSTEM SET LOCAL_LISTENER='(ADDRESS=(PROTOCOL=TCP)(HOST=<ip_lan>)(PORT=1521))' SCOPE=BOTH;
|
||||||
|
ALTER SYSTEM REGISTER;
|
||||||
|
```
|
||||||
|
|
||||||
### Erori la import
|
### Erori la import
|
||||||
|
|
||||||
| Eroare | Rezolvare |
|
| Eroare | Rezolvare |
|
||||||
|
|||||||
@@ -10,8 +10,11 @@
|
|||||||
- Auto-detects CDB vs non-CDB configuration
|
- Auto-detects CDB vs non-CDB configuration
|
||||||
- Configures DEFAULT_PROFILE (disables password expiry)
|
- Configures DEFAULT_PROFILE (disables password expiry)
|
||||||
- Configures sqlnet.ora for Instant Client 10/11 compatibility
|
- Configures sqlnet.ora for Instant Client 10/11 compatibility
|
||||||
|
- Writes sqlnet.ora and tnsnames.ora into the machine TNS_ADMIN as well
|
||||||
|
- Pins LOCAL_LISTENER to a literal address (no tnsnames alias dependency)
|
||||||
- Creates tablespace ROA
|
- Creates tablespace ROA
|
||||||
- Creates user CONTAFIN_ORACLE with required privileges
|
- Creates user CONTAFIN_ORACLE with required privileges
|
||||||
|
- Rewrites the CONTAFIN_ORACLE and SYSTEM passwords so both get a 10G verifier
|
||||||
|
|
||||||
.PARAMETER OracleHome
|
.PARAMETER OracleHome
|
||||||
Oracle home directory. If not specified, auto-detects from registry or environment.
|
Oracle home directory. If not specified, auto-detects from registry or environment.
|
||||||
@@ -362,13 +365,18 @@ NAMES.DIRECTORY_PATH = (TNSNAMES, EZCONNECT)
|
|||||||
Write-Log "Old client compatibility enabled (SQLNET.ALLOWED_LOGON_VERSION=8)"
|
Write-Log "Old client compatibility enabled (SQLNET.ALLOWED_LOGON_VERSION=8)"
|
||||||
|
|
||||||
# Daca exista TNS_ADMIN la nivel de masina, ACELA castiga - si pentru
|
# Daca exista TNS_ADMIN la nivel de masina, ACELA castiga - si pentru
|
||||||
# clienti, si pentru serviciul Oracle, care mosteneste variabilele de
|
# clienti, si pentru procesele bazei, care mostenesc variabilele de
|
||||||
# masina. Instalarea ROAClient il pune sa arate spre instantclient-ul
|
# masina la pornirea serviciului. Instalarea ROAClient il pune sa arate
|
||||||
# ei (D:\ROA\instantclient_11_2_0_2), unde de obicei nu exista niciun
|
# spre instantclient-ul ei (D:\ROA\instantclient_11_2_0_2), unde de
|
||||||
# sqlnet.ora: atunci serverul cade pe valorile implicite, adica
|
# obicei nu exista niciun sqlnet.ora: atunci serverul cade pe valorile
|
||||||
# ALLOWED_LOGON_VERSION_SERVER=12, si clientii vechi primesc ORA-28040
|
# implicite, adica ALLOWED_LOGON_VERSION_SERVER=12, si clientii vechi
|
||||||
# desi fisierul de mai sus a fost scris corect. Scriem acelasi continut
|
# primesc ORA-28040 desi fisierul de mai sus a fost scris corect.
|
||||||
# si acolo, altfel toata configurarea de compatibilitate e degeaba.
|
# Scriem acelasi continut si acolo, altfel toata configurarea de
|
||||||
|
# compatibilitate e degeaba.
|
||||||
|
# Atentie: efectul apare abia la primul restart al serviciului Oracle -
|
||||||
|
# instanta pornita INAINTE ca TNS_ADMIN sa existe nu il vede. De aceea
|
||||||
|
# instalarea poate parea perfecta si sa cada la primul reboot. Detalii
|
||||||
|
# in docs/lectii-conectare-client-oracle.md.
|
||||||
$tnsAdmin = [Environment]::GetEnvironmentVariable('TNS_ADMIN', 'Machine')
|
$tnsAdmin = [Environment]::GetEnvironmentVariable('TNS_ADMIN', 'Machine')
|
||||||
if ($tnsAdmin) {
|
if ($tnsAdmin) {
|
||||||
$tnsAdminFull = [IO.Path]::GetFullPath($tnsAdmin.TrimEnd('\'))
|
$tnsAdminFull = [IO.Path]::GetFullPath($tnsAdmin.TrimEnd('\'))
|
||||||
@@ -377,12 +385,62 @@ NAMES.DIRECTORY_PATH = (TNSNAMES, EZCONNECT)
|
|||||||
if (-not (Test-Path $tnsAdminFull)) {
|
if (-not (Test-Path $tnsAdminFull)) {
|
||||||
New-Item -ItemType Directory -Path $tnsAdminFull -Force | Out-Null
|
New-Item -ItemType Directory -Path $tnsAdminFull -Force | Out-Null
|
||||||
}
|
}
|
||||||
|
$stampTns = Get-Date -Format 'yyyyMMdd_HHmmss'
|
||||||
|
|
||||||
$tnsSqlnet = Join-Path $tnsAdminFull "sqlnet.ora"
|
$tnsSqlnet = Join-Path $tnsAdminFull "sqlnet.ora"
|
||||||
if (Test-Path $tnsSqlnet) {
|
if (Test-Path $tnsSqlnet) {
|
||||||
Copy-Item $tnsSqlnet "$tnsSqlnet.bak_$(Get-Date -Format 'yyyyMMdd_HHmmss')" -Force
|
Copy-Item $tnsSqlnet "$tnsSqlnet.bak_$stampTns" -Force
|
||||||
}
|
}
|
||||||
Set-Content -Path $tnsSqlnet -Value $sqlnetContent -Encoding ASCII
|
Set-Content -Path $tnsSqlnet -Value $sqlnetContent -Encoding ASCII
|
||||||
Write-LogSuccess "sqlnet.ora scris si in TNS_ADMIN: $tnsSqlnet"
|
Write-LogSuccess "sqlnet.ora scris si in TNS_ADMIN: $tnsSqlnet"
|
||||||
|
|
||||||
|
# tnsnames.ora din TNS_ADMIN - doua motive, amandoua serioase:
|
||||||
|
# 1. ROAClient cauta aici aliasul ROA. Sablonul livrat cu el
|
||||||
|
# arata spre HOST=SERVER_ROA / SID=ROA, care nu exista.
|
||||||
|
# 2. instanta rezolva LOCAL_LISTENER tot de aici dupa un
|
||||||
|
# restart. La Oracle XE, LOCAL_LISTENER e implicit aliasul
|
||||||
|
# LISTENER_XE, definit doar in tnsnames.ora din Oracle
|
||||||
|
# Home. Cand instanta reporneste cu TNS_ADMIN pe folderul
|
||||||
|
# instantclient-ului, aliasul nu se mai rezolva, instanta
|
||||||
|
# nu se inregistreaza la listener si TOTI clientii iau
|
||||||
|
# ORA-12514 - cu baza sus si listenerul pornit.
|
||||||
|
$gazdaTns = Get-ServerLanIPv4
|
||||||
|
if (-not $gazdaTns) {
|
||||||
|
$gazdaTns = $env:COMPUTERNAME
|
||||||
|
Write-LogWarning "Nu am putut determina IP-ul din LAN; folosesc numele masinii ($gazdaTns) in tnsnames.ora."
|
||||||
|
}
|
||||||
|
|
||||||
|
$tnsNames = Join-Path $tnsAdminFull "tnsnames.ora"
|
||||||
|
if (Test-Path $tnsNames) {
|
||||||
|
$aliasuriVechi = @([regex]::Matches((Get-Content $tnsNames -Raw),
|
||||||
|
'(?m)^\s*([A-Za-z0-9_\.]+)\s*=') |
|
||||||
|
ForEach-Object { $_.Groups[1].Value })
|
||||||
|
Copy-Item $tnsNames "$tnsNames.bak_$stampTns" -Force
|
||||||
|
Write-LogWarning "Rescriu $tnsNames (aliasuri existente: $($aliasuriVechi -join ', ')). Copia veche: tnsnames.ora.bak_$stampTns"
|
||||||
|
}
|
||||||
|
|
||||||
|
$tnsContent = @"
|
||||||
|
# tnsnames.ora - generat de 01-setup-database.ps1 pe $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
|
||||||
|
#
|
||||||
|
# HOST e IP-ul serverului din LAN, nu localhost: acelasi fisier trebuie sa
|
||||||
|
# functioneze si copiat pe statiile de lucru.
|
||||||
|
|
||||||
|
ROA =
|
||||||
|
(DESCRIPTION =
|
||||||
|
(ADDRESS = (PROTOCOL = TCP)(HOST = $gazdaTns)(PORT = $Port))
|
||||||
|
(CONNECT_DATA =
|
||||||
|
(SERVER = DEDICATED)
|
||||||
|
(SERVICE_NAME = $ServiceName)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Folosit de instanta pentru LOCAL_LISTENER. Fara el, o instanta care
|
||||||
|
# porneste cu TNS_ADMIN aici nu se mai inregistreaza la listener.
|
||||||
|
LISTENER_XE =
|
||||||
|
(ADDRESS = (PROTOCOL = TCP)(HOST = $gazdaTns)(PORT = $Port))
|
||||||
|
"@
|
||||||
|
Set-Content -Path $tnsNames -Value $tnsContent -Encoding ASCII
|
||||||
|
Write-LogSuccess "tnsnames.ora scris in TNS_ADMIN: alias ROA -> ${gazdaTns}:$Port/$ServiceName"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -421,6 +479,60 @@ NAMES.DIRECTORY_PATH = (TNSNAMES, EZCONNECT)
|
|||||||
Write-Log "Please restart listener manually: lsnrctl stop && lsnrctl start"
|
Write-Log "Please restart listener manually: lsnrctl stop && lsnrctl start"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------
|
||||||
|
# LOCAL_LISTENER ca adresa literala, nu ca alias
|
||||||
|
# --------------------------------------------------------------------
|
||||||
|
# La Oracle XE, LOCAL_LISTENER e implicit aliasul LISTENER_XE, care se
|
||||||
|
# rezolva din tnsnames.ora - deci depinde de TNS_ADMIN. Daca cineva
|
||||||
|
# instaleaza ROAClient dupa noi (sau muta folderul instantclient),
|
||||||
|
# aliasul nu se mai rezolva la urmatoarea pornire a instantei, aceasta
|
||||||
|
# nu se mai inregistreaza la listener si toti clientii iau ORA-12514.
|
||||||
|
# Adresa literala e in spfile si nu depinde de niciun fisier de retea.
|
||||||
|
Write-LogSection "LOCAL_LISTENER"
|
||||||
|
|
||||||
|
$gazdaListener = Get-ServerLanIPv4
|
||||||
|
if (-not $gazdaListener) {
|
||||||
|
$gazdaListener = $env:COMPUTERNAME
|
||||||
|
Write-LogWarning "Nu am putut determina IP-ul din LAN; pun $gazdaListener in LOCAL_LISTENER."
|
||||||
|
}
|
||||||
|
|
||||||
|
$numeDbSql = @"
|
||||||
|
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF
|
||||||
|
SELECT 'DBNAME:' || name FROM v`$database;
|
||||||
|
EXIT;
|
||||||
|
"@
|
||||||
|
$numeDbOut = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName -DbHost $DbHost -Port $Port `
|
||||||
|
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $numeDbSql -Silent
|
||||||
|
|
||||||
|
# LOCAL_LISTENER e parametru de instanta: intr-un CDB se pune din root,
|
||||||
|
# al carui serviciu poarta numele bazei (XE la Oracle XE).
|
||||||
|
$serviciiDeIncercat = @()
|
||||||
|
if ($numeDbOut -match 'DBNAME:(\S+)') { $serviciiDeIncercat += $Matches[1].Trim() }
|
||||||
|
if ($serviciiDeIncercat -notcontains $ServiceName) { $serviciiDeIncercat += $ServiceName }
|
||||||
|
|
||||||
|
$llSql = @"
|
||||||
|
SET FEEDBACK OFF VERIFY OFF HEADING OFF PAGESIZE 0
|
||||||
|
ALTER SYSTEM SET LOCAL_LISTENER='(ADDRESS=(PROTOCOL=TCP)(HOST=$gazdaListener)(PORT=$Port))' SCOPE=BOTH;
|
||||||
|
ALTER SYSTEM REGISTER;
|
||||||
|
SELECT 'LL_DONE' FROM DUAL;
|
||||||
|
EXIT;
|
||||||
|
"@
|
||||||
|
$llPus = $false
|
||||||
|
foreach ($srv in $serviciiDeIncercat) {
|
||||||
|
$llOut = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $srv -DbHost $DbHost -Port $Port `
|
||||||
|
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $llSql -Silent
|
||||||
|
if ($llOut -match 'LL_DONE') {
|
||||||
|
Write-LogSuccess "LOCAL_LISTENER = (ADDRESS=(PROTOCOL=TCP)(HOST=$gazdaListener)(PORT=$Port)), pus prin serviciul $srv"
|
||||||
|
$llPus = $true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
Write-LogDebug "LOCAL_LISTENER prin serviciul ${srv}: $llOut"
|
||||||
|
}
|
||||||
|
if (-not $llPus) {
|
||||||
|
Write-LogWarning "Nu am putut seta LOCAL_LISTENER. Ramane pe alias (LISTENER_XE)."
|
||||||
|
Write-LogWarning "Risc: dupa un restart al instantei cu alt TNS_ADMIN, inregistrarea la listener poate esua (ORA-12514)."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Write-Log "Skipping sqlnet.ora configuration as requested"
|
Write-Log "Skipping sqlnet.ora configuration as requested"
|
||||||
@@ -602,6 +714,47 @@ EXIT;
|
|||||||
else {
|
else {
|
||||||
Write-LogWarning "Could not verify password reset"
|
Write-LogWarning "Could not verify password reset"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# SYSTEM are nevoie de acelasi tratament, si nu e o rafinare.
|
||||||
|
# Cu SQLNET.ALLOWED_LOGON_VERSION_SERVER=8, serverul autentifica orice
|
||||||
|
# client pre-12c pe baza verificatorului 10G. Un cont care nu are 10G
|
||||||
|
# in PASSWORD_VERSIONS (SYSTEM, dupa o instalare 21c, are doar 11G 12C)
|
||||||
|
# nu se mai poate conecta din Instant Client 10/11 - si eroarea NU e
|
||||||
|
# ORA-28040, ci ORA-01017 "invalid username/password", care trimite pe
|
||||||
|
# o pista gresita ore intregi. Aceeasi parola, doar rescrisa, produce
|
||||||
|
# verificatorul care lipseste.
|
||||||
|
$sysPwdSql = if ($versionInfo.IsCDB) {
|
||||||
|
@"
|
||||||
|
SET ECHO OFF FEEDBACK OFF VERIFY OFF HEADING OFF PAGESIZE 0
|
||||||
|
ALTER USER SYSTEM IDENTIFIED BY "$SystemPassword" CONTAINER=ALL;
|
||||||
|
SELECT 'SYS_PWD_DONE' FROM DUAL;
|
||||||
|
EXIT;
|
||||||
|
"@
|
||||||
|
} else {
|
||||||
|
@"
|
||||||
|
SET ECHO OFF FEEDBACK OFF VERIFY OFF HEADING OFF PAGESIZE 0
|
||||||
|
ALTER USER SYSTEM IDENTIFIED BY "$SystemPassword";
|
||||||
|
SELECT 'SYS_PWD_DONE' FROM DUAL;
|
||||||
|
EXIT;
|
||||||
|
"@
|
||||||
|
}
|
||||||
|
|
||||||
|
# Utilizator comun => se modifica din root, al carui serviciu poarta
|
||||||
|
# numele bazei. Reutilizam lista construita pentru LOCAL_LISTENER.
|
||||||
|
$sysPwdPus = $false
|
||||||
|
foreach ($srv in $serviciiDeIncercat) {
|
||||||
|
$sysOut = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $srv -DbHost $DbHost -Port $Port `
|
||||||
|
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $sysPwdSql -Silent
|
||||||
|
if ($sysOut -match 'SYS_PWD_DONE') {
|
||||||
|
Write-LogSuccess "SYSTEM a primit verificator 10G (parola nu se schimba, doar se rescrie)"
|
||||||
|
$sysPwdPus = $true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
Write-LogDebug "Rescrierea parolei SYSTEM prin serviciul ${srv}: $sysOut"
|
||||||
|
}
|
||||||
|
if (-not $sysPwdPus) {
|
||||||
|
Write-LogWarning "Nu am putut rescrie parola lui SYSTEM. Conturile fara verificator 10G dau ORA-01017 din Instant Client 10/11."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Summary
|
# Summary
|
||||||
|
|||||||
@@ -67,7 +67,17 @@ param(
|
|||||||
[string]$RoaUpdatePath = "D:\ROAUPDATE",
|
[string]$RoaUpdatePath = "D:\ROAUPDATE",
|
||||||
|
|
||||||
[Parameter(Mandatory = $false)]
|
[Parameter(Mandatory = $false)]
|
||||||
[string]$ExportPath = "D:\ROA\EXPORT_ORADMP"
|
[string]$ExportPath = "D:\ROA\EXPORT_ORADMP",
|
||||||
|
|
||||||
|
# Parola CONTAFIN_ORACLE, folosita pentru proba de conectare cu Instant
|
||||||
|
# Client-ul vechi. Daca e gresita, proba raporteaza esec - nu instalarea.
|
||||||
|
[Parameter(Mandatory = $false)]
|
||||||
|
[string]$ContafinPassword = "ROMFASTSOFT",
|
||||||
|
|
||||||
|
# Folderul Instant Client-ului vechi (cel al ROAClient). Implicit se
|
||||||
|
# deduce din TNS_ADMIN sau se cauta sub D:\ROA si C:\ROA.
|
||||||
|
[Parameter(Mandatory = $false)]
|
||||||
|
[string]$InstantClientDir
|
||||||
)
|
)
|
||||||
|
|
||||||
$ErrorActionPreference = 'Stop'
|
$ErrorActionPreference = 'Stop'
|
||||||
@@ -835,6 +845,225 @@ EXIT;
|
|||||||
$extraIssues += "Scheduled task 'ROA Export Oracle' missing"
|
$extraIssues += "Scheduled task 'ROA Export Oracle' missing"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------
|
||||||
|
# Conectivitate pentru clientii vechi (Instant Client 10/11)
|
||||||
|
# ------------------------------------------------------------------------
|
||||||
|
# Sectiunea asta exista pentru ca toate esecurile de aici arata, la prima
|
||||||
|
# vedere, ca altceva: ORA-01017 pare parola gresita, ORA-12514 pare baza
|
||||||
|
# oprita. Vezi docs/lectii-conectare-client-oracle.md.
|
||||||
|
Add-ReportSection "Conectivitate client vechi (Instant Client)"
|
||||||
|
|
||||||
|
# --- unde se citeste, de fapt, sqlnet.ora
|
||||||
|
$oraBaseRoot = Split-Path (Split-Path (Split-Path $oraHome -Parent) -Parent) -Parent
|
||||||
|
$homesRoot = Join-Path $oraBaseRoot "product\21c\homes"
|
||||||
|
$adminOh = $null
|
||||||
|
if (Test-Path $homesRoot) {
|
||||||
|
$bh = Get-ChildItem -Path $homesRoot -Directory -ErrorAction SilentlyContinue |
|
||||||
|
Where-Object { $_.Name -match "OraDB" } | Select-Object -First 1
|
||||||
|
if ($bh) { $adminOh = Join-Path $bh.FullName "network\admin" }
|
||||||
|
}
|
||||||
|
if (-not $adminOh) { $adminOh = Join-Path $oraHome "network\admin" }
|
||||||
|
|
||||||
|
$sqlnetOh = Join-Path $adminOh "sqlnet.ora"
|
||||||
|
if (Test-Path $sqlnetOh) {
|
||||||
|
$continutOh = Get-Content $sqlnetOh -Raw
|
||||||
|
$verOh = if ($continutOh -match '(?im)^\s*SQLNET\.ALLOWED_LOGON_VERSION_SERVER\s*=\s*(\d+)') { $Matches[1] } else { $null }
|
||||||
|
Add-ReportLine "sqlnet.ora (Oracle Home): $sqlnetOh"
|
||||||
|
if ($verOh) {
|
||||||
|
Add-ReportLine " ALLOWED_LOGON_VERSION_SERVER = $verOh"
|
||||||
|
if ([int]$verOh -gt 11) {
|
||||||
|
Add-ReportLine "[WARNING] Valoare peste 11: clientii 10/11 vor primi ORA-28040."
|
||||||
|
$extraIssues += "ALLOWED_LOGON_VERSION_SERVER=$verOh in $sqlnetOh"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Add-ReportLine "[WARNING] Nu contine ALLOWED_LOGON_VERSION_SERVER."
|
||||||
|
$extraIssues += "ALLOWED_LOGON_VERSION_SERVER missing from $sqlnetOh"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Add-ReportLine "sqlnet.ora (Oracle Home): LIPSA ($sqlnetOh)"
|
||||||
|
$extraIssues += "sqlnet.ora missing from $adminOh"
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- TNS_ADMIN de masina: castiga in fata Oracle Home, si pentru clienti,
|
||||||
|
# si pentru instanta - dar abia de la urmatoarea pornire a serviciului.
|
||||||
|
$tnsAdminM = [Environment]::GetEnvironmentVariable('TNS_ADMIN', 'Machine')
|
||||||
|
Add-ReportLine ""
|
||||||
|
if ($tnsAdminM) {
|
||||||
|
$tnsAdminM = [IO.Path]::GetFullPath($tnsAdminM.TrimEnd('\'))
|
||||||
|
Add-ReportLine "TNS_ADMIN (masina): $tnsAdminM"
|
||||||
|
|
||||||
|
if ($tnsAdminM -ne [IO.Path]::GetFullPath($adminOh.TrimEnd('\'))) {
|
||||||
|
$sqlnetTns = Join-Path $tnsAdminM "sqlnet.ora"
|
||||||
|
if (Test-Path $sqlnetTns) {
|
||||||
|
Add-ReportLine " sqlnet.ora acolo: OK"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Add-ReportLine " sqlnet.ora acolo: LIPSA"
|
||||||
|
Add-ReportLine "[WARNING] Instanta citeste TNS_ADMIN-ul de masina de la urmatorul restart."
|
||||||
|
Add-ReportLine " Fara sqlnet.ora acolo, dupa primul reboot toti clientii vechi"
|
||||||
|
Add-ReportLine " iau ORA-28040. Ruleaza din nou 01-setup-database.ps1."
|
||||||
|
$extraIssues += "sqlnet.ora missing from TNS_ADMIN ($tnsAdminM)"
|
||||||
|
}
|
||||||
|
|
||||||
|
$tnsFile = Join-Path $tnsAdminM "tnsnames.ora"
|
||||||
|
if (Test-Path $tnsFile) {
|
||||||
|
$tnsTxt = Get-Content $tnsFile -Raw
|
||||||
|
$areRoa = $tnsTxt -match '(?im)^\s*ROA\s*='
|
||||||
|
$areLsn = $tnsTxt -match '(?im)^\s*LISTENER_XE\s*='
|
||||||
|
$areSablon = $tnsTxt -match 'SERVER_ROA'
|
||||||
|
Add-ReportLine (" tnsnames.ora acolo: alias ROA={0}, LISTENER_XE={1}" -f `
|
||||||
|
$(if ($areRoa) { 'da' } else { 'NU' }), $(if ($areLsn) { 'da' } else { 'NU' }))
|
||||||
|
if ($areSablon) {
|
||||||
|
Add-ReportLine "[WARNING] tnsnames.ora e inca sablonul (HOST=SERVER_ROA). Statiile nu se pot conecta."
|
||||||
|
$extraIssues += "tnsnames.ora still template (SERVER_ROA) in $tnsAdminM"
|
||||||
|
}
|
||||||
|
elseif (-not $areRoa) {
|
||||||
|
Add-ReportLine "[WARNING] Lipseste aliasul ROA. ROAClient nu stie unde e baza."
|
||||||
|
$extraIssues += "TNS alias ROA missing from $tnsFile"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Add-ReportLine " tnsnames.ora acolo: LIPSA"
|
||||||
|
$extraIssues += "tnsnames.ora missing from TNS_ADMIN ($tnsAdminM)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Add-ReportLine " (coincide cu Oracle Home - nimic de dublat)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Add-ReportLine "TNS_ADMIN (masina): nesetat (se citeste din Oracle Home)"
|
||||||
|
Add-ReportLine "[NOTA] Daca se instaleaza ROAClient dupa asta, TNS_ADMIN va aparea si"
|
||||||
|
Add-ReportLine " va trebui rulat din nou 01-setup-database.ps1."
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- LOCAL_LISTENER: alias sau adresa literala
|
||||||
|
$llSql = @"
|
||||||
|
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF LINESIZE 300
|
||||||
|
SELECT 'LL:' || value FROM v`$parameter WHERE name = 'local_listener';
|
||||||
|
EXIT;
|
||||||
|
"@
|
||||||
|
$llOut = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
|
||||||
|
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $llSql -Silent
|
||||||
|
|
||||||
|
Add-ReportLine ""
|
||||||
|
if ($llOut -match 'LL:(.*)') {
|
||||||
|
$llVal = $Matches[1].Trim()
|
||||||
|
Add-ReportLine "LOCAL_LISTENER: $(if ($llVal) { $llVal } else { '(gol - implicit)' })"
|
||||||
|
if ($llVal -and $llVal -notmatch '\(ADDRESS') {
|
||||||
|
Add-ReportLine "[WARNING] LOCAL_LISTENER e un alias ($llVal), deci depinde de tnsnames.ora."
|
||||||
|
Add-ReportLine " Daca aliasul nu se rezolva la urmatoarea pornire a instantei, aceasta"
|
||||||
|
Add-ReportLine " nu se mai inregistreaza la listener si toti clientii iau ORA-12514."
|
||||||
|
Add-ReportLine " Ruleaza din nou 01-setup-database.ps1 ca sa il fixeze pe adresa literala."
|
||||||
|
$extraIssues += "LOCAL_LISTENER is an alias ($llVal), not a literal address"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- verificatoare de parola: fara 10G, clientii vechi iau ORA-01017
|
||||||
|
# SYSTEM lipseste intentionat din lista: fiind utilizator comun, randul lui
|
||||||
|
# din DBA_USERS al PDB-ului ramane cu vechile PASSWORD_VERSIONS chiar dupa
|
||||||
|
# ce parola a fost rescrisa din root, iar autentificarea foloseste oricum
|
||||||
|
# definitia din root. Verificarea care conteaza pentru el e proba de
|
||||||
|
# conectare de mai jos, nu coloana asta.
|
||||||
|
$pvSql = @"
|
||||||
|
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF LINESIZE 300
|
||||||
|
SELECT 'PV:' || username || '|' || password_versions
|
||||||
|
FROM dba_users
|
||||||
|
WHERE username = 'CONTAFIN_ORACLE'
|
||||||
|
OR username IN (SELECT UPPER(schema) FROM CONTAFIN_ORACLE.NOM_FIRME
|
||||||
|
WHERE sters = 0 AND schema IS NOT NULL)
|
||||||
|
ORDER BY username;
|
||||||
|
EXIT;
|
||||||
|
"@
|
||||||
|
$pvOut = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName `
|
||||||
|
-Username "SYSTEM" -Password $SystemPassword -SqlCommand $pvSql -Silent
|
||||||
|
|
||||||
|
Add-ReportLine ""
|
||||||
|
Add-ReportLine "Verificatoare de parola (10G e obligatoriu pentru Instant Client 10/11):"
|
||||||
|
$fara10G = @()
|
||||||
|
foreach ($line in $pvOut -split "`n") {
|
||||||
|
if ($line -match '^PV:([^|]+)\|(.*)$') {
|
||||||
|
$u = $Matches[1].Trim(); $v = $Matches[2].Trim()
|
||||||
|
$are = $v -match '10G'
|
||||||
|
Add-ReportLine (" {0,-24} {1,-16} {2}" -f $u, $v, $(if ($are) { 'OK' } else { 'FARA 10G' }))
|
||||||
|
if (-not $are) { $fara10G += $u }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($fara10G.Count -gt 0) {
|
||||||
|
Add-ReportLine "[WARNING] Conturi fara verificator 10G: $($fara10G -join ', ')"
|
||||||
|
Add-ReportLine " Din Instant Client 10/11 vor da ORA-01017, care pare parola gresita."
|
||||||
|
Add-ReportLine " Se repara rescriind aceeasi parola: ALTER USER <nume> IDENTIFIED BY <parola>;"
|
||||||
|
$extraIssues += "Accounts without 10G password verifier: $($fara10G -join ', ')"
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- proba adevarata: o conectare cu Instant Client-ul vechi
|
||||||
|
Add-ReportLine ""
|
||||||
|
$icDir = $InstantClientDir
|
||||||
|
if (-not $icDir -and $tnsAdminM -and (Test-Path (Join-Path $tnsAdminM "sqlplus.exe"))) {
|
||||||
|
$icDir = $tnsAdminM
|
||||||
|
}
|
||||||
|
if (-not $icDir) {
|
||||||
|
foreach ($radacina in @('D:\ROA', 'C:\ROA', 'D:\', 'C:\')) {
|
||||||
|
if (-not (Test-Path $radacina)) { continue }
|
||||||
|
$g = Get-ChildItem -Path $radacina -Directory -Filter 'instantclient*' -ErrorAction SilentlyContinue |
|
||||||
|
Where-Object { Test-Path (Join-Path $_.FullName 'sqlplus.exe') } | Select-Object -First 1
|
||||||
|
if ($g) { $icDir = $g.FullName; break }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not $icDir) {
|
||||||
|
Add-ReportLine "Proba de conectare: nu am gasit Instant Client pe masina (sarita)"
|
||||||
|
Add-ReportLine "[NOTA] Fara ROAClient instalat aici, proba se face de pe o statie."
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$icSqlplus = Join-Path $icDir "sqlplus.exe"
|
||||||
|
Add-ReportLine "Instant Client: $icSqlplus"
|
||||||
|
|
||||||
|
$probaSql = Join-Path $env:TEMP "roa_proba_client.sql"
|
||||||
|
Set-Content -Path $probaSql -Encoding ASCII -Value @(
|
||||||
|
'SET FEEDBACK OFF PAGESIZE 0 LINESIZE 200',
|
||||||
|
"SELECT 'PROBA_OK ' || USER FROM DUAL;",
|
||||||
|
'EXIT')
|
||||||
|
|
||||||
|
$ipLan = Get-ServerLanIPv4
|
||||||
|
$tinte = @()
|
||||||
|
$areAliasRoa = $tnsAdminM -and (Test-Path (Join-Path $tnsAdminM 'tnsnames.ora')) -and
|
||||||
|
((Get-Content (Join-Path $tnsAdminM 'tnsnames.ora') -Raw) -match '(?im)^\s*ROA\s*=')
|
||||||
|
if ($areAliasRoa) {
|
||||||
|
$tinte += @{ Nume = 'CONTAFIN_ORACLE / alias ROA'; Sir = "CONTAFIN_ORACLE/$ContafinPassword@ROA" }
|
||||||
|
}
|
||||||
|
if ($ipLan) {
|
||||||
|
$tinte += @{ Nume = "CONTAFIN_ORACLE / $ipLan"; Sir = "CONTAFIN_ORACLE/$ContafinPassword@//${ipLan}:1521/$ServiceName" }
|
||||||
|
}
|
||||||
|
if ($tinte.Count -eq 0) {
|
||||||
|
$tinte += @{ Nume = 'CONTAFIN_ORACLE / localhost'; Sir = "CONTAFIN_ORACLE/$ContafinPassword@//localhost:1521/$ServiceName" }
|
||||||
|
}
|
||||||
|
# SYSTEM: singura verificare valida a verificatorului lui de parola.
|
||||||
|
$gazdaSys = if ($ipLan) { $ipLan } else { 'localhost' }
|
||||||
|
$tinte += @{ Nume = "SYSTEM / $gazdaSys"; Sir = "SYSTEM/$SystemPassword@//${gazdaSys}:1521/$ServiceName" }
|
||||||
|
|
||||||
|
foreach ($t in $tinte) {
|
||||||
|
$iesire = (& $icSqlplus -S -L $t.Sir "@$probaSql" 2>&1 | Where-Object { $_ -match '\S' }) -join ' '
|
||||||
|
if ($iesire -match 'PROBA_OK') {
|
||||||
|
Add-ReportLine (" {0,-32} OK" -f $t.Nume)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$eroare = if ($iesire -match '(ORA-\d+|TNS-\d+|SP2-\d+)') { $Matches[1] } else { 'esec' }
|
||||||
|
Add-ReportLine (" {0,-32} ESEC ({1})" -f $t.Nume, $eroare)
|
||||||
|
Add-ReportLine " $iesire"
|
||||||
|
switch ($eroare) {
|
||||||
|
'ORA-01017' { Add-ReportLine " Verifica intai verificatorul 10G, nu parola: ALTER USER ... IDENTIFIED BY <aceeasi parola>;" }
|
||||||
|
'ORA-28040' { Add-ReportLine " sqlnet.ora nu e citit de unde crezi. Verifica TNS_ADMIN de mai sus." }
|
||||||
|
'ORA-12514' { Add-ReportLine " Instanta nu e inregistrata la listener. Verifica LOCAL_LISTENER de mai sus." }
|
||||||
|
}
|
||||||
|
$extraIssues += "Instant Client connect test failed via $($t.Nume): $eroare"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Remove-Item $probaSql -Force -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
|
||||||
# Final Summary
|
# Final Summary
|
||||||
Add-ReportSection "Verification Summary"
|
Add-ReportSection "Verification Summary"
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,65 @@
|
|||||||
# Source logging functions
|
# Source logging functions
|
||||||
. "$PSScriptRoot\logging-functions.ps1"
|
. "$PSScriptRoot\logging-functions.ps1"
|
||||||
|
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
IP-ul din LAN al serverului - cel pe care il vad statiile de lucru.
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
Alege adresa IPv4 a interfetei care are ruta implicita, sarind peste:
|
||||||
|
- loopback (127.x) si APIPA (169.254.x);
|
||||||
|
- intervalul Tailscale (100.64.0.0/10). Pe serverele la care intram prin
|
||||||
|
Tailscale, adresa 100.x exista si e perfect functionala pentru noi, dar
|
||||||
|
e inutila intr-un tnsnames.ora dus pe statii: statia nu e in tailnet.
|
||||||
|
Daca nu gaseste nimic potrivit, intoarce sirul gol - apelantul decide.
|
||||||
|
|
||||||
|
.OUTPUTS
|
||||||
|
String. Adresa IPv4 din LAN, sau "" daca nu poate fi determinata.
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
$ip = Get-ServerLanIPv4
|
||||||
|
#>
|
||||||
|
function Get-ServerLanIPv4 {
|
||||||
|
[CmdletBinding()]
|
||||||
|
param()
|
||||||
|
|
||||||
|
$eTailscale = { param($ip) $ip -match '^100\.(6[4-9]|[7-9][0-9]|1[01][0-9]|12[0-7])\.' }
|
||||||
|
|
||||||
|
$adrese = @()
|
||||||
|
try {
|
||||||
|
$adrese = @(Get-NetIPAddress -AddressFamily IPv4 -ErrorAction Stop |
|
||||||
|
Where-Object {
|
||||||
|
$_.IPAddress -notmatch '^(127\.|169\.254\.)' -and
|
||||||
|
-not (& $eTailscale $_.IPAddress)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
# Masini fara modulul NetTCPIP: cadem pe rezolvarea numelui propriu.
|
||||||
|
$ipuri = @([Net.Dns]::GetHostAddresses([Net.Dns]::GetHostName()) |
|
||||||
|
Where-Object { $_.AddressFamily -eq 'InterNetwork' } |
|
||||||
|
ForEach-Object { $_.IPAddressToString } |
|
||||||
|
Where-Object { $_ -notmatch '^(127\.|169\.254\.)' -and -not (& $eTailscale $_) })
|
||||||
|
if ($ipuri.Count -gt 0) { return $ipuri[0] }
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($adrese.Count -eq 0) { return "" }
|
||||||
|
if ($adrese.Count -eq 1) { return $adrese[0].IPAddress }
|
||||||
|
|
||||||
|
# Mai multe placi: o alegem pe cea cu ruta implicita.
|
||||||
|
try {
|
||||||
|
$rute = @(Get-NetRoute -DestinationPrefix '0.0.0.0/0' -ErrorAction Stop |
|
||||||
|
Sort-Object RouteMetric, ifMetric)
|
||||||
|
foreach ($r in $rute) {
|
||||||
|
$potrivire = $adrese | Where-Object { $_.InterfaceIndex -eq $r.ifIndex } | Select-Object -First 1
|
||||||
|
if ($potrivire) { return $potrivire.IPAddress }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
|
||||||
|
return $adrese[0].IPAddress
|
||||||
|
}
|
||||||
|
|
||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Get the listener host address.
|
Get the listener host address.
|
||||||
@@ -64,9 +123,7 @@ function Get-ListenerHost {
|
|||||||
|
|
||||||
# If listener is bound to 0.0.0.0, try to get actual IP
|
# If listener is bound to 0.0.0.0, try to get actual IP
|
||||||
if ($listenerHost -eq "0.0.0.0") {
|
if ($listenerHost -eq "0.0.0.0") {
|
||||||
$ip = (Get-NetIPAddress -AddressFamily IPv4 |
|
$ip = Get-ServerLanIPv4
|
||||||
Where-Object { $_.IPAddress -notmatch "^127\." -and $_.PrefixOrigin -ne "WellKnown" } |
|
|
||||||
Select-Object -First 1).IPAddress
|
|
||||||
if ($ip) { return $ip }
|
if ($ip) { return $ip }
|
||||||
return "localhost"
|
return "localhost"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user