# 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 ""