{"id":353634,"date":"2024-08-02T08:49:06","date_gmt":"2024-08-02T08:49:06","guid":{"rendered":"https:\/\/www.ninjaone.com\/script-hub\/liste-de-toutes-les-extensions-de-navigateur-windows-powershell\/"},"modified":"2024-10-13T19:05:37","modified_gmt":"2024-10-13T19:05:37","slug":"liste-de-toutes-les-extensions-de-navigateur-windows-powershell","status":"publish","type":"script_hub","link":"https:\/\/www.ninjaone.com\/fr\/script-hub\/liste-de-toutes-les-extensions-de-navigateur-windows-powershell\/","title":{"rendered":"Comment utiliser PowerShell pour obtenir la liste de toutes les extensions de navigateur Windows"},"content":{"rendered":"<p>La gestion des extensions de navigateur pour plusieurs utilisateurs et syst\u00e8mes est un challenge courant dans la gestion informatique. Les extensions de navigateur, bien qu&rsquo;utiles, peuvent pr\u00e9senter des risques importants pour la s\u00e9curit\u00e9 si elles ne sont pas contr\u00f4l\u00e9es correctement. Elles peuvent introduire des vuln\u00e9rabilit\u00e9s, espionner les activit\u00e9s des utilisateurs ou devenir des points d&rsquo;entr\u00e9e pour les <a href=\"https:\/\/www.ninjaone.com\/blog\/5-steps-for-removing-malware-from-your-computer\/\" target=\"_blank\" rel=\"noopener\">logiciels malveillants<\/a>.<\/p>\n<p>Ce script offre une solution optimale aux professionnels de l&rsquo;informatique et aux<a href=\"https:\/\/www.ninjaone.com\/fr\/quest-ce-quun-msp\" target=\"_blank\" rel=\"noopener\"> fournisseurs de services g\u00e9r\u00e9s (MSP)<\/a> <strong>pour obtenir l&rsquo;inventaire des extensions de navigateur install\u00e9es dans les navigateurs<\/strong> tels que Chrome, Firefox et Edge.<\/p>\n<h2>Contexte<\/h2>\n<p>Comme les entreprises s&rsquo;appuient de plus en plus sur des applications bas\u00e9es sur le web, les extensions de navigateur jouent un r\u00f4le de plus en plus important. Cependant, cela augmente \u00e9galement le besoin de surveillance pour s&rsquo;assurer que les extensions sont s\u00e9curis\u00e9es et conformes aux politiques de l&rsquo;entreprise. Ce script r\u00e9pond \u00e0 ces besoins en fournissant un rapport complet de toutes les extensions de navigateur install\u00e9es pour les principaux navigateurs, ce qui en fait un outil essentiel pour les professionnels de l&rsquo;informatique et les entreprises MSP qui doivent maintenir la s\u00e9curit\u00e9 et la conformit\u00e9.<\/p>\n<h2>Le script<\/h2>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"powershell\">#Requires -Version 5.1\r\n\r\n&lt;#\r\n.SYNOPSIS\r\n    Reports on all installed browser extensions for Chrome, Firefox and Edge.\r\n.DESCRIPTION\r\n    Reports on all installed browser extensions for Chrome, Firefox and Edge.\r\n.EXAMPLE\r\n    (No Parameters)\r\n\r\n    A Google Chrome installation was detected. Searching Chrome for browser extensions...\r\n    A Microsoft Edge installation was detected. Searching Microsoft Edge for browser extensions...\r\n    A Firefox installation was detected. Searching Firefox for browser extensions...\r\n    Attempting to set Custom Field 'Multiline'.\r\n    WARNING: 10,000 Character Limit has been reached! Trimming output until the character limit is satisfied...\r\n    Successfully set Custom Field 'Multiline'!\r\n    Attempting to set Custom Field 'WYSIWYG'.\r\n    Successfully set Custom Field 'WYSIWYG'!\r\n    Browser extensions were detected.\r\n\r\n\r\n    Browser      : Chrome\r\n    User         : cheart\r\n    Name         : askBelynda | Sustainable Shopping\r\n    Extension ID : pcmbjnfbjkeieekkahdfgchcbjfhhgdi\r\n    Description  : Sustainable shopping made simple with askBelynda. Choose ethical products o(...)\r\n\r\n    Browser      : Chrome\r\n    User         : cheart\r\n    Name         : Beni - Your secondhand shopping assistant\r\n    Extension ID : efdgbhncnligcbloejoaemnfhjihkccj\r\n    Description  : The easiest way to shop secondhand.  Beni finds the best resale alternative(...)\r\n\r\n    Browser      : Chrome\r\n    User         : cheart\r\n    Name         : Bonjourr \u00c3\u201a\u00c2\u00b7 Minimalist Startpage\r\n    Extension ID : dlnejlppicbjfcfcedcflplfjajinajd\r\n    Description  : Improve your web browsing experience with Bonjourr, a beautiful, customizab(...)\r\n\r\n    Browser      : Chrome\r\n    User         : cheart\r\n    Name         : Boxel 3D\r\n    Extension ID : mjjgmlmpeaikcaajghilhnioimmaibon\r\n    Description  : Boxel 3D is the 3rd release of your favorite box jumping game made by the d(...)\r\n\r\n    ...\r\n\r\nPARAMETER: -MultilineCustomField \"ReplaceMeWithNameOfAMultilineCustomField\"\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 \"ReplaceMeWithAnyWYSIWYGCustomField\"\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\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]$MultilineCustomField,\r\n    [Parameter()]\r\n    [String]$WysiwygCustomField\r\n)\r\n\r\nbegin {\r\n    # Replace parameters with the dynamic script variables.\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 $MultilineCustomField and $WysiwygCustomField are both not null and have the same value\r\n    if ($MultilineCustomField -and $WysiwygCustomField -and $MultilineCustomField -eq $WysiwygCustomField) {\r\n        Write-Host \"[Error] Custom Fields of different types cannot have the same name.\"\r\n        Write-Host \"https:\/\/ninjarmm.zendesk.com\/hc\/en-us\/articles\/360060920631-Custom-Fields-Configuration-Device-Role-Fields\"\r\n        exit 1\r\n    }\r\n\r\n    # Function to get user registry hives based on the type of account\r\n    function Get-UserHives {\r\n        param (\r\n            [Parameter()]\r\n            [ValidateSet('AzureAD', 'DomainAndLocal', 'All')]\r\n            [String]$Type = \"All\",\r\n            [Parameter()]\r\n            [String[]]$ExcludedUsers,\r\n            [Parameter()]\r\n            [switch]$IncludeDefault\r\n        )\r\n    \r\n        # Patterns for user SID depending on account type\r\n        $Patterns = switch ($Type) {\r\n            \"AzureAD\" { \"S-1-12-1-(\\d+-?){4}$\" }\r\n            \"DomainAndLocal\" { \"S-1-5-21-(\\d+-?){4}$\" }\r\n            \"All\" { \"S-1-12-1-(\\d+-?){4}$\" ; \"S-1-5-21-(\\d+-?){4}$\" } \r\n        }\r\n    \r\n        # Fetch user profiles whose SIDs match the defined patterns and prepare objects with their details\r\n        $UserProfiles = Foreach ($Pattern in $Patterns) { \r\n            Get-ItemProperty \"HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\*\" |\r\n                Where-Object { $_.PSChildName -match $Pattern } | \r\n                Select-Object @{Name = \"SID\"; Expression = { $_.PSChildName } },\r\n                @{Name = \"UserName\"; Expression = { \"$($_.ProfileImagePath | Split-Path -Leaf)\" } }, \r\n                @{Name = \"UserHive\"; Expression = { \"$($_.ProfileImagePath)\\NTuser.dat\" } }, \r\n                @{Name = \"Path\"; Expression = { $_.ProfileImagePath } }\r\n        }\r\n    \r\n        # Handle inclusion of the default user profile if requested\r\n        switch ($IncludeDefault) {\r\n            $True {\r\n                $DefaultProfile = \"\" | Select-Object UserName, SID, UserHive, Path\r\n                $DefaultProfile.UserName = \"Default\"\r\n                $DefaultProfile.SID = \"DefaultProfile\"\r\n                $DefaultProfile.Userhive = \"$env:SystemDrive\\Users\\Default\\NTUSER.DAT\"\r\n                $DefaultProfile.Path = \"C:\\Users\\Default\"\r\n    \r\n                $DefaultProfile | Where-Object { $ExcludedUsers -notcontains $_.UserName }\r\n            }\r\n        }\r\n\r\n        # Return user profiles, excluding any specified users\r\n        $UserProfiles | Where-Object { $ExcludedUsers -notcontains $_.UserName }\r\n    }\r\n\r\n    # Function to check if the current PowerShell session is running with elevated permissions\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    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; the value is greater than or equal to 200,000 characters.\")\r\n        }\r\n        \r\n        # If 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 specified, it is assumed that the input does not 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                # Redirect error output to the success stream to make it easier to handle errors if nothing is found or if something else goes 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 with an exception property, the function will exit with that error information.\r\n        if ($NinjaPropertyOptions.Exception) { throw $NinjaPropertyOptions }\r\n        \r\n        # The below types 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                # Although 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 options.\")\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 to find installation keys based on the display name, optionally returning uninstall strings\r\n    function Find-InstallKey {\r\n        [CmdletBinding()]\r\n        param (\r\n            [Parameter(ValueFromPipeline = $True)]\r\n            [String]$DisplayName,\r\n            [Parameter()]\r\n            [Switch]$UninstallString,\r\n            [Parameter()]\r\n            [String]$UserBaseKey\r\n        )\r\n        process {\r\n            # Initialize an empty list to hold installation objects\r\n            $InstallList = New-Object System.Collections.Generic.List[Object]\r\n\r\n            # If no user base key is specified, search in the default system-wide uninstall paths\r\n            if (!$UserBaseKey) {\r\n                # Search for programs in 32-bit and 64-bit locations. Then add them to the list if they match the display name\r\n                $Result = Get-ChildItem -Path \"HKLM:\\Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*\" | Get-ItemProperty | Where-Object { $_.DisplayName -like \"*$DisplayName*\" }\r\n                if ($Result) { $InstallList.Add($Result) }\r\n\r\n                $Result = Get-ChildItem -Path \"HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*\" | Get-ItemProperty | Where-Object { $_.DisplayName -like \"*$DisplayName*\" }\r\n                if ($Result) { $InstallList.Add($Result) }\r\n            }\r\n            else {\r\n                # If a user base key is specified, search in the user-specified 64-bit and 32-bit paths.\r\n                $Result = Get-ChildItem -Path \"$UserBaseKey\\Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*\" | Get-ItemProperty | Where-Object { $_.DisplayName -like \"*$DisplayName*\" }\r\n                if ($Result) { $InstallList.Add($Result) }\r\n    \r\n                $Result = Get-ChildItem -Path \"$UserBaseKey\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*\" | Get-ItemProperty | Where-Object { $_.DisplayName -like \"*$DisplayName*\" }\r\n                if ($Result) { $InstallList.Add($Result) }\r\n            }\r\n    \r\n            # If the UninstallString switch is specified, return only the uninstall strings; otherwise, return the full installation objects.\r\n            if ($UninstallString) {\r\n                $InstallList | Select-Object -ExpandProperty UninstallString -ErrorAction SilentlyContinue\r\n            }\r\n            else {\r\n                $InstallList\r\n            }\r\n        }\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 permissions (administrator rights)\r\n    if (!(Test-IsElevated)) {\r\n        Write-Host -Object \"[Error] Access Denied. Please run with Administrator privileges.\"\r\n        exit 1\r\n    }\r\n\r\n    # Search for Chrome installations on the system and enable chrome extension search if found.\r\n    Find-InstallKey -DisplayName \"Chrome\" | ForEach-Object {\r\n        $ChromeInstallations = $True\r\n    }\r\n\r\n    # Search for Firefox installations on the system and enable firefox extension search if found.\r\n    Find-InstallKey -DisplayName \"Firefox\" | ForEach-Object {\r\n        $FireFoxInstallations = $True\r\n    }\r\n\r\n    # Search for Edge installations on the system and flag if found and enable edge extension search if found.\r\n    Find-InstallKey -DisplayName \"Edge\" | ForEach-Object {  \r\n        $EdgeInstallations = $True\r\n    }\r\n\r\n    # Retrieve all user profiles from the system\r\n    $UserProfiles = Get-UserHives -Type \"All\"\r\n    # Loop through each profile on the machine\r\n    Foreach ($UserProfile in $UserProfiles) {\r\n        # Load User ntuser.dat if it's not already loaded\r\n        If (($ProfileWasLoaded = Test-Path Registry::HKEY_USERS\\$($UserProfile.SID)) -eq $false) {\r\n            Start-Process -FilePath \"cmd.exe\" -ArgumentList \"\/C reg.exe LOAD HKU\\$($UserProfile.SID) `\"$($UserProfile.UserHive)`\"\" -Wait -WindowStyle Hidden\r\n        }\r\n\r\n        # Repeat search for installations of browsers but in the user's registry context\r\n        Find-InstallKey -UserBaseKey \"Registry::HKEY_USERS\\$($UserProfile.SID)\" -DisplayName \"Chrome\" | ForEach-Object { \r\n            $ChromeInstallations = $True\r\n        }\r\n        Find-InstallKey -UserBaseKey \"Registry::HKEY_USERS\\$($UserProfile.SID)\" -DisplayName \"Firefox\" | ForEach-Object { \r\n            $FireFoxInstallations = $True\r\n        }\r\n        Find-InstallKey -UserBaseKey \"Registry::HKEY_USERS\\$($UserProfile.SID)\" -DisplayName \"Edge\" | ForEach-Object { \r\n            $EdgeInstallations = $True\r\n        }\r\n\r\n        # Unload NTuser.dat\r\n        If ($ProfileWasLoaded -eq $false) {\r\n            [gc]::Collect()\r\n            Start-Sleep 1\r\n            Start-Process -FilePath \"cmd.exe\" -ArgumentList \"\/C reg.exe UNLOAD HKU\\$($UserProfile.SID)\" -Wait -WindowStyle Hidden | Out-Null\r\n        }\r\n    }\r\n\r\n    # Initialize a list to store details of detected browser extensions\r\n    $BrowserExtensions = New-Object System.Collections.Generic.List[object]\r\n\r\n    # If Chrome was found, search for Chrome extensions in each user's profile\r\n    if ($ChromeInstallations) {\r\n        Write-Host -Object \"A Google Chrome installation was detected. Searching Chrome for browser extensions...\"\r\n        $UserProfiles | ForEach-Object {\r\n            if (!(Test-Path -Path \"$($_.Path)\\AppData\\Local\\Google\\Chrome\\User Data\" -ErrorAction SilentlyContinue)) {\r\n                return\r\n            }\r\n\r\n            if(Test-Path -Path \"$($_.Path)\\AppData\\Local\\Google\\Chrome\\User Data\\Local State\" -ErrorAction SilentlyContinue){\r\n                $AllProfiles = Get-Content -Path \"$($_.Path)\\AppData\\Local\\Google\\Chrome\\User Data\\Local State\" | ConvertFrom-JSON\r\n            }\r\n\r\n            $PreferenceFiles = Get-ChildItem \"$($_.Path)\\AppData\\Local\\Google\\Chrome\\User Data\\*\\Preferences\" -Exclude \"System Profile\" | Select-Object -ExpandProperty Fullname\r\n\r\n            foreach ($PreferenceFile in $PreferenceFiles) {\r\n\r\n                $GooglePreferences = Get-Content -Path $PreferenceFile | ConvertFrom-Json\r\n                if($AllProfiles){\r\n                    $ProfileLocation = $PreferenceFile | Get-Item | Select-Object -ExpandProperty Directory | Split-Path -Leaf\r\n                    $ProfileName = $AllProfiles.profile.info_cache | Select-Object -ExpandProperty $ProfileLocation | Select-Object -ExpandProperty Name\r\n                }else{\r\n                    $ProfileName = $GooglePreferences.profile.name\r\n                }\r\n\r\n                foreach ($Extension in $GooglePreferences.extensions.settings.PSObject.Properties) {\r\n                    $BrowserExtensions.Add(\r\n                        [PSCustomObject]@{\r\n                            Browser        = \"Chrome\"\r\n                            User           = $_.UserName\r\n                            Profile        = $ProfileName\r\n                            Name           = $Extension.Value.manifest.name\r\n                            \"Extension ID\" = $Extension.name\r\n                            Description    = $Extension.Value.manifest.description\r\n                        }\r\n                    )\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    # If Edge was found, search for Edge extensions in each user's profile\r\n    if ($EdgeInstallations) {\r\n        Write-Host -Object \"A Microsoft Edge installation was detected. Searching Microsoft Edge for browser extensions...\"\r\n        $UserProfiles | ForEach-Object {\r\n            if (!(Test-Path -Path \"$($_.Path)\\AppData\\Local\\Microsoft\\Edge\\User Data\" -ErrorAction SilentlyContinue)) {\r\n                return\r\n            }\r\n\r\n            if(Test-Path -Path \"$($_.Path)\\AppData\\Local\\Microsoft\\Edge\\User Data\\Local State\" -ErrorAction SilentlyContinue){\r\n                $AllProfiles = Get-Content -Path \"$($_.Path)\\AppData\\Local\\Microsoft\\Edge\\User Data\\Local State\" | ConvertFrom-JSON\r\n            }\r\n\r\n            $PreferenceFiles = Get-ChildItem \"$($_.Path)\\AppData\\Local\\Microsoft\\Edge\\User Data\\*\\Preferences\" -Exclude \"System Profile\" | Select-Object -ExpandProperty Fullname\r\n\r\n            foreach ($PreferenceFile in $PreferenceFiles) {\r\n\r\n                $EdgePreferences = Get-Content -Path $PreferenceFile | ConvertFrom-Json\r\n                if($AllProfiles){\r\n                    $ProfileLocation = $PreferenceFile | Get-Item | Select-Object -ExpandProperty Directory | Split-Path -Leaf\r\n                    $ProfileName = $AllProfiles.profile.info_cache | Select-Object -ExpandProperty $ProfileLocation | Select-Object -ExpandProperty Name\r\n                }else{\r\n                    $ProfileName = $EdgePreferences.profile.name\r\n                }\r\n\r\n                foreach ($Extension in $EdgePreferences.extensions.settings.PSObject.Properties) {\r\n                    if ($Extension.Value.active_bit -like \"False\" ) { continue }\r\n                    if (!$Extension.Value.manifest.name) { continue }\r\n                    $BrowserExtensions.Add(\r\n                        [PSCustomObject]@{\r\n                            Browser        = \"Edge\"\r\n                            User           = $_.UserName\r\n                            Profile        = $ProfileName\r\n                            Name           = $Extension.Value.manifest.name\r\n                            \"Extension ID\" = $Extension.name\r\n                            Description    = $Extension.Value.manifest.description\r\n                        }\r\n                    )\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    # If Firefox was found, search for Firefox extensions in each user's profile\r\n    if ($FireFoxInstallations) {\r\n        Write-Host -Object \"A Firefox installation was detected. Searching Firefox for browser extensions...\" \r\n        $UserProfiles | ForEach-Object {\r\n            if (!(Test-Path -Path \"$($_.Path)\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\" -ErrorAction SilentlyContinue)) {\r\n                return\r\n            }\r\n\r\n            $FirefoxProfileFolders = Get-ChildItem -Path \"$($_.Path)\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\" -Directory | Where-Object { $_.Name -match \"\\.default-release$\" } | Select-Object -ExpandProperty Fullname\r\n\r\n            foreach ( $FirefoxProfile in $FirefoxProfileFolders ) {\r\n\r\n                if (!(Test-Path -Path \"$FirefoxProfile\\extensions.json\")) {\r\n                    continue\r\n                }\r\n\r\n                $Extensions = Get-Content -Path \"$FirefoxProfile\\extensions.json\" | ConvertFrom-Json\r\n\r\n                foreach ($Extension in $Extensions.addons) {\r\n                    $BrowserExtensions.Add(\r\n                        [PSCustomObject]@{\r\n                            Browser        = \"Firefox\"\r\n                            User           = $_.UserName\r\n                            Profile        = \"N\/A\"\r\n                            Name           = $Extension.defaultlocale.name\r\n                            \"Extension ID\" = $Extension.id\r\n                            Description    = $Extension.defaultlocale.description\r\n                        }\r\n                    )\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    # Check if there are any browser extensions to process\r\n    if ($BrowserExtensions.Count -gt 0) {\r\n        # Format the BrowserExtensions list to include a shortened description if the description is too long.\r\n        $BrowserExtensions = $BrowserExtensions | Select-Object Browser, User, Profile, Name, \"Extension ID\", @{\r\n            Name       = \"Description\"\r\n            Expression = {\r\n                $Characters = $_.Description | Measure-Object -Character | Select-Object -ExpandProperty Characters\r\n                if ($Characters -gt 75) {\r\n                    \"$(($_.Description).SubString(0,75))(...)\"\r\n                }\r\n                else {\r\n                    $_.Description\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    # Check if extensions were found and if we were requested to set a multiline custom field\r\n    if ($BrowserExtensions.Count -gt 0 -and $MultilineCustomField) {\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            # Sort and format the list of extensions for output\r\n            $CustomFieldList = $BrowserExtensions | Sort-Object Browser, User, Profile, Name | Select-Object Browser, User, Profile, Name, \"Extension ID\", Description\r\n            $CustomFieldValue.Add(($CustomFieldList | Format-List | Out-String))\r\n\r\n            # Measure the total character count of the formatted string\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 satisfied...\"\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                    # Flip the array so that the last entry is on top.\r\n                    [array]::Reverse($CustomFieldList)\r\n    \r\n                    # Remove the next 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 | 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    # Check if extensions were found and if we were requested to set a WYSIWYG custom field.\r\n    if ($BrowserExtensions.Count -gt 0 -and $WysiwygCustomField) {\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 = $BrowserExtensions | Sort-Object Browser, User, Profile, Name | Select-Object Browser, User, Profile, Name, \"Extension ID\", Description | ConvertTo-Html -Fragment\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 satisfied...\"\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                    # Flip the array so that the last entry is on top.\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    if ($BrowserExtensions.Count -gt 0) {\r\n        Write-Host \"Browser extensions were detected.\"\r\n        $BrowserExtensions | Sort-Object Browser, User, Profile, Name | Format-List | Out-String | Write-Host\r\n    }\r\n    else {\r\n        Write-Host \"No browser extensions were 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>Description d\u00e9taill\u00e9e<\/h2>\n<p>Ce script est \u00e9crit en PowerShell et n\u00e9cessite la version 5.1 ou une plus r\u00e9cente. Voici une description d\u00e9taill\u00e9e de son fonctionnement :<\/p>\n<h3>1. Initialisation et param\u00e8tres :<\/h3>\n<ul>\n<li>Le script commence par v\u00e9rifier les param\u00e8tres requis, $MultilineCustomField et $WysiwygCustomField, qui peuvent \u00eatre d\u00e9finis via des variables d&rsquo;environnement ou transmis directement.<\/li>\n<li>Il valide que ces champs, s&rsquo;ils sont tous deux fournis, ne sont pas identiques afin d&rsquo;\u00e9viter les conflits.<\/li>\n<\/ul>\n<h3>2. R\u00e9cup\u00e9ration de ruche d&rsquo;utilisateur :<\/h3>\n<ul>\n<li>La fonction Get-UserHives identifie les profils d&rsquo;utilisateurs sur le syst\u00e8me, y compris les comptes AzureAD et les comptes de domaine.<\/li>\n<li>Cette fonction est essentielle pour garantir que le script analyse tous les r\u00e9pertoires d&rsquo;utilisateurs pertinents pour les donn\u00e9es du navigateur.<\/li>\n<\/ul>\n<h3>3. Contr\u00f4le d&rsquo;autorisation:<\/h3>\n<ul>\n<li>La fonction Test-IsElevated permet de s&rsquo;assurer que le script s&rsquo;ex\u00e9cute avec des privil\u00e8ges administratifs, n\u00e9cessaires pour acc\u00e9der aux ruches et aux r\u00e9pertoires du registre sp\u00e9cifiques \u00e0 l&rsquo;utilisateur.<\/li>\n<\/ul>\n<h3>4. D\u00e9tection du navigateur :<\/h3>\n<ul>\n<li>Le script recherche les installations de Chrome, Firefox et Edge \u00e0 l&rsquo;aide de la fonction Find-InstallKey, qui analyse les cl\u00e9s de registre du syst\u00e8me et de l&rsquo;utilisateur.<\/li>\n<\/ul>\n<h3>5. Chargement de profil :<\/h3>\n<ul>\n<li>Pour chaque navigateur d\u00e9tect\u00e9, le script parcourt les profils des utilisateurs, charge les ruches d&rsquo;enregistrement n\u00e9cessaires et recherche les donn\u00e9es relatives aux extensions du navigateur.<\/li>\n<li>Il s&rsquo;agit de v\u00e9rifier les r\u00e9pertoires sp\u00e9cifiques et les fichiers de configuration dans lesquels les navigateurs stockent les informations relatives aux extensions.<\/li>\n<\/ul>\n<h3>6. Collecte des donn\u00e9es :<\/h3>\n<ul>\n<li>Il compile une liste des extensions install\u00e9es, comprenant des d\u00e9tails tels que le nom du navigateur, l&rsquo;utilisateur, le profil, le nom de l&rsquo;extension, l&rsquo;ID et la description.<\/li>\n<\/ul>\n<h3>7. Mises \u00e0 jour des champs personnalis\u00e9s :<\/h3>\n<ul>\n<li>Si des extensions sont trouv\u00e9es, le script tente de d\u00e9finir des champs personnalis\u00e9s dans un syst\u00e8me de documentation \u00e0 l&rsquo;aide de Set-NinjaProperty. Il g\u00e8re les limites potentielles de caract\u00e8res en r\u00e9duisant la sortie si n\u00e9cessaire.<\/li>\n<\/ul>\n<h3>8. R\u00e9sultat :<\/h3>\n<ul>\n<li>Le r\u00e9sultat final est une liste tri\u00e9e des extensions de navigateur, qui peut \u00eatre affich\u00e9e ou stock\u00e9e dans des champs personnalis\u00e9s en vue d&rsquo;une analyse plus approfondie.<\/li>\n<\/ul>\n<h2>Cas d&rsquo;utilisation potentiels<\/h2>\n<p>Imaginez un professionnel de l&rsquo;informatique qui g\u00e8re l&rsquo;infrastructure informatique d&rsquo;une entreprise de taille moyenne. Il doit s&rsquo;assurer que toutes les extensions de navigateur install\u00e9es sur les machines des utilisateurs sont conformes aux politiques de l&rsquo;entreprise. En ex\u00e9cutant ce script, il peut rapidement faire l&rsquo;inventaire de toutes les extensions dans Chrome, Firefox et Edge, identifier les extensions non autoris\u00e9es ou \u00e0 risque, et prendre des mesures correctives.<\/p>\n<p>Par exemple, si une nouvelle politique interdit les extensions qui n&rsquo;ont pas \u00e9t\u00e9 approuv\u00e9es par le d\u00e9partement informatique, ce script permet \u00e0 l&rsquo;administrateur informatique de g\u00e9n\u00e9rer une liste compl\u00e8te des extensions actuelles. L&rsquo;administrateur peut ensuite croiser cette liste avec les extensions approuv\u00e9es et supprimer \u00e0 distance celles qui pr\u00e9sentent un risque.<\/p>\n<h2>Comparaisons<\/h2>\n<p>Par rapport aux m\u00e9thodes manuelles consistant \u00e0 v\u00e9rifier chaque navigateur et chaque profil d&rsquo;utilisateur individuellement, ce script est nettement plus efficace et plus complet. D&rsquo;autres approches peuvent impliquer l&rsquo;utilisation d&rsquo;outils sp\u00e9cifiques aux navigateurs ou une inspection manuelle, deux m\u00e9thodes qui prennent du temps et sont sujettes aux erreurs humaines. Ce script automatise le processus, garantissant la coh\u00e9rence et permettant de gagner un temps pr\u00e9cieux.<\/p>\n<h2>FAQ<\/h2>\n<h3>Q\u00a0: Ce script peut-il \u00eatre ex\u00e9cut\u00e9 \u00e0 distance ?<\/h3>\n<p>R\u00a0: Oui, \u00e0 condition que vous disposiez des autorisations administratives n\u00e9cessaires et de l&rsquo;acc\u00e8s aux machines distantes.<\/p>\n<h3>Q\u00a0: Que se passe-t-il si la description d&rsquo;une extension d\u00e9passe la limite de caract\u00e8res ?<\/h3>\n<p>R\u00a0: Le script r\u00e9duit la description pour qu&rsquo;elle tienne dans la limite des caract\u00e8res, ce qui garantit que le r\u00e9sultat reste g\u00e9rable.<\/p>\n<h3>Q\u00a0: Le script fonctionne-t-il sur toutes les versions de Windows ?<\/h3>\n<p>R\u00a0: Le script n\u00e9cessite Windows 10 ou Windows Server 2016 et les versions plus r\u00e9centes, car il d\u00e9pend des fonctionnalit\u00e9s disponibles dans ces versions.<\/p>\n<h3>Q\u00a0: Le script peut-il \u00eatre modifi\u00e9 pour prendre en charge d&rsquo;autres navigateurs ?<\/h3>\n<p>R\u00a0: Oui, en apportant des modifications appropri\u00e9es \u00e0 la logique de d\u00e9tection et de collecte des donn\u00e9es, il est possible de le rendre compatible avec d&rsquo;autres navigateurs.<\/p>\n<h2>Implications<\/h2>\n<p>Les r\u00e9sultats de ce script peuvent avoir des cons\u00e9quences importantes pour la s\u00e9curit\u00e9 informatique. En identifiant toutes les extensions de navigateur install\u00e9es, les professionnels de l&rsquo;informatique peuvent d\u00e9tecter les risques de s\u00e9curit\u00e9 potentiels et garantir la conformit\u00e9 avec les politiques de l&rsquo;entreprise. Cette approche proactive permet <a href=\"https:\/\/www.ninjaone.com\/fr\/blog\/meilleures-solutions-de-protection-contre-les-malwares\/\" target=\"_blank\" rel=\"noopener\">d&rsquo;att\u00e9nuer le risque d&rsquo;infections par des logiciels malveillants<\/a> et de vols de donn\u00e9es dues \u00e0 des extensions malveillantes ou mal entretenues.<\/p>\n<h2>Recommandations<\/h2>\n<p>Lors de l&rsquo;utilisation de ce script, il est important de suivre les bonnes pratiques suivantes :<\/p>\n<ul>\n<li>Ex\u00e9cutez le script r\u00e9guli\u00e8rement dans le cadre de votre programme de maintenance informatique.<\/li>\n<li>Examinez la liste des extensions d\u00e9tect\u00e9es et comparez-les \u00e0 votre liste approuv\u00e9e.<\/li>\n<li>Sensibilisez les utilisateurs aux risques associ\u00e9s aux extensions de navigateur et encouragez-les \u00e0 n&rsquo;installer que des extensions approuv\u00e9es.<\/li>\n<\/ul>\n<h2>Conclusion<\/h2>\n<p>La gestion des extensions de navigateur est un aspect essentiel du maintien de la s\u00e9curit\u00e9 informatique. Ce script fournit un moyen automatis\u00e9 et <a href=\"https:\/\/www.ninjaone.com\/fr\/efficacite\/\" target=\"_blank\" rel=\"noopener\">efficace<\/a> d&rsquo;inventorier et de surveiller les extensions de navigateur pour plusieurs utilisateurs et navigateurs. En int\u00e9grant cet outil dans vos processus de gestion informatique, vous pouvez am\u00e9liorer la posture de s\u00e9curit\u00e9 de votre entreprise et garantir le respect des politiques.<\/p>\n<p><a href=\"https:\/\/www.ninjaone.com\/fr\/\" target=\"_blank\" rel=\"noopener\">NinjaOne<\/a> offre une gamme d&rsquo;outils et de fonctionnalit\u00e9s qui compl\u00e8tent ce script, fournissant une solution compl\u00e8te pour la gestion et la s\u00e9curit\u00e9 informatique. Avec NinjaOne, vous pouvez automatiser les t\u00e2ches de routine, surveiller les terminaux et garantir la s\u00e9curit\u00e9 et la conformit\u00e9 de votre environnement informatique.<\/p>\n","protected":false},"author":35,"featured_media":0,"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":"","_lmt_disable":""},"operating_system":[4212],"use_cases":[4286,4285],"class_list":["post-353634","script_hub","type-script_hub","status-publish","hentry","script_hub_category-windows"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.ninjaone.com\/fr\/wp-json\/wp\/v2\/script_hub\/353634","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=353634"}],"wp:attachment":[{"href":"https:\/\/www.ninjaone.com\/fr\/wp-json\/wp\/v2\/media?parent=353634"}],"wp:term":[{"taxonomy":"script_hub_category","embeddable":true,"href":"https:\/\/www.ninjaone.com\/fr\/wp-json\/wp\/v2\/operating_system?post=353634"},{"taxonomy":"use_cases","embeddable":true,"href":"https:\/\/www.ninjaone.com\/fr\/wp-json\/wp\/v2\/use_cases?post=353634"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}