Files
info-pc/tools-info-pc-Win10-11.ps1
2026-03-24 08:02:01 +01:00

1606 lines
59 KiB
PowerShell
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 = @"
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Info PC - $($SystemInfo.ComputerName)</title>
<style>
* { box-sizing: border-box; }
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
padding: 0;
background-color: #f5f5f5;
color: #333;
}
.header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 20px;
text-align: center;
position: sticky;
top: 0;
z-index: 100;
}
.header h1 { margin: 0 0 5px 0; }
.header .subtitle { opacity: 0.9; font-size: 0.9em; }
.tab-container {
background: white;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
position: sticky;
top: 70px;
z-index: 99;
overflow-x: auto;
white-space: nowrap;
}
.tab {
display: inline-flex;
padding: 0 10px;
}
.tab button {
background: transparent;
border: none;
padding: 15px 20px;
cursor: pointer;
font-size: 14px;
color: #666;
transition: all 0.3s;
border-bottom: 3px solid transparent;
}
.tab button:hover { color: #667eea; }
.tab button.active {
color: #667eea;
border-bottom-color: #667eea;
font-weight: 600;
}
.tabcontent {
display: none;
padding: 20px;
max-width: 1400px;
margin: 0 auto;
animation: fadeIn 0.3s;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.info-block {
background: white;
border-radius: 10px;
padding: 20px;
margin-bottom: 20px;
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
}
.section-title {
font-size: 1.1em;
font-weight: 600;
color: #444;
margin: 0 0 15px 0;
padding-bottom: 10px;
border-bottom: 2px solid #667eea;
display: flex;
align-items: center;
gap: 10px;
}
.section-title::before {
content: '';
width: 4px;
height: 20px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 2px;
}
.info-table {
width: 100%;
border-collapse: collapse;
}
.info-table th, .info-table td {
padding: 12px;
text-align: left;
border-bottom: 1px solid #eee;
}
.info-table th {
background: #f8f9fa;
font-weight: 600;
color: #555;
}
.info-table tr:hover { background: #f8f9fa; }
.health-ok { color: #28a745; font-weight: 600; }
.health-warning { color: #ffc107; font-weight: 600; }
.health-error { color: #dc3545; font-weight: 600; }
.progress-bar {
background: #e9ecef;
border-radius: 10px;
height: 24px;
overflow: hidden;
position: relative;
}
.progress-fill {
height: 100%;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 12px;
font-weight: 600;
transition: width 0.5s ease;
}
.progress-green { background: linear-gradient(90deg, #28a745, #20c997); }
.progress-yellow { background: linear-gradient(90deg, #ffc107, #fd7e14); }
.progress-red { background: linear-gradient(90deg, #dc3545, #c82333); }
.badge {
display: inline-block;
padding: 4px 12px;
border-radius: 20px;
font-size: 0.85em;
font-weight: 500;
}
.badge-success { background: #d4edda; color: #155724; }
.badge-warning { background: #fff3cd; color: #856404; }
.badge-danger { background: #f8d7da; color: #721c24; }
.badge-info { background: #d1ecf1; color: #0c5460; }
.grid-2 {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
}
.warning-box {
background: #fff3cd;
border-left: 4px solid #ffc107;
padding: 15px;
border-radius: 5px;
margin-bottom: 20px;
}
pre {
background: #f8f9fa;
padding: 15px;
border-radius: 8px;
overflow-x: auto;
font-size: 13px;
max-height: 300px;
}
.truncate {
max-width: 300px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
@media (max-width: 768px) {
.tab button { padding: 12px 15px; font-size: 13px; }
.info-table th, .info-table td { padding: 8px; font-size: 13px; }
}
@media print {
.header, .tab-container { position: static; }
.tabcontent { display: block !important; page-break-inside: avoid; }
}
</style>
</head>
<body>
<div class="header">
<h1>🖥 Info PC - $($SystemInfo.ComputerName)</h1>
<div class="subtitle">Rapport généré le $(Get-Date -Format "dd/MM/yyyy à HH:mm")</div>
</div>
<div class="tab-container">
<div class="tab">
<button class="active" onclick="openTab(event, 'InfoPC')">💻 Système</button>
<button onclick="openTab(event, 'Utilisateurs')">👥 Utilisateurs</button>
<button onclick="openTab(event, 'Logiciels')">📦 Logiciels</button>
<button onclick="openTab(event, 'Reseaux')">🌐 Réseaux</button>
<button onclick="openTab(event, 'Stockage')">💾 Stockage</button>
<button onclick="openTab(event, 'Mail')">📧 Mail</button>
<button onclick="openTab(event, 'Demarrage')">🚀 Démarrage</button>
<button onclick="openTab(event, 'Batterie')">🔋 Batterie</button>
<button onclick="openTab(event, 'Imprimante')">🖨 Imprimantes</button>
</div>
</div>
<!-- ONGLET SYSTÈME -->
<div id="InfoPC" class="tabcontent" style="display: block;">
<div class="grid-2">
<div class="info-block">
<h3 class="section-title">Informations Système</h3>
<table class="info-table">
<tr><td><strong>Nom du PC</strong></td><td>$($SystemInfo.ComputerName)</td></tr>
<tr><td><strong>Windows</strong></td><td>$($SystemInfo.WindowsVersion)</td></tr>
<tr><td><strong>Architecture</strong></td><td>$($SystemInfo.Architecture)</td></tr>
<tr><td><strong>Date d'installation</strong></td><td>$($SystemInfo.InstallDate)</td></tr>
<tr><td><strong>Dernier démarrage</strong></td><td>$($SystemInfo.LastBoot)</td></tr>
<tr><td><strong>Uptime</strong></td><td>$($SystemInfo.Uptime)</td></tr>
</table>
</div>
<div class="info-block">
<h3 class="section-title">Sécurité</h3>
<table class="info-table">
<tr><td><strong>Secure Boot</strong></td><td>$(if($SystemInfo.SecureBoot -eq 'Activé'){'<span class="badge badge-success">Activé</span>'}else{'<span class="badge badge-warning">'+$SystemInfo.SecureBoot+'</span>'})</td></tr>
<tr><td><strong>TPM</strong></td><td>$(if($SystemInfo.TPM.Present){'<span class="badge badge-success">Présent</span>'}else{'<span class="badge badge-danger">Non détecté</span>'})</td></tr>
$(if($SystemInfo.TPM.Present){"<tr><td><strong>Version TPM</strong></td><td>$($SystemInfo.TPM.Version)</td></tr>"}else{""})
</table>
</div>
</div>
<div class="grid-2">
<div class="info-block">
<h3 class="section-title">Matériel</h3>
<table class="info-table">
<tr><td><strong>Fabricant</strong></td><td>$($SystemInfo.Manufacturer)</td></tr>
<tr><td><strong>Modèle</strong></td><td>$($SystemInfo.Model)</td></tr>
<tr><td><strong>Carte mère</strong></td><td>$($SystemInfo.MotherboardMfr) $($SystemInfo.Motherboard)</td></tr>
</table>
</div>
<div class="info-block">
<h3 class="section-title">BIOS</h3>
<table class="info-table">
<tr><td><strong>Version</strong></td><td>$($SystemInfo.BiosVersion)</td></tr>
<tr><td><strong>Fabricant</strong></td><td>$($SystemInfo.BiosManufacturer)</td></tr>
<tr><td><strong>Date</strong></td><td>$($SystemInfo.BiosDate)</td></tr>
</table>
</div>
</div>
<div class="info-block">
<h3 class="section-title">Processeur</h3>
<table class="info-table">
<tr><td><strong>CPU</strong></td><td>$($SystemInfo.CPU)</td></tr>
<tr><td><strong>Cœurs / Threads</strong></td><td>$($SystemInfo.CPUCores) cœurs / $($SystemInfo.CPUThreads) threads</td></tr>
<tr><td><strong>Socket</strong></td><td>$($SystemInfo.CPUSocket)</td></tr>
<tr><td><strong>Fréquence max</strong></td><td>$($SystemInfo.CPUMaxSpeed)</td></tr>
</table>
</div>
<div class="info-block">
<h3 class="section-title">Mémoire RAM</h3>
<table class="info-table">
<tr><td><strong>Capacité totale</strong></td><td>$($MemoryInfo.TotalCapacity)</td></tr>
<tr><td><strong>Slots utilisés</strong></td><td>$($MemoryInfo.UsedSlots) / $($MemoryInfo.TotalSlots)</td></tr>
</table>
<h4 style="margin-top: 20px;">Détails des modules</h4>
<table class="info-table">
<tr><th>Emplacement</th><th>Fabricant</th><th>Référence</th><th>Capacité</th><th>Type</th><th>Vitesse</th></tr>
$(foreach($module in $MemoryInfo.Modules) {
"<tr><td>$($module.DeviceLocator)</td><td>$($module.Manufacturer)</td><td>$($module.PartNumber)</td><td>$($module.Capacity)</td><td>$($module.Type)</td><td>$($module.Speed)</td></tr>"
})
</table>
</div>
<div class="info-block">
<h3 class="section-title">Carte(s) Graphique(s)</h3>
<table class="info-table">
<tr><th>Nom</th><th>Processeur</th><th>VRAM</th><th>Driver</th><th>Résolution</th></tr>
$(foreach($gpu in $GPUInfo) {
"<tr><td>$($gpu.Name)</td><td>$($gpu.Processor)</td><td>$($gpu.RAM)</td><td>$($gpu.Driver)</td><td>$($gpu.Resolution) @ $($gpu.RefreshRate)</td></tr>"
})
</table>
</div>
</div>
<!-- ONGLET UTILISATEURS -->
<div id="Utilisateurs" class="tabcontent">
<div class="info-block">
<h3 class="section-title">Comptes Utilisateurs Locaux</h3>
<table class="info-table">
<tr><th>Nom</th><th>Nom complet</th><th>Description</th><th>Statut</th></tr>
$(foreach($user in $UserInfo) {
$statusBadge = if($user.Status -eq 'Actif'){'<span class="badge badge-success">Actif</span>'}else{'<span class="badge badge-danger">Désactivé</span>'}
"<tr><td>$($user.Name)</td><td>$($user.FullName)</td><td>$($user.Description)</td><td>$statusBadge</td></tr>"
})
</table>
</div>
</div>
<!-- ONGLET LOGICIELS -->
<div id="Logiciels" class="tabcontent">
<div class="info-block">
<h3 class="section-title">Logiciels Installés ($($SoftwareInfo.Count) programmes)</h3>
<table class="info-table">
<tr><th>Nom</th><th>Version</th><th>Éditeur</th><th>Date d'installation</th></tr>
$(foreach($soft in $SoftwareInfo) {
"<tr><td>$($soft.Name)</td><td>$($soft.Version)</td><td>$($soft.Publisher)</td><td>$($soft.InstallDate)</td></tr>"
})
</table>
</div>
</div>
<!-- ONGLET RÉSEAUX -->
<div id="Reseaux" class="tabcontent">
<div class="info-block">
<h3 class="section-title">Configuration Réseau</h3>
<table class="info-table">
<tr><td><strong>Domaine / Groupe</strong></td><td>$($NetworkInfo.DomainInfo)</td></tr>
<tr><td><strong>DNS</strong></td><td>$($NetworkInfo.DNS)</td></tr>
<tr><td><strong>Passerelle</strong></td><td>$($NetworkInfo.Gateway)</td></tr>
</table>
</div>
<div class="info-block">
<h3 class="section-title">Adaptateurs Réseau</h3>
<table class="info-table">
<tr><th>Nom</th><th>Description</th><th>Statut</th><th>Vitesse</th><th>MAC</th><th>IP</th></tr>
$(foreach($adapter in $NetworkInfo.Adapters) {
$statusBadge = if($adapter.Status -eq 'Up'){'<span class="badge badge-success">Connecté</span>'}else{'<span class="badge badge-warning">'+$adapter.Status+'</span>'}
"<tr><td>$($adapter.Name)</td><td class='truncate' title='$($adapter.Description)'>$($adapter.Description)</td><td>$statusBadge</td><td>$($adapter.Speed)</td><td>$($adapter.MAC)</td><td>$($adapter.IPAddress)</td></tr>"
})
</table>
</div>
$(if($NetworkInfo.NetworkDrives.Count -gt 0) {
"<div class='info-block'>
<h3 class='section-title'>Lecteurs Réseau</h3>
<table class='info-table'>
<tr><th>Lettre</th><th>Chemin réseau</th></tr>
$(foreach($drive in $NetworkInfo.NetworkDrives) {
"<tr><td>$($drive.Letter)</td><td>$($drive.Path)</td></tr>"
})
</table>
</div>"
} else {
"<div class='info-block'><h3 class='section-title'>Lecteurs Réseau</h3><p>Aucun lecteur réseau connecté.</p></div>"
})
$(if($NetworkInfo.WifiProfiles.Count -gt 0) {
"<div class='info-block'>
<h3 class='section-title'>Profils WiFi Enregistrés ($($NetworkInfo.WifiProfiles.Count))</h3>
<table class='info-table'>
<tr><th>SSID</th><th>Authentification</th></tr>
$(foreach($wifi in $NetworkInfo.WifiProfiles) {
"<tr><td>$($wifi.SSID)</td><td>$($wifi.Authentication)</td></tr>"
})
</table>
</div>"
})
<div class="info-block">
<h3 class="section-title">Fichier Hosts</h3>
<pre>$($NetworkInfo.HostsFile)</pre>
</div>
</div>
<!-- ONGLET STOCKAGE -->
<div id="Stockage" class="tabcontent">
<div class="info-block">
<h3 class="section-title">Disques Physiques</h3>
<table class="info-table">
<tr><th>Modèle</th><th>Type</th><th>Capacité</th><th>Interface</th><th>Santé</th><th>N° Série</th></tr>
$(foreach($disk in $StorageInfo.Disks) {
$healthBadge = switch($disk.Health) {
'Healthy' { '<span class="health-ok">Bon</span>' }
'Warning' { '<span class="health-warning">Attention</span>' }
'Unhealthy' { '<span class="health-error">Défectueux</span>' }
default { $disk.Health }
}
"<tr><td>$($disk.Model)</td><td>$($disk.Type)</td><td>$($disk.Size)</td><td>$($disk.BusType)</td><td>$healthBadge</td><td class='truncate' title='$($disk.Serial)'>$($disk.Serial)</td></tr>"
})
</table>
</div>
<div class="info-block">
<h3 class="section-title">Volumes</h3>
<table class="info-table">
<tr><th>Lettre</th><th>Nom</th><th>Système de fichiers</th><th>Utilisation</th><th>BitLocker</th></tr>
$(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' { '<span class="badge badge-success">Protégé</span>' }
'Off' { '<span class="badge badge-warning">Désactivé</span>' }
default { '<span class="badge badge-info">Non protégé</span>' }
}
"<tr>
<td><strong>$($vol.Letter)</strong></td>
<td>$($vol.Label)</td>
<td>$($vol.FileSystem)</td>
<td style='min-width: 200px;'>
<div class='progress-bar'>
<div class='progress-fill $progressClass' style='width: $($vol.UsedPercent)%;'>$($vol.UsedPercent)%</div>
</div>
<small>$($vol.Used) / $($vol.Size) (libre: $($vol.Free))</small>
</td>
<td>$blBadge</td>
</tr>"
})
</table>
</div>
</div>
<!-- ONGLET MAIL -->
<div id="Mail" class="tabcontent">
<div class="warning-box">
<strong>Note:</strong> Le script scanne uniquement les dossiers AppData\Microsoft\Outlook, Thunderbird\Profiles, et le dossier Documents.
</div>
$(if($MailInfo.OutlookAccounts.Count -gt 0) {
"<div class='info-block'>
<h3 class='section-title'>Comptes Outlook Configurés</h3>
<table class='info-table'>
<tr><th>Nom</th><th>Email</th><th>Type</th><th>Fichier de données</th></tr>
$(foreach($account in $MailInfo.OutlookAccounts) {
"<tr><td>$($account.Name)</td><td>$($account.Email)</td><td>$($account.Type)</td><td class='truncate' title='$($account.Store)'>$($account.Store)</td></tr>"
})
</table>
</div>"
} else {
"<div class='info-block'><h3 class='section-title'>Comptes Outlook</h3><p>Aucun compte Outlook détecté ou Outlook n'est pas installé.</p></div>"
})
<div class="info-block">
<h3 class="section-title">Fichiers Outlook (PST/OST)</h3>
$(if($MailInfo.OutlookFiles.Count -gt 0) {
"<table class='info-table'>
<tr><th>Fichier</th><th>Type</th><th>Taille</th><th>Chemin</th></tr>
$(foreach($file in $MailInfo.OutlookFiles) {
"<tr><td>$($file.Name)</td><td>$($file.Type)</td><td>$($file.Size)</td><td class='truncate' title='$($file.Path)'>$($file.Path)</td></tr>"
})
</table>"
} else {
"<p>Aucun fichier PST ou OST trouvé.</p>"
})
</div>
<div class="info-block">
<h3 class="section-title">Profils Thunderbird</h3>
$(if($MailInfo.ThunderbirdProfiles.Count -gt 0) {
"<table class='info-table'>
<tr><th>Profil</th><th>Taille</th><th>Chemin</th></tr>
$(foreach($profile in $MailInfo.ThunderbirdProfiles) {
"<tr><td>$($profile.Name)</td><td>$($profile.Size)</td><td class='truncate' title='$($profile.Path)'>$($profile.Path)</td></tr>"
})
</table>"
} else {
"<p>Aucun profil Thunderbird trouvé.</p>"
})
</div>
</div>
<!-- ONGLET DÉMARRAGE -->
<div id="Demarrage" class="tabcontent">
<div class="info-block">
<h3 class="section-title">Programmes au Démarrage ($($StartupInfo.Count))</h3>
$(if($StartupInfo.Count -gt 0) {
"<table class='info-table'>
<tr><th>Nom</th><th>Statut</th><th>Commande</th><th>Emplacement</th><th>Utilisateur</th></tr>
$(foreach($item in $StartupInfo) {
$statusBadge = if($item.Status -eq 'Activé'){'<span class="badge badge-success">Activé</span>'}else{'<span class="badge badge-warning">Désactivé</span>'}
"<tr>
<td>$($item.Name)</td>
<td>$statusBadge</td>
<td class='truncate' title='$($item.Command)'>$($item.Command)</td>
<td>$($item.Location)</td>
<td>$($item.User)</td>
</tr>"
})
</table>
<p style='font-size: 0.85em; color: #666; margin-top: 10px;'>💡 Survolez les cellules tronquées pour voir le contenu complet.</p>"
} else {
"<p>Aucun programme de démarrage trouvé.</p>"
})
</div>
</div>
<!-- ONGLET BATTERIE -->
<div id="Batterie" class="tabcontent">
$(if($BatteryInfo.Available) {
$healthClass = if ($BatteryInfo.HealthPercent -ge 80) { 'health-ok' } elseif ($BatteryInfo.HealthPercent -ge 50) { 'health-warning' } else { 'health-error' }
$batteryHtml = "<div class='info-block'>
<h3 class='section-title'>État de la Batterie</h3>
<div class='grid-2'>
<table class='info-table'>
<tr><td><strong>Niveau de charge</strong></td><td>$($BatteryInfo.ChargeLevel)</td></tr>
<tr><td><strong>Statut</strong></td><td>$($BatteryInfo.Status)</td></tr>
<tr><td><strong>Identifiant</strong></td><td>$($BatteryInfo.DeviceID)</td></tr>
</table>
<table class='info-table'>
<tr><td><strong>Capacité d'origine</strong></td><td>$($BatteryInfo.DesignCapacity)</td></tr>
<tr><td><strong>Capacité actuelle</strong></td><td>$($BatteryInfo.FullChargeCapacity)</td></tr>
<tr><td><strong>Santé estimée</strong></td><td><span class='$healthClass'>$($BatteryInfo.HealthPercent)% ($($BatteryInfo.HealthStatus))</span></td></tr>
</table>
</div>
</div>"
if($BatteryInfo.ReportGenerated) {
$batteryHtml += "<div class='info-block'>
<h3 class='section-title'>Rapport Windows Battery Report</h3>
<p>Le rapport détaillé de la batterie a été généré : <code>$($BatteryInfo.ReportPath)</code></p>
<p>Ce fichier contient l'historique complet de la batterie et est inclus dans le dossier du rapport.</p>
</div>"
}
$batteryHtml
} else {
"<div class='info-block'>
<h3 class='section-title'>Batterie</h3>
<p>$($BatteryInfo.Message)</p>
</div>"
})
</div>
<!-- ONGLET IMPRIMANTES -->
<div id="Imprimante" class="tabcontent">
<div class="info-block">
<h3 class="section-title">Imprimantes Installées</h3>
$(if($PrinterInfo.Count -gt 0) {
"<table class='info-table'>
<tr><th>Nom</th><th>Statut</th><th>Port</th><th>Pilote</th><th>Par défaut</th><th>Partagée</th></tr>
$(foreach($printer in $PrinterInfo) {
$defaultBadge = if($printer.Default){'<span class="badge badge-success">Oui</span>'}else{'Non'}
$sharedBadge = if($printer.Shared){'<span class="badge badge-info">Oui</span>'}else{'Non'}
"<tr>
<td>$($printer.Name)</td>
<td>$($printer.Status)</td>
<td>$($printer.Port)</td>
<td class='truncate' title='$($printer.Driver)'>$($printer.Driver)</td>
<td>$defaultBadge</td>
<td>$sharedBadge</td>
</tr>"
})
</table>"
} else {
"<p>Aucune imprimante installée sur ce système.</p>"
})
</div>
</div>
<script>
function openTab(evt, tabName) {
var tabcontent = document.getElementsByClassName("tabcontent");
for (var i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
var tablinks = document.getElementsByClassName("tab")[0].getElementsByTagName("button");
for (var i = 0; i < tablinks.length; i++) {
tablinks[i].classList.remove("active");
}
document.getElementById(tabName).style.display = "block";
evt.currentTarget.classList.add("active");
}
</script>
</body>
</html>
"@
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 ""