commit e1b14a42aa7795ac0c57b3fe9e9669bb41a92abd Author: zogzog Date: Tue Mar 24 08:02:01 2026 +0100 initial commit diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..72f5169 --- /dev/null +++ b/Readme.md @@ -0,0 +1,37 @@ +# Readme + +--- + +## Description + +Le script **Info PC** récupère des informations détaillées sur le système informatique, y compris les données sur le matériel, le logiciel, le réseau et plus encore. Les résultats sont enregistrés dans un fichier HTML, offrant une vue d'ensemble conviviale des spécifications du PC. + +## Fonctionnalités + +- Récupère les informations suivantes : + - Nom du PC + - Version de Windows + - Informations sur le processeur et la mémoire + - État de la batterie (pour les ordinateurs portables) + - Détails sur les imprimantes installées + - Liste des utilisateurs + - Logiciels installés + - Configuration réseau + - Utilisation de l'espace disque +- Génère un rapport en format HTML avec des onglets pour naviguer facilement entre les différentes sections. +- Possibilité d'envoyer le rapport par e-mail. + +## Utilisation + +1. Exécutez le script dans PowerShell. +2. Saisissez le nom du fichier HTML souhaité (sans extension) ou laissez vide pour utiliser le nom de la machine. +3. Choisissez le type de PC (PC de bureau ou portable). +4. Le rapport sera généré et enregistré dans un dossier nommé ` - Info PC`. +5. Un e-mail sera envoyé avec le rapport en pièce jointe. + +## Prérequis + +- PowerShell exécuté avec les autorisations nécessaires pour accéder aux informations système. +- Connexion Internet (pour l'envoi d'e-mail). + +![](/api/files/019c509f-7139-739d-821f-014fcb297de7/image.png) \ No newline at end of file diff --git a/tools-info-pc-Win10-11.ps1 b/tools-info-pc-Win10-11.ps1 new file mode 100644 index 0000000..bbba839 --- /dev/null +++ b/tools-info-pc-Win10-11.ps1 @@ -0,0 +1,1606 @@ +# Powershell + +# Nom: Info PC +# Description: Récupère les informations du PC +# Version: 0.5.0 +# Categorie: Tools +# Changelog: +# - Ajout de la section Batterie complète +# - Amélioration de la gestion des erreurs +# - Configuration externalisée (SMTP) +# - Utilisation cohérente de Get-CimInstance +# - Ajout d'informations système supplémentaires +# - Meilleure détection du type de RAM +# - Ajout des informations TPM +# - Optimisation des performances + +#Requires -Version 5.1 + +# ============================================================================ +# CONFIGURATION +# ============================================================================ + +$Script:Config = @{ + # Configuration SMTP - À externaliser dans un fichier config.json + SMTP = @{ + Server = "ssl0.ovh.net" + Port = 587 + From = "system@microinfoservice.fr" + To = "system@microinfoservice.fr" + Username = "system@microinfoservice.fr" + # ATTENTION: Ne pas laisser le mot de passe en clair en production! + # Utiliser: Get-Credential | Export-Clixml -Path "cred.xml" + # Puis: Import-Clixml -Path "cred.xml" + Password = $null # Sera demandé ou chargé depuis un fichier sécurisé + } + + # Options du script + Options = @{ + SendEmail = $true + OpenReportOnEnd = $true + IncludeWifiPasswords = $false # Attention: nécessite droits admin + } +} + +# ============================================================================ +# FONCTIONS UTILITAIRES +# ============================================================================ + +function Write-Log { + param( + [string]$Message, + [ValidateSet('Info', 'Warning', 'Error', 'Success')] + [string]$Level = 'Info' + ) + + $colors = @{ + 'Info' = 'White' + 'Warning' = 'Yellow' + 'Error' = 'Red' + 'Success' = 'Green' + } + + $timestamp = Get-Date -Format "HH:mm:ss" + Write-Host "[$timestamp] " -NoNewline -ForegroundColor Gray + Write-Host $Message -ForegroundColor $colors[$Level] +} + +function Format-Size { + param([int64]$Size) + + if ($Size -lt 0) { return "N/A" } + if ($Size -gt 1TB) { return "{0:N2} To" -f ($Size / 1TB) } + if ($Size -gt 1GB) { return "{0:N2} Go" -f ($Size / 1GB) } + if ($Size -gt 1MB) { return "{0:N2} Mo" -f ($Size / 1MB) } + if ($Size -gt 1KB) { return "{0:N2} Ko" -f ($Size / 1KB) } + return "$Size octets" +} + +function Get-FormattedInstallDate { + param([string]$InstallDate) + + if ([string]::IsNullOrEmpty($InstallDate)) { return 'N/A' } + + try { + return [DateTime]::ParseExact($InstallDate, 'yyyyMMdd', $null).ToString("dd/MM/yyyy") + } + catch { + return 'N/A' + } +} + +function Get-SafeValue { + param( + $Value, + [string]$Default = "N/A" + ) + + if ($null -eq $Value -or [string]::IsNullOrWhiteSpace($Value.ToString())) { + return $Default + } + return $Value +} + +function Get-RAMTypeName { + param([int]$TypeCode) + + $ramTypes = @{ + 0 = "Unknown" + 1 = "Other" + 2 = "DRAM" + 3 = "Synchronous DRAM" + 4 = "Cache DRAM" + 5 = "EDO" + 6 = "EDRAM" + 7 = "VRAM" + 8 = "SRAM" + 9 = "RAM" + 10 = "ROM" + 11 = "Flash" + 12 = "EEPROM" + 13 = "FEPROM" + 14 = "EPROM" + 15 = "CDRAM" + 16 = "3DRAM" + 17 = "SDRAM" + 18 = "SGRAM" + 19 = "RDRAM" + 20 = "DDR" + 21 = "DDR2" + 22 = "DDR2 FB-DIMM" + 24 = "DDR3" + 25 = "FBD2" + 26 = "DDR4" + 27 = "LPDDR" + 28 = "LPDDR2" + 29 = "LPDDR3" + 30 = "LPDDR4" + 34 = "DDR5" + 35 = "LPDDR5" + } + + if ($ramTypes.ContainsKey($TypeCode)) { + return $ramTypes[$TypeCode] + } + return "Unknown ($TypeCode)" +} + +function Test-IsAdmin { + $currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent()) + return $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) +} + +# ============================================================================ +# FONCTIONS DE COLLECTE D'INFORMATIONS +# ============================================================================ + +function Get-SystemInfo { + Write-Log "Collecte des informations système..." -Level Info + + try { + $os = Get-CimInstance Win32_OperatingSystem + $cs = Get-CimInstance Win32_ComputerSystem + $bios = Get-CimInstance Win32_BIOS + $mb = Get-CimInstance Win32_BaseBoard + $cpu = Get-CimInstance Win32_Processor | Select-Object -First 1 + + # Correction pour Windows 11 + $buildNumber = [int](Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion').CurrentBuildNumber + $windowsVersion = $os.Caption + if ($buildNumber -ge 22000) { + $windowsVersion = $windowsVersion -replace "Windows 10", "Windows 11" + } + + # DisplayVersion (ex: 23H2) + $displayVersion = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' -ErrorAction SilentlyContinue).DisplayVersion + if ($displayVersion) { + $windowsVersion += " ($displayVersion)" + } + + # Secure Boot + try { + $secureBootStatus = Confirm-SecureBootUEFI -ErrorAction Stop + $secureBootText = if ($secureBootStatus) { "Activé" } else { "Désactivé" } + } + catch { + $secureBootText = "Non disponible (BIOS legacy)" + } + + # TPM + try { + $tpm = Get-CimInstance -Namespace "root\cimv2\Security\MicrosoftTpm" -ClassName Win32_Tpm -ErrorAction Stop + $tpmInfo = @{ + Present = $true + Version = $tpm.SpecVersion + Enabled = $tpm.IsEnabled_InitialValue + Activated = $tpm.IsActivated_InitialValue + } + } + catch { + $tpmInfo = @{ + Present = $false + Version = "N/A" + Enabled = $false + Activated = $false + } + } + + # Uptime + $uptime = (Get-Date) - $os.LastBootUpTime + $uptimeString = "{0}j {1}h {2}m" -f $uptime.Days, $uptime.Hours, $uptime.Minutes + + return @{ + ComputerName = $env:COMPUTERNAME + WindowsVersion = $windowsVersion + BuildNumber = $buildNumber + Architecture = $os.OSArchitecture + InstallDate = $os.InstallDate.ToString("dd/MM/yyyy HH:mm") + LastBoot = $os.LastBootUpTime.ToString("dd/MM/yyyy HH:mm") + Uptime = $uptimeString + SecureBoot = $secureBootText + TPM = $tpmInfo + Manufacturer = Get-SafeValue $cs.Manufacturer + Model = Get-SafeValue $cs.Model + Motherboard = Get-SafeValue $mb.Product + MotherboardMfr = Get-SafeValue $mb.Manufacturer + BiosVersion = Get-SafeValue $bios.SMBIOSBIOSVersion + BiosManufacturer = Get-SafeValue $bios.Manufacturer + BiosName = Get-SafeValue $bios.Name + BiosDate = if ($bios.ReleaseDate) { $bios.ReleaseDate.ToString("dd/MM/yyyy") } else { "N/A" } + CPU = Get-SafeValue $cpu.Name + CPUCores = $cpu.NumberOfCores + CPUThreads = $cpu.NumberOfLogicalProcessors + CPUSocket = Get-SafeValue $cpu.SocketDesignation + CPUMaxSpeed = "{0} MHz" -f $cpu.MaxClockSpeed + } + } + catch { + Write-Log "Erreur lors de la collecte des informations système: $_" -Level Error + return $null + } +} + +function Get-MemoryInfo { + Write-Log "Collecte des informations mémoire..." -Level Info + + try { + $memoryArray = Get-CimInstance Win32_PhysicalMemoryArray + $memoryModules = Get-CimInstance Win32_PhysicalMemory + + $totalSlots = ($memoryArray | Measure-Object -Property MemoryDevices -Sum).Sum + $usedSlots = ($memoryModules | Measure-Object).Count + $totalCapacity = ($memoryModules | Measure-Object -Property Capacity -Sum).Sum + + $modules = @() + foreach ($module in $memoryModules) { + $modules += @{ + Manufacturer = Get-SafeValue $module.Manufacturer + PartNumber = Get-SafeValue ($module.PartNumber -replace '\s+', ' ').Trim() + Capacity = Format-Size $module.Capacity + Speed = "{0} MHz" -f $module.ConfiguredClockSpeed + Type = Get-RAMTypeName $module.SMBIOSMemoryType + DeviceLocator = Get-SafeValue $module.DeviceLocator + FormFactor = switch ($module.FormFactor) { + 8 { "DIMM" } + 12 { "SO-DIMM" } + default { "Autre" } + } + } + } + + return @{ + TotalCapacity = Format-Size $totalCapacity + TotalSlots = $totalSlots + UsedSlots = $usedSlots + Modules = $modules + } + } + catch { + Write-Log "Erreur lors de la collecte des informations mémoire: $_" -Level Error + return $null + } +} + +function Get-GPUInfo { + Write-Log "Collecte des informations GPU..." -Level Info + + try { + $gpus = Get-CimInstance Win32_VideoController + $gpuList = @() + + foreach ($gpu in $gpus) { + $gpuList += @{ + Name = Get-SafeValue $gpu.Name + Processor = Get-SafeValue $gpu.VideoProcessor + RAM = if ($gpu.AdapterRAM -gt 0) { Format-Size $gpu.AdapterRAM } else { "N/A" } + Driver = Get-SafeValue $gpu.DriverVersion + Resolution = "{0}x{1}" -f $gpu.CurrentHorizontalResolution, $gpu.CurrentVerticalResolution + RefreshRate = "{0} Hz" -f $gpu.CurrentRefreshRate + } + } + + return $gpuList + } + catch { + Write-Log "Erreur lors de la collecte des informations GPU: $_" -Level Error + return @() + } +} + +function Get-StorageInfo { + Write-Log "Collecte des informations stockage..." -Level Info + + try { + $disks = Get-PhysicalDisk -ErrorAction SilentlyContinue + $volumes = Get-Volume -ErrorAction SilentlyContinue | Where-Object { $_.DriveLetter } + $bitlockerVolumes = @{} + + try { + $blVolumes = Get-BitLockerVolume -ErrorAction SilentlyContinue + foreach ($bl in $blVolumes) { + $bitlockerVolumes[$bl.MountPoint.TrimEnd('\')] = $bl + } + } + catch { + Write-Log "BitLocker non disponible ou accès refusé" -Level Warning + } + + $diskList = @() + foreach ($disk in $disks) { + $diskList += @{ + Model = Get-SafeValue $disk.FriendlyName + Type = Get-SafeValue $disk.MediaType "Unknown" + Size = Format-Size $disk.Size + Health = Get-SafeValue $disk.HealthStatus + BusType = Get-SafeValue $disk.BusType + Serial = Get-SafeValue $disk.SerialNumber + } + } + + $volumeList = @() + foreach ($vol in $volumes) { + $driveLetter = "$($vol.DriveLetter):" + $bl = $bitlockerVolumes[$driveLetter] + + $usedPercent = 0 + if ($vol.Size -gt 0) { + $usedPercent = [math]::Round((($vol.Size - $vol.SizeRemaining) / $vol.Size) * 100) + } + + $volumeList += @{ + Letter = $driveLetter + Label = Get-SafeValue $vol.FileSystemLabel "Sans nom" + FileSystem = Get-SafeValue $vol.FileSystem + Size = Format-Size $vol.Size + Free = Format-Size $vol.SizeRemaining + Used = Format-Size ($vol.Size - $vol.SizeRemaining) + UsedPercent = $usedPercent + BitLockerStatus = if ($bl) { $bl.ProtectionStatus.ToString() } else { "Non protégé" } + BitLockerMethod = if ($bl -and $bl.EncryptionMethod) { $bl.EncryptionMethod.ToString() } else { "N/A" } + } + } + + return @{ + Disks = $diskList + Volumes = $volumeList + } + } + catch { + Write-Log "Erreur lors de la collecte des informations stockage: $_" -Level Error + return @{ Disks = @(); Volumes = @() } + } +} + +function Get-NetworkInfo { + Write-Log "Collecte des informations réseau..." -Level Info + + try { + $cs = Get-CimInstance Win32_ComputerSystem + $adapters = Get-NetAdapter | Where-Object { $_.Status -eq 'Up' -or $_.PhysicalMediaType } + $ipConfigs = Get-NetIPAddress -AddressFamily IPv4 | Where-Object { $_.InterfaceAlias -ne 'Loopback Pseudo-Interface 1' } + $dnsServers = (Get-DnsClientServerAddress -AddressFamily IPv4 | Select-Object -ExpandProperty ServerAddresses) -join ', ' + $gateway = (Get-NetRoute -AddressFamily IPv4 | Where-Object { $_.DestinationPrefix -eq '0.0.0.0/0' } | Select-Object -First 1).NextHop + $networkDrives = Get-CimInstance Win32_NetworkConnection | Where-Object { $_.LocalName } + + # Domaine/Workgroup + $domainInfo = if ($cs.PartOfDomain) { + "Domaine: $($cs.Domain)" + } else { + "Groupe de travail: $($cs.Workgroup)" + } + + # Adaptateurs + $adapterList = @() + foreach ($adapter in $adapters) { + $ipConfig = $ipConfigs | Where-Object { $_.InterfaceAlias -eq $adapter.Name } + + $adapterList += @{ + Name = $adapter.Name + Description = $adapter.InterfaceDescription + Status = $adapter.Status + Speed = if ($adapter.LinkSpeed) { $adapter.LinkSpeed } else { "N/A" } + MAC = $adapter.MacAddress + IPAddress = if ($ipConfig) { $ipConfig.IPAddress -join ', ' } else { "N/A" } + Type = Get-SafeValue $adapter.MediaType + } + } + + # Lecteurs réseau + $drivesList = @() + foreach ($drive in $networkDrives) { + $drivesList += @{ + Letter = $drive.LocalName + Path = $drive.RemoteName + } + } + + # Profils WiFi + $wifiProfiles = @() + try { + $profilesOutput = netsh wlan show profiles 2>$null + if ($profilesOutput) { + $profileNames = $profilesOutput | Select-String -Pattern ':\s*(.+)$' | ForEach-Object { + $_.ToString().Split(':')[-1].Trim() + } | Where-Object { $_ } + + foreach ($profileName in $profileNames) { + if ([string]::IsNullOrWhiteSpace($profileName)) { continue } + + $profileDetails = netsh wlan show profile name="$profileName" 2>$null | Out-String + + $authType = "N/A" + if ($profileDetails -match "(Type d'authentification|Authentication)\s*:\s*(.*)") { + $authType = $matches[2].Trim() + } + + $wifiProfiles += @{ + SSID = $profileName + Authentication = $authType + } + } + } + } + catch { + Write-Log "Erreur lors de la récupération des profils WiFi: $_" -Level Warning + } + + # Fichier hosts + $hostsContent = "" + try { + $hostsPath = "$env:SystemRoot\System32\drivers\etc\hosts" + $hostsContent = Get-Content -Path $hostsPath -Raw -ErrorAction Stop + } + catch { + $hostsContent = "Impossible de lire le fichier hosts" + } + + return @{ + DomainInfo = $domainInfo + Adapters = $adapterList + DNS = $dnsServers + Gateway = Get-SafeValue $gateway + NetworkDrives = $drivesList + WifiProfiles = $wifiProfiles + HostsFile = $hostsContent + } + } + catch { + Write-Log "Erreur lors de la collecte des informations réseau: $_" -Level Error + return $null + } +} + +function Get-UserInfo { + Write-Log "Collecte des informations utilisateurs..." -Level Info + + try { + $users = Get-CimInstance Win32_UserAccount | Where-Object { $_.LocalAccount -eq $true } + + $userList = @() + foreach ($user in $users) { + $userList += @{ + Name = $user.Name + FullName = Get-SafeValue $user.FullName + Description = Get-SafeValue $user.Description + Status = if ($user.Disabled) { "Désactivé" } else { "Actif" } + SID = $user.SID + } + } + + return $userList + } + catch { + Write-Log "Erreur lors de la collecte des informations utilisateurs: $_" -Level Error + return @() + } +} + +function Get-SoftwareInfo { + Write-Log "Collecte des logiciels installés..." -Level Info + + try { + $software = @() + + $regPaths = @( + "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*", + "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" + ) + + foreach ($path in $regPaths) { + $items = Get-ItemProperty $path -ErrorAction SilentlyContinue | + Where-Object { $_.DisplayName } | + Select-Object DisplayName, DisplayVersion, Publisher, InstallDate + + $software += $items + } + + $software = $software | Sort-Object -Property DisplayName -Unique | ForEach-Object { + @{ + Name = $_.DisplayName + Version = Get-SafeValue $_.DisplayVersion + Publisher = Get-SafeValue $_.Publisher + InstallDate = Get-FormattedInstallDate $_.InstallDate + } + } + + return $software + } + catch { + Write-Log "Erreur lors de la collecte des logiciels: $_" -Level Error + return @() + } +} + +function Get-StartupInfo { + Write-Log "Collecte des programmes de démarrage..." -Level Info + + try { + $startupItems = @() + + # WMI Startup Commands + $wmiItems = Get-CimInstance Win32_StartupCommand -ErrorAction SilentlyContinue + foreach ($item in $wmiItems) { + $startupItems += @{ + Name = Get-SafeValue $item.Name + Command = Get-SafeValue $item.Command + Location = Get-SafeValue $item.Location + User = if ([string]::IsNullOrEmpty($item.User)) { "Tous" } else { $item.User } + Status = "Activé" + } + } + + # Registry Run keys + $runKeys = @( + @{ Path = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"; User = "Tous" }, + @{ Path = "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"; User = $env:USERNAME } + ) + + foreach ($key in $runKeys) { + if (Test-Path $key.Path) { + $items = Get-ItemProperty -Path $key.Path -ErrorAction SilentlyContinue + foreach ($prop in $items.PSObject.Properties) { + if ($prop.Name -notin @("PSPath", "PSParentPath", "PSChildName", "PSDrive", "PSProvider")) { + $startupItems += @{ + Name = $prop.Name + Command = $prop.Value + Location = $key.Path -replace 'HKLM:|HKCU:', '' + User = $key.User + Status = "Activé" + } + } + } + } + } + + # Remove duplicates based on Name + $uniqueItems = @{} + foreach ($item in $startupItems) { + if (-not $uniqueItems.ContainsKey($item.Name)) { + $uniqueItems[$item.Name] = $item + } + } + + return $uniqueItems.Values + } + catch { + Write-Log "Erreur lors de la collecte des programmes de démarrage: $_" -Level Error + return @() + } +} + +function Get-PrinterInfo { + Write-Log "Collecte des informations imprimantes..." -Level Info + + try { + $printers = Get-CimInstance Win32_Printer + + $printerList = @() + foreach ($printer in $printers) { + $driver = Get-PrinterDriver -Name $printer.DriverName -ErrorAction SilentlyContinue + + $printerList += @{ + Name = $printer.Name + Status = switch ($printer.PrinterStatus) { + 1 { "Other" } + 2 { "Unknown" } + 3 { "Idle" } + 4 { "Printing" } + 5 { "Warmup" } + 6 { "Stopped Printing" } + 7 { "Offline" } + default { $printer.PrinterStatus } + } + Port = Get-SafeValue $printer.PortName + Driver = Get-SafeValue $printer.DriverName + Manufacturer = if ($driver) { Get-SafeValue $driver.Manufacturer } else { "N/A" } + Default = $printer.Default + Shared = $printer.Shared + } + } + + return $printerList + } + catch { + Write-Log "Erreur lors de la collecte des informations imprimantes: $_" -Level Error + return @() + } +} + +function Get-MailInfo { + Write-Log "Collecte des informations mail..." -Level Info + + $result = @{ + OutlookAccounts = @() + OutlookFiles = @() + ThunderbirdProfiles = @() + } + + # Fichiers Outlook (PST/OST) + $searchPaths = @( + "$env:LOCALAPPDATA\Microsoft\Outlook", + [System.IO.Path]::Combine($env:USERPROFILE, 'Documents'), + [System.IO.Path]::Combine($env:USERPROFILE, 'Documents', 'Outlook Files') + ) + + foreach ($searchPath in $searchPaths) { + if (Test-Path $searchPath) { + try { + $files = Get-ChildItem -Path $searchPath -Include "*.pst", "*.ost" -Recurse -ErrorAction SilentlyContinue + foreach ($file in $files) { + $result.OutlookFiles += @{ + Name = $file.Name + Path = $file.FullName + Size = Format-Size $file.Length + Type = $file.Extension.ToUpper().TrimStart('.') + } + } + } + catch { + Write-Log "Erreur lors de la recherche des fichiers Outlook dans $searchPath" -Level Warning + } + } + } + + # Profils Thunderbird + $thunderbirdPath = "$env:APPDATA\Thunderbird\Profiles" + if (Test-Path $thunderbirdPath) { + try { + $profiles = Get-ChildItem -Path $thunderbirdPath -Directory -ErrorAction SilentlyContinue + foreach ($profile in $profiles) { + $size = (Get-ChildItem -Path $profile.FullName -Recurse -File -ErrorAction SilentlyContinue | + Measure-Object -Property Length -Sum).Sum + + $result.ThunderbirdProfiles += @{ + Name = $profile.Name + Path = $profile.FullName + Size = Format-Size $size + } + } + } + catch { + Write-Log "Erreur lors de la recherche des profils Thunderbird" -Level Warning + } + } + + # Comptes Outlook (via COM) + try { + $outlook = New-Object -ComObject Outlook.Application -ErrorAction Stop + $namespace = $outlook.GetNamespace("MAPI") + + foreach ($account in $outlook.Session.Accounts) { + $accountType = "Inconnu" + $deliveryStore = $account.DeliveryStore.FilePath + + if ($deliveryStore -like "*.ost") { + $accountType = "Exchange/Office 365" + } + elseif ($deliveryStore -like "*.pst") { + $accountType = switch ($account.AccountType) { + 1 { "IMAP" } + 2 { "POP3" } + default { "POP3/IMAP" } + } + } + + $result.OutlookAccounts += @{ + Name = $account.DisplayName + Email = $account.SmtpAddress + Type = $accountType + Store = $deliveryStore + } + } + + [System.Runtime.Interopservices.Marshal]::ReleaseComObject($namespace) | Out-Null + [System.Runtime.Interopservices.Marshal]::ReleaseComObject($outlook) | Out-Null + [System.GC]::Collect() + [System.GC]::WaitForPendingFinalizers() + } + catch { + Write-Log "Outlook non installé ou non accessible" -Level Warning + } + + return $result +} + +function Get-BatteryInfo { + param([bool]$IncludeBatteryTest) + + if (-not $IncludeBatteryTest) { + return @{ + Available = $false + Message = "Test de batterie ignoré (PC de bureau)" + } + } + + Write-Log "Collecte des informations batterie..." -Level Info + + try { + $battery = Get-CimInstance Win32_Battery -ErrorAction SilentlyContinue + + if (-not $battery) { + return @{ + Available = $false + Message = "Aucune batterie détectée" + } + } + + # Générer le rapport batterie Windows + $reportPath = [System.IO.Path]::Combine($script:FolderPath, 'battery_report.html') + + try { + $null = powercfg /batteryreport /output $reportPath 2>&1 + $reportGenerated = Test-Path $reportPath + } + catch { + $reportGenerated = $false + } + + # Status de la batterie + $batteryStatus = switch ($battery.BatteryStatus) { + 1 { "Décharge" } + 2 { "Secteur (non en charge)" } + 3 { "Chargement" } + 4 { "Charge faible" } + 5 { "Charge critique" } + 6 { "En charge" } + 7 { "En charge et haute" } + 8 { "En charge et faible" } + 9 { "En charge et critique" } + 10 { "Non défini" } + 11 { "Partiellement chargée" } + default { "Inconnu" } + } + + # Santé estimée + $designCapacity = $battery.DesignCapacity + $fullChargeCapacity = $battery.FullChargeCapacity + $healthPercent = 100 + + if ($designCapacity -gt 0 -and $fullChargeCapacity -gt 0) { + $healthPercent = [math]::Round(($fullChargeCapacity / $designCapacity) * 100) + } + + $healthStatus = if ($healthPercent -ge 80) { "Bonne" } + elseif ($healthPercent -ge 50) { "Moyenne" } + else { "Faible" } + + return @{ + Available = $true + ChargeLevel = "$($battery.EstimatedChargeRemaining)%" + Status = $batteryStatus + DesignCapacity = if ($designCapacity) { "$designCapacity mWh" } else { "N/A" } + FullChargeCapacity = if ($fullChargeCapacity) { "$fullChargeCapacity mWh" } else { "N/A" } + HealthPercent = $healthPercent + HealthStatus = $healthStatus + DeviceID = Get-SafeValue $battery.DeviceID + ReportGenerated = $reportGenerated + ReportPath = if ($reportGenerated) { $reportPath } else { $null } + } + } + catch { + Write-Log "Erreur lors de la collecte des informations batterie: $_" -Level Error + return @{ + Available = $false + Message = "Erreur: $_" + } + } +} + +# ============================================================================ +# GÉNÉRATION HTML +# ============================================================================ + +function New-HTMLReport { + param( + [hashtable]$SystemInfo, + [hashtable]$MemoryInfo, + [array]$GPUInfo, + [hashtable]$StorageInfo, + [hashtable]$NetworkInfo, + [array]$UserInfo, + [array]$SoftwareInfo, + [array]$StartupInfo, + [array]$PrinterInfo, + [hashtable]$MailInfo, + [hashtable]$BatteryInfo + ) + + $htmlTemplate = @" + + + + + + Info PC - $($SystemInfo.ComputerName) + + + + +
+

