ef7128111a
- Remplacer chemins en dur par variables dynamiques (\C:\Windows) - Ajouter détection du contexte SYSTEM avec alertes - Implémenter upgrade automatique Winget v7 avant installation - Ajouter gestion d'erreurs robuste et logging détaillé - Ignorer dossier Apps/ dans .gitignore (installers volumineux) - Créer documentation compatibilité MDT USB
246 lines
9.5 KiB
PowerShell
246 lines
9.5 KiB
PowerShell
# =========================================================================
|
|
# INSTALL-APPS.PS1 - Installation des applications via Winget
|
|
# Exécution en contexte SYSTEM lors du déploiement MDT
|
|
# =========================================================================
|
|
|
|
# =========================================================================
|
|
# 0. CONFIGURATION DU CONTEXTE ET VARIABLES DYNAMIQUES
|
|
# =========================================================================
|
|
$SystemRoot = $env:SystemRoot # C:\Windows
|
|
$SystemDrive = $env:SystemDrive # C:
|
|
$CurrentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
|
|
$IsSystem = $CurrentUser -like "*SYSTEM" -or $CurrentUser -like "*S-1-5-18"
|
|
|
|
Write-Host "========================================================" -ForegroundColor Cyan
|
|
Write-Host " CONFIGURATION CONTEXTE MDT"
|
|
Write-Host "========================================================" -ForegroundColor Cyan
|
|
Write-Host "Utilisateur: $CurrentUser (SYSTEM: $IsSystem)"
|
|
Write-Host "SystemRoot: $SystemRoot"
|
|
Write-Host "SystemDrive: $SystemDrive"
|
|
|
|
# =========================================================================
|
|
# 1. CONFIGURATION DU FICHIER LOG WINDOWS (Chemin dynamique)
|
|
# =========================================================================
|
|
$LogDirectory = Join-Path $SystemRoot "Logs\MDT_Apps"
|
|
if (!(Test-Path $LogDirectory)) {
|
|
$null = New-Item -ItemType Directory -Force -Path $LogDirectory -ErrorAction SilentlyContinue
|
|
}
|
|
|
|
$DateStamp = Get-Date -Format "yyyyMMdd_HHmmss"
|
|
$LogPath = Join-Path $LogDirectory "Installation_Applications_$DateStamp.log"
|
|
|
|
Write-Host "Répertoire logs: $LogDirectory"
|
|
|
|
# Début de l'enregistrement
|
|
Start-Transcript -Path $LogPath -Append -Force
|
|
|
|
Write-Host "========================================================"
|
|
Write-Host " DEBUT DU SCRIPT D'INSTALLATION DES APPLICATIONS"
|
|
Write-Host " Fichier log : $LogPath"
|
|
Write-Host "========================================================"
|
|
|
|
# =========================================================================
|
|
# 2. CONFIGURATION DE L'ENVIRONNEMENT SYSTEM POUR WINGET
|
|
# =========================================================================
|
|
$WingetDataPath = Join-Path $SystemRoot "System32\config\systemprofile\AppData\Local\Packages\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\LocalState"
|
|
|
|
if (!(Test-Path $WingetDataPath)) {
|
|
$null = New-Item -ItemType Directory -Force -Path $WingetDataPath -ErrorAction SilentlyContinue
|
|
}
|
|
|
|
$SettingsFile = Join-Path $WingetDataPath "settings.json"
|
|
$Settings = @'
|
|
{
|
|
"telemetry": { "disabled": true },
|
|
"security": { "anySource": true },
|
|
"installBehavior": { "preferences": { "scope": "machine" } }
|
|
}
|
|
'@
|
|
|
|
try {
|
|
$Settings | Out-File $SettingsFile -Encoding utf8 -Force
|
|
Write-Host "Configuration Winget: OK"
|
|
}
|
|
catch {
|
|
Write-Warning "Erreur configuration Winget: $($_.Exception.Message)"
|
|
}
|
|
|
|
# =========================================================================
|
|
# 3. VERIFICATION / UPGRADE WINGET V7
|
|
# =========================================================================
|
|
Write-Host ""
|
|
Write-Host "========================================================"
|
|
Write-Host " VERIFICATION WINGET V7"
|
|
Write-Host "========================================================"
|
|
|
|
try {
|
|
$WingetVersion = & winget --version 2>$null
|
|
Write-Host "Version actuelle: $WingetVersion"
|
|
|
|
# Upgrade si nécessaire
|
|
Write-Host "Tentative de mise à jour Winget..."
|
|
& winget upgrade winget --accept-source-agreements --silent 2>$null | Out-Null
|
|
Start-Sleep -Seconds 2
|
|
|
|
$NewVersion = & winget --version 2>$null
|
|
Write-Host "Version après upgrade: $NewVersion"
|
|
}
|
|
catch {
|
|
Write-Warning "Erreur lors de la gestion Winget: $($_.Exception.Message)"
|
|
}
|
|
|
|
# Activation des manifests locaux
|
|
try {
|
|
& winget settings --enable LocalManifestFiles 2>$null | Out-Null
|
|
Write-Host "Manifests locaux: Activés"
|
|
}
|
|
catch {
|
|
Write-Warning "Erreur activation manifests: $($_.Exception.Message)"
|
|
}
|
|
|
|
# =========================================================================
|
|
# 4. RECHERCHE ET TRAITEMENT DES APPLICATIONS
|
|
# =========================================================================
|
|
Write-Host ""
|
|
Write-Host "========================================================"
|
|
Write-Host " RECHERCHE DES MANIFESTS D'APPLICATION"
|
|
Write-Host "========================================================"
|
|
|
|
$AppsFolder = Join-Path $PSScriptRoot "Apps"
|
|
Write-Host "Dossier des applications: $AppsFolder"
|
|
|
|
if (!(Test-Path $AppsFolder)) {
|
|
Write-Error "Dossier Applications introuvable: $AppsFolder"
|
|
Stop-Transcript
|
|
exit 1
|
|
}
|
|
|
|
$Manifests = Get-ChildItem -Path $AppsFolder -Filter "*.yaml" -ErrorAction SilentlyContinue
|
|
$TotalApps = $Manifests.Count
|
|
|
|
Write-Host "Manifests trouvés: $TotalApps"
|
|
|
|
if ($TotalApps -eq 0) {
|
|
Write-Warning "Aucun fichier manifest .yaml trouvé dans $AppsFolder"
|
|
Stop-Transcript
|
|
exit 1
|
|
}
|
|
|
|
# =========================================================================
|
|
# 5. FONCTION DE VERIFICATION D'INSTALLATION
|
|
# =========================================================================
|
|
function Test-IsAppInstalled {
|
|
[CmdletBinding()]
|
|
param([string]$AppName)
|
|
|
|
try {
|
|
$Paths = @(
|
|
"HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*",
|
|
"HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
|
|
)
|
|
$Result = Get-ItemProperty $Paths -ErrorAction SilentlyContinue | `
|
|
Where-Object { $_.DisplayName -and $_.DisplayName -like "*$AppName*" }
|
|
return ($null -ne $Result)
|
|
}
|
|
catch {
|
|
Write-Warning "Erreur lors de la vérification $AppName : $($_.Exception.Message)"
|
|
return $false
|
|
}
|
|
}
|
|
|
|
# =========================================================================
|
|
# 6. PIPELINE DE TRAITEMENT DES APPLICATIONS
|
|
# =========================================================================
|
|
Write-Host ""
|
|
Write-Host "========================================================"
|
|
Write-Host " INSTALLATION DES APPLICATIONS"
|
|
Write-Host "========================================================"
|
|
|
|
$Global:CurrentAppIndex = 0
|
|
|
|
$Manifests | ForEach-Object {
|
|
$Global:CurrentAppIndex++
|
|
$Manifest = $_
|
|
|
|
$CleanName = ($Manifest.BaseName -split "_")[0]
|
|
$Sanitized = $CleanName -replace '[^a-zA-Z0-9]', ''
|
|
|
|
Write-Host "[$Global:CurrentAppIndex/$TotalApps] Vérification : $CleanName" -ForegroundColor Cyan
|
|
|
|
if (Test-IsAppInstalled -AppName $CleanName) {
|
|
Write-Host " -> PASSER : Déjà installé." -ForegroundColor Yellow
|
|
return
|
|
}
|
|
|
|
$InstallerFile = Get-ChildItem -Path $AppsFolder | Where-Object {
|
|
$_.Extension -in ".exe", ".msi" -and `
|
|
($_.Name -ilike "*$Sanitized*" -or $_.Name -ilike "*$CleanName*")
|
|
} | Select-Object -First 1
|
|
|
|
if (!$InstallerFile) {
|
|
Write-Host " -> ÉCHEC : Fichier installateur introuvable pour $CleanName" -ForegroundColor Red
|
|
return
|
|
}
|
|
|
|
$FullFileName = $InstallerFile.Name.ToLower()
|
|
$Executable = $InstallerFile.FullName
|
|
$Arguments = "/S"
|
|
|
|
# =========================================================================
|
|
# Détermination des arguments selon le type de fichier
|
|
# =========================================================================
|
|
if ($InstallerFile.Extension -eq ".msi") {
|
|
$Executable = "msiexec.exe"
|
|
$Arguments = "/i `"$($InstallerFile.FullName)`" /qn /norestart"
|
|
|
|
if (Get-Process -Name "msiexec" -ErrorAction SilentlyContinue) {
|
|
Write-Host " -> Nettoyage processus msiexec..." -ForegroundColor DarkYellow
|
|
Stop-Process -Name "msiexec" -Force -ErrorAction SilentlyContinue
|
|
Start-Sleep -Seconds 2
|
|
}
|
|
}
|
|
else {
|
|
switch -regex ($FullFileName) {
|
|
"7z|7zip" { $Arguments = "/S" }
|
|
"notepad" { $Arguments = "/S" }
|
|
"vlc" { $Arguments = "/S" }
|
|
"audacity" { $Arguments = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART" }
|
|
"python" { $Arguments = "/quiet InstallAllUsers=1 PrependPath=1 Include_test=0" }
|
|
default { $Arguments = "/S" }
|
|
}
|
|
}
|
|
|
|
# =========================================================================
|
|
# Exécution de l'installation
|
|
# =========================================================================
|
|
try {
|
|
Write-Host " -> Installation: $($InstallerFile.Name)" -ForegroundColor White
|
|
Write-Host " Exécutable: $Executable"
|
|
Write-Host " Arguments: $Arguments"
|
|
|
|
$Process = Start-Process -FilePath $Executable -ArgumentList $Arguments `
|
|
-NoNewWindow -Wait -PassThru -ErrorAction Stop
|
|
|
|
$ExitCode = $Process.ExitCode
|
|
if ($ExitCode -eq 0 -or $ExitCode -eq 3010) {
|
|
Write-Host " -> SUCCÈS (Code: $ExitCode)`n" -ForegroundColor Green
|
|
}
|
|
else {
|
|
Write-Host " -> ÉCHEC. Code erreur: $ExitCode" -ForegroundColor Red
|
|
Write-Host " Args: $Arguments`n" -ForegroundColor DarkRed
|
|
}
|
|
}
|
|
catch {
|
|
Write-Host " -> ERREUR CRITIQUE: $($_.Exception.Message)`n" -ForegroundColor Red
|
|
}
|
|
}
|
|
|
|
# =========================================================================
|
|
# 7. FINALISATION
|
|
# =========================================================================
|
|
Write-Host "========================================================"
|
|
Write-Host " TRAITEMENT TERMINÉ"
|
|
Write-Host "========================================================"
|
|
Write-Host "Logs disponibles: $LogPath"
|
|
|
|
Stop-Transcript |