# NCinfo - Rapport de configuration du PC # Lecture seule : ce script ne modifie rien et n'installe rien. # Il affiche les caracteristiques du PC, les copie dans le presse-papiers # et enregistre un fichier "Rapport-PC-NCinfo.txt" sur le Bureau. # Le rapport n'est envoye a NCinfo que si l'utilisateur l'accepte a la fin. & { $NcSite = 'https://ncinfo.fr' $ErrorActionPreference = 'SilentlyContinue' $ProgressPreference = 'SilentlyContinue' $report = New-Object System.Collections.Generic.List[string] $isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) function Sec($title) { Write-Host '' Write-Host (" " + $title.ToUpper()) -ForegroundColor Red Write-Host (" " + ('-' * 58)) -ForegroundColor DarkGray $report.Add(''); $report.Add('== ' + $title.ToUpper() + ' ==') } function Row($label, $value, $color = 'White') { if ($null -eq $value -or "$value" -eq '') { $value = 'non disponible' } Write-Host (" {0,-26}" -f $label) -NoNewline -ForegroundColor Gray Write-Host $value -ForegroundColor $color $report.Add(('{0} : {1}' -f $label, $value)) } function Go($bytes, $dec = 0) { if ($bytes) { "{0:N$dec} Go" -f ($bytes / 1GB) } } # Fabricant de barrette : code JEDEC ou debut de reference function RamBrand($m) { $mf = "$($m.Manufacturer)".Trim(); $pn = "$($m.PartNumber)".Trim() $codes = @{ '80CE'='Samsung'; 'CE00'='Samsung'; '80AD'='SK Hynix'; 'AD00'='SK Hynix'; '802C'='Micron'; '2C00'='Micron' '859B'='Crucial'; '9B05'='Crucial'; '04CD'='G.Skill'; 'CD04'='G.Skill'; '0198'='Kingston'; '9801'='Kingston' '029E'='Corsair'; '9E02'='Corsair'; '04CB'='ADATA'; 'CB04'='ADATA'; '0443'='Ramaxel'; '8551'='Qimonda'; '02FE'='Elpida' } $prefix = [ordered]@{ '^F[345][-\s]'='G.Skill'; '^(CM[KWTHSDN]|CMSX|VS\d)'='Corsair'; '^(KHX|KF\d|KVR|KCP|ACR|HX\d)'='Kingston' '^(CT\d|BL\d|BLS)'='Crucial'; '^M[34]\d{2}'='Samsung'; '^HM[ACT]'='SK Hynix'; '^(MT|4ATF|8ATF|16ATF)'='Micron'; '^(AX|AD)\d'='ADATA' } if ($codes[$mf.ToUpper()]) { return $codes[$mf.ToUpper()] } foreach ($k in $prefix.Keys) { if ($pn -match $k) { return $prefix[$k] } } if ($mf -and $mf -notmatch '^[0-9A-F]{4}$' -and $mf -notmatch 'Undefined|Unknown') { return $mf } return 'marque inconnue' } Clear-Host Write-Host '' Write-Host ' NCinfo ' -ForegroundColor White -BackgroundColor DarkRed -NoNewline Write-Host ' Rapport de configuration du PC' -ForegroundColor White Write-Host ' Analyse en cours, merci de patienter une trentaine de secondes...' -ForegroundColor DarkGray $os = Get-CimInstance Win32_OperatingSystem $cs = Get-CimInstance Win32_ComputerSystem $bios = Get-CimInstance Win32_BIOS $board= Get-CimInstance Win32_BaseBoard $cpu = @(Get-CimInstance Win32_Processor) $ram = @(Get-CimInstance Win32_PhysicalMemory) $cv = Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' $report.Add('Rapport de configuration - genere par NCinfo (ncinfo.fr)') $report.Add('Date : ' + (Get-Date -Format 'dd/MM/yyyy HH:mm')) # --- Ordinateur --- Sec 'Ordinateur' Row 'Nom du PC' $env:COMPUTERNAME Row 'Fabricant' $cs.Manufacturer Row 'Modele' $cs.Model $serial = "$($bios.SerialNumber)".Trim() Row 'Numero de serie' $(if ($serial -and $serial -notmatch 'O\.E\.M|Default|System Serial|^0+$') { $serial } else { 'non renseigne (PC assemble)' }) Row 'Carte mere' (($board.Manufacturer, $board.Product) -join ' ').Trim() Row 'BIOS' ('{0} ({1:dd/MM/yyyy})' -f $bios.SMBIOSBIOSVersion, $bios.ReleaseDate) Row 'Mode de demarrage' $(switch ($env:firmware_type) { 'UEFI' { 'UEFI' } 'Legacy' { 'BIOS ancien (Legacy)' } default { $env:firmware_type } }) $chassis = (Get-CimInstance Win32_SystemEnclosure).ChassisTypes Row 'Type' $(if ($chassis | Where-Object { $_ -in 8,9,10,11,12,14,18,21,30,31,32 }) { 'Portable' } else { 'Fixe' }) # --- Windows --- Sec 'Windows' Row 'Systeme' ($os.Caption -replace '^Microsoft ', '') Row 'Version' $cv.DisplayVersion Row 'Build' ('{0}.{1}' -f $cv.CurrentBuild, $cv.UBR) Row 'Architecture' $os.OSArchitecture Row 'Installe le' ('{0:dd/MM/yyyy}' -f $os.InstallDate) $lic = Get-CimInstance SoftwareLicensingProduct -Filter "ApplicationID='55c92734-d682-4d71-983e-d6ec3f16059f' AND PartialProductKey IS NOT NULL" | Select-Object -First 1 Row 'Activation' $(if ($lic) { if ($lic.LicenseStatus -eq 1) { 'Active' } else { 'NON ACTIVE' } }) $(if ($lic.LicenseStatus -eq 1) { 'White' } else { 'Yellow' }) $up = (Get-Date) - $os.LastBootUpTime Row 'Allume depuis' ('{0} j {1} h {2} min' -f $up.Days, $up.Hours, $up.Minutes) $hf = Get-HotFix | Where-Object InstalledOn | Sort-Object InstalledOn -Descending | Select-Object -First 1 Row 'Derniere mise a jour' $(if ($hf) { '{0:dd/MM/yyyy} ({1})' -f $hf.InstalledOn, $hf.HotFixID }) $reboot = (Test-Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired') -or (Test-Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending') Row 'Redemarrage en attente' $(if ($reboot) { 'Oui' } else { 'Non' }) $(if ($reboot) { 'Yellow' } else { 'White' }) Row 'Utilisateur' $env:USERNAME # --- Compatibilite Windows 11 --- Sec 'Securite materielle (Windows 11)' $tpmOut = tpmtool getdeviceinformation 2>$null $tpmVer = if ($LASTEXITCODE -eq 0) { ([regex]::Match(($tpmOut -join ' '), '\b(2\.0|1\.2)\b')).Value } Row 'Puce TPM' $(if ($tpmVer) { "Presente (version $tpmVer)" } else { 'Absente ou desactivee dans le BIOS' }) $(if ($tpmVer -eq '2.0') { 'White' } else { 'Yellow' }) $sb = (Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\State').UEFISecureBootEnabled Row 'Secure Boot' $(if ($sb -eq 1) { 'Active' } else { 'Desactive' }) $(if ($sb -eq 1) { 'White' } else { 'Yellow' }) Row 'Virtualisation (VT)' $(if ($cpu[0].VirtualizationFirmwareEnabled -or $cs.HypervisorPresent) { 'Activee' } else { 'Desactivee dans le BIOS' }) # --- Processeur --- Sec 'Processeur' foreach ($c in $cpu) { Row 'Modele' ($c.Name -replace '\s+', ' ').Trim() Row 'Coeurs / threads' ('{0} coeurs / {1} threads' -f $c.NumberOfCores, $c.NumberOfLogicalProcessors) Row 'Frequence de base' ('{0:N2} GHz' -f ($c.MaxClockSpeed / 1000)) Row 'Cache L2 / L3' ('{0} Mo / {1} Mo' -f [math]::Round($c.L2CacheSize / 1024, 1), [math]::Round($c.L3CacheSize / 1024, 1)) if ($c.SocketDesignation -notmatch '^(SOCKET|CPU|U3E1|Proc)\s*\d*$') { Row 'Socket' $c.SocketDesignation } Row 'Charge actuelle' ('{0} %' -f $c.LoadPercentage) } # --- Memoire --- Sec 'Memoire vive (RAM)' $total = ($ram | Measure-Object Capacity -Sum).Sum $arr = @(Get-CimInstance Win32_PhysicalMemoryArray | Where-Object Use -eq 3) if (-not $arr) { $arr = @(Get-CimInstance Win32_PhysicalMemoryArray) } $slots = ($arr | Measure-Object MemoryDevices -Sum).Sum $maxKB = ($arr | ForEach-Object { if ($_.MaxCapacityEx) { $_.MaxCapacityEx } else { $_.MaxCapacity } } | Measure-Object -Sum).Sum $types = @{ 20='DDR'; 21='DDR2'; 24='DDR3'; 26='DDR4'; 30='LPDDR4'; 34='DDR5'; 35='LPDDR5' } $first = $ram | Select-Object -First 1 $t = $types[[int]$first.SMBIOSMemoryType] $ff = switch ([int]$first.FormFactor) { 8 { 'DIMM (PC fixe)' } 12 { 'SO-DIMM (portable)' } 0 { 'soudee a la carte mere' } default { '' } } Row 'Total installe' ((Go $total) + $(if ($t) { " $t" })) Row 'Maximum supporte' $(if ($maxKB -gt 0) { Go ($maxKB * 1KB) }) Row 'Format' $ff $used = 100 - $os.FreePhysicalMemory * 100 / $os.TotalVisibleMemorySize Row 'Utilisee actuellement' ('{0:N0} %' -f $used) $(if ($used -ge 85) { 'Yellow' } else { 'White' }) if ($slots) { $free = [math]::Max(0, $slots - $ram.Count) Row 'Emplacements' ('{0} au total : {1} occupe(s), {2} libre(s)' -f $slots, $ram.Count, $free) $(if ($free) { 'Green' } else { 'White' }) } else { Row 'Emplacements' "$($ram.Count) occupe(s)" } $channels = @($ram | ForEach-Object { if ($_.DeviceLocator -match 'Channel\s*([A-D])|DIMM\s*([A-D])\d') { $matches[1] + $matches[2] } } | Sort-Object -Unique) if ($channels.Count -ge 2) { Row 'Mode' ('Multi-canal (' + $channels.Count + ' canaux)') } elseif ($ram.Count -eq 1) { Row 'Mode' 'Simple canal (une seule barrette)' 'Yellow' } foreach ($m in $ram) { $speed = if ($m.ConfiguredClockSpeed) { $m.ConfiguredClockSpeed } else { $m.Speed } $slot = ("$($m.DeviceLocator)".Trim(), "$($m.BankLabel)".Trim() | Where-Object { $_ }) -join ' / ' $volt = if ($m.ConfiguredVoltage) { ' - {0:N2} V' -f ($m.ConfiguredVoltage / 1000) } Row (" " + $slot) ('{0} {1} - {2} MHz{3} - {4} {5}' -f (Go $m.Capacity), $t, $speed, $volt, (RamBrand $m), "$($m.PartNumber)".Trim()) } # --- Graphisme --- Sec 'Carte graphique' $vram = @{} Get-ChildItem 'HKLM:\SYSTEM\CurrentControlSet\Control\Class\{4d36e968-e325-11ce-bfc1-08002be10318}' | ForEach-Object { $p = Get-ItemProperty $_.PSPath if ($p.DriverDesc -and $p.'HardwareInformation.qwMemorySize') { $vram[$p.DriverDesc] = [uint64]$p.'HardwareInformation.qwMemorySize' } } foreach ($g in Get-CimInstance Win32_VideoController) { $mem = if ($vram[$g.Name]) { $vram[$g.Name] } else { [uint64]$g.AdapterRAM } Row 'Carte graphique' ($g.Name + $(if ($mem -ge 256MB) { ' - ' + (Go $mem) })) Row ' Pilote' ('{0} ({1:dd/MM/yyyy})' -f $g.DriverVersion, $g.DriverDate) if ($g.CurrentHorizontalResolution) { Row ' Affichage' ('{0} x {1} - {2} Hz' -f $g.CurrentHorizontalResolution, $g.CurrentVerticalResolution, $g.CurrentRefreshRate) } } # --- Ecrans --- $mons = @(Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorID) if ($mons) { Sec 'Ecrans' $i = 1 foreach ($mon in $mons) { $name = -join [char[]]($mon.UserFriendlyName | Where-Object { $_ -ne 0 }) $sn = -join [char[]]($mon.SerialNumberID | Where-Object { $_ -ne 0 }) $info = @($(if ($name) { $name } elseif ($mon.InstanceName -match 'DISPLAY\\(\w+)') { $matches[1] } else { 'Ecran' })) if ($mon.YearOfManufacture) { $info += "fabrique en $($mon.YearOfManufacture)" } if ($sn -and $sn -ne '0') { $info += "S/N $sn" } Row ("Ecran $i") ($info -join ' - ') $i++ } } # --- Stockage --- Sec 'Stockage' foreach ($d in Get-PhysicalDisk | Sort-Object DeviceId) { $kind = switch ("$($d.MediaType)") { 'SSD' { 'SSD' } 'HDD' { 'Disque dur (HDD)' } default { 'Disque' } } if ($d.BusType -eq 'NVMe') { $kind = 'SSD NVMe' } elseif ($d.BusType -eq 'USB') { $kind += ' USB' } $health = switch ("$($d.HealthStatus)") { 'Healthy' { 'bon etat' } 'Warning' { 'AVERTISSEMENT' } 'Unhealthy' { 'DEFAILLANT' } default { "$($d.HealthStatus)" } } Row $kind ('{0} - {1} - {2}' -f $d.FriendlyName, (Go $d.Size), $health) $(if ($health -eq 'bon etat') { 'White' } else { 'Red' }) if ($isAdmin) { $rc = $d | Get-StorageReliabilityCounter if ($rc) { $bits = @() if ($rc.Temperature) { $bits += "$($rc.Temperature) degres C" } if ($null -ne $rc.Wear) { $bits += "usure $($rc.Wear) %" } if ($rc.PowerOnHours) { $bits += "{0:N0} h de fonctionnement" -f $rc.PowerOnHours } if ($rc.ReadErrorsUncorrected) { $bits += "$($rc.ReadErrorsUncorrected) erreurs de lecture" } if ($bits) { Row ' Details' ($bits -join ' - ') } } } } foreach ($v in Get-CimInstance Win32_LogicalDisk -Filter 'DriveType=3') { $pct = if ($v.Size) { [math]::Round($v.FreeSpace * 100 / $v.Size) } else { 0 } Row (" Lecteur $($v.DeviceID)") ('{0} libres sur {1} ({2} %)' -f (Go $v.FreeSpace), (Go $v.Size), $pct) $(if ($pct -lt 10) { 'Yellow' } else { 'White' }) } # --- Batterie --- $bat = Get-CimInstance Win32_Battery if ($bat) { Sec 'Batterie' Row 'Charge' ('{0} %' -f $bat.EstimatedChargeRemaining) $full = (Get-CimInstance -Namespace root\wmi -ClassName BatteryFullChargedCapacity | Select-Object -First 1).FullChargedCapacity $design = (Get-CimInstance -Namespace root\wmi -ClassName BatteryStaticData | Select-Object -First 1).DesignedCapacity if ($full -and $design) { $h = [math]::Round($full * 100 / $design) Row 'Etat de sante' ('{0} % de la capacite d''origine' -f $h) $(if ($h -lt 60) { 'Yellow' } else { 'White' }) } $cyc = (Get-CimInstance -Namespace root\wmi -ClassName BatteryCycleCount | Select-Object -First 1).CycleCount if ($cyc) { Row 'Cycles de charge' $cyc } } # --- Reseau --- Sec 'Reseau' foreach ($a in Get-NetAdapter -Physical | Where-Object Status -eq 'Up') { $cfg = Get-NetIPConfiguration -InterfaceIndex $a.ifIndex Row $a.Name ('{0} - {1}' -f $a.InterfaceDescription, $a.LinkSpeed) Row ' Adresse IP' ($cfg.IPv4Address.IPAddress -join ', ') Row ' Passerelle (box)' ($cfg.IPv4DefaultGateway.NextHop -join ', ') Row ' DNS' (($cfg.DNSServer | Where-Object AddressFamily -eq 2).ServerAddresses -join ', ') Row ' Adresse MAC' $a.MacAddress } $wlan = netsh wlan show interfaces $ssid = ($wlan -match '^\s+SSID\s+:' | Select-Object -First 1) -replace '^\s+SSID\s+:\s*', '' if ($ssid) { $sig = ($wlan -match '^\s+Signal\s+:' | Select-Object -First 1) -replace '^\s+Signal\s+:\s*', '' Row 'Wi-Fi connecte a' ($ssid + $(if ($sig) { " (signal $sig)" })) } # --- Peripheriques --- Sec 'Peripheriques' $prn = Get-CimInstance Win32_Printer | Where-Object { $_.Name -notmatch 'Microsoft|OneNote|Fax|PDF|XPS' } Row 'Imprimantes' $(if ($prn) { ($prn | ForEach-Object { $_.Name + $(if ($_.Default) { ' (par defaut)' }) }) -join ', ' } else { 'aucune' }) $bad = @(Get-CimInstance Win32_PnPEntity -Filter 'ConfigManagerErrorCode <> 0' | Where-Object { $_.Name }) if ($bad) { Row 'En erreur' ("{0} peripherique(s)" -f $bad.Count) 'Yellow' foreach ($b in $bad | Select-Object -First 10) { Row ' -' ('{0} (code {1})' -f $b.Name, $b.ConfigManagerErrorCode) 'Yellow' } } else { Row 'En erreur' 'aucun' } # --- Stabilite --- Sec 'Stabilite (30 derniers jours)' $since = (Get-Date).AddDays(-30) $bsod = @(Get-WinEvent -FilterHashtable @{ LogName='System'; ProviderName='Microsoft-Windows-WER-SystemErrorReporting'; Id=1001; StartTime=$since } -MaxEvents 50) $cuts = @(Get-WinEvent -FilterHashtable @{ LogName='System'; ProviderName='Microsoft-Windows-Kernel-Power'; Id=41; StartTime=$since } -MaxEvents 50) $apps = @(Get-WinEvent -FilterHashtable @{ LogName='Application'; ProviderName='Application Error'; Id=1000; StartTime=$since } -MaxEvents 200) Row 'Ecrans bleus' $bsod.Count $(if ($bsod.Count) { 'Yellow' } else { 'White' }) Row 'Arrets brutaux' $cuts.Count $(if ($cuts.Count) { 'Yellow' } else { 'White' }) Row 'Plantages de logiciels' $apps.Count if ($apps) { $top = $apps | ForEach-Object { $_.Properties[0].Value } | Group-Object | Sort-Object Count -Descending | Select-Object -First 3 Row ' Les plus frequents' (($top | ForEach-Object { '{0} ({1}x)' -f $_.Name, $_.Count }) -join ', ') } # --- Logiciels --- Sec 'Logiciels' $av = Get-CimInstance -Namespace root\SecurityCenter2 -ClassName AntiVirusProduct Row 'Antivirus' (($av | ForEach-Object { $_.displayName }) -join ', ') $fw = Get-NetFirewallProfile | Where-Object Enabled Row 'Pare-feu Windows' $(if ($fw) { 'Active' } else { 'DESACTIVE' }) $(if ($fw) { 'White' } else { 'Yellow' }) $c2r = Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Office\ClickToRun\Configuration' Row 'Microsoft Office' $(if ($c2r.ProductReleaseIds) { '{0} ({1})' -f ($c2r.ProductReleaseIds -replace 'Retail|Volume', ''), $c2r.VersionToReport } else { 'non detecte' }) $startup = @(Get-CimInstance Win32_StartupCommand | Where-Object { $_.Name -and $_.Name -ne 'desktop.ini' } | ForEach-Object { $_.Name -replace '_[0-9A-F]{16,}$', '' -replace 'AutoLaunch$', '' } | Select-Object -Unique) Row 'Lances au demarrage' ("{0} programme(s)" -f $startup.Count) $(if ($startup.Count -gt 12) { 'Yellow' } else { 'White' }) if ($startup) { Row ' Liste' (($startup | Select-Object -First 15) -join ', ') } # --- Sortie --- $text = $report -join "`r`n" $desktop = [Environment]::GetFolderPath('Desktop') $file = Join-Path $desktop 'Rapport-PC-NCinfo.txt' $saved = $false try { [IO.File]::WriteAllText($file, $text, [Text.Encoding]::UTF8); $saved = $true } catch {} $copied = $false try { Set-Clipboard -Value $text; $copied = $true } catch {} Write-Host '' Write-Host (" " + ('=' * 58)) -ForegroundColor DarkGray if ($copied) { Write-Host ' [OK] Rapport copie : collez-le (Ctrl+V) dans un e-mail ou un message.' -ForegroundColor Green } if ($saved) { Write-Host " [OK] Rapport enregistre sur le Bureau : Rapport-PC-NCinfo.txt" -ForegroundColor Green } if (-not $isAdmin) { Write-Host ' Astuce : lance en administrateur, le rapport inclut aussi l''usure et la temperature des disques.' -ForegroundColor DarkGray } # --- Envoi a NCinfo (uniquement avec l'accord de l'utilisateur) --- Write-Host '' $answer = Read-Host ' Envoyer ce rapport a NCinfo par e-mail ? (O/N)' if ($answer -match '^\s*[oOyY]') { $nom = ''; while (-not $nom.Trim()) { $nom = Read-Host ' Votre nom' } $contact = Read-Host ' Votre telephone ou e-mail (facultatif, Entree pour passer)' $msg = Read-Host ' Votre probleme en quelques mots (facultatif, Entree pour passer)' $fields = [ordered]@{ nom = $nom; contact = $contact; message = $msg; rapport = $text; source = 'script' } $body = ($fields.Keys | ForEach-Object { $_ + '=' + [Uri]::EscapeDataString([string]$fields[$_]) }) -join '&' try { [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 $res = Invoke-RestMethod -Uri "$NcSite/envoi-rapport.php" -Method Post -Body ([Text.Encoding]::UTF8.GetBytes($body)) ` -ContentType 'application/x-www-form-urlencoded; charset=utf-8' -UseBasicParsing -ErrorAction Stop if ($res.ok) { Write-Host ' [OK] Rapport envoye a NCinfo, merci ! Je reviens vers vous rapidement.' -ForegroundColor Green } else { Write-Host (' [!] Envoi refuse : ' + $res.error) -ForegroundColor Yellow } } catch { Write-Host ' [!] Envoi impossible. Envoyez le fichier du Bureau a contact@ncinfo.fr.' -ForegroundColor Yellow } } Write-Host '' Write-Host ' Une question ? contact@ncinfo.fr - ncinfo.fr' -ForegroundColor Gray Write-Host '' }