{"id":353680,"date":"2024-09-20T21:46:28","date_gmt":"2024-09-20T21:46:28","guid":{"rendered":"https:\/\/www.ninjaone.com\/script-hub\/recherche-dans-les-journaux-des-evenements-powershell\/"},"modified":"2024-10-13T19:02:21","modified_gmt":"2024-10-13T19:02:21","slug":"recherche-dans-les-journaux-des-evenements-powershell","status":"publish","type":"script_hub","link":"https:\/\/www.ninjaone.com\/fr\/script-hub\/recherche-dans-les-journaux-des-evenements-powershell\/","title":{"rendered":"Guide complet de l&rsquo;utilisation de PowerShell pour faire une recherche dans les journaux des \u00e9v\u00e9nements"},"content":{"rendered":"<p>Dans le monde informatique en constante \u00e9volution, la surveillance et l&rsquo;analyse des journaux d&rsquo;\u00e9v\u00e9nements sont essentielles pour maintenir la sant\u00e9 du syst\u00e8me, diagnostiquer les probl\u00e8mes et garantir la conformit\u00e9 \u00e0 la s\u00e9curit\u00e9.<\/p>\n<p>Les journaux des \u00e9v\u00e9nements constituent une riche source d&rsquo;informations sur l&rsquo;\u00e9tat et le comportement des syst\u00e8mes, et le fait de pouvoir rechercher et filtrer efficacement ces journaux peut consid\u00e9rablement am\u00e9liorer la capacit\u00e9 d&rsquo;un professionnel de l&rsquo;informatique \u00e0 g\u00e9rer son infrastructure.<\/p>\n<p>Cet article pr\u00e9sente un script PowerShell qui simplifie le processus de <strong>recherche dans les journaux des \u00e9v\u00e9nements<\/strong>, en facilitant l&rsquo;identification d&rsquo;\u00e9v\u00e9nements sp\u00e9cifiques sur la base de crit\u00e8res tels que le nom du journal d&rsquo;\u00e9v\u00e9nements, la source, l&rsquo;identifiant de l&rsquo;\u00e9v\u00e9nement, etc.<\/p>\n<h2>L&rsquo;importance de la gestion des journaux des \u00e9v\u00e9nements dans l&rsquo;informatique<\/h2>\n<p>Les journaux des \u00e9v\u00e9nements sont des enregistrements d&rsquo;\u00e9v\u00e9nements li\u00e9s au syst\u00e8me, \u00e0 la s\u00e9curit\u00e9 et aux applications sur un ordinateur. Ces journaux sont indispensables pour r\u00e9soudre les probl\u00e8mes, contr\u00f4ler les incidents de s\u00e9curit\u00e9 et garantir le respect des normes r\u00e9glementaires.<\/p>\n<p>Pour les <a href=\"https:\/\/www.ninjaone.com\/fr\/quest-ce-quun-msp\/\" target=\"_blank\" rel=\"noopener\">fournisseurs de services g\u00e9r\u00e9s (MSP)<\/a> et les professionnels de l&rsquo;informatique, il est essentiel de pouvoir effectuer des recherches rapides et pr\u00e9cises dans ces journaux. Sans outils efficaces, cette t\u00e2che peut s&rsquo;av\u00e9rer fastidieuse, en particulier lorsqu&rsquo;il s&rsquo;agit d&rsquo;un grand nombre de syst\u00e8mes ou d&rsquo;environnements complexes.<\/p>\n<p><a href=\"https:\/\/www.ninjaone.com\/fr\/it-hub\/endpoint-management\/qu-est-ce-que-powershell\/\" target=\"_blank\" rel=\"noopener\">PowerShell<\/a>, un puissant langage de script d\u00e9velopp\u00e9 par Microsoft, offre de solides possibilit\u00e9s d&rsquo;interaction avec les journaux d&rsquo;\u00e9v\u00e9nements. Le script dont nous parlons aujourd&rsquo;hui est con\u00e7u pour optimiser le processus de recherche, permettant aux professionnels de l&rsquo;informatique de localiser rapidement les \u00e9v\u00e9nements pertinents dans l&rsquo;observateur d&rsquo;\u00e9v\u00e9nements.<\/p>\n<h2>Le script\u00a0:<\/h2>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"powershell\">#Requires -Version 5.1\r\n\r\n&lt;#\r\n.SYNOPSIS\r\n    Search for specific events in Event Viewer based on the event log they were in, the source of the event, or the specific event IDs used. One of these three options is required for the search.\r\n.DESCRIPTION\r\n    Search for specific events in Event Viewer based on the event log they were in, the source of the event, or the specific event IDs used. One of these three options is required for the search.\r\n.EXAMPLE\r\n    -EventLogName \"Application\"\r\n    \r\n    Matching Events Found!\r\n\r\n    LogName      : Application\r\n    ProviderName : Microsoft-Windows-Security-SPP\r\n    Id           : 16384\r\n    TimeCreated  : 4\/4\/2024 10:00:48 AM\r\n    Message      : Successfully scheduled Software Protection service for re-start at 2024-04-04T21:19:48Z. Reason: Rul...\r\n\r\n    LogName      : Application\r\n    ProviderName : Microsoft-Windows-Security-SPP\r\n    Id           : 16394\r\n    TimeCreated  : 4\/4\/2024 10:00:17 AM\r\n    Message      : Offline downlevel migration succeeded.\r\n\r\n    LogName      : Application\r\n    ProviderName : Microsoft-Windows-Security-SPP\r\n    Id           : 16384\r\n    TimeCreated  : 4\/4\/2024 9:59:59 AM\r\n    Message      : Successfully scheduled Software Protection service for re-start at 2024-04-04T21:19:59Z. Reason: Rul...\r\n\r\nPARAMETER: -EventLogName \"Application\"\r\n    Specify the name of the Event Log from which to retrieve events.\r\n\r\nPARAMETER: -EventLogSource \"Microsoft-Windows-Kernel-General\"\r\n    Determines the source of the events to retrieve.\r\n\r\nPARAMETER: -EventLogMessage \"Alert\"\r\n    Filters events by the text contained in the event's message.\r\n\r\nPARAMETER: -EventIDs \"12, 13, 6008\"\r\n    A comma-separated list of event IDs to include in the search.\r\n\r\nPARAMETER: -excludeEventIDs \"13\"\r\n    A comma-separated list of event IDs to exclude from the search.\r\n\r\nPARAMETER: -StartDate \"12\/24\/2021\"\r\n    Defines the start date and time for the event search. Events logged before this time will not be included in the results.\r\n\r\nPARAMETER: -EndDate \"12\/29\/2021\"\r\n    Sets the end date and time for the event search. Events logged after this time will not be included.\r\n\r\nPARAMETER: -MultilineCustomField \"replaceMeWithAcustomFieldName\"\r\n    Specify the name of a multiline custom field to optionally store the search results in. Leave blank to not set a multiline field.\r\n\r\nPARAMETER: -WysiwygCustomField \"replaceMeWithACustomFieldName\"\r\n    Specify the name of a WYSIWYG custom field to optionally store the search results in. Leave blank to not set a WYSIWYG field.\r\n.NOTES\r\n    Minimum OS Architecture Supported: Windows 10, Windows Server 2016\r\n    Release Notes: 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#&gt;\r\n\r\n[CmdletBinding()]\r\nparam (\r\n    [Parameter()]\r\n    [String]$EventLogName,\r\n    [Parameter()]\r\n    [String]$EventLogSource,\r\n    [Parameter()]\r\n    [String]$EventLogMessage,\r\n    [Parameter()]\r\n    [String]$EventIDs,\r\n    [Parameter()]\r\n    [String]$ExcludeEventIDs,\r\n    [Parameter()]\r\n    [datetime]$StartDate,\r\n    [Parameter()]\r\n    [datetime]$EndDate,\r\n    [Parameter()]\r\n    [String]$MultilineCustomField,\r\n    [Parameter()]\r\n    [String]$WysiwygCustomField\r\n)\r\n\r\nbegin {\r\n    # Set parameters using dynamic script variables.\r\n    if ($env:eventLogName -and $env:eventLogName -notlike \"null\") { $EventLogName = $env:eventLogName }\r\n    if ($env:eventLogSource -and $env:eventLogSource -notlike \"null\") { $EventLogSource = $env:eventLogSource }\r\n    if ($env:eventLogMessage -and $env:eventLogMessage -notlike \"null\") { $EventLogMessage = $env:eventLogMessage }\r\n    if ($env:eventIds -and $env:eventIds -notlike \"null\") { $EventIDs = $env:eventIds }\r\n    if ($env:excludeEventIds -and $env:excludeEventIds -notlike \"null\") { $ExcludeEventIDs = $env:excludeEventIds }\r\n    if ($env:eventStart -and $env:eventStart -notlike \"null\") { $StartDate = $env:eventStart }\r\n    if ($env:eventEnd -and $env:eventEnd -notlike \"null\") { $EndDate = $env:eventEnd }\r\n    if ($env:multilineCustomFieldName -and $env:multilineCustomFieldName -notlike \"null\") { $MultilineCustomField = $env:multilineCustomFieldName }\r\n    if ($env:wysiwygCustomFieldName -and $env:wysiwygCustomFieldName -notlike \"null\") { $WysiwygCustomField = $env:wysiwygCustomFieldName }\r\n\r\n    # Check if both StartDate and EndDate are provided and if StartDate is earlier than EndDate\r\n    if (($StartDate -and $EndDate) -and $StartDate -gt $EndDate) {\r\n        Write-Host -Object \"[Error] Start date cannot be earlier than end date!\"\r\n        exit 1\r\n    }\r\n\r\n    # Verify that WysiwygField and MultiLineField are not the same, exiting with an error if they are.\r\n    if ($WysiwygCustomField -and $MultilineCustomField -and ($WysiwygCustomField -eq $MultilineCustomField)) {\r\n        Write-Host -Object \"[Error] Wysiwyg Field and Multiline Field are the same! Custom fields cannot be the same type.\"\r\n        Write-Host -Object \"https:\/\/ninjarmm.zendesk.com\/hc\/en-us\/articles\/18601842971789-Custom-Fields-by-Type-and-Functionality\"\r\n        exit 1\r\n    }\r\n\r\n    # Ensure that at least one of Event ID, Event Log Name, or Event Source is provided for the query\r\n    if (!$EventIDs -and !$EventLogName -and !$EventLogSource) {\r\n        Write-Host -Object \"[Error] You must provide either an Event ID, Event Log Name or Event Source.\"\r\n        exit 1\r\n    }\r\n\r\n    # Trimming trailing spaces.\r\n    if ($EventLogName) {\r\n        $EventLogName = $EventLogName.Trim()\r\n    }\r\n\r\n    # Retrieve and sort all event log names available on the system\r\n    $EventLogNamesOnSystem = Get-WinEvent -ListLog * -ErrorAction SilentlyContinue | Sort-Object LogName\r\n    # Check if the provided EventLogName exists in the system's event logs\r\n    if ($EventLogName -and ($EventLogNamesOnSystem).LogName -notcontains $EventLogName) {\r\n        # If not found, print an error message and a list of valid event log names, then exit the script\r\n        Write-Host -Object \"[Error] Event Log '$EventLogName' doesn't exist! See the list below for valid event log names.\"\r\n        Write-Host -Object \"### Valid Event Log Names ###\"\r\n        $EventLogNamesOnSystem | Select-Object -ExpandProperty LogName | Write-Host\r\n        exit 1 \r\n    }\r\n\r\n    $InvalidEventSourceCharacters = \"[\\\\\/&lt;&gt;&amp;`\"%\\|']\"\r\n    if ($EventLogSource) {\r\n        if ($EventLogSource -match $InvalidEventSourceCharacters) {\r\n            Write-Host -Object \"[Error] Event Log Source '$EventLogSource' contains an invalid character!\"\r\n            exit 1\r\n        }\r\n\r\n        if ($EventLogSource.Length -gt 255) {\r\n            Write-Host -Object \"[Error] Event Log Source '$EventLogSource' is too large to be an event source!\"\r\n            exit 1\r\n        }\r\n\r\n        # Trims the event log source for trailing spaces\r\n        $EventLogSource = $EventLogSource.Trim()\r\n    }\r\n\r\n    # Prepare a list to hold valid event IDs to search for\r\n    $EventIdsToSearch = New-Object System.Collections.Generic.List[int]\r\n    # Process the input event IDs, removing any that are not purely numerical\r\n    if ($EventIDs -and $EventIDs -match \",\") {\r\n        # If multiple event IDs are provided and separated by commas, split them\r\n        $EventIDs -split \",\" | ForEach-Object {\r\n            $EventId = $_.Trim()\r\n            # Validate each event ID to ensure it's numerical\r\n            if ($EventId -match '[a-zA-Z]|\\W') {\r\n                # If not, print an error and skip adding this ID to the list\r\n                Write-Host \"[Error] Event ID '$EventId' is not a valid event id. Removing it from the search.\"\r\n                $ExitCode = 1\r\n                return\r\n            }\r\n            # Check size of event id\r\n            if ([long]$EventId -gt 65535 -or [long]$EventId -lt 0) {\r\n                Write-Host \"[Error] Event ID '$EventId' is not a valid event id. Event ID's must be less than or equal to 65535 and greater than or equal to 0. Removing it from the search.\"\r\n                $ExitCode = 1\r\n                return\r\n            }\r\n             \r\n            # Add the validated event ID to the list\r\n            $EventIdsToSearch.Add($EventId)\r\n        }\r\n    }\r\n    elseif ($EventIDs) {\r\n        $EventId = $EventIDs.Trim()\r\n        # Handle a single event ID input\r\n        if ($EventId -match '[a-zA-Z]|\\W') {\r\n            Write-Host \"[Error] Event ID '$EventId' is not a valid event id. Removing it from the search.\"\r\n            $ExitCode = 1\r\n        }\r\n        elseif ([long]$EventId -gt 65535 -or [long]$EventId -lt 0) {\r\n            Write-Host \"[Error] Event ID '$EventId' is not a valid event id. Event ID's must be less than or equal to 65535 and greater than or equal to 0. Removing it from the search.\"\r\n            $ExitCode = 1\r\n        }\r\n        else {\r\n            $EventIdsToSearch.Add($EventId)\r\n        }\r\n    }\r\n \r\n    # Prepare a list to hold event IDs that should be excluded from the search\r\n    $EventsToExclude = New-Object System.Collections.Generic.List[int]\r\n     \r\n    # Similar process for excluded event IDs as regular event IDs\r\n    if ($ExcludeEventIDs -and $ExcludeEventIDs -match \",\") {\r\n        $ExcludeEventIDs -split \",\" | ForEach-Object {\r\n            $ExcludeEventId = $_.Trim()\r\n            if ($ExcludeEventId -match '[a-zA-Z]|\\W') {\r\n                Write-Host \"[Error] Event ID '$ExcludeEventId' is not a valid event id. Removing it from the exclusions.\"\r\n                $ExitCode = 1\r\n                return\r\n            }\r\n \r\n            if ([long]$ExcludeEventId -gt 65535 -or [long]$ExcludeEventId -lt 0) {\r\n                Write-Host \"[Error] Event ID '$ExcludeEventId' is not a valid event id. Event ID's must be less than or equal to 65535 and greater than or equal to 0. Removing it from the exclusions.\"\r\n                $ExitCode = 1\r\n                return\r\n            }\r\n             \r\n            $EventsToExclude.Add($ExcludeEventId)\r\n        }\r\n    }\r\n    elseif ($ExcludeEventIDs) {\r\n        $ExcludeEventId = $ExcludeEventIDs.Trim()\r\n        if ($ExcludeEventId -match '[a-zA-Z]|\\W') {\r\n            Write-Host \"[Error] Event ID '$ExcludeEventId' is not a valid event id. Removing it from the exclusions.\"\r\n            $ExitCode = 1\r\n        }\r\n        elseif ([long]$ExcludeEventId -gt 65535 -or [long]$ExcludeEventId -lt 0) {\r\n            Write-Host \"[Error] Event ID '$ExcludeEventId' is not a valid event id. Event ID's must be less than or equal to 65535 and greater than or equal to 0. Removing it from the exclusions.\"\r\n            $ExitCode = 1\r\n        }\r\n        else {\r\n            $EventsToExclude.Add($ExcludeEventId)\r\n        }\r\n    }\r\n \r\n    # Check if there are any event IDs to exclude and if the list of event IDs to search for is not empty.\r\n    if ($EventsToExclude.Count -gt 0 -and $EventIdsToSearch.Count -gt 0) {\r\n        $EventsToExclude | ForEach-Object {\r\n            # Check if the current event ID from the exclusion list is also in the list of event IDs to search for.\r\n            if ($EventIdsToSearch -contains $_) {\r\n                Write-Warning \"Event ID $_ has been specified for both inclusion and exclusion. It will be excluded.\"\r\n            }\r\n        }\r\n    }\r\n \r\n    # Check if there's no valid event ID, log name, or log source provided and exit if true\r\n    if ($EventIdsToSearch.Count -eq 0 -and !$EventLogName -and !$EventLogSource) {\r\n        Write-Host \"[Error] No valid Event ID given and no Event Log Name or Event Log Source given.\"\r\n        exit 1\r\n    }\r\n\r\n    # Handy function to set a custom field.\r\n    function Set-NinjaProperty {\r\n        [CmdletBinding()]\r\n        Param(\r\n            [Parameter(Mandatory = $True)]\r\n            [String]$Name,\r\n            [Parameter()]\r\n            [String]$Type,\r\n            [Parameter(Mandatory = $True, ValueFromPipeline = $True)]\r\n            $Value,\r\n            [Parameter()]\r\n            [String]$DocumentName\r\n        )\r\n\r\n        $Characters = $Value | Out-String | Measure-Object -Character | Select-Object -ExpandProperty Characters\r\n        if ($Characters -ge 200000) {\r\n            throw [System.ArgumentOutOfRangeException]::New(\"Character limit exceeded, value with $Characters characters is greater than or equal to 200,000 characters.\")\r\n        }\r\n    \r\n        # If we're requested to set the field value for a Ninja document we'll specify it here.\r\n        $DocumentationParams = @{}\r\n        if ($DocumentName) { $DocumentationParams[\"DocumentName\"] = $DocumentName }\r\n    \r\n        # This is a list of valid fields that can be set. If no type is given, it will be assumed that the input doesn't need to be changed.\r\n        $ValidFields = \"Attachment\", \"Checkbox\", \"Date\", \"Date or Date Time\", \"Decimal\", \"Dropdown\", \"Email\", \"Integer\", \"IP Address\", \"MultiLine\", \"MultiSelect\", \"Phone\", \"Secure\", \"Text\", \"Time\", \"URL\", \"WYSIWYG\"\r\n        if ($Type -and $ValidFields -notcontains $Type) { Write-Warning \"$Type is an invalid type! Please check here for valid types. https:\/\/ninjarmm.zendesk.com\/hc\/en-us\/articles\/16973443979789-Command-Line-Interface-CLI-Supported-Fields-and-Functionality\" }\r\n    \r\n        # The field below requires additional information to be set\r\n        $NeedsOptions = \"Dropdown\"\r\n        if ($DocumentName) {\r\n            if ($NeedsOptions -contains $Type) {\r\n                # We'll redirect the error output to the success stream to make it easier to error out if nothing was found or something else went wrong.\r\n                $NinjaPropertyOptions = Ninja-Property-Docs-Options -AttributeName $Name @DocumentationParams 2&gt;&amp;1\r\n            }\r\n        }\r\n        else {\r\n            if ($NeedsOptions -contains $Type) {\r\n                $NinjaPropertyOptions = Ninja-Property-Options -Name $Name 2&gt;&amp;1\r\n            }\r\n        }\r\n    \r\n        # If an error is received it will have an exception property, the function will exit with that error information.\r\n        if ($NinjaPropertyOptions.Exception) { throw $NinjaPropertyOptions }\r\n    \r\n        # The below type's require values not typically given in order to be set. The below code will convert whatever we're given into a format ninjarmm-cli supports.\r\n        switch ($Type) {\r\n            \"Checkbox\" {\r\n                # While it's highly likely we were given a value like \"True\" or a boolean datatype it's better to be safe than sorry.\r\n                $NinjaValue = [System.Convert]::ToBoolean($Value)\r\n            }\r\n            \"Date or Date Time\" {\r\n                # Ninjarmm-cli expects the GUID of the option to be selected. Therefore, the given value will be matched with a GUID.\r\n                $Date = (Get-Date $Value).ToUniversalTime()\r\n                $TimeSpan = New-TimeSpan (Get-Date \"1970-01-01 00:00:00\") $Date\r\n                $NinjaValue = $TimeSpan.TotalSeconds\r\n            }\r\n            \"Dropdown\" {\r\n                # Ninjarmm-cli is expecting the guid of the option we're trying to select. So we'll match up the value we were given with a guid.\r\n                $Options = $NinjaPropertyOptions -replace '=', ',' | ConvertFrom-Csv -Header \"GUID\", \"Name\"\r\n                $Selection = $Options | Where-Object { $_.Name -eq $Value } | Select-Object -ExpandProperty GUID\r\n    \r\n                if (-not $Selection) {\r\n                    throw [System.ArgumentOutOfRangeException]::New(\"Value is not present in dropdown\")\r\n                }\r\n    \r\n                $NinjaValue = $Selection\r\n            }\r\n            default {\r\n                # All the other types shouldn't require additional work on the input.\r\n                $NinjaValue = $Value\r\n            }\r\n        }\r\n    \r\n        # We'll need to set the field differently depending on if its a field in a Ninja Document or not.\r\n        if ($DocumentName) {\r\n            $CustomField = Ninja-Property-Docs-Set -AttributeName $Name -AttributeValue $NinjaValue @DocumentationParams 2&gt;&amp;1\r\n        }\r\n        else {\r\n            $CustomField = $NinjaValue | Ninja-Property-Set-Piped -Name $Name 2&gt;&amp;1\r\n        }\r\n    \r\n        if ($CustomField.Exception) {\r\n            throw $CustomField\r\n        }\r\n    }\r\n\r\n    function Test-IsElevated {\r\n        $id = [System.Security.Principal.WindowsIdentity]::GetCurrent()\r\n        $p = New-Object System.Security.Principal.WindowsPrincipal($id)\r\n        $p.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)\r\n    }\r\n\r\n    if (!$ExitCode) {\r\n        $ExitCode = 0\r\n    }\r\n}\r\nprocess {\r\n    # Check if the script is running with elevated (Administrator) privileges\r\n    if (!(Test-IsElevated)) {\r\n        # If not, display an error message and exit with status code 1\r\n        Write-Host -Object \"[Error] Access Denied. Please run with Administrator privileges.\"\r\n        exit 1\r\n    }\r\n\r\n    # Prepare a list to hold event log names to search for\r\n    $EventLogNamesToSearch = New-Object System.Collections.Generic.List[string]\r\n\r\n    # If no event log name was required we'll search all the event\r\n    if (!$EventLogName) {\r\n        $EventLogNamesOnSystem | Where-Object { $_.RecordCount -gt 0 } | Select-Object -ExpandProperty LogName | ForEach-Object {\r\n            $EventLogNamesToSearch.Add($_)\r\n        }\r\n    }\r\n    else {\r\n        $EventLogNamesToSearch.Add($EventLogName)\r\n    }\r\n\r\n    # Create XML object.\r\n    [xml]$XML = New-Object System.Xml.XmlDocument\r\n\r\n    # Add QueryList element to xml.\r\n    $QueryList = $XML.CreateElement(\"QueryList\")\r\n    $QueryList = $XML.AppendChild($QueryList)\r\n\r\n    # Create query element and nest it under QueryList.\r\n    $Query = $XML.CreateElement(\"Query\")\r\n    $Query.SetAttribute(\"Id\", \"0\")\r\n    $Query = $QueryList.AppendChild($Query)\r\n    \r\n\r\n    # Foreach event log to search we're going to create a select element.\r\n    $EventLogNamesToSearch | ForEach-Object {\r\n        # We'll start each loop by selecting the query element to add to.\r\n        $Query = $XML.SelectSingleNode(\"\/\/Query\")\r\n\r\n        # The select element starts off with the event log to search.\r\n        $Select = $XML.CreateElement(\"Select\")\r\n        $Select.SetAttribute(\"Path\", \"$_\")\r\n        \r\n        # Reset the inner text between runnings\r\n        $XMLInnerText = $Null\r\n\r\n        # The inner text of each element (&lt;Element1&gt;InnerText&lt;\/Element1&gt;) will need to be built differently depending on the parameters.\r\n        if ($EventLogSource) {\r\n            $XMLInnerText = \"*[System[Provider[@Name='$EventLogSource']]]\"\r\n        }\r\n        \r\n        # If we're given a select number of event id's to search we'll filter them here.\r\n        if ($EventIdsToSearch.Count -gt 0) {\r\n            $EventIDSearchText = $Null\r\n            $EventIdsToSearch | ForEach-Object {\r\n                # We may have been given one event id or more than one.\r\n                if ($EventIDSearchText) {\r\n                    $EventIDSearchText = \"$EventIDSearchText or EventID=$_\"\r\n                }\r\n                else {\r\n                    $EventIDSearchText = \"EventID=$_\"\r\n                }\r\n            }\r\n\r\n            # We'll replace the two ending brackets with our given search text\r\n            if ($XMLInnerText) {\r\n                $XMLInnerText = $XMLInnerText -replace ']]$', \" and ($EventIDSearchText)]]\"\r\n            }\r\n            else {\r\n                $XMLInnerText = \"*[System[($EventIDSearchText)]]\"\r\n            }\r\n        }\r\n\r\n        # If we're also asked to filter based on the date the event was created we'll create the filter text here.\r\n        if ($StartDate -or $EndDate) {\r\n            $DateFilter = $Null \r\n            if ($StartDate) {\r\n                $XMLstartDate = Get-Date $StartDate -Format \"yyyy-MM-ddTHH:mm:ss\"\r\n                # PowerShell will convert the &lt; or &gt; symbol for us when we go to save to the xml.\r\n                $DateFilter = \"@SystemTime&gt;='$XMLstartDate'\"\r\n            }\r\n\r\n            # We may or may not have been given a start date.\r\n            if ($EndDate -and $DateFilter) {\r\n                $XMLendDate = Get-Date $EndDate -Format \"yyyy-MM-ddTHH:mm:ss\"\r\n                $DateFilter = \"$DateFilter and @SystemTime&lt;='$XMLendDate'\"\r\n            }\r\n            elseif ($EndDate) {\r\n                $XMLendDate = Get-Date $EndDate -Format \"yyyy-MM-ddTHH:mm:ss\"\r\n                $DateFilter = \"@SystemTime&lt;='$XMLendDate'\"\r\n            }\r\n\r\n            # Replace the last two closing brackets and add our filter text.\r\n            if($XMLInnerText){\r\n                $XMLInnerText = $XMLInnerText -replace ']]$', \" and TimeCreated[$DateFilter]]]\"\r\n            }else{\r\n                $XMLInnerText = \"*[System[TimeCreated[$DateFilter]]]\"\r\n            }\r\n        }\r\n\r\n        # If no filters were given (other than the event log name) we'll need to select everything in that log\r\n        if(!$XMLInnerText){\r\n            $XMLInnerText = \"*\"\r\n        }\r\n\r\n        # Save our filter text to the select statement\r\n        $Select.InnerText = $XMLInnerText\r\n\r\n        # Append our select statement to our xml file\r\n        $Query.AppendChild($Select) | Out-Null\r\n    }\r\n\r\n    # Search for matching events using the XML filter\r\n    $MatchingEvents = Get-WinEvent -FilterXml $XML -ErrorAction SilentlyContinue\r\n\r\n    # Exclude events based on the excluded event IDs if any are specified\r\n    if ($EventsToExclude.Count -gt 0) {\r\n        $MatchingEvents = $MatchingEvents | Where-Object { $EventsToExclude -notcontains $_.ID }\r\n    }\r\n\r\n    # Exclude events that do not match the keywords you specified.\r\n    if ($EventLogMessage) {\r\n        $MatchingEvents = $MatchingEvents | Where-Object { $_.Message -like \"*$EventLogMessage*\" }\r\n    }\r\n\r\n    # If the event log message is larger than 100 characters trim it and add ...\r\n    if ($MatchingEvents) {\r\n        $MatchingEvents = $MatchingEvents | Select-Object LevelDisplayName, LogName, ProviderName, Id, TimeCreated, @{\r\n            Name       = 'Message'\r\n            Expression = {\r\n                $Characters = $_.Message | Measure-Object -Character | Select-Object -ExpandProperty Characters\r\n                if ($Characters -gt 100) {\r\n                    \"$(($_.Message).SubString(0,100))(...)\"\r\n                }\r\n                else {\r\n                    $_.Message\r\n                }\r\n            }\r\n        }\r\n\r\n        # Sort the object by newest event to oldest\r\n        $MatchingEvents = $MatchingEvents | Sort-Object TimeCreated -Descending\r\n    }\r\n\r\n    # Set a Wysiwyg custom field if any matching events are found and it was requested.\r\n    if ($WysiwygCustomField -and $MatchingEvents) {\r\n        try {\r\n            Write-Host \"Attempting to set Custom Field '$WysiwygCustomField'.\"\r\n\r\n            # Prepare the custom field output.\r\n            $CustomFieldValue = New-Object System.Collections.Generic.List[string]\r\n\r\n            # Convert the matching events into an html report.\r\n            $htmlTable = $MatchingEvents | Select-Object -Property LevelDisplayName, LogName, ProviderName, Id, TimeCreated, Message | ConvertTo-Html -Fragment\r\n            \r\n            # Set color coding\r\n            $htmlTable = $htmlTable -replace \"&lt;tr&gt;&lt;td&gt;Verbose&lt;\/td&gt;\", \"&lt;tr class=`\"other`\"&gt;&lt;td&gt;Verbose&lt;\/td&gt;\"\r\n            $htmlTable = $htmlTable -replace \"&lt;tr&gt;&lt;td&gt;Warning&lt;\/td&gt;\", \"&lt;tr class=`\"warning`\"&gt;&lt;td&gt;Warning&lt;\/td&gt;\"\r\n            $htmlTable = $htmlTable -replace \"&lt;tr&gt;&lt;td&gt;Error&lt;\/td&gt;\", \"&lt;tr class=`\"danger`\"&gt;&lt;td&gt;Error&lt;\/td&gt;\"\r\n            $htmlTable = $htmlTable -replace \"&lt;tr&gt;&lt;td&gt;Critical Error&lt;\/td&gt;\", \"&lt;tr class=`\"danger`\"&gt;&lt;td&gt;Critical Error&lt;\/td&gt;\"\r\n\r\n            # Remove Level Display Name\r\n            $LevelDisplayNames = $MatchingEvents | Select-Object -Property LevelDisplayName -Unique\r\n            $LevelDisplayNames | ForEach-Object {\r\n                $htmlTable = $htmlTable -replace \"&lt;td&gt;$([Regex]::Escape($_.LevelDisplayName))&lt;\/td&gt;\"\r\n            }\r\n            $htmlTable = $htmlTable -replace \"&lt;th&gt;LevelDisplayName&lt;\/th&gt;\"\r\n\r\n            # Add the newly created html into the custom field output.\r\n            $CustomFieldValue.Add($htmlTable)\r\n\r\n            # Check that the output complies with the hard character limits.\r\n            $Characters = $CustomFieldValue | Out-String | Measure-Object -Character | Select-Object -ExpandProperty Characters\r\n            if ($Characters -ge 199500) {\r\n                Write-Warning \"200,000 Character Limit has been reached! Trimming output until the character limit is satisified...\"\r\n                \r\n                # If it doesn't comply with the limits we'll need to recreate it with some adjustments.\r\n                $i = 0\r\n                do {\r\n                    # Recreate the custom field output starting with a warning that we truncated the output.\r\n                    $CustomFieldValue = New-Object System.Collections.Generic.List[string]\r\n                    $CustomFieldValue.Add(\"&lt;h1&gt;This info has been truncated to accommodate the 200,000 character limit.&lt;\/h1&gt;\")\r\n\r\n                    # The custom field information is sorted from newest to oldest. We'll remove the oldest first by flipping the array upside down.\r\n                    [array]::Reverse($htmlTable)\r\n                    # If the next entry is a row we'll delete it.\r\n                    if ($htmlTable[$i] -match '&lt;tr&gt;&lt;td&gt;' -or $htmlTable[$i] -match '&lt;tr class=') {\r\n                        $htmlTable[$i] = $null\r\n                    }\r\n                    $i++\r\n                    # We'll flip the array back to right side up.\r\n                    [array]::Reverse($htmlTable)\r\n\r\n                    # Add it back to the output.\r\n                    $CustomFieldValue.Add($htmlTable)\r\n\r\n                    # Check that we now comply with the character limit. If not restart the do loop.\r\n                    $Characters = $CustomFieldValue | Out-String | Measure-Object -Character | Select-Object -ExpandProperty Characters\r\n                }while ($Characters -ge 199500)\r\n            }\r\n\r\n            # Set the custom field.\r\n            Set-NinjaProperty -Name $WysiwygCustomField -Value $CustomFieldValue\r\n            Write-Host \"Successfully set Custom Field '$WysiwygCustomField'!\"\r\n        }\r\n        catch {\r\n            Write-Host \"[Error] $($_.Exception.Message)\"\r\n            $ExitCode = 1\r\n        }\r\n    }\r\n\r\n    # Set a multiline custom field if any matching events are found and it was requested.\r\n    if ($MultilineCustomField -and $MatchingEvents) {\r\n        try {\r\n            Write-Host \"Attempting to set Custom Field '$MultilineCustomField'.\"\r\n            $CustomFieldValue = New-Object System.Collections.Generic.List[string]\r\n\r\n            # We don't want to edit the matching Events array if we have to truncate later so we'll create a duplicate here.\r\n            $CustomFieldList = $MatchingEvents | Select-Object -Property LogName, ProviderName, Id, TimeCreated, Message\r\n\r\n            # Format the matching items into a nice list with the relevant properties.\r\n            $CustomFieldValue.Add(($CustomFieldList | Format-List -Property LogName, ProviderName, Id, TimeCreated, Message | Out-String))\r\n            \r\n            # Check that the output complies with the hard character limits.\r\n            $Characters = $CustomFieldValue | Out-String | Measure-Object -Character | Select-Object -ExpandProperty Characters\r\n            if ($Characters -ge 9500) {\r\n                Write-Warning \"10,000 Character Limit has been reached! Trimming output until the character limit is satisified...\"\r\n                \r\n                # If it doesn't comply with the limits we'll need to recreate it with some adjustments.\r\n                $i = 0\r\n                do {\r\n                    # Recreate the custom field output starting with a warning that we truncated the output.\r\n                    $CustomFieldValue = New-Object System.Collections.Generic.List[string]\r\n                    $CustomFieldValue.Add(\"This info has been truncated to accommodate the 10,000 character limit.\")\r\n                    \r\n                    # The custom field information is sorted from newest to oldest. We'll remove the oldest events first by flipping the array upside down.\r\n                    [array]::Reverse($CustomFieldList)\r\n\r\n                    # Remove the next item which in this case will be the oldest item.\r\n                    $CustomFieldList[$i] = $null\r\n                    $i++\r\n\r\n                    # We'll flip the array back to right side up.\r\n                    [array]::Reverse($CustomFieldList)\r\n\r\n                    # Add it back to the output.\r\n                    $CustomFieldValue.Add(($CustomFieldList | Format-List -Property LogName, ProviderName, Id, TimeCreated, Message | Out-String))\r\n\r\n                    # Check that we now comply with the character limit. If not restart the do loop.\r\n                    $Characters = $CustomFieldValue | Out-String | Measure-Object -Character | Select-Object -ExpandProperty Characters\r\n                }while ($Characters -ge 9500)\r\n            }\r\n\r\n            Set-NinjaProperty -Name $MultilineCustomField -Value $CustomFieldValue\r\n            Write-Host \"Successfully set Custom Field '$MultilineCustomField'!\"\r\n        }\r\n        catch {\r\n            Write-Host \"[Error] $($_.Exception.Message)\"\r\n            $ExitCode = 1\r\n        }\r\n    }\r\n\r\n    # If any matching events were found output them into the activity log.\r\n    if ($MatchingEvents) {\r\n        Write-Host \"Matching Events Found!\"\r\n        $MatchingEvents | Format-List LogName, ProviderName, Id, TimeCreated, Message | Out-String | Write-Host\r\n    }\r\n    else {\r\n        Write-Host \"No matching events found!\"\r\n    }\r\n\r\n    exit $ExitCode\r\n}\r\nend {\r\n    \r\n    \r\n    \r\n}<\/pre>\n<p>&nbsp;<\/p>\n\n<div class=\"blog-cta-new blog-cta-style-1\"><div class=\"cta-left\"><h2><\/h2><p><\/p><\/div><div class=\"cta-right\"><a class=\"button\" href=\"\"><\/a><\/div><\/div>\n<h2>Comprendre le script PowerShell<\/h2>\n<p>Ce script PowerShell est un outil polyvalent qui permet aux utilisateurs de rechercher des \u00e9v\u00e9nements sp\u00e9cifiques dans l&rsquo;observateur d&rsquo;\u00e9v\u00e9nements en fonction de divers crit\u00e8res. Le script peut filtrer les \u00e9v\u00e9nements en fonction du nom du journal, de la source, de l&rsquo;ID de l&rsquo;\u00e9v\u00e9nement, du contenu du message et de la plage de dates. De plus, il offre des options permettant d&rsquo;exclure certains ID d&rsquo;\u00e9v\u00e9nements de la recherche et de stocker les r\u00e9sultats dans des champs personnalis\u00e9s.<\/p>\n<p>Voici une description d\u00e9taill\u00e9e du fonctionnement du script :<\/p>\n<h3>1. Param\u00e8tres et variables d&rsquo;environnement :<\/h3>\n<ul>\n<li>Le script commence par d\u00e9finir les param\u00e8tres permettant aux utilisateurs de d\u00e9finir leurs crit\u00e8res de recherche, tels que EventLogName, EventLogSource, EventIDs, StartDate et EndDate. Il prend \u00e9galement en charge les variables d&rsquo;environnement pour ces param\u00e8tres, ce qui permet l&rsquo;int\u00e9gration avec d&rsquo;autres flux de travail automatis\u00e9s.<\/li>\n<\/ul>\n<h3>2. Validation et traitement des erreurs :<\/h3>\n<ul>\n<li>Le script comprend plusieurs couches de validation pour s&rsquo;assurer que les param\u00e8tres d&rsquo;entr\u00e9e sont corrects. Par exemple, il v\u00e9rifie si la date de d\u00e9but fournie est ant\u00e9rieure \u00e0 la date de fin et valide que les identifiants d&rsquo;\u00e9v\u00e9nements sont num\u00e9riques et se situent dans la plage acceptable.<\/li>\n<li>Si les param\u00e8tres WysiwygCustomField et MultilineCustomField ont la m\u00eame valeur, le script g\u00e9n\u00e8re une erreur, ce qui permet d&rsquo;\u00e9viter les conflits de configuration.<\/li>\n<\/ul>\n<h3>3. Logique de recherche dans le journal des \u00e9v\u00e9nements :<\/h3>\n<ul>\n<li>Le script construit une requ\u00eate XML pour filtrer les \u00e9v\u00e9nements sur la base des crit\u00e8res fournis. Cette requ\u00eate est ensuite utilis\u00e9e avec la cmdlet Get-WinEvent pour r\u00e9cup\u00e9rer les \u00e9v\u00e9nements correspondants dans les journaux sp\u00e9cifi\u00e9s.<\/li>\n<li>Le script permet d&rsquo;exclure certains identifiants d&rsquo;\u00e9v\u00e9nements et peut filtrer les \u00e9v\u00e9nements en fonction du contenu du message, ce qui le rend hautement personnalisable.<\/li>\n<\/ul>\n<h3>4. R\u00e9glage du champ personnalis\u00e9:<\/h3>\n<ul>\n<li>Si des \u00e9v\u00e9nements correspondants sont trouv\u00e9s, le script peut stocker les r\u00e9sultats dans des champs personnalis\u00e9s, soit sous la forme d&rsquo;un champ de texte multiligne, soit sous la forme d&rsquo;un rapport au format HTML. Cette fonction est particuli\u00e8rement utile pour les MSP qui ont besoin de documenter les r\u00e9sultats ou d&rsquo;automatiser les rapports.<\/li>\n<\/ul>\n<h3>5. Sortie et tri :<\/h3>\n<ul>\n<li>Le script affiche les r\u00e9sultats dans un format lisible, tri\u00e9s en fonction de l&rsquo;heure \u00e0 laquelle les \u00e9v\u00e9nements ont \u00e9t\u00e9 cr\u00e9\u00e9s, du plus r\u00e9cent au plus ancien. Il r\u00e9duit \u00e9galement les messages trop longs pour ne pas surcharger la sortie.<\/li>\n<\/ul>\n<h2>Applications pratiques du script<\/h2>\n<p>Prenons l&rsquo;exemple d&rsquo;un professionnel de l&rsquo;informatique charg\u00e9 d&rsquo;identifier les erreurs r\u00e9currentes sur plusieurs serveurs dans un environnement d&rsquo;entreprise. L&rsquo;examen manuel des journaux d&rsquo;\u00e9v\u00e9nements sur chaque serveur prendrait beaucoup de temps et serait source d&rsquo;erreurs.<\/p>\n<p>Gr\u00e2ce \u00e0 ce script PowerShell, le professionnel peut automatiser le processus de recherche, en filtrant les journaux sur la base d&rsquo;ID d&rsquo;\u00e9v\u00e9nements d&rsquo;erreur sp\u00e9cifiques et en limitant les r\u00e9sultats \u00e0 une p\u00e9riode donn\u00e9e. Cette approche permet non seulement de gagner du temps, mais aussi d&rsquo;am\u00e9liorer la pr\u00e9cision, ce qui permet \u00e0 l&rsquo;\u00e9quipe informatique de diagnostiquer et de r\u00e9soudre rapidement les probl\u00e8mes.<\/p>\n<p>Un autre cas d&rsquo;utilisation pourrait concerner l&rsquo;audit de conformit\u00e9. Une entreprise MSP peut avoir besoin de v\u00e9rifier que certains \u00e9v\u00e9nements de s\u00e9curit\u00e9, tels que les tentatives de connexion r\u00e9ussies ou \u00e9chou\u00e9es, se produisent comme pr\u00e9vu dans les syst\u00e8mes g\u00e9r\u00e9s. Ce script peut \u00eatre utilis\u00e9 pour extraire ces \u00e9v\u00e9nements et g\u00e9n\u00e9rer des rapports qui d\u00e9montrent la conformit\u00e9 avec les politiques de s\u00e9curit\u00e9.<\/p>\n<h2>Comparaison des approches pour la recherche dans le journal des \u00e9v\u00e9nements<\/h2>\n<p>Bien qu&rsquo;il existe plusieurs m\u00e9thodes pour effectuer une recherche dans les journaux d&rsquo;\u00e9v\u00e9nements, notamment en utilisant l&rsquo;interface graphique int\u00e9gr\u00e9e de l&rsquo;observateur d&rsquo;\u00e9v\u00e9nements ou d&rsquo;autres outils tiers, ce script PowerShell offre des avantages distincts. Contrairement aux recherches manuelles effectu\u00e9es \u00e0 l&rsquo;aide de l&rsquo;interface graphique, ce script peut \u00eatre automatis\u00e9 et int\u00e9gr\u00e9 dans des flux de travail plus importants. De plus, par rapport \u00e0 d&rsquo;autres outils, PowerShell offre un degr\u00e9 \u00e9lev\u00e9 de personnalisation, ce qui permet aux professionnels de l&rsquo;informatique d&rsquo;adapter les crit\u00e8res de recherche \u00e0 leurs besoins particuliers.<\/p>\n<h2>Questions fr\u00e9quemment pos\u00e9es<\/h2>\n<h3>Q\u00a0: Ce script peut-il \u00eatre utilis\u00e9 sur des syst\u00e8mes utilisant d&rsquo;anciennes versions de Windows ?<\/h3>\n<p>R\u00a0: Le script n\u00e9cessite Windows PowerShell 5.1 et est pris en charge sur Windows 10 et Windows Server 2016 ou une version ult\u00e9rieure.<\/p>\n<h3>Q\u00a0: Que se passe-t-il si la limite de caract\u00e8res est d\u00e9pass\u00e9e lors de la d\u00e9finition d&rsquo;un champ personnalis\u00e9 ?<\/h3>\n<p>R\u00a0: Le script comprend une logique permettant de tronquer la sortie afin de respecter la limite de caract\u00e8res, ce qui garantit que le script n&rsquo;\u00e9choue pas en raison d&rsquo;ensembles de donn\u00e9es trop volumineux.<\/p>\n<h3>Q\u00a0: Est-il possible de rechercher tous les journaux des \u00e9v\u00e9nements d&rsquo;un syst\u00e8me \u00e0 l&rsquo;aide de ce script ?<\/h3>\n<p>R\u00a0: Oui, si aucun nom de journal d&rsquo;\u00e9v\u00e9nements sp\u00e9cifique n&rsquo;est fourni, le script recherchera tous les journaux d&rsquo;\u00e9v\u00e9nements disponibles sur le syst\u00e8me.<\/p>\n<h2>Implications pour la s\u00e9curit\u00e9 informatique<\/h2>\n<p>La possibilit\u00e9 d&rsquo;effectuer des recherches efficaces dans les journaux des \u00e9v\u00e9nements a des cons\u00e9quences importantes pour la s\u00e9curit\u00e9 informatique. En identifiant rapidement les \u00e9v\u00e9nements suspects ou anormaux, les professionnels de l&rsquo;informatique peuvent r\u00e9agir plus efficacement aux incidents de s\u00e9curit\u00e9 potentiels. L&rsquo;automatisation fournie par ce script r\u00e9duit le risque d&rsquo;erreur humaine et garantit que les \u00e9v\u00e9nements critiques ne sont pas n\u00e9glig\u00e9s.<\/p>\n<h2>Bonnes pratiques de l&rsquo;utilisation du script<\/h2>\n<ul>\n<li><strong>Testez toujours le script dans un environnement contr\u00f4l\u00e9 avant de le d\u00e9ployer dans la production.<\/strong><\/li>\n<li><strong>Utilisez des variables d&rsquo;environnement pour int\u00e9grer le script dans des flux d&rsquo;automatisation plus importants.<\/strong><\/li>\n<li><strong>Mettez r\u00e9guli\u00e8rement le script \u00e0 jour pour y int\u00e9grer de nouvelles fonctionnalit\u00e9s ou rem\u00e9dier \u00e0 d&rsquo;\u00e9ventuelles failles de s\u00e9curit\u00e9.<\/strong><\/li>\n<\/ul>\n<h2>Conclusion<\/h2>\n<p>Une gestion des journaux d&rsquo;\u00e9v\u00e9nements efficace est essentielle pour maintenir la sant\u00e9 du syst\u00e8me, garantir la s\u00e9curit\u00e9 et assurer la conformit\u00e9. Ce script PowerShell fournit aux professionnels de l&rsquo;informatique un outil puissant de recherche et d&rsquo;analyse des journaux des \u00e9v\u00e9nements, ce qui leur permet d&rsquo;accomplir leurs t\u00e2ches plus efficacement.<\/p>\n<p>Pour les MSP et les \u00e9quipes informatiques qui g\u00e8rent plusieurs syst\u00e8mes, <a href=\"https:\/\/www.ninjaone.com\/fr\/\" target=\"_blank\" rel=\"noopener\">NinjaOne<\/a> offre une suite compl\u00e8te d&rsquo;outils qui peuvent am\u00e9liorer votre capacit\u00e9 \u00e0 surveiller et \u00e0 g\u00e9rer votre infrastructure informatique. En int\u00e9grant ce script dans vos flux de travail, vous pouvez optimiser vos recherches dans le journal des \u00e9v\u00e9nements et am\u00e9liorer l&rsquo;ensemble de vos op\u00e9rations informatiques.<\/p>\n","protected":false},"author":35,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"open","ping_status":"open","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":"","_lmt_disable":""},"operating_system":[4212],"use_cases":[4281],"class_list":["post-353680","script_hub","type-script_hub","status-publish","hentry","script_hub_category-windows","use_cases-configuration-generale"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.ninjaone.com\/fr\/wp-json\/wp\/v2\/script_hub\/353680","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=353680"}],"wp:attachment":[{"href":"https:\/\/www.ninjaone.com\/fr\/wp-json\/wp\/v2\/media?parent=353680"}],"wp:term":[{"taxonomy":"script_hub_category","embeddable":true,"href":"https:\/\/www.ninjaone.com\/fr\/wp-json\/wp\/v2\/operating_system?post=353680"},{"taxonomy":"use_cases","embeddable":true,"href":"https:\/\/www.ninjaone.com\/fr\/wp-json\/wp\/v2\/use_cases?post=353680"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}