From e1d8d77a6b719c96fdc69e0b3de423d1d102048d Mon Sep 17 00:00:00 2001 From: Almeyric Date: Sun, 24 May 2026 21:10:56 +0200 Subject: [PATCH] =?UTF-8?q?Modification=20NRD3=20-=20Customsettings=20&=20?= =?UTF-8?q?Join-Domain=20Combin=C3=A9=20NRD2-NRD3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- projects/MDT/Control/CustomSettings.ini | 71 +++- .../Scripts/SupportHDF/ps1/Join-Domain.ps1 | 353 ++++++++++++------ 2 files changed, 293 insertions(+), 131 deletions(-) diff --git a/projects/MDT/Control/CustomSettings.ini b/projects/MDT/Control/CustomSettings.ini index f93e38e..87a6d87 100644 --- a/projects/MDT/Control/CustomSettings.ini +++ b/projects/MDT/Control/CustomSettings.ini @@ -3,29 +3,27 @@ Priority= DefaultGateway, SetSiteCode, ByLaptop, ByRole, Model, Init, MachineMod Properties= SiteCode, Salle, Role, Prefix, PosteType, OSDComputerNumber, MachineModel, MyCustomProperty, ModelAlias ; , OSDSendMailFrom, OSDSendMailToPri, OSDSendMailToSec, OSDSendMailSubject, OSDSendMailBody, OSDSendMailSMTPServer, OSDSendMailIncludeBDDLog -;UserExit=SiteCode.vbs - ; ========================================================= ; MAPPING RESEAU -> SITE ; ========================================================= [DefaultGateway] -192.168.82.6 = S0082 +10.127.0.254=S1009 10.126.193.254=S2073 10.126.207.254=S2074 10.126.209.254=S2074 -10.126.221.254=S2075 -10.126.223.254=S2075 +10.126.225.254=S2075 +10.126.227.254=S2075 -10.126.235.254=S2076 -10.126.237.254=S2076 +; OK +10.127.241.254=S2076 -10.126.249.254=S2077 -10.126.251.254=S2077 +; OK +10.127.1.254=S2077 10.126.7.254=S2078 10.126.9.254=S2078 @@ -63,8 +61,9 @@ Properties= SiteCode, Salle, Role, Prefix, PosteType, OSDComputerNumber, Machine 10.126.161.254=S2089 10.126.163.254=S2089 -10.126.175.254=S2090 -10.126.177.254=S2090 +; OK +10.127.209.254=S2090 +10.127.211.254=S2090 10.126.189.254=S2091 10.126.191.254=S2091 @@ -72,8 +71,9 @@ Properties= SiteCode, Salle, Role, Prefix, PosteType, OSDComputerNumber, Machine 10.126.203.254=S2092 10.126.205.254=S2092 -10.126.217.254=S2093 -10.126.219.254=S2093 +; OK Vlan 120-121 +10.128.17.254=S2093 +10.128.19.254=S2093 10.126.231.254=S2094 10.126.233.254=S2094 @@ -84,59 +84,88 @@ Properties= SiteCode, Salle, Role, Prefix, PosteType, OSDComputerNumber, Machine 10.126.3.254=S2096 10.126.5.254=S2096 +; OK +10.134.49.254=S3147 + +192.168.82.6=SITKO ; ========================================================= ; PARAMETRES PAR SITE ; ========================================================= -[S0082] - -SiteCode=s0082 +[SITKO] +SiteCode=sitko +SLShare=\\192.168.82.189\MDT$\logs +SLShareDynamicLogging=\\192.168.82.189\MDT$\Logs\%OSDComputerName% [S1009] SiteCode=s1009 + + [S1027] SiteCode=s1027 + + [S2073] SiteCode=s2073 +SLShare=\\\MDT$\logs +SLShareDynamicLogging=\\\MDT$\Logs\%OSDComputerName% + [S2074] SiteCode=s2074 + + [S2075] SiteCode=s2075 +SLShare=\\10.126.224.129\MDT$\logs +SLShareDynamicLogging=\\10.126.224.129\MDT$\Logs\%OSDComputerName% + [S2076] SiteCode=s2076 + + [S2077] SiteCode=s2077 + + [S2078] SiteCode=s2078 + + [S2079] SiteCode=s2079 + + [S2080] SiteCode=s2080 + + [S2081] SiteCode=s2081 + + [S2082] SiteCode=s2082 @@ -224,6 +253,10 @@ SiteCode=s2095 SiteCode=s2096 +[S3147] + +SiteCode=s3147 + ; ========================================================= ; DETECTION AUTOMATIQUE TYPE POSTE ; ========================================================= @@ -283,9 +316,11 @@ MachineModel=#Left("%Model%",4)# [Default] - OSInstall=Y + +AdminPassword=crhdf!@2026 + SkipComputerName=NO SkipDomainMembership=YES SkipAdminPassword=YES @@ -324,4 +359,4 @@ _SMSTSPackageName=Deploiment %TaskSequenceName% Subsection=VM-%ISVM% [VM-TRUE] -; OSDComputerName=#Right(Replace("VM-%macaddress001%",":",""),15)# \ No newline at end of file +; OSDComputerName=#Right(Replace("VM-%macaddress001%",":",""),15)# diff --git a/projects/MDT/Scripts/SupportHDF/ps1/Join-Domain.ps1 b/projects/MDT/Scripts/SupportHDF/ps1/Join-Domain.ps1 index 1fb207a..79c9645 100644 --- a/projects/MDT/Scripts/SupportHDF/ps1/Join-Domain.ps1 +++ b/projects/MDT/Scripts/SupportHDF/ps1/Join-Domain.ps1 @@ -1,16 +1,24 @@ <# - Join-Domain-USB.ps1 + Join-Domain.ps1 (COMBINE NRD2 + NRD3) + Ce script fonctionne pour les deux secteurs NRD2 (s20XX) et NRD3 (s31XX/s3147). Usage: placer ce script sur la clé USB avec (optionnel) key.bin + pwd.sec - key.bin : clé symétrique (base64) - pwd.sec : mot de passe chiffré (ConvertFrom-SecureString -Key) Logs -> %SystemRoot%\Logs (ex: C:\Windows\Logs) + Appelé depuis MDT via ZTIPowerShell.wsf avec paramètre -path #> +# ----------------------- +# Paramètres MDT +# ----------------------- +param( + [string]$path = $null # Reçu de MDT: chemin du script +) + # ----------------------- # Configuration utilisateur # ----------------------- $user_migration_edu = "EDU\ajoutpc" -$secteur = "NRD2" # Noms de fichiers $keyFileName = "key.bin" @@ -18,12 +26,13 @@ $pwdFileName = "pwd.sec" $logPrefix = "migration-log" # ----------------------- -# Déterminer le dossier du script (fonctionne si lancé depuis clé ou ailleurs) +# Déterminer le dossier du script (priorité au paramètre MDT) # ----------------------- -# $PSScriptRoot fonctionne quand le script est exécuté depuis un fichier, -# sinon on essaie de récupérer via MyInvocation; sinon on prend le répertoire courant. $scriptDir = $null -if ($PSScriptRoot) { +if (-not [string]::IsNullOrWhiteSpace($path)) { + $scriptDir = $path + Write-Output "[DEBUG] Utilisation du chemin MDT (-path) : $scriptDir" +} elseif ($PSScriptRoot) { $scriptDir = $PSScriptRoot } else { try { @@ -38,27 +47,49 @@ if (-not $scriptDir) { $scriptDir = (Get-Location).Path } $keyPath = Join-Path -Path $scriptDir -ChildPath $keyFileName $pwdPath = Join-Path -Path $scriptDir -ChildPath $pwdFileName -# Emplacement des logs : dossier "Logs" de Windows +$ScriptVersion = '2026-05-22.1-combined' + +function Log-FileAcl { + param([string]$Path) + try { + if (-not (Test-Path -Path $Path)) { Write-LogMessage "Fichier absent pour ACL : $Path" -Type "WARNING"; return } + $acl = Get-Acl -Path $Path + $entries = $acl.Access | ForEach-Object { "$($_.IdentityReference.Value):$($_.FileSystemRights)" } + Write-LogMessage "ACL pour $Path : $($entries -join '; ')" -Type "INFO" + $current = [Security.Principal.WindowsIdentity]::GetCurrent().Name + $hasRead = $false + foreach ($r in $acl.Access) { + if ($r.IdentityReference.Value -eq $current -or $r.IdentityReference.Value -match 'Administrators' -or $r.IdentityReference.Value -match 'SYSTEM') { + if ($r.FileSystemRights -band [System.Security.AccessControl.FileSystemRights]::FullControl -or + $r.FileSystemRights -band [System.Security.AccessControl.FileSystemRights]::Modify -or + $r.FileSystemRights -band [System.Security.AccessControl.FileSystemRights]::ReadAndExecute -or + $r.FileSystemRights -band [System.Security.AccessControl.FileSystemRights]::ReadData -or + $r.FileSystemRights -band [System.Security.AccessControl.FileSystemRights]::ReadAttributes -or + $r.FileSystemRights -band [System.Security.AccessControl.FileSystemRights]::ReadExtendedAttributes) { + $hasRead = $true + } + } + } + if (-not $hasRead) { Write-LogMessage "Attention: L'identite courante ($current) ne semble pas avoir de droit de lecture sur $Path" -Type "WARNING" } + } catch { + Write-LogMessage "Impossible de lire ACL pour $Path : $_" -Type "WARNING" + } +} + $windowsLogsDir = Join-Path -Path $env:windir -ChildPath "Logs" if (-not (Test-Path -Path $windowsLogsDir)) { New-Item -Path $windowsLogsDir -ItemType Directory -Force | Out-Null } $logFilePath = Join-Path -Path $windowsLogsDir -ChildPath ("$logPrefix-$(Get-Date -Format 'yyyy-MM-dd').log") -# ----------------------- -# Helpers -# ----------------------- - function Assert-RunAsAdministrator { $currentIdentity = [Security.Principal.WindowsIdentity]::GetCurrent() $principal = New-Object System.Security.Principal.WindowsPrincipal($currentIdentity) $isAdmin = $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) $isSystem = $currentIdentity.Name -eq 'NT AUTHORITY\SYSTEM' - - Write-LogMessage "Identité courante : $($currentIdentity.Name). IsAdmin=$isAdmin IsSystem=$isSystem" - + Write-LogMessage "Identite courante : $($currentIdentity.Name). IsAdmin=$isAdmin IsSystem=$isSystem" if (-not ($isAdmin -or $isSystem)) { - throw "Le script doit être exécuté avec des privilèges élevés. Exécution automatique MDT non interactive attendue." + throw "Le script doit etre execute avec des privileges eleves. Execution automatique MDT non interactive attendue." } } @@ -70,40 +101,86 @@ function Write-LogMessage { Write-Output $entry } +Write-LogMessage "Version du script Join-Domain : $ScriptVersion" -Type "INFO" + function Set-RestrictiveAcl { param([string]$Path) try { $acl = Get-Acl -Path $Path $acl.SetAccessRuleProtection($true, $false) - # Remove existing explicit rules (best-effort) - $acl.Access | ForEach-Object { $acl.RemoveAccessRule($_) } - $admin = New-Object System.Security.Principal.NTAccount("BUILTIN\Administrators") - $system = New-Object System.Security.Principal.NTAccount("NT AUTHORITY\SYSTEM") - $ruleAdmin = New-Object System.Security.AccessControl.FileSystemAccessRule($admin,"FullControl","None","Allow") - $ruleSystem = New-Object System.Security.AccessControl.FileSystemAccessRule($system,"FullControl","None","Allow") - $acl.AddAccessRule($ruleAdmin) + $sidAdmins = New-Object System.Security.Principal.SecurityIdentifier('S-1-5-32-544') + $acctAdmins = $sidAdmins.Translate([System.Security.Principal.NTAccount]) + $acctSystem = New-Object System.Security.Principal.NTAccount("NT AUTHORITY\SYSTEM") + $ruleAdmin = New-Object System.Security.AccessControl.FileSystemAccessRule($acctAdmins,"FullControl","None","Allow") + $ruleSystem = New-Object System.Security.AccessControl.FileSystemAccessRule($acctSystem,"FullControl","None","Allow") + $acl.ResetAccessRule($ruleAdmin) $acl.AddAccessRule($ruleSystem) + try { + $current = [Security.Principal.WindowsIdentity]::GetCurrent().Name + $acctCurrent = New-Object System.Security.Principal.NTAccount($current) + $ruleCurrent = New-Object System.Security.AccessControl.FileSystemAccessRule($acctCurrent,"FullControl","None","Allow") + $acl.AddAccessRule($ruleCurrent) + } catch {} Set-Acl -Path $Path -AclObject $acl } catch { - # sur certaines clés USB, Set-Acl échoue; on ignore mais logguer Write-LogMessage "Impossible d'appliquer ACL restrictive sur $Path : $_" -Type "WARNING" } } -# ----------------------- -# Elevation -# ----------------------- +function Get-ValidIPAddressesWMI { + $validIPs = @() + try { + $adapters = Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter "IPEnabled=True" -ErrorAction SilentlyContinue + foreach ($adapter in $adapters) { + if ($adapter.IPAddress) { + foreach ($ip in $adapter.IPAddress) { + if ($ip -and -not ($ip -like '169.254.*') -and -not ($ip -like '0.*') -and -not ($ip -like '127.*')) { + $validIPs += (New-Object PSObject -Property @{IPAddress = $ip}) + } + } + } + } + if ($validIPs.Count -gt 0) { return $validIPs } + } catch { + Write-LogMessage "Erreur WMI lors de la recuperation des IPs : $_" -Type "WARNING" + } + try { + $netIPs = Get-NetIPAddress -AddressFamily IPv4 -ErrorAction SilentlyContinue | Where-Object { $_.IPAddress -and -not ($_.IPAddress -like '169.254.*') -and -not ($_.IPAddress -like '0.*') -and -not ($_.IPAddress -like '127.*') } + if ($netIPs) { + return $netIPs | ForEach-Object { New-Object PSObject -Property @{IPAddress = $_.IPAddress} } + } + } catch { + Write-LogMessage "Fallback Get-NetIPAddress a echoue : $_" -Type "WARNING" + } + return @() +} + +function Test-ValidIPAvailable { + try { + $ips = Get-ValidIPAddressesWMI + if ($ips -and $ips.Count -gt 0) { + foreach ($ip in $ips) { Write-LogMessage "IP detectee : $($ip.IPAddress)" -Type "INFO" } + return $true + } else { + Write-LogMessage "Aucune adresse IPv4 valide detectee." -Type "WARNING" + return $false + } + } catch { + Write-LogMessage "Erreur lors de la verification IP : $_" -Type "WARNING" + return $false + } +} + Assert-RunAsAdministrator - -# Créer fichier log si absent if (-not (Test-Path -Path $logFilePath)) { New-Item -Path $logFilePath -ItemType File -Force | Out-Null } -Write-LogMessage "Dossier script : $scriptDir" -Write-LogMessage "Chemin key : $keyPath" -Write-LogMessage "Chemin mot de passe : $pwdPath" +Write-LogMessage "========== DEMARRAGE SCRIPT JOIN-DOMAIN ==========" +Log-FileAcl -Path $keyPath +Log-FileAcl -Path $pwdPath +Write-LogMessage "Parametres recus de MDT : -path \"$path\"" -Type "INFO" +Write-LogMessage "Dossier script detecte : $scriptDir" +Write-LogMessage "Chemin key : $keyPath" +Write-LogMessage "Chemin mot de passe : $pwdPath" -# ----------------------- -# Gestion clé et mot de passe (dans dossier du script / clé USB) -# ----------------------- function New-SymmetricKeyFile { param([string]$OutPath) $rng = New-Object System.Security.Cryptography.RNGCryptoServiceProvider @@ -128,7 +205,7 @@ function Get-SymmetricKeyBytes { function New-EncryptedPasswordFile { param([string]$KeyFile, [string]$PwdFile, [string]$UserName) - Write-Host "Fichier mot de passe chiffré absent. Initialisation..." + Write-Host "Fichier mot de passe chiffre absent. Initialisation..." $plain = Read-Host -AsSecureString "Saisir le mot de passe pour $UserName (sera chiffré et stocké sur la clé)" $keyBytes = Get-SymmetricKeyBytes -KeyFile $KeyFile if (-not $keyBytes) { $keyBytes = New-SymmetricKeyFile -OutPath $KeyFile } @@ -138,29 +215,27 @@ function New-EncryptedPasswordFile { Write-LogMessage "Fichier mot de passe chiffré créé sur la clé : $PwdFile" } -# Si absent, le script ne peut pas fonctionner en mode automatique if (-not (Test-Path -Path $pwdPath) -or -not (Test-Path -Path $keyPath)) { Write-LogMessage "Fichiers requis manquants : $keyPath ou $pwdPath" -Type "ERROR" - throw "Les fichiers $keyFileName et $pwdFileName sont obligatoires pour une exécution automatique." + throw "Les fichiers $keyFileName et $pwdFileName sont obligatoires pour une execution automatique." } -# Lire et déchiffrer $keyBytes = Get-SymmetricKeyBytes -KeyFile $keyPath if (-not $keyBytes) { - Write-LogMessage "Impossible de lire la clé symétrique ($keyPath)." -Type "ERROR" - throw "Clé symétrique manquante ou illisible." + Write-LogMessage "Impossible de lire la cle symetrique ($keyPath)." -Type "ERROR" + throw "Cle symetrique manquante ou illisible." } try { $encString = Get-Content -Path $pwdPath -Raw $securePassword = ConvertTo-SecureString $encString -Key $keyBytes } catch { - Write-LogMessage "Erreur lors du déchiffrement du mot de passe : $_" -Type "ERROR" - throw "Impossible de déchiffrer le mot de passe." + Write-LogMessage "Erreur lors du dechiffrement du mot de passe : $_" -Type "ERROR" + throw "Impossible de dechiffrer le mot de passe." } $cred_edu = New-Object System.Management.Automation.PSCredential -ArgumentList $user_migration_edu, $securePassword # ----------------------- -# OU / UAI (inchangé) +# OU / UAI (fusion des deux secteurs) # ----------------------- $OuSites = @{ "009" = "009-Labbe-LaMadeleine"; "027" = "027-VertesFeuilles-StAndreLille"; "073" = "073-StExupery-Halluin"; @@ -170,21 +245,37 @@ $OuSites = @{ "083" = "083-Lavoisier-Roubaix"; "084" = "084-Meersch-Roubaix"; "085" = "085-Esaat-Roubaix"; "087" = "087-Corbusier-Tourcoing"; "089" = "089-Gambetta-Tourcoing"; "090" = "090-Colbert-Tourcoing"; "091" = "091-Sevigne-Tourcoing"; "092" = "092-Derycke-VilleneuvedAscq"; "093" = "093-Queneau-VilleneuvedAscq"; - "094" = "094-Cousteau-Wasquehal"; "095" = "095-Zola-Wattrelos"; "096" = "096-Savary-Wattrelos" + "094" = "094-Cousteau-Wasquehal"; "095" = "095-Zola-Wattrelos"; "096" = "096-Savary-Wattrelos"; "147" = "147-Chatelet-Douai" } $OuUAI = @{ "009" = "0590122M"; "027" = "0592832H"; "073" = "0592850C"; "074" = "0594380R"; "075" = "0590144L"; "076" = "0597100X"; "077" = "0590143K"; "078" = "0590187H"; "079" = "0590182C"; "080" = "0590184E"; "081" = "0590185F"; "082" = "0590186G"; "083" = "0590189K"; "084" = "0590181B"; "085" = "0594391C"; "087" = "0590216P"; "089" = "0590212K"; "090" = "0590214M"; "091" = "0590215N"; "092" = "0594375K"; - "093" = "0594424N"; "094" = "0590249A"; "095" = "0590233H"; "096" = "0595787V" + "093" = "0594424N"; "094" = "0590249A"; "095" = "0590233H"; "096" = "0595787V"; "147" = "0590063Y" } -# ----------------------- -# Détection hostname / site et jointure domaine (inchangé mais robuste) -# ----------------------- +Write-LogMessage "\n=== VERIFICATION RESEAU ===" +if (-not (Test-ValidIPAvailable)) { + Write-LogMessage "ARRET : Pas d'adresse IP valide. La connexion reseau n'a pas pu etre etablie." -Type "ERROR" + throw "Pas d'IP valide disponible. Impossible de continuer." +} +Write-LogMessage "Verification reseau reussie - Au moins une IP valide detectee." -Type "INFO" + +Write-LogMessage "\n=== DETECTION HOSTNAME ET JOINTURE DOMAINE ===" $hostname = $env:COMPUTERNAME +Write-LogMessage "Hostname detecte : $hostname" -Type "INFO" + +$secteur = $null +$Site = $null +$Ou_site = $null +$uai = $null +$Ou = $null +$dc = "999-dc01.EDU.HDF" +$joined = $false + if ($hostname -match '^s20(\d{2})') { + $secteur = "NRD2" $siteNumber = $matches[1] $siteNumberFormatted = "{0:D3}" -f [int]$siteNumber if ($OuSites.ContainsKey($siteNumberFormatted)) { @@ -192,74 +283,110 @@ if ($hostname -match '^s20(\d{2})') { $Ou_site = $OuSites[$siteNumberFormatted] $uai = $OuUAI[$siteNumberFormatted] $Ou = "OU=Pedagogie,OU=$uai,OU=Parc-Informatique,OU=$Ou_site,OU=$secteur,OU=HDF,DC=EDU,DC=HDF" - # $dc = "$Site-dc.EDU.HDF" - $dc = "999-dc01.EDU.HDF" - Write-LogMessage "Traitement du site : $Site avec l'OU : $Ou_site" - - try { - $netConfigs = Get-NetIPConfiguration -All -ErrorAction Stop - } catch { - Write-LogMessage "Impossible de récupérer la configuration IP : $_" -Type "ERROR" - throw $_ - } - - $joined = $false - foreach ($cfg in $netConfigs) { - foreach ($addr in $cfg.IPv4Address) { - $ipv4 = $addr.IPAddress - if (-not $ipv4) { continue } - Write-LogMessage "IP détectée : $ipv4" - $parts = $ipv4.Split('.') - if ($parts.Length -lt 4) { Write-LogMessage "IP $ipv4 non conforme." -Type "WARNING"; continue } - try { $thirdOctet = [int]$parts[2] } catch { Write-LogMessage "Impossible de parser $ipv4" -Type "WARNING"; continue } - - if ($thirdOctet -ge 192 -and $thirdOctet -le 224) { - $isDomain = $false - try { - $dom = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain() - if ($dom -and $dom.Name -eq "EDU.HDF") { $isDomain = $true } - } catch { $isDomain = $false } - - if (-not $isDomain) { - try { - $envKey = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" - $siteExists = Get-ItemProperty -Path $envKey -Name "site" -ErrorAction SilentlyContinue - if (-not $siteExists) { - New-ItemProperty -Path $envKey -Name "site" -Value $Site -PropertyType String -Force | Out-Null - Write-LogMessage "Variable d'environnement 'site' créée : $Site" - } - } catch { Write-LogMessage "Impossible d'écrire la variable d'environnement 'site' : $_" -Type "WARNING" } - - try { - Remove-Computer -UnjoinDomaincredential $cred_edu -WorkgroupName "WORKGROUP" -Force -ErrorAction SilentlyContinue - } catch { Write-LogMessage "Remove-Computer NON requis / échoué : $_" -Type "INFO" } - - try { - Add-Computer -DomainName "edu.hdf" -Credential $cred_edu -OUPath $Ou -Force -ErrorAction Stop - Write-LogMessage "La machine a été ajoutée au domaine $dc avec succès." - $joined = $true - break - } catch { - Write-LogMessage "Erreur lors de l'ajout au domaine (interface $ipv4) : $_" -Type "ERROR" - } - } else { - Write-LogMessage "Machine déjà membre du domaine EDU.HDF." - $joined = $true - break - } - } else { - Write-LogMessage "IP $ipv4 hors des plages autorisées (3ème octet = $thirdOctet)." - } - } - if ($joined) { break } - } - - if (-not $joined) { Write-LogMessage "Aucune interface IP valide trouvée pour joindre le domaine." -Type "ERROR" } } else { Write-LogMessage "Le numéro de site $siteNumberFormatted n'est pas dans le tableau d'OU définies." -Type "ERROR" + throw "Site inconnu pour NRD2 : $siteNumberFormatted" + } +} elseif ($hostname -match '^s3(\d{3})') { + $secteur = "NRD3" + $siteNumber = $matches[1] + $siteNumberFormatted = "{0:D3}" -f [int]$siteNumber + if ($OuSites.ContainsKey($siteNumberFormatted)) { + $Site = "03-$siteNumberFormatted" + $Ou_site = $OuSites[$siteNumberFormatted] + $uai = $OuUAI[$siteNumberFormatted] + $Ou = "OU=Pedagogie,OU=$uai,OU=Parc-Informatique,OU=$Ou_site,OU=$secteur,OU=HDF,DC=EDU,DC=HDF" + } else { + Write-LogMessage "Le numéro de site $siteNumberFormatted n'est pas dans le tableau d'OU définies." -Type "ERROR" + throw "Site inconnu pour NRD3 : $siteNumberFormatted" } } else { - Write-LogMessage "Hostname ne correspond pas au format attendu (ex: s2009, s2027, s2073 à s2096)." -Type "ERROR" + Write-LogMessage "ERREUR : Hostname ne correspond pas au format attendu (s20XX ou s3XXX)." -Type "ERROR" + Write-LogMessage "Format attendu : s2009, s2027, s2073 à s2096 (ex: s2075 pour site 075) ou s3147 pour NRD3." -Type "ERROR" + throw "Hostname invalide : $hostname - Format attendu s20XX ou s3XXX" } -Write-LogMessage "Traitement terminé." +Write-LogMessage "Site detecte : $Site | OU : $Ou_site | UAI : $uai" -Type "INFO" +Write-LogMessage "Chemin LDAP : $Ou" -Type "INFO" + +Write-LogMessage "Recherche d'une interface reseau avec IP valide pour la jointure domaine..." -Type "INFO" +$netConfigs = Get-ValidIPAddressesWMI +if (-not $netConfigs -or $netConfigs.Count -eq 0) { + Write-LogMessage "Aucune interface reseau disponible." -Type "ERROR" + throw "Pas de configuration reseau valide." +} +foreach ($addr in $netConfigs) { + $ipv4 = $addr.IPAddress + if (-not $ipv4) { continue } + Write-LogMessage "Interface trouvee avec IP : $ipv4" -Type "INFO" + $parts = $ipv4.Split('.') + if ($parts.Length -lt 4) { + Write-LogMessage "Format IP invalide : $ipv4" -Type "WARNING" + continue + } + try { + $thirdOctet = [int]$parts[2] + } catch { + Write-LogMessage "Impossible de parser le 3eme octet de $ipv4" -Type "WARNING" + continue + } + if ($thirdOctet -ge 1 -and $thirdOctet -le 254) { + Write-LogMessage "IP $ipv4 est dans les plages autorisees (3eme octet = $thirdOctet). Verification statut domaine..." -Type "INFO" + $isDomain = $false + try { + $dom = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain() + if ($dom -and $dom.Name -eq "EDU.HDF") { + $isDomain = $true + } + } catch { + $isDomain = $false + } + if (-not $isDomain) { + Write-LogMessage "Machine n'est pas encore membre du domaine. Preparation de la jointure..." -Type "INFO" + try { + $envKey = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" + $siteExists = Get-ItemProperty -Path $envKey -Name "site" -ErrorAction SilentlyContinue + if (-not $siteExists) { + New-ItemProperty -Path $envKey -Name "site" -Value $Site -PropertyType String -Force | Out-Null + Write-LogMessage "Variable d'environnement 'site' creee : $Site" -Type "INFO" + } else { + Write-LogMessage "Variable d'environnement 'site' deja presente : $(Get-ItemProperty -Path $envKey -Name 'site' -ErrorAction SilentlyContinue).site" -Type "INFO" + } + } catch { + Write-LogMessage "Impossible d'ecrire la variable d'environnement 'site' : $_" -Type "WARNING" + } + try { + Write-LogMessage "Tentative de suppression du groupe de travail (si applicable)..." -Type "INFO" + Remove-Computer -UnjoinDomaincredential $cred_edu -WorkgroupName "WORKGROUP" -Force -ErrorAction SilentlyContinue + Write-LogMessage "Suppression du groupe de travail reussie." -Type "INFO" + } catch { + Write-LogMessage "Pas de groupe de travail a supprimer ou erreur (OK en environnement vierge) : $_" -Type "INFO" + } + try { + Write-LogMessage "Jointure du domaine EDU.HDF avec l'OU $Ou_site..." -Type "INFO" + Add-Computer -DomainName "edu.hdf" -Credential $cred_edu -OUPath $Ou -Force -ErrorAction Stop + Write-LogMessage "SUCCESS : La machine a ete correctement ajoutee au domaine EDU.HDF !" -Type "INFO" + Write-LogMessage "Serveur DC : $dc" -Type "INFO" + Write-LogMessage "Site : $Site" -Type "INFO" + Write-LogMessage "OU : $Ou" -Type "INFO" + $joined = $true + break + } catch { + Write-LogMessage "ERREUR lors de l'ajout au domaine (interface IP: $ipv4) : $_" -Type "ERROR" + } + } else { + Write-LogMessage "Machine est deja membre du domaine EDU.HDF." -Type "INFO" + $joined = $true + break + } + } else { + Write-LogMessage "IP $ipv4 est HORS des plages autorisees (3eme octet = $thirdOctet, doit etre 1-254). Ignoree." -Type "WARNING" + } + if ($joined) { break } +} +if (-not $joined) { + Write-LogMessage "ERREUR : Aucune interface IP valide n'a permis la jointure au domaine." -Type "ERROR" + throw "Jointure au domaine échouée : pas d'interface IP valide." +} +Write-LogMessage "\n========== FIN SCRIPT JOIN-DOMAIN ==========" +Write-LogMessage "Traitement du script terminé avec succès." -Type "INFO"