🖥️ Info PC - $($SystemInfo.ComputerName)

+
Rapport généré le $(Get-Date -Format "dd/MM/yyyy à HH:mm")
+
+ +
+
+ + + + + + + + + +
+
+ + +
+
+
+

Informations Système

+ + + + + + + +
Nom du PC$($SystemInfo.ComputerName)
Windows$($SystemInfo.WindowsVersion)
Architecture$($SystemInfo.Architecture)
Date d'installation$($SystemInfo.InstallDate)
Dernier démarrage$($SystemInfo.LastBoot)
Uptime$($SystemInfo.Uptime)
+
+ +
+

Sécurité

+ + + + $(if($SystemInfo.TPM.Present){""}else{""}) +
Secure Boot$(if($SystemInfo.SecureBoot -eq 'Activé'){'Activé'}else{''+$SystemInfo.SecureBoot+''})
TPM$(if($SystemInfo.TPM.Present){'Présent'}else{'Non détecté'})
Version TPM$($SystemInfo.TPM.Version)
+
+
+ +
+
+

Matériel

+ + + + +
Fabricant$($SystemInfo.Manufacturer)
Modèle$($SystemInfo.Model)
Carte mère$($SystemInfo.MotherboardMfr) $($SystemInfo.Motherboard)
+
+ +
+

