{"id":208359,"date":"2024-01-03T09:36:33","date_gmt":"2024-01-03T09:36:33","guid":{"rendered":"https:\/\/www.ninjaone.com\/script-hub\/trouver-tentatives-de-connexion-echouees-sur-windows-powershell\/"},"modified":"2024-03-04T19:17:49","modified_gmt":"2024-03-04T19:17:49","slug":"trouver-tentatives-de-connexion-echouees-sur-windows-powershell","status":"publish","type":"script_hub","link":"https:\/\/www.ninjaone.com\/fr\/script-hub\/trouver-tentatives-de-connexion-echouees-sur-windows-powershell\/","title":{"rendered":"Comment trouver les tentatives de connexion \u00e9chou\u00e9es sur Windows avec PowerShell ?"},"content":{"rendered":"<p>Il est crucial d&rsquo;assurer la s\u00e9curit\u00e9 des syst\u00e8mes informatiques. L&rsquo;identification d&rsquo;activit\u00e9s suspectes, telles que de nombreuses tentatives de connexion \u00e9chou\u00e9es, est une mesure importante pour att\u00e9nuer les menaces potentielles. Le script fourni est \u00e9crit en PowerShell et est un outil polyvalent qui aide les professionnels de l&rsquo;informatique et les MSP \u00e0 <strong>obtenir des informations sur les \u00e9checs de connexion<\/strong>.<\/p>\n<h2>Contexte<\/h2>\n<p>Comprendre les \u00e9checs des tentatives de connexion sur un syst\u00e8me peut fournir des informations cruciales aux administrateurs informatiques. Ils peuvent d\u00e9tecter d&rsquo;\u00e9ventuelles failles de s\u00e9curit\u00e9, surveiller les comportements des utilisateurs et maintenir l&rsquo;int\u00e9grit\u00e9 du syst\u00e8me. Ce script PowerShell r\u00e9cup\u00e8re efficacement ces donn\u00e9es, offrant ainsi une solution optimale aux professionnels. Cet outil est d&rsquo;une importance consid\u00e9rable. Face \u00e0 l&rsquo;augmentation des menaces de cybers\u00e9curit\u00e9, il est essentiel pour les MSP et les professionnels de l&rsquo;informatique de disposer d&rsquo;une m\u00e9thode efficace pour d\u00e9tecter les anomalies au niveau des connexions des utilisateurs.<\/p>\n<h2>Le script<\/h2>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"powershell\">#Requires -Version 3.0 -RunAsAdministrator\r\n\r\n&lt;#\r\n.SYNOPSIS\r\n    Returns the number of recent failed login attempts.\r\n.DESCRIPTION\r\n    Returns the number of recent failed login attempts of all users or of a specific user. If a user is specified then just a number is returned.\r\n.EXAMPLE\r\n    No parameters needed.\r\n    Returns all users, of the local machine, with a could of failed login attempts.\r\nOutput Example:\r\nUserName  FailedLoginAttempts\r\n--------  -------------------\r\nFred                        4\r\nBob                         0\r\n.EXAMPLE\r\n     -UserName \"Fred\"\r\n    Returns the number of failed login attempts of the user Fred on the local machine.\r\nOutput Example:\r\n4\r\n.EXAMPLE\r\n     -ComputerName \"FredPC\" -UserName \"Fred\"\r\n    Returns the number of failed login attempts of the user Fred on the computer named FredPC.\r\nOutput Example:\r\n4\r\n.EXAMPLE\r\n     -ComputerName \"FredPC\" -UserName \"Fred\" -Detailed\r\n    Returns the number of failed login attempts of the user Fred on the computer named FredPC, but will more details of each failed and successful logins.\r\nOutput Example:\r\n\r\nTimeGenerated   : 10\/18\/2019 7:52:43 AM\r\nEventID         : 4624\r\nCategory        : 12544\r\nADUsername      : Fred\r\nDomain          : FredPC\r\nUserSID         : S-1-0-0\r\nWorkstation     : -\r\nSourceIP        : -\r\nPort            : -\r\nFailureReason   : Interactive\r\nFailureStatus   : Incorrect password\r\nFailureSubStatus: Other\r\n.EXAMPLE\r\n    PS C:&gt; Monitor-Failed-Password-Attempts.ps1 -ComputerName \"FredPC\" -UserName \"Fred\"\r\n    Returns the number of failed login attempts of the user Fred on the computer named FredPC.\r\nOutput Example:\r\n4\r\n.OUTPUTS\r\n    System.Int32 Number of failed login attempts.\r\n.OUTPUTS\r\n    PSCustomObject List of user names and a count of failed login attempts.\r\n.NOTES\r\n    Minimum OS Architecture Supported: Windows 7, Windows Server 2012\r\n    If ComputerName is specified, then be sure that the computer that this script is running on has network and permissions to access the Event Log on the remote computer.\r\n    Release Notes:\r\n    Initial Release\r\nBy using this script, you indicate your acceptance of the following legal terms as well as our Terms of Use at https:\/\/www.ninjaone.com\/terms-of-use.\r\n    Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms. \r\n    Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party. \r\n    Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library or website belonging to or under the control of any other software provider. \r\n    Warranty Disclaimer: The script is provided \u201cas is\u201d and \u201cas available\u201d, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations. \r\n    Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks. \r\n    Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script. \r\n    EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA).\r\n.COMPONENT\r\n    ManageUsers\r\n#&gt;\r\n\r\nparam (\r\n    # The name of a remote computer to get event logs for failed logins\r\n    [Parameter(Mandatory = $false)]\r\n    [String]\r\n    $ComputerName = [System.Net.Dns]::GetHostName(),\r\n    # A username\r\n    [Parameter(Mandatory = $false)]\r\n    [String]\r\n    $UserName,\r\n    # Returns all relevant events, sorted by TimeGenerated\r\n    [Switch]\r\n    $Detailed\r\n)\r\n\r\n# Support functions\r\n# Returns the matching FailureReason like Incorrect password\r\nfunction Get-FailureReason {\r\n    Param($FailureReason)\r\n    switch ($FailureReason) {\r\n        '0xC0000064' { \"Account does not exist\"; break; }\r\n        '0xC000006A' { \"Incorrect password\"; break; }\r\n        '0xC000006D' { \"Incorrect username or password\"; break; }\r\n        '0xC000006E' { \"Account restriction\"; break; }\r\n        '0xC000006F' { \"Invalid logon hours\"; break; }\r\n        '0xC000015B' { \"Logon type not granted\"; break; }\r\n        '0xc0000070' { \"Invalid Workstation\"; break; }\r\n        '0xC0000071' { \"Password expired\"; break; }\r\n        '0xC0000072' { \"Account disabled\"; break; }\r\n        '0xC0000133' { \"Time difference at DC\"; break; }\r\n        '0xC0000193' { \"Account expired\"; break; }\r\n        '0xC0000224' { \"Password must change\"; break; }\r\n        '0xC0000234' { \"Account locked out\"; break; }\r\n        '0x0' { \"0x0\"; break; }\r\n        default { \"Other\"; break; }\r\n    }\r\n}\r\nfunction Get-LogonType {\r\n    Param($LogonType)\r\n    switch ($LogonType) {\r\n        '0' { 'Interactive'; break; }\r\n        '2' { 'Interactive'; break; }\r\n        '3' { 'Network'; break; }\r\n        '4' { 'Batch'; break; }\r\n        '5' { 'Service'; break; }\r\n        '6' { 'Proxy'; break; }\r\n        '7' { 'Unlock'; break; }\r\n        '8' { 'Networkcleartext'; break; }\r\n        '9' { 'NewCredentials'; break; }\r\n        '10' { 'RemoteInteractive'; break; }\r\n        '11' { 'CachedInteractive'; break; }\r\n        '12' { 'CachedRemoteInteractive'; break; }\r\n        '13' { 'CachedUnlock'; break; }\r\n        Default {}\r\n    }\r\n}\r\n#-Newest $Records\r\n$Events = Get-EventLog -ComputerName $ComputerName -LogName 'security' -InstanceId 4625, 4624 | Sort-Object -Property TimeGenerated | ForEach-Object {\r\n    if ($_.InstanceId -eq 4625) {\r\n        $_ | Select-Object -Property @(\r\n            @{Label = 'TimeGenerated'; Expression = { $_.TimeGenerated } },\r\n            @{Label = 'EventID'; Expression = { $_.InstanceId } },\r\n            @{Label = 'Category'; Expression = { $_.CategoryNumber } },\r\n            @{Label = 'Username'; Expression = { $_.ReplacementStrings[5] } },\r\n            @{Label = 'Domain'; Expression = { $_.ReplacementStrings[6] } },\r\n            @{Label = 'UserSID'; Expression = { (($_.Message -Split 'rn' | Select-String 'Security ID')[1] -Split 's+')[3] } },\r\n            # @{Label = 'UserSID'; Expression = { $_.ReplacementStrings[0] } },\r\n            @{Label = 'Workstation'; Expression = { $_.ReplacementStrings[13] } },\r\n            @{Label = 'SourceIP'; Expression = { $_.ReplacementStrings[19] } },\r\n            @{Label = 'Port'; Expression = { $_.ReplacementStrings[20] } },\r\n            @{Label = 'LogonType'; Expression = { $_.ReplacementStrings[8] } },\r\n            @{Label = 'FailureStatus'; Expression = { Get-FailureReason($_.ReplacementStrings[7]) } },\r\n            @{Label = 'FailureSubStatus'; Expression = { Get-FailureReason($_.ReplacementStrings[9]) } }\r\n        )\r\n    }\r\n    elseif ($_.InstanceId -eq 4624 -and (Get-LogonType($_.ReplacementStrings[8])) -notlike 'Service') {\r\n        $_ | Select-Object -Property @(\r\n            @{Label = 'TimeGenerated'; Expression = { $_.TimeGenerated } },\r\n            @{Label = 'EventID'; Expression = { $_.InstanceId } },\r\n            @{Label = 'Category'; Expression = { $_.CategoryNumber } },\r\n            @{Label = 'Username'; Expression = { $_.ReplacementStrings[5] } },\r\n            @{Label = 'Domain'; Expression = { $_.ReplacementStrings[6] } },\r\n            @{Label = 'UserSID'; Expression = { $_.ReplacementStrings[0] } },\r\n            @{Label = 'Workstation'; Expression = { $_.ReplacementStrings[11] } },\r\n            @{Label = 'SourceIP'; Expression = { $_.ReplacementStrings[18] } },\r\n            @{Label = 'Port'; Expression = { $_.ReplacementStrings[19] } },\r\n            @{Label = 'LogonType'; Expression = { Get-LogonType($_.ReplacementStrings[8]) } },\r\n            @{Label = 'LogonID'; Expression = { Get-FailureReason($_.ReplacementStrings[7]) } },\r\n            @{Label = 'LogonProcess'; Expression = { Get-FailureReason($_.ReplacementStrings[9]) } }\r\n        )\r\n    }\r\n}\r\n\r\nif ($Detailed) {\r\n    if ($UserName) {\r\n        $Events | Where-Object {\r\n            $_.Username -like $UserName\r\n        }\r\n    }\r\n    else {\r\n        $Events | Where-Object {\r\n            $_.Username -notlike \"DWM*\" -and\r\n            $_.Username -notlike \"UMFD*\" -and\r\n            $_.Username -notlike \"SYSTEM\"\r\n        }\r\n    }\r\n}\r\nelse {\r\n    $UserNames = if ($UserName) {\r\n        ($Events | Select-Object -Property Username -Unique).Username | Where-Object {\r\n            $_ -like \"$UserName\"\r\n        }\r\n    }\r\n    else {\r\n        ($Events | Select-Object -Property Username -Unique).Username | Where-Object {\r\n            $_ -notlike \"DWM*\" -and\r\n            $_ -notlike \"UMFD*\" -and\r\n            $_ -notlike \"SYSTEM\"\r\n        }\r\n    }\r\n    \r\n    $UserNames | ForEach-Object {\r\n        $CurrentUserName = $_\r\n        $FailedLoginCount = 0\r\n        for ($i = 0; $i -lt $Events.Count; $i++) {\r\n            if ($Events[$i].EventID -eq 4625 -and $Events[$i].Username -like $CurrentUserName) {\r\n                # User failed to login X times\r\n                # Count the number of failed logins\r\n                $FailedLoginCount++\r\n            }\r\n            elseif ($Events[$i].EventID -eq 4624 -and $Events[$i].Username -like $CurrentUserName) {\r\n                # User logged in successfully\r\n                # Reset the number of failed logins to 0\r\n                $FailedLoginCount = 0\r\n            }\r\n        }\r\n        if ($UserName) {\r\n            # If a UserName was specified, then return only the failed login count\r\n            $FailedLoginCount\r\n        }\r\n        else {\r\n            # If no UserName was specified, then return the user name and failed login count\r\n            [PSCustomObject]@{\r\n                UserName            = $CurrentUserName\r\n                FailedLoginAttempts = $FailedLoginCount\r\n            }\r\n        }\r\n    }\r\n}<\/pre>\n<p>&nbsp;<\/p>\n\n<div class=\"in-context-cta\"><p>Acc\u00e9dez \u00e0 plus de 700 scripts dans le Dojo NinjaOne<\/p>\n<p><a href=\"https:\/\/www.ninjaone.com\/fr\/phase-de-test-gratuit\/\">Obtenez l&rsquo;acc\u00e8s<\/a><\/p>\n<\/div>\n<h2>Description d\u00e9taill\u00e9e du script<\/h2>\n<p>Le script r\u00e9cup\u00e8re les donn\u00e9es des journaux d&rsquo;\u00e9v\u00e9nements d&rsquo;un ordinateur donn\u00e9, en ciblant des ID d&rsquo;\u00e9v\u00e9nements sp\u00e9cifiques qui repr\u00e9sentent des tentatives de connexion \u00e9chou\u00e9es ou r\u00e9ussies.<\/p>\n<ul>\n<li><strong>Param\u00e8tres<\/strong>: Le script commence par d\u00e9finir des param\u00e8tres tels que <strong>ComputerName<\/strong>, <strong>UserName<\/strong> et <strong>Detailed<\/strong>. Cela permet \u00e0 l&rsquo;utilisateur de sp\u00e9cifier la machine, l&rsquo;utilisateur et le niveau de d\u00e9tail des tentatives de connexion.<\/li>\n<li><strong>Fonctions<\/strong>: Deux fonctions, <strong>Get-FailureReason<\/strong> et <strong>Get-LogonType<\/strong>, traduisent les informations cod\u00e9es des journaux d&rsquo;\u00e9v\u00e9nements en donn\u00e9es lisibles concernant le type de connexion et la raison de l&rsquo;\u00e9chec de la connexion.<\/li>\n<li><strong>Recherche d&rsquo;\u00e9v\u00e9nements<\/strong>: Le script r\u00e9cup\u00e8re ensuite les journaux d&rsquo;\u00e9v\u00e9nements et les filtre pour ne conserver que les informations n\u00e9cessaires. Il faut s\u00e9lectionner les instances avec les ID d&rsquo;\u00e9v\u00e9nement pertinents.<\/li>\n<li><strong>Traitement<\/strong>: Selon que des donn\u00e9es d\u00e9taill\u00e9es sont demand\u00e9es ou non, le script fournit une analyse d\u00e9taill\u00e9e de chaque tentative de connexion ou un r\u00e9sum\u00e9 des \u00e9checs pour chaque utilisateur.<\/li>\n<\/ul>\n<h2>Cas d&rsquo;utilisation potentiels<\/h2>\n<p>Imaginez un administrateur informatique dans une entreprise de taille moyenne. R\u00e9cemment, le service informatique a constat\u00e9 une augmentation du nombre de tentatives de connexion \u00e9chou\u00e9es, en particulier en dehors des heures de travail. Gr\u00e2ce \u00e0 ce script, l&rsquo;administrateur peut rapidement v\u00e9rifier quels sont les utilisateurs dont les tentatives de connexion ont \u00e9chou\u00e9 et \u00e0 quelle fr\u00e9quence. En constatant qu&rsquo;un seul compte d&rsquo;utilisateur avait fait l&rsquo;objet de plusieurs tentatives infructueuses dans un court laps de temps, ils ont pu conclure que ce compte pouvait avoir \u00e9t\u00e9 cibl\u00e9. Ainsi, le script permet une d\u00e9tection pr\u00e9coce et une rem\u00e9diation rapide.<\/p>\n<h2>Approche alternative<\/h2>\n<p>Il existe plusieurs m\u00e9thodes pour suivre les \u00e9checs des tentatives de connexion. L&rsquo;audit de s\u00e9curit\u00e9 int\u00e9gr\u00e9 \u00e0 Windows, par exemple, vous permet de consulter les journaux de s\u00e9curit\u00e9 via l&rsquo;Observateur d&rsquo;\u00e9v\u00e9nements. Bien que cette approche soit simple, elle peut prendre du temps. Notre script PowerShell simplifie le processus, offrant une solution plus efficace et personnalisable.<\/p>\n<h2>FAQ<\/h2>\n<ul>\n<li>Comment le script identifie-t-il un \u00e9chec de connexion ?<br \/>\nLe script recherche des ID d&rsquo;\u00e9v\u00e9nements sp\u00e9cifiques dans le journal des \u00e9v\u00e9nements, tels que 4625 pour les \u00e9checs de connexion.<\/li>\n<li>Puis-je r\u00e9cup\u00e9rer des donn\u00e9es \u00e0 partir d&rsquo;une machine distante ?<br \/>\nOui, en fournissant le param\u00e8tre <strong>ComputerName<\/strong>, vous pouvez obtenir des donn\u00e9es d&rsquo;un ordinateur distant.<\/li>\n<\/ul>\n<h2>Implications<\/h2>\n<p>En connaissant le nombre de tentatives de connexion \u00e9chou\u00e9es, les administrateurs informatiques peuvent anticiper les failles de s\u00e9curit\u00e9. Les anomalies dans les habitudes de connexion sont souvent un signe pr\u00e9coce d&rsquo;activit\u00e9 malveillante. Par cons\u00e9quent, en agissant sur ces donn\u00e9es, les professionnels peuvent renforcer leurs syst\u00e8mes contre les menaces potentielles.<\/p>\n<h2>Recommandations<\/h2>\n<ul>\n<li>Assurez-vous que vous disposez des autorisations n\u00e9cessaires pour r\u00e9cup\u00e9rer les journaux d&rsquo;\u00e9v\u00e9nements.<\/li>\n<li>Ex\u00e9cutez r\u00e9guli\u00e8rement le script, en particulier pour les syst\u00e8mes contenant des informations sensibles.<\/li>\n<li>Examinez tous les cas d&rsquo;\u00e9chec de connexion et informez les utilisateurs concern\u00e9s.<\/li>\n<\/ul>\n<h2>Conclusions<\/h2>\n<p>Les outils tels que notre script PowerShell sont essentiels face \u00e0 l&rsquo;augmentation des cyber-menaces. Pour une solution de s\u00e9curit\u00e9 compl\u00e8te, des plateformes telles que NinjaOne peuvent \u00eatre int\u00e9gr\u00e9es, assurant une <a href=\"https:\/\/www.ninjaone.com\/fr\/plateforme-de-gestion-de-terminaux\/surveillance-a-distance-du-parc-informatique\/\">surveillance et une gestion en temps r\u00e9el<\/a>. NinjaOne, associ\u00e9 \u00e0 des scripts proactifs tels que celui-ci, constitue une d\u00e9fense suppl\u00e9mentaire contre les cybermenaces.<\/p>\n","protected":false},"author":35,"featured_media":207200,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"_relevanssi_hide_post":"","_relevanssi_hide_content":"","_relevanssi_pin_for_all":"","_relevanssi_pin_keywords":"","_relevanssi_unpin_keywords":"","_relevanssi_related_keywords":"","_relevanssi_related_include_ids":"","_relevanssi_related_exclude_ids":"","_relevanssi_related_no_append":"","_relevanssi_related_not_related":"","_relevanssi_related_posts":"","_relevanssi_noindex_reason":"","_lmt_disableupdate":"no","_lmt_disable":""},"operating_system":[4212],"use_cases":[4289],"class_list":["post-208359","script_hub","type-script_hub","status-publish","has-post-thumbnail","hentry","script_hub_category-windows","use_cases-gestion-des-utilisateurs-et-des-acces"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.ninjaone.com\/fr\/wp-json\/wp\/v2\/script_hub\/208359","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.ninjaone.com\/fr\/wp-json\/wp\/v2\/script_hub"}],"about":[{"href":"https:\/\/www.ninjaone.com\/fr\/wp-json\/wp\/v2\/types\/script_hub"}],"author":[{"embeddable":true,"href":"https:\/\/www.ninjaone.com\/fr\/wp-json\/wp\/v2\/users\/35"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ninjaone.com\/fr\/wp-json\/wp\/v2\/comments?post=208359"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.ninjaone.com\/fr\/wp-json\/wp\/v2\/media\/207200"}],"wp:attachment":[{"href":"https:\/\/www.ninjaone.com\/fr\/wp-json\/wp\/v2\/media?parent=208359"}],"wp:term":[{"taxonomy":"script_hub_category","embeddable":true,"href":"https:\/\/www.ninjaone.com\/fr\/wp-json\/wp\/v2\/operating_system?post=208359"},{"taxonomy":"use_cases","embeddable":true,"href":"https:\/\/www.ninjaone.com\/fr\/wp-json\/wp\/v2\/use_cases?post=208359"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}