Mes scripts

Scripts PowerShell utiles

Hello World

Afficher un simple message dans la console PowerShell.

📥
Write-Host "Hello, World!"
✔ Copié

Rapport HTML

Analyse Matériel/logiciel et génère un rapport HTML.

📥
# Forcer la culture FR pour affichage date uniforme
[System.Threading.Thread]::CurrentThread.CurrentCulture = 'fr-FR'
[System.Threading.Thread]::CurrentThread.CurrentUICulture = 'fr-FR'
try {
    $serverTime = (Invoke-WebRequest -Uri "https://gmzone.fr/time.php" -UseBasicParsing).Content.Trim()
} catch {
    $serverTime = "<b>A completer</b>"
}
$rapportPath = "$env:USERPROFILE\Desktop\rapport_analyse_$(hostname).html"
$sectionId = 0
function Encode-HTML($text) {
    return [System.Net.WebUtility]::HtmlEncode($text)
}
function Format-BiosDate($rawDate) {
    if ($rawDate -is [datetime]) {
        return $rawDate.ToString('dd/MM/yyyy HH:mm:ss')
    } else {
        return [Management.ManagementDateTimeConverter]::ToDateTime($rawDate).ToString('dd/MM/yyyy HH:mm:ss')
    }
}
$html = @"
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Rapport d’analyse</title>
    <style>
        body { font-family: Consolas, monospace; background: #f4f4f4; color: #222; padding: 20px; }
        h1 { color: #222; text-align: center; font-size: 32px; }
        .container { display: flex; gap: 20px; }
        .column { flex: 1; padding: 10px; background: #fff; border: 1px solid #ccc; display: flex; flex-direction: column; max-height: 65vh; }
        .scroll-header { flex-shrink: 0; position: sticky; top: 0; background: #fff; z-index: 1; padding-bottom: 5px; }
        .scroll-body { flex-grow: 1; overflow-y: auto; }
        pre { background: #fff; padding: 10px; border: 1px solid #ccc; overflow-x: auto; }
        h3 { border-bottom: 1px solid #ccc; padding-bottom: 5px; }
    </style>
</head>
<body>
<h1>Rapport d’analyse de $(hostname)</h1>
"@
# --------------------------------------------------------------------------------
# --------------------------------------------------------------------------------
#                     PARTIE 1 – informations générales
# --------------------------------------------------------------------------------
# --------------------------------------------------------------------------------
$html += "<br><br><br><br><hr><center><h2>Informations générales</h2></center><hr><br><br>"
# COLONNE 1 – MATÉRIEL
$html += '<div class="container"><div class="column"><h3>Informations Matérielles</h3><pre>'
$bios = Get-CimInstance Win32_BIOS | Select-Object -First 1 Manufacturer, SMBIOSBIOSVersion, ReleaseDate
$board = Get-CimInstance Win32_BaseBoard | Select-Object -First 1 Manufacturer, Product, SerialNumber
$fullModel = (Get-CimInstance Win32_ComputerSystem | Select-Object -ExpandProperty Model)
$cpu = Get-CimInstance Win32_Processor | Select-Object -First 1 Name, NumberOfCores
$slots = Get-CimInstance Win32_PhysicalMemory
$slotTotal = (Get-CimInstance Win32_PhysicalMemoryArray).MemoryDevices
$capaciteTotale = ($slots | Measure-Object -Property Capacity -Sum).Sum / 1GB
$memoireText = "Nombre total de slots physiques : $slotTotal`nNombre de barrettes installées : $($slots.Count)`n"
$memoireText += ($slots | ForEach-Object {
    "- {0} Go @ {1} MHz ({2})" -f [math]::Round($_.Capacity / 1GB, 2), $_.Speed, $_.Manufacturer
}) -join "`n"
$memoireText += "`nCapacité totale installée : {0:N2} Go" -f $capaciteTotale
$gpuList = Get-CimInstance Win32_VideoController | ForEach-Object {
    $ramMB = [math]::Round($_.AdapterRAM / 1MB, 0)
    "- $($_.Name) ($ramMB MB)"
} | Out-String
$disqueText = ""
$disks = Get-Disk | Sort-Object Number
foreach ($disk in $disks) {
    $index = $disk.Number
    $name = $disk.FriendlyName
    $size = [math]::Round($disk.Size / 1GB, 2)
    $disqueText += "- Disque $index : $size Go ($name)`n"
}
$net = Get-CimInstance Win32_NetworkAdapterConfiguration | Where-Object {
    $_.IPEnabled -and $_.Description -notmatch "Virtual|Loopback|Bluetooth|TAP|TUN|WSL"
} | ForEach-Object {
    $ip = ($_.IPAddress | Where-Object { $_ -match "^\d{1,3}(\.\d{1,3}){3}$" }) -join ", "
    $dns = ($_.DNSServerSearchOrder -join ", ")
    "Interface : $($_.Description)`nIPv4 : $ip`nPasserelle : $($_.DefaultIPGateway -join ", ")`nDNS : $dns`n"
}
$biosDate = Format-BiosDate $bios.ReleaseDate
$html += Encode-HTML "[BIOS]`nFabricant : $($bios.Manufacturer) (Date de mise à jour : $biosDate)`n`n"
$html += Encode-HTML "[Carte Mère]`nFabricant : $($board.Manufacturer) (ref : $($board.Product))`nNuméro de série : $($board.SerialNumber)`n`n"
$html += Encode-HTML "[Processeur]`n$($cpu.Name) ($($cpu.NumberOfCores) cœurs)`n`n"
$html += Encode-HTML "[Mémoire Vive]`n$memoireText`n`n"
$html += Encode-HTML "[Carte Graphique]`n$gpuList`n"
$html += Encode-HTML "[Disques]`n$disqueText`n"
$html += Encode-HTML "[Cartes Réseau]`n$net"
$html += '</pre></div>'
# COLONNE 2 – DISQUES COMPLETS + PARTITIONS
$html += '<div class="column"><h3>Disques & Partitions</h3><br>'
$disks = Get-Disk
$volumes = Get-Volume | Where-Object { $_.DriveLetter -ne $null -and $_.Size -gt 0 }
foreach ($disk in $disks) {
    $diskIndex = $disk.Number
    $diskName = $disk.FriendlyName
    $sizeGB = [math]::Round($disk.Size / 1GB, 2)
    # Démarre le bloc disque
    $html += '<div style="border:1px solid #ccc; padding:10px; margin-bottom:10px;">'
    $html += "<div><b>$diskName</b></div>"
    # Recherche d’un volume lié à une partition de ce disque
    $volMatch = Get-Partition -DiskNumber $diskIndex |
        ForEach-Object { Get-Volume -Partition $_ -ErrorAction SilentlyContinue } |
        Where-Object { $_.DriveLetter -ne $null -and $_.Size -gt 0 } |
        Select-Object -First 1
    # Ajout de la barre si un volume est trouvé
    if ($volMatch) {
        $used = $volMatch.Size - $volMatch.SizeRemaining
        $percent = [math]::Round(($used / $volMatch.Size) * 100)
        $html += '<div style="width:100%;background:#eee;border:1px solid #ccc;height:18px;margin:5px 0;">'
        $html += '<div style="background:#0078D7;height:100%;width:' + $percent + '%;"></div>'
        $html += '</div>'
    }
    # Détails disque + partitions
    $html += '<pre>'
    $html += "Disque $diskIndex – $sizeGB Go ($diskName)`n"
    $partitions = Get-Partition -DiskNumber $diskIndex | Sort-Object PartitionNumber
    foreach ($part in $partitions) {
        $partIndex = $part.PartitionNumber
        $sizePart = [math]::Round($part.Size / 1MB, 0)
        $sizeDisplay = if ($sizePart -ge 1024) { "{0:N0} Go" -f ($sizePart / 1024) } else { "$sizePart Mo" }
        $volume = Get-Volume -Partition $part -ErrorAction SilentlyContinue
        $letter = if ($part.DriveLetter) { "$($part.DriveLetter):" } else { "" }
        $fs = if ($volume -and $volume.FileSystem) { $volume.FileSystem } else { "?" }
        $label = if ($volume -and $volume.FileSystemLabel) { $volume.FileSystemLabel } else { "" }
        $line = "  ├─ Partition $partIndex : $sizeDisplay"
        if ($letter) { $line += " <b>($letter)</b>" }
        if ($fs -ne "?") { $line += " – $fs" }
        if ($label) { $line += " [$label]" }
        $html += "$line`n"
    }
    $html += '</pre>'
    $html += '</div>' # Fin du bloc disque
}
$html += '</div>' # Fin de la colonne
# COLONNE 3 – SYSTÈME + COMPTES UTILISATEURS
$html += '<div class="column"><h3>Système d&#39;exploitation &amp; Comptes</h3><pre>'
$os = Get-CimInstance Win32_OperatingSystem
$tz = Get-TimeZone
$now = Get-Date
$serial = (Get-CimInstance Win32_BIOS | Select-Object -ExpandProperty SerialNumber)
$html += "Nom de l’ordinateur : $env:COMPUTERNAME`n"
$html += "Modèle : $fullModel`n"
$html += "Numéro de série : $serial`n`n"
$html += "Nom OS : $($os.Caption)`n"
# Ajout – Date d'installation de l'OS
if ($os.InstallDate) {
    $html += "Installé le : $($os.InstallDate.ToString('dd/MM/yyyy HH:mm:ss'))`n"
}
# Ajout – Dernière mise à jour KB installée
$lastUpdate = Get-HotFix | Sort-Object InstalledOn -Descending | Select-Object -First 1
if ($lastUpdate) {
    $html += "Dernière mise à jour : $($lastUpdate.HotFixID) le $($lastUpdate.InstalledOn.ToString('dd/MM/yyyy'))`n"
}
$html += "Version : $($os.Version)`n"
$html += "Architecture : $($os.OSArchitecture)`n"
$html += "Dernier démarrage : $($os.LastBootUpTime.ToString('dd/MM/yyyy HH:mm:ss'))`n"
$html += "Heure système : $($now.ToString('dd/MM/yyyy HH:mm:ss')) ($($tz.Id))`n`n"
$users = Get-LocalUser
$html += "Comptes utilisateurs locaux :`n"
foreach ($user in $users) {
    $statut = if ($user.Enabled) { "Actif" } else { "Désactivé" }
    $logonStr = if ($user.LastLogon) {
        " <small><i>LastLogon : $($user.LastLogon.ToString('dd/MM/yyyy HH:mm:ss'))</i></small>"
    } else {
        ""
    }
    $profilePath = "$env:SystemDrive\Users\$($user.Name)"
    $creation = ""
    if (Test-Path $profilePath) {
        try {
            $creationDate = (Get-Item $profilePath).CreationTime
            $creation = " | <small><i>Créé le : $($creationDate.ToString('dd/MM/yyyy HH:mm:ss'))</i></small>"
        } catch {
            $creation = " | <small><i>Création : inconnue</i></small>"
        }
    }
    $html += "- $($user.Name) ($statut)$logonStr$creation`n"
}
$html += "`nUtilisateur actuel : $env:USERNAME ($env:USERDOMAIN)`n"
$html += '</pre></div>'
$html += "</div>"
# --------------------------------------------------------------------------------
# --------------------------------------------------------------------------------
#                PARTIE 2 – Programmes installés par l'utilisateur
# --------------------------------------------------------------------------------
# --------------------------------------------------------------------------------
$html += "<br><br><br><br><hr><center><h2>Analyse Logiciel</h2></center><hr><br><br>"
# JavaScript compact, compatible irm | iex
$html += '<script>var preOriginals={};function storeOriginal(id){var p=document.getElementById(id);if(p){preOriginals[id]=p.innerText;}}function filterColumn(i,p){var f=document.getElementById(i).value.toLowerCase();var full=preOriginals[p];if(!f){document.getElementById(p).textContent=full;return;}var l=full.split("\n").filter(x=>x.toLowerCase().includes(f));document.getElementById(p).textContent=l.join("\n");}window.onload=function(){storeOriginal("preProc");storeOriginal("preApps");}</script>'
$html += '<div class="container">'
# ───── Colonne de gauche : Processus en cours (1/3) ─────
$html += "<div class='column' style='flex: 1;'>"
$html += "<div style='display:flex; justify-content:space-between; align-items:center;'><h3 style='margin:0;'>Processus en cours</h3><input type='text' id='filterProc' placeholder='Filtrer...' oninput=""filterColumn('filterProc','preProc')"" style='margin-left:10px; padding:3px 6px;'></div><br>"
$html += "<pre id='preProc'>"
$procText = ""
$processList = Get-Process | Sort-Object WorkingSet64 -Descending
foreach ($proc in $processList) {
    try {
        $name = Encode-HTML $proc.ProcessName
        $id = $proc.Id
        $mem = '{0:N1}' -f ($proc.WorkingSet64 / 1MB)
        $procText += "$name (PID $id) – RAM: $mem Mo`n"
    } catch {}
}
$html += $procText
$html += "</pre></div>"
# ───── Colonne de droite : Programmes installés (2/3) ─────
$html += "<div class='column' style='flex: 2;'>"
$html += "<div style='display:flex; justify-content:space-between; align-items:center;'><h3 style='margin:0;'>Programmes installés par l&#39;utilisateur</h3><input type='text' id='filterApps' placeholder='Filtrer...' oninput=""filterColumn('filterApps','preApps')"" style='margin-left:10px; padding:3px 6px;'></div><br>"
$html += "<pre id='preApps'>"
$appText = ""
$regPaths = @(
    "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
    "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*",
    "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*"
)
$apps = foreach ($path in $regPaths) {
    Get-ItemProperty $path -ErrorAction SilentlyContinue | Where-Object {
        $_.DisplayName -and $_.InstallDate -match '^\d{8}$'
    } | Select-Object DisplayName, Publisher, InstallDate
}
$filteredApps = $apps | Where-Object {
    $_.Publisher -notmatch 'Microsoft|Windows|MSI|Visual C\+\+|Update|Security|Hotfix'
} | Sort-Object {
    try {
        [datetime]::ParseExact($_.InstallDate, 'yyyyMMdd', $null)
    } catch {
        [datetime]::MinValue
    }
} -Descending
foreach ($app in $filteredApps) {
    $date = try {
        [datetime]::ParseExact($app.InstallDate, 'yyyyMMdd', $null).ToString('dd/MM/yyyy')
    } catch {
        "Date inconnue"
    }
    $name = Encode-HTML $app.DisplayName
    $publisher = Encode-HTML $app.Publisher
    $appText += "$name – $publisher ($date)`n"
}
$html += $appText
$html += "</pre></div>"
$html += "</div>"
# --------------------------------------------------------------------------------
# --------------------------------------------------------------------------------
#                              PARTIE 3 – Autre
# --------------------------------------------------------------------------------
# --------------------------------------------------------------------------------
$html += "<br><br><br><br><hr><center><h2>Autre</h2></center><hr><br><br>"
$html += '<div class="container">'
# ───── Colonne 1 : Réseau ─────
$html += '<div class="column"><h3>Informations Réseau</h3><pre>'
# Adresse IP publique
try {
    $ipPublique = (Invoke-WebRequest -Uri "https://api.ipify.org" -UseBasicParsing).Content.Trim()
    $html += "🌍 Adresse IP publique : $ipPublique`n"
} catch {
    $html += "🌍 Adresse IP publique : [non disponible]`n"
}
# Interfaces réseau locales (hors virtuelles)
$html += "`n📶 Interfaces réseau locales :`n"
$interfaces = Get-NetIPAddress -AddressFamily IPv4 |
    Where-Object { $_.IPAddress -notmatch "^169\.254" -and $_.IPAddress -notmatch "^127\." } |
    Sort-Object InterfaceAlias
foreach ($iface in $interfaces) {
    $html += "- $($iface.InterfaceAlias) : $($iface.IPAddress)`n"
}
 $html += "`n"
# Lecteurs réseau
$netConns = Get-WmiObject -Class Win32_NetworkConnection
if ($netConns) {
    $html += "📁 Lecteurs réseau mappés :`n"
    foreach ($nc in $netConns) {
        $html += "- $($nc.LocalName) → $($nc.RemoteName) (utilisateur : $($nc.UserName))`n"
    }
} else {
    $html += "📁 Aucun lecteur réseau mappé détecté.`n"
}
# Connexions RDP récentes (MRU)
$rdpKeyPath = "HKCU:\Software\Microsoft\Terminal Server Client\Default"
if (Test-Path $rdpKeyPath) {
    $rdpHosts = Get-ItemProperty -Path $rdpKeyPath |
        Select-Object -ExpandProperty PSObject.Properties |
        Where-Object { $_.Name -like "MRU*" } |
        ForEach-Object { $_.Value }
    if ($rdpHosts) {
        $html += "`n🖥️ Connexions RDP récentes :`n"
        foreach ($host in $rdpHosts) {
            $html += "- $host`n"
        }
    } else {
        $html += "`n🖥️ Aucun hôte RDP trouvé dans les MRU.`n"
    }
} else {
    $html += "`n🖥️ Aucune clé RDP MRU détectée (aucune connexion passée ?).`n"
}
# RDP - hôtes avec certificats enregistrés
$rdpServerKey = "HKCU:\Software\Microsoft\Terminal Server Client\Servers"
if (Test-Path $rdpServerKey) {
    $rdpServers = Get-ChildItem -Path $rdpServerKey -ErrorAction SilentlyContinue
    if ($rdpServers) {
        $html += "`n🔐 Hôtes RDP avec certificat mémorisé :`n"
        foreach ($srv in $rdpServers) {
            $html += "- $($srv.PSChildName)`n"
        }
    }
}
$html += '</pre></div>'
# ───── Colonne 2 : Sécurité ─────
$html += '<div class="column"><h3>Sécurité</h3><pre>'
# Liste des noms de processus AV connus
# Liste étendue des processus antivirus connus
$knownAV = @(
    # Windows Defender
    'MsMpEng',
    # Avast / AVG
    'avastui', 'avastsvc', 'avgui', 'avgnsx', 'avgsvc',
    # Malwarebytes
    'mbamtray', 'mbamservice', 'MBAMWsc',
    # BitDefender
    'bdagent', 'vsserv', 'updatesrv', 'epsecurityservice', 'bdservicehost',
    # Kaspersky
    'avp', 'kavsvc', 'avpsus',
    # ESET NOD32
    'ekrn', 'eguiProxy',
    # Norton / Symantec
    'ccSvcHst', 'navapsvc', 'nortonsecurity',
    # McAfee
    'mcshield', 'mfemms', 'mcuihost', 'masvc', 'mfefire',
    # Sophos
    'savservice', 'sophosfs', 'sophossps', 'sophosui', 'sophosclean',
    # Panda
    'psanhost', 'psanprxy', 'PavFnSvr', 'PavProt', 'pavsrvx86',
    # Trend Micro
    'coreServiceShell', 'TmCCSF', 'NTRTScan',
    # Avira
    'avira', 'avguard', 'avgnt',
    # ZoneAlarm
    'zlclient',
    # Comodo
    'cmdagent', 'cfp',
    # Qihoo 360
    '360tray', '360sd', 'QHSafeTray', 'QHActiveDefense',
    # Webroot
    'WRSA',
    # F-Secure
    'fshoster32', 'fsgk32', 'fsdfwd',
    # Dr.Web
    'dwengine', 'drwebspider',
    # G Data
    'AVKService', 'AVKWCtl',
    # Fortinet
    'fortitray', 'forticlient',
    # Cylance
    'CylanceSvc',
    # SentinelOne
    'SentinelAgent',
    # CrowdStrike Falcon
    'CSFalconService',
    # Immunet
    'iptray', 'agentui',
    # Others / rare
    'clamtray', 'clamd', 'escantray', 'emsisoft', 'vba32ldr', 'V3Tray'
)
# Détection par processus
$runningAVs = Get-Process -ErrorAction SilentlyContinue | Where-Object {
    $knownAV -contains $_.Name
} | Select-Object Name, Id
if ($runningAVs.Count -gt 0) {
    $html += "🔍 Processus antivirus détectés dans la mémoire :`n"
    foreach ($av in $runningAVs) {
        $html += "• $($av.Name) (PID: $($av.Id))`n"
    }
} else {
    $html += "❌ Aucun processus antivirus connu détecté dans les processus en cours.`n"
}
$html += "`n"
# Détection via Security Center
$avProducts = Get-CimInstance -Namespace root/SecurityCenter2 -Class AntiVirusProduct -ErrorAction SilentlyContinue
if ($avProducts.Count -gt 0) {
    $html += "📋 Antivirus reconnus par Windows (Security Center) :`n"
    foreach ($av in $avProducts) {
        $html += "- $($av.displayName)`n"
    }
} else {
    $html += "⚠️ Aucun antivirus déclaré dans le Security Center.`n"
}
$html += "`n"
# Windows Defender : statut précis
$defenderStatus = Get-MpComputerStatus -ErrorAction SilentlyContinue
if ($defenderStatus) {
    $html += "🛡️ État de Windows Defender :`n"
    $html += "• Service actif         : $($defenderStatus.AMServiceEnabled)`n"
    $html += "• Antivirus activé      : $($defenderStatus.AntivirusEnabled)`n"
    $html += "• Protection temps réel : $($defenderStatus.RealTimeProtectionEnabled)`n"
} else {
    $html += "🛡️ Windows Defender : Indisponible (peut être désactivé ou non installé).`n"
}
$html += "`n"
# ───── Conclusion finale ─────
$defenderRealTime = $defenderStatus -and $defenderStatus.RealTimeProtectionEnabled
if ($runningAVs.Count -eq 0 -and -not $defenderRealTime) {
    $html += "`n🛑 Aucun antivirus actif détecté (ni tiers en mémoire, ni Defender en temps réel)."
} elseif ($runningAVs.Count -gt 0 -or $defenderRealTime) {
    $html += "`n✅ Une protection antivirus est active."
} else {
    $html += "`n⚠️ Aucun antivirus actif en mémoire, et Defender est inactif en temps réel. Vérification manuelle recommandée."
}
$html += '</pre></div>'
# ───── Colonne 3 : Liens utiles ─────
$html += '<div class="column"><h3>Nirsoft</h3><pre>'
$html += "<center>Pensez à désactiver l'antivirus</center><br>`n"
$html += "<a href='https://www.gmzone.fr/downloads/tools/BrowsingHistoryView-32.exe'>BrowsingHistoryView (32bits)</a> - <a href='https://www.gmzone.fr/downloads/tools/BrowsingHistoryView-64.exe'>BrowsingHistoryView (64bits)</a>`n<br>"
$html += "<a href='https://www.gmzone.fr/downloads/tools/OutlookAccountsView-32.exe'>OutlookAccountsView (32bits)</a> - <a href='https://www.gmzone.fr/downloads/tools/OutlookAccountsView-64.exe'>OutlookAccountsView (64bits)</a>`n<br>"
$html += "<a href='https://www.gmzone.fr/downloads/tools/SearchMyFiles-32.exe'>SearchMyFiles (32bits)</a>       - <a href='https://www.gmzone.fr/downloads/tools/SearchMyFiles-64.exe'>SearchMyFiles (64bits)</a>`n<br>"
$html += "<a href='https://www.gmzone.fr/downloads/tools/Ext_Password.exe'>ExtPassword</a>`n<br>"
$html += "<a href='https://www.gmzone.fr/downloads/tools/WBPV.exe'>Web Browser Pass View</a>`n<br>"
$html += "<a href='https://www.gmzone.fr/downloads/tools/ftk.zip'>Ftk Imager Portable</a>`n<br>"
$html += '</pre></div>'
$html += '</div>'
$html += '<br>'
# ───── Connexions distantes ─────
$html += '<br><br><hr><center><h2>Connexions distantes</h2></center><hr><br>'
$html += '<div class="container">'
# ───── Colonne 1 : IP Locales ─────
$html += '<div class="column"><h3>Connexions IP Locales</h3>'
$html += '<pre><table style="width:100%; border-collapse:collapse; font-family:monospace;">'
$html += '<thead><tr style="background:#eee;"><th>PROTO</th><th>IP LOCALE</th><th>IP DISTANTE</th><th>PID</th><th>Appli</th></tr></thead><tbody>'
$localTable = ""
# ───── Colonne 2 : IP Externes ─────
$externalTable = ""
function Is-LocalIP($ip) {
    return $ip -match '^127\.|^192\.168\.|^10\.|^172\.(1[6-9]|2[0-9]|3[0-1])\.|^::1$|^fe80::|^fc00:|^fd00:'
}
# TCP
$tcpConnections = Get-NetTCPConnection -State Established
foreach ($conn in $tcpConnections) {
    $proc = Get-Process -Id $conn.OwningProcess -ErrorAction SilentlyContinue
    $procName = if ($proc) { $proc.ProcessName } else { "?" }
    $local = "$($conn.LocalAddress):$($conn.LocalPort)"
    $remote = "$($conn.RemoteAddress):$($conn.RemotePort)"
    $line = "<tr><td>TCP</td><td>$local</td><td>$remote</td><td>$($conn.OwningProcess)</td><td>$procName</td></tr>"
    if (Is-LocalIP $conn.RemoteAddress) {
        $localTable += $line
    } else {
        $externalTable += $line
    }
}
# UDP
$udpConnections = Get-NetUDPEndpoint
foreach ($conn in $udpConnections) {
    $proc = Get-Process -Id $conn.OwningProcess -ErrorAction SilentlyContinue
    $procName = if ($proc) { $proc.ProcessName } else { "?" }
    $local = "$($conn.LocalAddress):$($conn.LocalPort)"
    $remote = if ($conn.RemoteAddress -and $conn.RemotePort) {
        "$($conn.RemoteAddress):$($conn.RemotePort)"
    } else {
        "en attente"
    }
    $line = "<tr><td>UDP</td><td>$local</td><td>$remote</td><td>$($conn.OwningProcess)</td><td>$procName</td></tr>"
    if ($conn.RemoteAddress -and (Is-LocalIP $conn.RemoteAddress)) {
        $localTable += $line
    } else {
        $externalTable += $line
    }
}
$html += "$localTable</tbody></table></pre></div>"
$html += '<div class="column"><h3>Connexions IP Externes</h3>'
$html += '<pre><table style="width:100%; border-collapse:collapse; font-family:monospace;">'
$html += '<thead><tr style="background:#eee;"><th>PROTO</th><th>IP LOCALE</th><th>IP DISTANTE</th><th>PID</th><th>Appli</th></tr></thead><tbody>'
$html += "$externalTable</tbody></table></pre></div>"
$html += '</div>' # container
# --------------------------------------------------------------------------------
# --------------------------------------------------------------------------------
#                              PARTIE 4 – Rapport
# --------------------------------------------------------------------------------
# --------------------------------------------------------------------------------
$html += "<br><br><br><br><hr><center><h2>RAPPORT</h2></center><hr><br><br>"
$html += '<div class="container">'
# ───── Colonne 1 : Mémo ─────
$html += '<div class="column" style="flex: 1;"><h3>Mémo</h3><pre>'
$html += "• Noter date/heure du début/fin d'analyse.`n"
$html += "<br>"
$html += "• Verifier si Bitlocker ou autre n'est pas activé.`n"
$html += "<small><i>irm 'https://gmzone.fr/scripts/index.php?file=check_encryption.ps1' | iex</i></small>`n"
$html += "<small><i>irm 'https://gmzone.fr/scripts/index.php?file=bitlocker.ps1' | iex</i></small>`n"
$html += "<br>"
$html += "• Verifier la présence de logiciel de P2P.`n"
$html += "<small><i>irm 'https://gmzone.fr/scripts/index.php?file=p2p_check.ps1' | iex</i></small>`n"
$html += "<br>"
$html += "• Chrome bloque les téléchargements de Nirsoft.`n"
$html += "<small><i>Paramètres > Confidentialité & Sécurité > Sécurité > Aucune protection.</i></small>`n"
$html += '</pre></div>'
# ───── Colonne 2 : rapport ─────
# ───── Colonne 2 : rapport ─────
$html += '<div class="column" style="flex: 2;"><h3>Rapport</h3><pre>'
# Infos déjà disponibles
$now = Get-Date -Format 'dd/MM/yyyy HH:mm:ss'
$os = Get-CimInstance Win32_OperatingSystem
$osName = $os.Caption
$osInstallDate = $os.InstallDate.ToString('dd/MM/yyyy HH:mm:ss')
$manufacturer = $cs.Manufacturer
$lastUpdateDate = $lastKbUpdateDate
$disks = Get-Disk
$partitions = Get-Partition | Group-Object DiskNumber
$systemDrive = $env:SystemDrive
$systemVolume = Get-Partition | Where-Object { $_.DriveLetter -eq $systemDrive.TrimEnd(':') }
$systemDiskNumber = $systemVolume.DiskNumber
$systemPartitionNumber = $systemVolume.PartitionNumber
$html += "• Débutons nos investigations le $serverTime.`n"
$html += "Nous constatons qu'il s'agit d'un ordinateur nommé '$env:COMPUTERNAME', Modèle : '$fullModel', Numéro de série : '$serial'.`n"
$html += "Il comporte '" + $disks.Count + "' disques durs :`n"
$diskDrives = Get-CimInstance Win32_DiskDrive
foreach ($disk in $disks) {
    $sizeGB = [math]::Round($disk.Size / 1GB, 0)
    $diskNumber = $disk.Number
    # Récupère les infos correspondantes dans Win32_DiskDrive
    $driveInfo = $diskDrives | Where-Object { $_.DeviceID -match "$diskNumber`$" }
    $friendlyName = $disk.FriendlyName
    $partCount = ($partitions | Where-Object { $_.Name -eq $diskNumber }).Group.Count
    $html += "- le disque $diskNumber : $friendlyName. Taille : $sizeGB Gb. Il contient $partCount partitions.`n"
}
$html += "Le système d'exploitation que nous analysons est situé sur la partition '$systemPartitionNumber' du disque '$systemDiskNumber'.`n"
$html += "Il s'agit de '$osName', installé le $osInstallDate et mis à jour pour la dernière fois le $($lastUpdate.InstalledOn.ToString('dd/MM/yyyy'))`n"
$html += "Nous relevons l'heure système : $now ($($tz.Id))`n"
$html += "Nous consultons la liste des logiciels installés. Constatons la présence des applications suivantes :`n"
$html += "- `n"
$html += "- `n"
$html += "- `n"
$html += "<small><i>(Bitlocker, P2P, Historique ...)</i></small><br>"
$html += "La suite de nos opérations ne permet pas d'apporter d'autres éléments utiles.`n"
$html += '</pre></div>'
$html += '</div>'
# ───── Fin 
$html += "</body></html>"
$html | Out-File -Encoding UTF8 -FilePath $rapportPath
Start-Process $rapportPath
✔ Copié

Statut de l'antivirus

Regarde si le processus d'un antivirus connu est en cours, ou si windows defendre est activé.

📥
function Show-AVStatus {
    Clear-Host
    $colorOK = 'Green'
    $colorWarn = 'Yellow'
    $colorKO = 'Red'
    Write-Host "`n═╦═ BILAN DE LA PROTECTION ANTIVIRUS ═╦═" -ForegroundColor Cyan
    Write-Host ("═" * 38) -ForegroundColor DarkGray
    Write-Host ""
    # Liste étendue de processus antivirus connus
    $knownAV = @(
        'MsMpEng','avastui','avastsvc','avgui','avgnsx','avgsvc','mbamtray','mbamservice','MBAMWsc','bdagent','vsserv',
        'updatesrv','epsecurityservice','bdservicehost','avp','kavsvc','avpsus','ekrn','eguiProxy','ccSvcHst','navapsvc',
        'nortonsecurity','mcshield','mfemms','mcuihost','masvc','mfefire','savservice','sophosfs','sophossps','sophosui',
        'sophosclean','psanhost','psanprxy','PavFnSvr','PavProt','pavsrvx86','coreServiceShell','TmCCSF','NTRTScan',
        'avira','avguard','avgnt','zlclient','cmdagent','cfp','360tray','360sd','QHSafeTray','QHActiveDefense','WRSA',
        'fshoster32','fsgk32','fsdfwd','dwengine','drwebspider','AVKService','AVKWCtl','fortitray','forticlient',
        'CylanceSvc','SentinelAgent','CSFalconService','iptray','agentui','clamtray','clamd','escantray','emsisoft',
        'vba32ldr','V3Tray'
    )
    # Recherche des processus antivirus en mémoire
    $runningAVs = Get-Process -ErrorAction SilentlyContinue | Where-Object {
        $knownAV -contains $_.Name
    } | Select-Object -ExpandProperty Name
    # Recherche via le Security Center
    $securityAVs = Get-CimInstance -Namespace root/SecurityCenter2 -Class AntiVirusProduct -ErrorAction SilentlyContinue |
                   Select-Object -ExpandProperty displayName
    # État de Defender
    $defenderStatus = Get-MpComputerStatus -ErrorAction SilentlyContinue
    $defenderRealTime = $false
    if ($defenderStatus) {
        $defenderRealTime = $defenderStatus.RealTimeProtectionEnabled
    }
    # Logique de conclusion unique
    if ($runningAVs.Count -eq 0 -and -not $defenderRealTime) {
        Write-Host "🛑 Aucun antivirus actif détecté." -ForegroundColor $colorKO
        if ($securityAVs.Count -gt 0) {
            Write-Host "⚠️  AV installés mais inactifs : $($securityAVs -join ', ')" -ForegroundColor $colorWarn
        } else {
            Write-Host "❌ Aucun antivirus tiers détecté (ni installé ni actif)." -ForegroundColor $colorWarn
        }
        if ($defenderStatus) {
            Write-Host "🛡️  Windows Defender est désactivé en temps réel : $($defenderStatus.RealTimeProtectionEnabled)" -ForegroundColor $colorWarn
        } else {
            Write-Host "🛡️  Windows Defender indisponible ou non installé." -ForegroundColor $colorWarn
        }
    } else {
        Write-Host "✅ Une protection antivirus est active." -ForegroundColor $colorOK
        if ($runningAVs.Count -gt 0) {
            Write-Host "🧠 En mémoire : $($runningAVs -join ', ')" -ForegroundColor $colorOK
        }
        if ($securityAVs.Count -gt 0) {
            Write-Host "🔎 Reconnus par Windows : $($securityAVs -join ', ')" -ForegroundColor $colorOK
        }
        if ($defenderStatus) {
            Write-Host "🛡️  Windows Defender - Temps réel : $($defenderStatus.RealTimeProtectionEnabled)" -ForegroundColor $colorOK
        }
    }
    Write-Host ""
    Write-Host "Appuie sur Entrée pour quitter..." -ForegroundColor Yellow
    [void][System.Console]::ReadLine()
}
Show-AVStatus
✔ Copié

Bitlocker

Vérifie si Bitlocker est activé ou non. Le cas échéant, affiche la clef de déchiffrement (A éxécuter en mode admin)

📥
function Show-BitlockerInfos {
    Clear-Host
    Write-Host "====== Vérification Chiffrement Disque & Clés BitLocker ======" -ForegroundColor Cyan
    # Vérification privilèges admin
    $isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()
    ).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
    if (-not $isAdmin) {
        Write-Host "ERREUR : Ce script doit être lancé en tant qu'administrateur." -ForegroundColor Red
        Write-Host "Faites un clic droit sur PowerShell et choisissez 'Exécuter en tant qu'administrateur'."
        Write-Host ""
        Write-Host "Appuie sur Entrée pour quitter..." -ForegroundColor Yellow
        [void][System.Console]::ReadLine()
        return
    }
    # Exécution de l’analyse BitLocker
    try {
        $bitlockerVolumes = Get-BitLockerVolume 2>$null
        if (-not $bitlockerVolumes) {
            Write-Host "BitLocker n'est pas activé ou inaccessible." -ForegroundColor Red
        } else {
            foreach ($volume in $bitlockerVolumes) {
                $mountPoint = $volume.MountPoint
                $status = $volume.ProtectionStatus
                $protectors = $volume.KeyProtector
                Write-Host "`n[Volume : $mountPoint]"
                if ($status -eq 'On') {
                    Write-Host "Statut : Chiffré avec BitLocker" -ForegroundColor Green
                    foreach ($protectorID in $protectors) {
                        $kp = Get-BitLockerKeyProtector -MountPoint $mountPoint -KeyProtectorId $protectorID.KeyProtectorId 2>$null
                        if ($kp -and $kp.KeyProtectorType -eq 'RecoveryPassword') {
                            Write-Host "Clé de récupération : $($kp.RecoveryPassword)"
                        }
                    }
                } else {
                    Write-Host "Statut : Non chiffré" -ForegroundColor Yellow
                }
            }
        }
    }
    catch {
        Write-Host "Erreur lors de la récupération des informations BitLocker." -ForegroundColor Red
    }
    Write-Host ""
    Write-Host "Appuie sur Entrée pour quitter..." -ForegroundColor Yellow
    [void][System.Console]::ReadLine()
}
# Lancement
Show-BitlockerInfos
✔ Copié

Encryption Check

Vérifie la présence de BitLocker, VeraCrypt, TrueCrypt, McAfee, Check Point, Symantec dans les processus, services, registre et programmes installés.

📥
function Show-EncryptionStatus {
    Clear-Host
    Write-Host "====== Détection des Chiffrements de Disque ======" -ForegroundColor Cyan
    # BitLocker (sans élévation)
    Write-Host "`n[BitLocker]"
    try {
        $keys = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\BitLockerStatus\*" 2>$null
        if ($keys) {
            foreach ($key in $keys) {
                $drive = $key.PSChildName
                switch ($key.ProtectionStatus) {
                    1 { $status = "Chiffré (BitLocker)" }
                    0 { $status = "Non chiffré" }
                    default { $status = "Inconnu" }
                }
                Write-Host "- $drive : $status" -ForegroundColor (if ($status -eq "Chiffré (BitLocker)") { "Green" } else { "White" })
            }
        } else {
            Write-Host "BitLocker : aucune information trouvée dans la base de registre (pas activé ou désactivé proprement)" -ForegroundColor DarkGray
        }
    } catch {
        Write-Host "Erreur lors de la lecture de l'état BitLocker (accès refusé ou registre absent)" -ForegroundColor Red
    }
    # Programmes installés (filtrage plus tard)
    $installedApps = @(Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*,
                                    HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* 2>$null)
    # VeraCrypt / TrueCrypt
    Write-Host "`n[VeraCrypt / TrueCrypt]"
    $vcProc = Get-Process | Where-Object { $_.Name -match 'veracrypt|truecrypt' }
    $vcInstalled = $installedApps | Where-Object { $_.DisplayName -match 'VeraCrypt|TrueCrypt' }
    if ($vcProc) {
        Write-Host "Processus détecté : $($vcProc.Name) actif" -ForegroundColor Green
    } elseif ((Test-Path "HKLM:\SOFTWARE\VeraCrypt") -or (Test-Path "HKLM:\SOFTWARE\Wow6432Node\VeraCrypt")) {
        Write-Host "Installation VeraCrypt détectée (registre)" -ForegroundColor Yellow
    } elseif ($vcInstalled) {
        Write-Host "Installation VeraCrypt détectée (programmes)" -ForegroundColor Yellow
    } else {
        Write-Host "Aucune trace détectée"
    }
    # McAfee Drive Encryption
    Write-Host "`n[McAfee Drive Encryption]"
    $mcafeeProc = Get-Process | Where-Object { $_.Name -match 'mcshield|frminst|masvc' }
    $mcafeeInstalled = $installedApps | Where-Object { $_.DisplayName -match 'McAfee.*(Encryption|Endpoint)' }
    if ($mcafeeProc) {
        Write-Host "Processus McAfee détecté : $($mcafeeProc.Name)" -ForegroundColor Green
    } elseif (Test-Path "HKLM:\Software\McAfee\Endpoint Encryption") {
        Write-Host "Installation McAfee détectée (registre)" -ForegroundColor Yellow
    } elseif ($mcafeeInstalled) {
        Write-Host "Installation McAfee détectée (programmes)" -ForegroundColor Yellow
    } else {
        Write-Host "Non détecté"
    }
    # Check Point Full Disk Encryption
    Write-Host "`n[Check Point Full Disk Encryption]"
    $cpProc = Get-Process | Where-Object { $_.Name -match 'tracsrv|epal' }
    $cpInstalled = $installedApps | Where-Object { $_.DisplayName -match 'Check Point|FDE' }
    if ($cpProc) {
        Write-Host "Processus Check Point détecté : $($cpProc.Name)" -ForegroundColor Green
    } elseif (Get-Service | Where-Object { $_.Name -match 'FDE' }) {
        Write-Host "Service FDE actif (Check Point ?)" -ForegroundColor Green
    } elseif (Test-Path "HKLM:\SOFTWARE\CheckPoint") {
        Write-Host "Installation CheckPoint détectée (registre)" -ForegroundColor Yellow
    } elseif ($cpInstalled) {
        Write-Host "Installation CheckPoint détectée (programmes)" -ForegroundColor Yellow
    } else {
        Write-Host "Non détecté"
    }
    # Symantec Encryption
    Write-Host "`n[Symantec Endpoint Encryption]"
    $symProc = Get-Process | Where-Object { $_.Name -match 'symantec|pgp' }
    $symInstalled = $installedApps | Where-Object { $_.DisplayName -match 'Symantec|PGP' }
    if ($symProc) {
        Write-Host "Processus Symantec détecté : $($symProc.Name)" -ForegroundColor Green
    } elseif (Get-Service | Where-Object { $_.DisplayName -match 'Symantec' }) {
        Write-Host "Service Symantec détecté" -ForegroundColor Green
    } elseif ($symInstalled) {
        Write-Host "Installation Symantec détectée (programmes)" -ForegroundColor Yellow
    } else {
        Write-Host "Non détecté"
    }
    Write-Host ""
    Write-Host "Appuie sur Entrée pour quitter..." -ForegroundColor Yellow
    [void][System.Console]::ReadLine()
}
Show-EncryptionStatus
✔ Copié

Informations logicielles

Affiche les informations logicielles : Partitions, OS, date d'installation, liste des utilisateurs, programmes installés (triés par date) , applications en cours d'éxécution.

📥
# Rapport logiciel PowerShell
function Show-SoftwareInfos {
    Clear-Host
    Write-Host "====== Informations LOGICIELLES ======" -ForegroundColor Cyan
    # Disques et partitions
    Write-Host "`n[Disques et Partitions]"
    $drives = Get-PhysicalDisk | ForEach-Object {
        $diskNumber = ($_ | Get-Disk).Number
        $partitions = (Get-Partition -DiskNumber $diskNumber | Measure-Object).Count
        $model = $_.FriendlyName
        "$model (Disque $diskNumber) : $partitions partition(s)"
    }
    $drives | ForEach-Object { Write-Host $_ }
    # Disque système
    Write-Host "`n[Disque contenant l'OS]"
    $systemDrive = (Get-CimInstance Win32_OperatingSystem).SystemDrive
    Write-Host "$systemDrive"
    # Détail OS
    Write-Host "`n[Système d'exploitation]"
    $os = Get-CimInstance Win32_OperatingSystem
    Write-Host "$($os.Caption) ($($os.OSArchitecture))"
    Write-Host "Version : $($os.Version)"
    # Date d'installation
    Write-Host "`n[Date d'installation de l'OS]"
    Write-Host $os.InstallDate
    # Utilisateurs
    Write-Host "`n[Utilisateurs Locaux]"
    Get-LocalUser | ForEach-Object {
        $logon = if ($_.LastLogon) {
		$_.LastLogon.ToString("dd/MM/yyyy HH:mm:ss")
			} else {
				"Inconnue"
			}
			Write-Host ("- {0,-20} | Activé: {1,-5} | Dernière connexion: {2}" -f $_.Name, $_.Enabled, $logon)
    }
    # Demander pour afficher les programmes installés
    $showApps = Read-Host "`nSouhaitez-vous afficher les applications installées par l'utilisateur ? (O/N)"
    if ($showApps -match '^[Oo]$') {
        Write-Host "`n[Applications installées par l'utilisateur]"
        $apps = Get-ItemProperty -Path @(
            "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
            "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*",
            "HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*"
        ) 2>$null |
        Where-Object {
            $_.DisplayName -and $_.InstallDate -match '^[0-9]{8}$' -and
            $_.DisplayName -notmatch 'Microsoft|Windows|Update|Hotfix'
        } | Sort-Object InstallDate -Descending
        if ($apps) {
            $apps | ForEach-Object {
                try {
                    $date = [datetime]::ParseExact($_.InstallDate, 'yyyyMMdd', $null)
                    Write-Host "$($date.ToString('dd/MM/yyyy')) - $($_.DisplayName)"
                } catch {
                    Write-Host "Date inconnue - $($_.DisplayName)"
                }
            }
        } else {
            Write-Host "Aucune application utilisateur détectée."
        }
    }
    # Demander pour afficher les processus utilisateurs
    $showProc = Read-Host "`nSouhaitez-vous afficher les processus utilisateurs actifs ? (O/N)"
    if ($showProc -match '^[Oo]$') {
        Write-Host "`n[Applications en cours d'exécution par l'utilisateur]"
        Get-Process | Where-Object {
            $_.Path -and $_.Path -notmatch 'Windows\\System32|Windows\\SysWOW64|Microsoft' 
        } | Sort-Object CPU -Descending | ForEach-Object {
            Write-Host "- $($_.ProcessName) [$($_.Path)]"
        }
    }
    Write-Host "`nAppuie sur Entrée pour quitter..." -ForegroundColor Yellow
    [void][System.Console]::ReadLine()
}
Show-SoftwareInfos
✔ Copié

Informations matériels

Affiche les informations matériel de l'ordinateur

📥
function Show-Infos {
    Clear-Host
    Write-Host "====== Informations Matériel ======" -ForegroundColor Cyan
    # BIOS
    $bios = Get-CimInstance Win32_BIOS | Select-Object -First 1 Manufacturer, ReleaseDate
    Write-Host "`n[BIOS]"
    Write-Host "$($bios.Manufacturer) (ReleaseDate : $($bios.ReleaseDate))"
    # Carte Mère
    $board = Get-CimInstance Win32_BaseBoard | Select-Object -First 1 Manufacturer, Product
    Write-Host "`n[Carte Mère]"
    Write-Host "$($board.Manufacturer) (Product : $($board.Product))"
    # Processeur
    $cpu = Get-CimInstance Win32_Processor | Select-Object -First 1 Name, NumberOfCores
    Write-Host "`n[Processeur]"
    Write-Host "$($cpu.Name) ($($cpu.NumberOfCores) coeurs)"
    # Mémoire Vive
    $slots = Get-CimInstance Win32_PhysicalMemory
    $slotTotal = (Get-CimInstance Win32_PhysicalMemoryArray).MemoryDevices
    $capaciteTotale = ($slots | Measure-Object -Property Capacity -Sum).Sum / 1GB
    Write-Host "`n[Mémoire Vive]"
    Write-Host "Nombre total de slots physiques : $slotTotal"
    Write-Host "Nombre de barrettes installées : $($slots.Count)"
    Write-Host "Détail des barrettes :"
    foreach ($s in $slots) {
        $taille = [math]::Round($s.Capacity / 1GB, 2)
        Write-Host "- $taille Go @ $($s.Speed) MHz ($($s.Manufacturer))"
    }
    Write-Host ("Capacité totale installée : {0:N2} Go" -f $capaciteTotale)
    # Carte Graphique
    $gpuList = Get-CimInstance Win32_VideoController | ForEach-Object {
        $ramMB = [math]::Round($_.AdapterRAM / 1MB, 0)
        "- $($_.Name) ($ramMB MB)"
    }
    Write-Host "`n[Carte Graphique]"
    $gpuList | ForEach-Object { Write-Host $_ }
    # Disques
    $disques = Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3"
    Write-Host "`n[Disques]"
    foreach ($d in $disques) {
        $used = ($d.Size - $d.FreeSpace) / 1GB
        $total = $d.Size / 1GB
        $usedStr = [math]::Round($used, 0)
        $totalStr = [math]::Round($total, 0)
        $volume = if ($d.VolumeName) { $d.VolumeName } else { "" }
        Write-Host "- $($d.DeviceID): $volume ($($d.FileSystem)) ($usedStr/$totalStr GB)"
    }
    # Cartes Réseau Physiques
    $networkAdapters = Get-CimInstance Win32_NetworkAdapterConfiguration | Where-Object {
        $_.IPEnabled -and $_.Description -notmatch "Virtual|VMware|Loopback|Bluetooth|TAP|TUN|Host-only|Hyper-V|vEthernet|WSL"
    }
    Write-Host "`n[Cartes Réseau Physiques]"
    foreach ($n in $networkAdapters) {
        $ip = ($n.IPAddress | Where-Object { $_ -match "^\d{1,3}(\.\d{1,3}){3}$" }) -join ", "
        $dns = ($n.DNSServerSearchOrder -join ", ")
        Write-Host "Interface : $($n.Description)"
        Write-Host "IPv4 : $ip"
        Write-Host "Passerelle : $($n.DefaultIPGateway -join ", ")"
        Write-Host "DNS : $dns"
        Write-Host ""
    }
    Write-Host "`nAppuie sur Entrée pour quitter..." -ForegroundColor Yellow
    [void][System.Console]::ReadLine()
}
Show-Infos
✔ Copié

P2P

Vérifie si un programme de P2P est installé, puis cherche dans les processus s'il est en cours d'utilisation.

📥
function Show-P2PStatus {
    Clear-Host
    Write-Host "`n🔍 Analyse des logiciels Peer-to-Peer (P2P) installés et actifs..." -ForegroundColor Cyan
    Write-Host "───────────────────────────────────────────────────────────────`n"
    # Liste élargie de clients P2P connus (à compléter selon les besoins)
    $p2pSofts = @(
        'qBittorrent', 'qbittorrent',
        'uTorrent', 'utorrent',
        'BitTorrent', 'bittorrent',
        'Deluge', 'deluge',
        'Vuze', 'vuze',
        'eMule', 'emule',
        'FrostWire', 'frostwire',
        'Shareaza', 'shareaza',
        'Tixati', 'tixati',
        'Transmission', 'transmission',
        'aMule', 'amule',
        'BitComet', 'bitcomet'
    )
    # Détection des logiciels installés
    $installed = Get-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*" -ErrorAction SilentlyContinue
    $installed += Get-ItemProperty -Path "HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" -ErrorAction SilentlyContinue
    $foundInstalled = $installed | Where-Object {
        $p2pSofts -contains $_.DisplayName
    }
    if ($foundInstalled.Count -gt 0) {
        Write-Host "💾 Logiciels P2P installés :" -ForegroundColor Yellow
        $foundInstalled | ForEach-Object { Write-Host " - $($_.DisplayName)" }
    } else {
        Write-Host "✅ Aucun logiciel P2P installé parmi les plus connus." -ForegroundColor Green
    }
    Write-Host ""
    # Détection des processus en cours
    $running = Get-Process -ErrorAction SilentlyContinue | Where-Object {
        $p2pSofts -contains $_.Name
    }
    if ($running.Count -gt 0) {
        Write-Host "⚙️  Logiciels P2P en cours d'exécution :" -ForegroundColor Red
        foreach ($proc in $running) {
            Write-Host " • $($proc.Name) (PID: $($proc.Id))"
        }
    } else {
        Write-Host "🟢 Aucun logiciel P2P actif actuellement." -ForegroundColor Green
    }
    Write-Host "`nAppuie sur Entrée pour quitter..." -ForegroundColor DarkGray
    [void][System.Console]::ReadLine()
}
Show-P2PStatus
✔ Copié

Switch AZERTY - QWERTY

Si le clavier est en AZERTY, il passe en QWERTY, et inversement

📥
# Force l'exécution en mode silencieux, sans fenêtre noire
Add-Type -Namespace WinAPI -Name User32 -MemberDefinition @"
    [DllImport("user32.dll")]
    public static extern long LoadKeyboardLayout(string pwszKLID, uint Flags);
"@
# Langues à gérer
# 040C = Français (France) / 0000040C = layout AZERTY
# 0409 = Anglais (US)     / 00000409 = layout QWERTY
# → Important : on switch juste le layout actif du thread courant
# Récupère la langue/clavier actif
$currentCulture = (Get-WinUserLanguageList)[0].InputMethodTips
# On teste si on est en FR ou en US
if ($currentCulture -match "040C") {
    # On est en FR -> passer en QWERTY US
    $newList = New-WinUserLanguageList en-US
    $newList[0].InputMethodTips.Clear()
    $newList[0].InputMethodTips.Add("0409:00000409")
    Set-WinUserLanguageList $newList -Force
    # Charge layout QWERTY direct (évite le délai)
    [WinAPI.User32]::LoadKeyboardLayout("00000409", 1) | Out-Null
} else {
    # On est en US -> passer en AZERTY FR
    $newList = New-WinUserLanguageList fr-FR
    $newList[0].InputMethodTips.Clear()
    $newList[0].InputMethodTips.Add("040C:0000040C")
    Set-WinUserLanguageList $newList -Force
    [WinAPI.User32]::LoadKeyboardLayout("0000040C", 1) | Out-Null
}
✔ Copié

Wifi connections

Récupère les connexions Wi-Fi effectuées depuis un poste Windows, en s'appuyant sur les journaux d’événements système (WLAN-AutoConfig) et les profils réseau enregistrés (netsh).

📥
# Configuration
$logName = "Microsoft-Windows-WLAN-AutoConfig/Operational"
# Récupération des événements connexions (8001) et déconnexions (8003)
$events = Get-WinEvent -LogName $logName -FilterXPath "*[System[(EventID=8001 or EventID=8003)]]" -MaxEvents 10000
# Groupement par SSID
$grouped = @{}
foreach ($event in $events) {
    $xml = [xml]$event.ToXml()
    $ssid = $xml.Event.EventData.Data | Where-Object { $_.Name -eq "SSID" } | Select-Object -ExpandProperty "#text"
    $timestamp = $event.TimeCreated
    $eventId = $event.Id
    if (-not $grouped.ContainsKey($ssid)) {
        $grouped[$ssid] = @()
    }
    $grouped[$ssid] += [PSCustomObject]@{
        Time  = $timestamp
        Event = $eventId
    }
}
# Fonction pour récupérer la clé Wi-Fi en clair
function Get-WifiKey {
    param($ssid)
    try {
        $profile = netsh wlan show profile name="$ssid" key=clear
        $keyLine = $profile | Where-Object { $_ -match "Contenu de la clé" }
        if ($keyLine) {
            return ($keyLine -split ":")[1].Trim()
        } else {
            return "Non disponible"
        }
    } catch {
        return "Erreur"
    }
}
# Calcul par SSID
$resultats = @()
foreach ($ssid in $grouped.Keys) {
    $entries = $grouped[$ssid] | Sort-Object Time
    $connectedTimes = 0
    $totalDuration = [timespan]::Zero
    $start = $null
    $firstSeen = $null
    $lastSeen = $null
    foreach ($entry in $entries) {
        if ($entry.Event -eq 8001) {
            if (-not $firstSeen) { $firstSeen = $entry.Time }
            $start = $entry.Time
        }
        elseif ($entry.Event -eq 8003 -and $start) {
            $duration = $entry.Time - $start
            $totalDuration += $duration
            $connectedTimes++
            $start = $null
            $lastSeen = $entry.Time
        }
    }
    $totalHours   = [math]::Floor($totalDuration.TotalHours)
    $totalMinutes = $totalDuration.Minutes
    $totalSeconds = $totalDuration.Seconds
    $totalDurationFormatted = "{0}:{1:00}:{2:00}" -f $totalHours, $totalMinutes, $totalSeconds
    # Récupération de la clé Wi-Fi
    $wifiKey = Get-WifiKey -ssid $ssid
    # Résultat final
    $resultats += [PSCustomObject]@{
        SSID           = $ssid
        Connections    = $connectedTimes
        TotalDuration  = $totalDurationFormatted
        FirstSeen      = $firstSeen
        LastSeen       = $lastSeen
        WifiKey        = $wifiKey
    }
}
# Affichage
$resultats | Sort-Object TotalDuration -Descending | Format-Table -AutoSize
# Export CSV facultatif
# $resultats | Export-Csv -Path "$env:USERPROFILE\wifi_stats_with_keys.csv" -NoTypeInformation -Encoding UTF8
✔ Copié

Local Windows Account

Listeles comptes utilisateurs windows (comptes locaux)

📥
# Force l'affichage des dates en français
[System.Threading.Thread]::CurrentThread.CurrentCulture = 'fr-FR'
[System.Threading.Thread]::CurrentThread.CurrentUICulture = 'fr-FR'
function Show-LocalUserCreationAttributes {
    [CmdletBinding(SupportsShouldProcess = $true)]
    [Alias('sluca')]
    param()
    $localAdmins = Get-LocalGroupMember -Group "Administrateurs" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Name
    Get-LocalUser | ForEach-Object {
        $user = $_
        $profilePath = "C:\Users\$($user.Name)"
        $profileExists = Test-Path -Path $profilePath
        $profileSizeMB = $null
        if ($profileExists) {
            $profileSizeBytes = (Get-ChildItem -Path $profilePath -Recurse -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum
            $profileSizeMB = [int]($profileSizeBytes / 1MB)
        }
        $desc = if ($user.Description.Length -gt 40) { $user.Description.Substring(0, 37) + "..." } else { $user.Description }
        [PSCustomObject]@{
            Nom       = $user.Name
            SID       = $user.SID.Value
            Desc      = $desc
            Actif     = $user.Enabled
            Admin     = $localAdmins -contains $user.Name
            MDPReq    = $user.PasswordRequired
            MDPSet    = $user.PasswordLastSet
            MDPModif  = $user.PasswordChangeableDate
            MDPExp    = $user.PasswordExpires
            ExpCpt    = $user.AccountExpires -ne $null
            ExpDate   = $user.AccountExpires
            Profil    = $profileExists
            TailleMo  = $profileSizeMB
        }
    }
}
Show-LocalUserCreationAttributes | Format-Table -AutoSize
✔ Copié

Résumé