BIOS

+ + + + +
Version$($SystemInfo.BiosVersion)
Fabricant$($SystemInfo.BiosManufacturer)
Date$($SystemInfo.BiosDate)
+
+
+ +
+

Processeur

+ + + + + +
CPU$($SystemInfo.CPU)
Cœurs / Threads$($SystemInfo.CPUCores) cœurs / $($SystemInfo.CPUThreads) threads
Socket$($SystemInfo.CPUSocket)
Fréquence max$($SystemInfo.CPUMaxSpeed)
+
+ +
+

Mémoire RAM

+ + + +
Capacité totale$($MemoryInfo.TotalCapacity)
Slots utilisés$($MemoryInfo.UsedSlots) / $($MemoryInfo.TotalSlots)
+ +

Détails des modules

+ + + $(foreach($module in $MemoryInfo.Modules) { + "" + }) +
EmplacementFabricantRéférenceCapacitéTypeVitesse
$($module.DeviceLocator)$($module.Manufacturer)$($module.PartNumber)$($module.Capacity)$($module.Type)$($module.Speed)
+
+ +
+

Carte(s) Graphique(s)

+ + + $(foreach($gpu in $GPUInfo) { + "" + }) +
NomProcesseurVRAMDriverRésolution
$($gpu.Name)$($gpu.Processor)$($gpu.RAM)$($gpu.Driver)$($gpu.Resolution) @ $($gpu.RefreshRate)
+
+
+ + +
+
+

Comptes Utilisateurs Locaux

+ + + $(foreach($user in $UserInfo) { + $statusBadge = if($user.Status -eq 'Actif'){'Actif'}else{'Désactivé'} + "" + }) +
NomNom completDescriptionStatut
$($user.Name)$($user.FullName)$($user.Description)$statusBadge
+
+
+ + +
+
+

Logiciels Installés ($($SoftwareInfo.Count) programmes)

+ + + $(foreach($soft in $SoftwareInfo) { + "" + }) +
NomVersionÉditeurDate d'installation
$($soft.Name)$($soft.Version)$($soft.Publisher)$($soft.InstallDate)
+
+
+ + +
+
+

Configuration Réseau

+ + + + +
Domaine / Groupe$($NetworkInfo.DomainInfo)
DNS$($NetworkInfo.DNS)
Passerelle$($NetworkInfo.Gateway)
+
+ +
+

Adaptateurs Réseau

+ + + $(foreach($adapter in $NetworkInfo.Adapters) { + $statusBadge = if($adapter.Status -eq 'Up'){'Connecté'}else{''+$adapter.Status+''} + "" + }) +
NomDescriptionStatutVitesseMACIP
$($adapter.Name)$($adapter.Description)$statusBadge$($adapter.Speed)$($adapter.MAC)$($adapter.IPAddress)
+
+ + $(if($NetworkInfo.NetworkDrives.Count -gt 0) { + "
+

Lecteurs Réseau

+ + + $(foreach($drive in $NetworkInfo.NetworkDrives) { + "" + }) +
LettreChemin réseau
$($drive.Letter)$($drive.Path)
+
" + } else { + "

Lecteurs Réseau

Aucun lecteur réseau connecté.

" + }) + + $(if($NetworkInfo.WifiProfiles.Count -gt 0) { + "
+

Profils WiFi Enregistrés ($($NetworkInfo.WifiProfiles.Count))

+ + + $(foreach($wifi in $NetworkInfo.WifiProfiles) { + "" + }) +
SSIDAuthentification
$($wifi.SSID)$($wifi.Authentication)
+
" + }) + +
+

Fichier Hosts

+
$($NetworkInfo.HostsFile)
+
+
+ + +
+
+

Disques Physiques

+ + + $(foreach($disk in $StorageInfo.Disks) { + $healthBadge = switch($disk.Health) { + 'Healthy' { 'Bon' } + 'Warning' { 'Attention' } + 'Unhealthy' { 'Défectueux' } + default { $disk.Health } + } + "" + }) +
ModèleTypeCapacitéInterfaceSantéN° Série
$($disk.Model)$($disk.Type)$($disk.Size)$($disk.BusType)$healthBadge$($disk.Serial)
+
+ +
+

Volumes

+ + + $(foreach($vol in $StorageInfo.Volumes) { + $progressClass = if($vol.UsedPercent -gt 90){'progress-red'}elseif($vol.UsedPercent -gt 75){'progress-yellow'}else{'progress-green'} + $blBadge = switch($vol.BitLockerStatus) { + 'On' { 'Protégé' } + 'Off' { 'Désactivé' } + default { 'Non protégé' } + } + " + + + + + + " + }) +
LettreNomSystème de fichiersUtilisationBitLocker
$($vol.Letter)$($vol.Label)$($vol.FileSystem) +
+
$($vol.UsedPercent)%
+
+ $($vol.Used) / $($vol.Size) (libre: $($vol.Free)) +
$blBadge
+
+
+ + +
+
+ ⚠️ Note: Le script scanne uniquement les dossiers AppData\Microsoft\Outlook, Thunderbird\Profiles, et le dossier Documents. +
+ + $(if($MailInfo.OutlookAccounts.Count -gt 0) { + "
+

Comptes Outlook Configurés

+ + + $(foreach($account in $MailInfo.OutlookAccounts) { + "" + }) +
NomEmailTypeFichier de données
$($account.Name)$($account.Email)$($account.Type)$($account.Store)
+
" + } else { + "

Comptes Outlook

Aucun compte Outlook détecté ou Outlook n'est pas installé.

" + }) + +
+

Fichiers Outlook (PST/OST)

+ $(if($MailInfo.OutlookFiles.Count -gt 0) { + " + + $(foreach($file in $MailInfo.OutlookFiles) { + "" + }) +
FichierTypeTailleChemin
$($file.Name)$($file.Type)$($file.Size)$($file.Path)
" + } else { + "

Aucun fichier PST ou OST trouvé.

" + }) +
+ +
+

Profils Thunderbird

+ $(if($MailInfo.ThunderbirdProfiles.Count -gt 0) { + " + + $(foreach($profile in $MailInfo.ThunderbirdProfiles) { + "" + }) +
ProfilTailleChemin
$($profile.Name)$($profile.Size)$($profile.Path)
" + } else { + "

Aucun profil Thunderbird trouvé.

" + }) +
+
+ + +
+
+

Programmes au Démarrage ($($StartupInfo.Count))

+ $(if($StartupInfo.Count -gt 0) { + " + + $(foreach($item in $StartupInfo) { + $statusBadge = if($item.Status -eq 'Activé'){'Activé'}else{'Désactivé'} + " + + + + + + " + }) +
NomStatutCommandeEmplacementUtilisateur
$($item.Name)$statusBadge$($item.Command)$($item.Location)$($item.User)
+

💡 Survolez les cellules tronquées pour voir le contenu complet.

" + } else { + "

Aucun programme de démarrage trouvé.

" + }) +
+
+ + +
+ $(if($BatteryInfo.Available) { + $healthClass = if ($BatteryInfo.HealthPercent -ge 80) { 'health-ok' } elseif ($BatteryInfo.HealthPercent -ge 50) { 'health-warning' } else { 'health-error' } + $batteryHtml = "
+

État de la Batterie

+
+ + + + +
Niveau de charge$($BatteryInfo.ChargeLevel)
Statut$($BatteryInfo.Status)
Identifiant$($BatteryInfo.DeviceID)
+ + + + +
Capacité d'origine$($BatteryInfo.DesignCapacity)
Capacité actuelle$($BatteryInfo.FullChargeCapacity)
Santé estimée$($BatteryInfo.HealthPercent)% ($($BatteryInfo.HealthStatus))
+
+
" + if($BatteryInfo.ReportGenerated) { + $batteryHtml += "
+

Rapport Windows Battery Report

+

Le rapport détaillé de la batterie a été généré : $($BatteryInfo.ReportPath)

+

Ce fichier contient l'historique complet de la batterie et est inclus dans le dossier du rapport.

+
" + } + $batteryHtml + } else { + "
+

Batterie

+

$($BatteryInfo.Message)

+
" + }) +
+ + +
+
+

Imprimantes Installées

+ $(if($PrinterInfo.Count -gt 0) { + " + + $(foreach($printer in $PrinterInfo) { + $defaultBadge = if($printer.Default){'Oui'}else{'Non'} + $sharedBadge = if($printer.Shared){'Oui'}else{'Non'} + " + + + + + + + " + }) +
NomStatutPortPilotePar défautPartagée
$($printer.Name)$($printer.Status)$($printer.Port)$($printer.Driver)$defaultBadge$sharedBadge
" + } else { + "

Aucune imprimante installée sur ce système.

" + }) +
+
+ + + + + +"@ + + return $htmlTemplate +} + +# ============================================================================ +# ENVOI EMAIL +# ============================================================================ + +function Send-ReportEmail { + param( + [string]$ReportPath, + [string]$BatteryReportPath, + [string]$ComputerName + ) + + Write-Log "Préparation de l'envoi par email..." -Level Info + + # Charger les credentials de manière sécurisée + $credPath = [System.IO.Path]::Combine($PSScriptRoot, "smtp_credentials.xml") + + if (Test-Path $credPath) { + try { + $credential = Import-Clixml -Path $credPath + } + catch { + Write-Log "Impossible de charger les credentials SMTP" -Level Error + return $false + } + } + else { + # Demander les credentials + Write-Log "Fichier de credentials non trouvé. Veuillez entrer les informations SMTP." -Level Warning + + $saveCredentials = Read-Host "Voulez-vous sauvegarder les credentials pour une utilisation future ? (O/N)" + + $credential = Get-Credential -Message "Entrez les identifiants SMTP" -UserName $Script:Config.SMTP.Username + + if ($saveCredentials -eq 'O') { + $credential | Export-Clixml -Path $credPath + Write-Log "Credentials sauvegardés dans $credPath" -Level Success + } + } + + $attachments = @($ReportPath) + + if ($BatteryReportPath -and (Test-Path $BatteryReportPath)) { + $attachments += $BatteryReportPath + } + + try { + $mailParams = @{ + SmtpServer = $Script:Config.SMTP.Server + Port = $Script:Config.SMTP.Port + UseSsl = $true + From = $Script:Config.SMTP.From + To = $Script:Config.SMTP.To + Subject = "Rapport PC - $ComputerName - $(Get-Date -Format 'dd/MM/yyyy HH:mm')" + Body = @" +Bonjour, + +Veuillez trouver ci-joint le rapport PC généré pour la machine : $ComputerName + +Rapport généré le : $(Get-Date -Format 'dd/MM/yyyy à HH:mm:ss') + +Cordialement, +Script Info PC v0.5.0 +"@ + Credential = $credential + Attachments = $attachments + } + + Send-MailMessage @mailParams -WarningAction SilentlyContinue + Write-Log "Email envoyé avec succès!" -Level Success + return $true + } + catch { + Write-Log "Erreur lors de l'envoi de l'email: $_" -Level Error + return $false + } +} + +# ============================================================================ +# SCRIPT PRINCIPAL +# ============================================================================ + +# Affichage du header +Clear-Host +Write-Host "" +Write-Host " ╔══════════════════════════════════════════╗" -ForegroundColor Cyan +Write-Host " ║ INFO PC - Version 0.5.0 ║" -ForegroundColor Cyan +Write-Host " ║ Diagnostic complet du système ║" -ForegroundColor Cyan +Write-Host " ╚══════════════════════════════════════════╝" -ForegroundColor Cyan +Write-Host "" + +# Vérification des droits admin +if (-not (Test-IsAdmin)) { + Write-Log "Ce script nécessite des droits administrateur pour certaines fonctionnalités." -Level Warning + Write-Log "Certaines informations pourraient être incomplètes." -Level Warning + Write-Host "" +} + +# Demande du nom du fichier +$htmlFileName = Read-Host "Entrez le nom du rapport (sans extension) [défaut: nom de la machine]" +if ([string]::IsNullOrWhiteSpace($htmlFileName)) { + $htmlFileName = $env:COMPUTERNAME +} + +# Choix du type de PC +Write-Host "" +Write-Host "Type de PC :" -ForegroundColor White +Write-Host " 1 - PC de bureau (pas de test batterie)" +Write-Host " 2 - PC Portable (test batterie inclus)" +Write-Host "" + +do { + $choice = Read-Host "Votre choix [1]" + if ([string]::IsNullOrWhiteSpace($choice)) { $choice = '1' } +} while ($choice -notin @('1', '2')) + +$includeBatteryTest = ($choice -eq '2') + +Write-Host "" +Write-Log "Démarrage de la collecte des informations..." -Level Info +Write-Host "" + +# Création du dossier de sortie +$folderName = "$htmlFileName - Info PC" +$script:FolderPath = [System.IO.Path]::Combine($PSScriptRoot, $folderName) +$null = New-Item -ItemType Directory -Path $script:FolderPath -Force -ErrorAction SilentlyContinue + +# Collecte des informations +$systemInfo = Get-SystemInfo +$memoryInfo = Get-MemoryInfo +$gpuInfo = Get-GPUInfo +$storageInfo = Get-StorageInfo +$networkInfo = Get-NetworkInfo +$userInfo = Get-UserInfo +$softwareInfo = Get-SoftwareInfo +$startupInfo = Get-StartupInfo +$printerInfo = Get-PrinterInfo +$mailInfo = Get-MailInfo +$batteryInfo = Get-BatteryInfo -IncludeBatteryTest $includeBatteryTest + +# Génération du rapport HTML +Write-Log "Génération du rapport HTML..." -Level Info + +$htmlContent = New-HTMLReport ` + -SystemInfo $systemInfo ` + -MemoryInfo $memoryInfo ` + -GPUInfo $gpuInfo ` + -StorageInfo $storageInfo ` + -NetworkInfo $networkInfo ` + -UserInfo $userInfo ` + -SoftwareInfo $softwareInfo ` + -StartupInfo $startupInfo ` + -PrinterInfo $printerInfo ` + -MailInfo $mailInfo ` + -BatteryInfo $batteryInfo + +$htmlFilePath = [System.IO.Path]::Combine($script:FolderPath, "$htmlFileName.html") +$htmlContent | Out-File -FilePath $htmlFilePath -Encoding UTF8 + +Write-Log "Rapport généré: $htmlFilePath" -Level Success + +# Envoi par email +if ($Script:Config.Options.SendEmail) { + Write-Host "" + $sendEmail = Read-Host "Voulez-vous envoyer le rapport par email ? (O/N) [O]" + if ([string]::IsNullOrWhiteSpace($sendEmail) -or $sendEmail -eq 'O') { + $batteryReportPath = if ($batteryInfo.ReportPath) { $batteryInfo.ReportPath } else { $null } + Send-ReportEmail -ReportPath $htmlFilePath -BatteryReportPath $batteryReportPath -ComputerName $systemInfo.ComputerName + } +} + +# Ouverture du rapport +if ($Script:Config.Options.OpenReportOnEnd) { + Write-Host "" + Write-Log "Ouverture du rapport..." -Level Info + Invoke-Item -Path $htmlFilePath +} + +Write-Host "" +Write-Host " ╔══════════════════════════════════════════╗" -ForegroundColor Green +Write-Host " ║ Script terminé ! ║" -ForegroundColor Green +Write-Host " ╚══════════════════════════════════════════╝" -ForegroundColor Green +Write-Host "" +Write-Host " Dossier: $script:FolderPath" -ForegroundColor Gray +Write-Host "" \ No newline at end of file