{"id":381851,"date":"2024-11-12T06:58:31","date_gmt":"2024-11-12T06:58:31","guid":{"rendered":"https:\/\/www.ninjaone.com\/?post_type=script_hub&#038;p=381851"},"modified":"2024-11-12T06:58:31","modified_gmt":"2024-11-12T06:58:31","slug":"auflisten-von-browsererweiterungen-unter-macos","status":"publish","type":"script_hub","link":"https:\/\/www.ninjaone.com\/de\/script-hub\/auflisten-von-browsererweiterungen-unter-macos\/","title":{"rendered":"Umfassender Guide zum Auflisten von Browsererweiterungen unter macOS"},"content":{"rendered":"<p>Browsererweiterungen sind leistungsstarke Tools, die die Funktionalit\u00e4t von Webbrowsern verbessern, aber sie k\u00f6nnen auch Sicherheitsrisiken bergen, wenn sie nicht richtig verwaltet werden. F\u00fcr IT-Experten und <a href=\"https:\/\/www.ninjaone.com\/de\/was-ist-ein-msp\" target=\"_blank\" rel=\"noopener\">Managed Service Provider (MSPs)<\/a>, die f\u00fcr die Aufrechterhaltung einer sicheren und effizienten Computerumgebung verantwortlich sind, ist eine Methode zur Inventarisierung von Browsererweiterungen in verschiedenen Browsern auf <a href=\"https:\/\/www.ninjaone.com\/de\/endpunkt-verwaltung\/mac-management\" target=\"_blank\" rel=\"noopener\">macOS-Systemen<\/a> entscheidend.<\/p>\n<p>In diesem Blogbeitrag wird <strong>ein umfassendes Skript zum Auflisten von Browsererweiterungen unter macOS<\/strong> vorgestellt, das sich f\u00fcr Safari, Chrome, Firefox und Edge verwenden l\u00e4sst. Das Verst\u00e4ndnis und die Verwaltung dieser Erweiterungen k\u00f6nnen die Sicherheitslage eines Unternehmens erheblich verbessern.<\/p>\n<h2>Kontext<\/h2>\n<p>In der modernen IT-Welt ist es eine grundlegende Aufgabe, daf\u00fcr zu sorgen, dass die gesamte Software, einschlie\u00dflich der Browsererweiterungen, auf dem neuesten Stand und sicher ist. Erweiterungen k\u00f6nnen gro\u00dfe Vorteile bieten, aber sie stellen auch potenzielle Schwachstellen dar, die <a href=\"https:\/\/www.ninjaone.com\/de\/it-hub\/endpoint-security\/was-ist-ein-bedrohungsakteur\/\" target=\"_blank\" rel=\"noopener\">b\u00f6swillige Akteure<\/a> ausnutzen k\u00f6nnen.<\/p>\n<p>Dieses Skript wurde entwickelt, um IT-Experten dabei zu helfen, schnell und effizient Informationen \u00fcber installierte Browsererweiterungen in mehreren Browsern auf macOS-Systemen zu sammeln. Diese Funktion ist unerl\u00e4sslich, um die Einhaltung der Sicherheitskonformit\u00e4t zu gew\u00e4hrleisten und sicherzustellen, dass nur autorisierte Erweiterungen verwendet werden.<\/p>\n<h2>Das Skript<\/h2>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">#!\/usr\/bin\/env bash\r\n\r\n#\r\n# Description: Get the browser extensions for Safari, Chrome, Firefox, and Edge that are installed on a macOS system.\r\n#\r\n# Usage: [multilineCustomFieldName] [wysiwygCustomFieldName]\r\n#\r\n# Release Notes: Fixed 10% width bug.\r\n# By 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#\r\n# Example Output:\r\n#\r\n# Safari Extensions:\r\n# User: john, Name: com.betafish.adblock-mac.SafariMenu, Id: 3KKZV48AQD\r\n# User: ken, Name: com.rockysandstudio.MKPlayer.MKPlayer-Extension, Id: 2N35YUC83U\r\n#\r\n# Chrome Extensions:\r\n# User: john, Name: Chrome Web Store Payments, Id: nmmhkkegccagdldgiimedpiccmgmieda, Version: 1.0.0.6, Profile Name: test1\r\n# User: john, Name: Turn Off the Lights, Id: bfbmjmiodbnnpllbbbfblcplfjjepjdn, Version: 4.2.6.0, Profile Name: test2\r\n# User: ken, Name: Google Docs Offline, Id: ghbmnnjooekpmoecnnnilnnbdlolhkhi, Version: 1.76.1, Profile Name: Person 1\r\n#\r\n# Firefox Addons:\r\n# User: john, Name: Return YouTube Dislike, Id: {762f9885-5a13-4abd-9c77-433dcd38b8fd}, Description: Returns ability to see dislike statistics on youtube, Profile Name: default-release\r\n# User: john, Name: Stylebot, Id: {52bda3fd-dc48-4b3d-a7b9-58af57879f1e}, Description: Change the appearance of the web instantly, Profile Name: default-release\r\n# User: ken, Name: Search by Image, Id: {2e5ff8c8-32fe-46d0-9fc8-6b8986621f3c}, Description: A powerful reverse image search tool, with support for various search engines, such as Google, Bing, Yandex, Baidu and TinEye., Profile Name: default-release\r\n#\r\n# Edge Extensions:\r\n# User: john, Name: Google Docs Offline, Id: ghbmnnjooekpmoecnnnilnnbdlolhkhi, Version: 1.76.2, Profile Name: test 3\r\n# User: john, Name: Edge relevant text changes, Id: jmjflgjpcpepeafmmgdpfkogkghcpiha, Version: 1.2.1, Profile Name: test 3\r\n# User: ken, Name: Google Docs Offline, Id: ghbmnnjooekpmoecnnnilnnbdlolhkhi, Version: 1.76.2, Profile Name: Profile 1\r\n\r\n_arg_multilineField=$1\r\n_arg_wysiwygField=$2\r\n\r\n# Determines whether or not help text is necessary and routes the output to stderr\r\ndie() {\r\n    local _ret=\"${2:-1}\"\r\n    echo \"$1\" &gt;&amp;2\r\n    test \"${_PRINT_HELP:-no}\" = yes &amp;&amp; print_help &gt;&amp;2\r\n    exit \"${_ret}\"\r\n}\r\n\r\n# Prints the help text\r\nprint_help() {\r\n    echo \"Get the browser extensions for Safari, Chrome, Firefox, and Edge that are installed on a macOS system.\"\r\n    echo \"Usage: [multilineCustomFieldName] [wysiwygCustomFieldName]\"\r\n}\r\n\r\n# Check if --help or -h is passed as an argument\r\nfor _arg in \"$@\"; do\r\n    case \"$_arg\" in\r\n    --help | -h)\r\n        print_help\r\n        exit 0\r\n        ;;\r\n    esac\r\ndone\r\n\r\n# Set the custom field value using ninjarmm-cli\r\nGetCustomField() {\r\n    customfieldName=$1\r\n    dataPath=$(printenv | grep -i NINJA_DATA_PATH | awk -F = '{print $2}')\r\n    value=\"\"\r\n    if [ -e \"${dataPath}\/ninjarmm-cli\" ]; then\r\n        value=$(\"${dataPath}\"\/ninjarmm-cli get \"$customfieldName\")\r\n    else\r\n        value=$(\/Applications\/NinjaRMMAgent\/programdata\/ninjarmm-cli get \"$customfieldName\")\r\n    fi\r\n    if [[ \"${value}\" == *\"Unable to find the specified field\"* ]]; then\r\n        echo \"\"\r\n        return 1\r\n    else\r\n        echo \"$value\"\r\n    fi\r\n}\r\n\r\n# Check if the multilineCustomFieldName is set as environment variables\r\nmultiline=$(printenv | grep -i multilineCustomFieldName | awk -F = '{print $2}')\r\nif [[ -n \"$multiline\" ]] &amp;&amp; [[ \"${multiline}\" != \"null\" ]]; then\r\n    _arg_multilineField=$(printenv | grep -i multilineCustomFieldName | awk -F = '{print $2}')\r\nfi\r\n\r\n# Check if the wysiwygCustomFieldName is set as environment variables\r\nwysiwygField=$(printenv | grep -i wysiwygCustomFieldName | awk -F = '{print $2}')\r\nif [[ -n \"$wysiwygField\" ]] &amp;&amp; [[ \"${wysiwygField}\" != \"null\" ]]; then\r\n    _arg_wysiwygField=$(printenv | grep -i wysiwygCustomFieldName | awk -F = '{print $2}')\r\nfi\r\n\r\n# Check if both _arg_multilineField and _arg_wysiwygField are set and not empty\r\nif [[ -n \"$_arg_multilineField\" &amp;&amp; -n \"$_arg_wysiwygField\" ]]; then\r\n    # Convert both field names to uppercase to check for equality\r\n    multiline=$(echo \"$_arg_multilineField\" | tr '[:lower:]' '[:upper:]')\r\n    wysiwyg=$(echo \"$_arg_wysiwygField\" | tr '[:lower:]' '[:upper:]')\r\n\r\n    # If the converted names are the same, it means both fields cannot be identical\r\n    # If they are, terminate the script with an error\r\n    if [[ \"$multiline\" == \"$wysiwyg\" ]]; then\r\n        _PRINT_HELP=yes die '[Error] Multline Field and WYSIWYG Field cannot be the same name. https:\/\/ninjarmm.zendesk.com\/hc\/en-us\/articles\/360060920631-Custom-Fields-Configuration-Device-Role-Fields'\r\n    fi\r\nfi\r\n\r\n# Warn that if not running as root, the script may not be able to access all user directories\r\nif [[ $EUID -ne 0 ]]; then\r\n    echo \"[Warn] This script may not be able to access all user directories unless run as root.\"\r\nfi\r\n\r\n# Converts a string input into an HTML table format\r\nconvertToHTMLTable() {\r\n    local _arg_delimiter=\" \"\r\n    local _arg_inputObject\r\n\r\n    # Process command-line arguments for the function\r\n    while test $# -gt 0; do\r\n        _key=\"$1\"\r\n        case \"$_key\" in\r\n        --delimiter | -d)\r\n            test $# -lt 2 &amp;&amp; echo \"[Error] Missing value for the optional argument\" &gt;&amp;2 &amp;&amp; return 1\r\n            _arg_delimiter=$2\r\n            shift\r\n            ;;\r\n        --*)\r\n            echo \"[Error] Got an unexpected argument\" &gt;&amp;2\r\n            return 1\r\n            ;;\r\n        *)\r\n            _arg_inputObject=$1\r\n            ;;\r\n        esac\r\n        shift\r\n    done\r\n\r\n    # Handles missing input by checking stdin or returning an error\r\n    if [[ -z $_arg_inputObject ]]; then\r\n        if [ -p \/dev\/stdin ]; then\r\n            _arg_inputObject=$(cat)\r\n        else\r\n            echo \"[Error] Missing input object to convert to table\" &gt;&amp;2\r\n            return 1\r\n        fi\r\n    fi\r\n\r\n    local htmlTable=\"&lt;table&gt;\\n\"\r\n    htmlTable+=$(printf '%b' \"$_arg_inputObject\" | head -n1 | awk -F \"$_arg_delimiter\" '{\r\n    printf \"&lt;tr&gt;\"\r\n    for (i=1; i&lt;=NF; i+=1)\r\n      { printf \"&lt;th&gt;\"$i\"&lt;\/th&gt;\" }\r\n    printf \"&lt;\/tr&gt;\"\r\n    }')\r\n    htmlTable+=\"\\n\"\r\n    htmlTable+=$(printf '%b' \"$_arg_inputObject\" | tail -n +2 | awk -F \"$_arg_delimiter\" '{\r\n    printf \"&lt;tr&gt;\"\r\n    for (i=1; i&lt;=NF; i+=1)\r\n      { printf \"&lt;td&gt;\"$i\"&lt;\/td&gt;\" }\r\n    print \"&lt;\/tr&gt;\"\r\n    }')\r\n    htmlTable+=\"\\n&lt;\/table&gt;\"\r\n\r\n    printf '%b' \"$htmlTable\" '\\n'\r\n}\r\n\r\ncreateExtList() {\r\n    userHome=$1\r\n    browser=$2 # chrome or edge\r\n    user_name=$(echo \"$userHome\" | cut -d \"\/\" -f 3)\r\n    if [[ \"${browser}\" == \"chrome\" ]]; then\r\n        manifests=$(find \"${userHome}\/Library\/Application Support\/Google\/Chrome\" -type f -name 'manifest.json' 2&gt;\/dev\/null | grep \"Extensions\")\r\n        profileLocalState=\"${userHome}\/Library\/Application Support\/Google\/Chrome\/Local State\"\r\n    elif [[ \"${browser}\" == \"edge\" ]]; then\r\n        manifests=$(find \"${userHome}\/Library\/Application Support\/Microsoft Edge\" -type f -name 'manifest.json' 2&gt;\/dev\/null | grep \"Extensions\")\r\n        profileLocalState=\"${userHome}\/Library\/Application Support\/Microsoft Edge\/Local State\"\r\n    fi\r\n\r\n    en_messages=\"_locales\/en\/messages.json\"\r\n    enUS_messages=\"_locales\/en_US\/messages.json\"\r\n\r\n    while IFS= read -r manifest; do\r\n        # Check if we can read the manifest file\r\n        if [ ! -f \"$manifest\" ]; then\r\n            continue\r\n        fi\r\n\r\n        profileName=$(\r\n            # Get profile name from profileLocalState that contains json data\r\n            # \"profile.info_cache.Default\" is the default profile\r\n            osascript -l JavaScript -e \"\r\n                    var profileLocalState = JSON.parse(ObjC.unwrap($.NSString.alloc.initWithDataEncoding($.NSData.dataWithContentsOfFile('$profileLocalState'), $.NSUTF8StringEncoding)));\r\n                    \/\/ Get each profile name based on the profile path\r\n                    if ('$browser' === 'chrome') {\r\n                        var profilePathName = '$manifest'.split('\/')[7];\r\n                    } else if ('$browser' === 'edge') {\r\n                        var profilePathName = '$manifest'.split('\/')[6];\r\n                    }\r\n                    for (var key in profileLocalState.profile.info_cache) {\r\n                        if (key.toLowerCase() === profilePathName.toLowerCase()) {\r\n                            var profileName = profileLocalState.profile.info_cache[key].name;\r\n                            break;\r\n                        }\r\n                    }\r\n                    profileName;\r\n                \"\r\n        )\r\n\r\n        # Get the id of the extension from the manifest path by splitting the path on '\/' and getting the 9th element\r\n        if [[ \"${browser}\" == \"chrome\" ]]; then\r\n            extID=$(awk -F '\/' '{print $10}' &lt;&lt;&lt;\"$manifest\")\r\n        elif [[ \"${browser}\" == \"edge\" ]]; then\r\n            extID=$(awk -F '\/' '{print $9}' &lt;&lt;&lt;\"$manifest\")\r\n        fi\r\n        # Get name from manifest\r\n        name=$(\r\n            osascript -l JavaScript -e \"\r\n                var data = JSON.parse(ObjC.unwrap($.NSString.alloc.initWithDataEncoding($.NSData.dataWithContentsOfFile('$manifest'), $.NSUTF8StringEncoding)));\r\n                var name = data.name;\r\n                name;\r\n            \"\r\n        )\r\n        # Get version from manifest\r\n        version=$(\r\n            osascript -l JavaScript -e \"\r\n                var data = JSON.parse(ObjC.unwrap($.NSString.alloc.initWithDataEncoding($.NSData.dataWithContentsOfFile('$manifest'), $.NSUTF8StringEncoding)));\r\n                var version = data.version;\r\n                version;\r\n            \"\r\n        )\r\n\r\n        # Get the name of the extension from the messages.json file if the name contains \"__MSG_\"\r\n        if [[ \"${name}\" =~ \"__MSG_\" ]]; then\r\n            name=$(echo \"$name\" | sed 's\/__MSG_\/\/g' | sed 's\/__$\/\/g')\r\n            if [ -f \"$(dirname \"$manifest\")\/$en_messages\" ]; then\r\n                # Check if message.json exists in en folder\r\n                name=$(\r\n                    osascript -l JavaScript -e \"\r\n                        var data = JSON.parse(ObjC.unwrap($.NSString.alloc.initWithDataEncoding($.NSData.dataWithContentsOfFile('$(dirname \"$manifest\")\/$en_messages'), $.NSUTF8StringEncoding)));\r\n                        var searchKey = '$name';\r\n                        var asLowercase = searchKey.toLowerCase();\r\n                        var name = data[Object.keys(data).find(key =&gt; key.toLowerCase() === asLowercase)].message;\r\n                        name;\r\n                    \" 2&gt;\/dev\/null\r\n                )\r\n            elif [ -f \"$(dirname \"$manifest\")\/$enUS_messages\" ]; then\r\n                # Check if message.json exists in enUS folder\r\n                name=$(\r\n                    osascript -l JavaScript -e \"\r\n                        var data = JSON.parse(ObjC.unwrap($.NSString.alloc.initWithDataEncoding($.NSData.dataWithContentsOfFile('$(dirname \"$manifest\")\/$enUS_messages'), $.NSUTF8StringEncoding)));\r\n                        var searchKey = '$name';\r\n                        var asLowercase = searchKey.toLowerCase();\r\n                        var name = data[Object.keys(data).find(key =&gt; key.toLowerCase() === asLowercase)].message;\r\n                        name;\r\n                    \" 2&gt;\/dev\/null\r\n                )\r\n            fi\r\n        fi\r\n        if [[ -n \"$name\" ]]; then\r\n            printf \"%s|%s|%s|%s|%s\\n\" \"$user_name\" \"$profileName\" \"$name\" \"$extID\" \"$version\"\r\n        else\r\n            printf \"%s|%s|%s|%s|%s\\n\" \"$user_name\" \"$profileName\" \"Name Not Found\" \"$extID\" \"$version\"\r\n        fi\r\n    done &lt;&lt;&lt;\"$manifests\"\r\n}\r\n\r\n# Get a list of all users in the \/Users directory except Shared\r\nusers=()\r\nfor user in \/Users\/*; do\r\n    if [[ -d \"$user\" &amp;&amp; ! \"$user\" =~ \/Users\/Shared ]]; then\r\n        users+=(\"${user##*\/}\")\r\n    fi\r\ndone\r\n\r\n# Error when no users are found\r\nif [[ ${#users[@]} -eq 0 ]]; then\r\n    _PRINT_HELP=no die \"[Error] No user directories found in \/Users\"\r\nfi\r\n\r\nsafari_title=\"Safari Extensions\"\r\nsafari_extensions=\"\"\r\nchrome_title=\"Chrome Extensions\"\r\nchrome_extensions=\"\"\r\nfirefox_title=\"Firefox Addons\"\r\nfirefox_addons=\"\"\r\nedge_title=\"Edge Extensions\"\r\nedge_extensions=\"\"\r\n\r\n# Safari\r\nfor user in \"${users[@]}\"; do\r\n    ext_plist=\"\/Users\/$user\/Library\/Containers\/com.apple.Safari\/Data\/Library\/Safari\/AppExtensions\/Extensions.plist\"\r\n    pattern='(com\\..*)\\s\\((.*)\\)'\r\n    if [[ -f \"$ext_plist\" ]]; then\r\n        safari_extensions+=$'\\n'\"$(\r\n            grep -Eo \"$pattern\" \"$ext_plist\" | while read -r line; do\r\n                ext_name=$(echo \"$line\" | awk -F ' ' '{print $1}')\r\n                ext_id=$(echo \"$line\" | awk -F ' ' '{print $2}' | tr -d '()')\r\n                printf \"%s|%s|%s\\n\" \"$user\" \"$ext_name\" \"$ext_id\"\r\n            done\r\n        )\"\r\n    fi\r\ndone\r\n\r\n# Chrome\r\nfor user in \"${users[@]}\"; do\r\n    # Add a newline to the beginning of the string to separate the results from the previous user\r\n    chrome_extensions+=$'\\n'\"$(createExtList \"\/Users\/$user\" \"chrome\")\"\r\ndone\r\n\r\n# Firefox Get installed Addons (not extensions)\r\nfirefox_addons=$(\r\n    # Loop through each user profile\r\n    for user in \"${users[@]}\"; do\r\n        firefox_path=\"\/Users\/$user\/Library\/Application Support\/Firefox\"\r\n        profile_dir=\"$firefox_path\/Profiles\"\r\n        # Check if Profiles directory exists\r\n        if [[ -d \"$profile_dir\" ]]; then\r\n            profiles_ini_path=\"$firefox_path\/profiles.ini\"\r\n            # Check if profiles.ini file exists\r\n            if [[ -f \"$profiles_ini_path\" ]]; then\r\n                profiles_ini=$(cat \"$profiles_ini_path\")\r\n                # Parse the profiles.ini file and get the profile names and paths\r\n                # Get each section\r\n                awk -F '=' '\/\\[\/{print $1}' &lt;&lt;&lt;\"$profiles_ini\" | while read -r section; do\r\n                    # Get the profile name\r\n                    profile_name=$(\r\n                        awk -F'=' -v section=\"$section\" -v k=\"Name\" '\r\n                        $0==section{ f=1; next }\r\n                        \/\\[\/{ f=0; next }\r\n                        f &amp;&amp; $1==k{ print $0 }\r\n                        ' &lt;&lt;&lt;\"$profiles_ini\" | sed 's\/^Name=\/\/'\r\n                    )\r\n                    # Get the profile path\r\n                    profile_path=$(\r\n                        awk -F'=' -v section=\"$section\" -v k=\"Path\" '\r\n                        $0==section{ f=1; next }\r\n                        \/\\[\/{ f=0; next }\r\n                        f &amp;&amp; $1==k{ print $0 }\r\n                        ' &lt;&lt;&lt;\"$profiles_ini\" | sed 's\/^Path=\/\/'\r\n                    )\r\n                    # Get the addons json file path\r\n                    ext_dir=\"$firefox_path\/$profile_path\/addons.json\"\r\n                    if [[ -f \"$ext_dir\" ]]; then\r\n                        # Get name, id, and description from the addons.json file\r\n                        ff_results=$(\r\n                            osascript -l JavaScript -e \"\r\n                                var data = JSON.parse(ObjC.unwrap($.NSString.alloc.initWithDataEncoding($.NSData.dataWithContentsOfFile('$ext_dir'), $.NSUTF8StringEncoding)));\r\n                                var addons = data.addons;\r\n                                var result = '';\r\n                                for (var i = 0; i &lt; addons.length; i++) {\r\n                                    var addon = addons[i];\r\n                                    result += addon.name + ',' + addon.id + ',' + addon.description + '\\n';\r\n                                }\r\n                                result;\r\n                            \"\r\n                        )\r\n                        Old_IFS=$IFS\r\n                        echo \"$ff_results\" | while IFS=, read -r name id description; do\r\n                            printf \"%s|%s|%s|%s|%s\\n\" \"$user\" \"$profile_name\" \"$name\" \"$id\" \"$description\"\r\n                        done\r\n                        IFS=$Old_IFS\r\n                    fi\r\n                done\r\n            fi\r\n        fi\r\n    done\r\n)\r\n\r\n# Edge\r\nfor user in \"${users[@]}\"; do\r\n    # Add a newline to the beginning of the string to separate the results from the previous user\r\n    edge_extensions+=$'\\n'\"$(createExtList \"\/Users\/$user\" \"edge\")\"\r\ndone\r\n\r\nif [[ -n $_arg_multilineField ]] || [[ -n $_arg_wysiwygField ]]; then\r\n    # Add headers if a custom field is set\r\n    if [[ -n \"${safari_extensions}\" ]]; then\r\n        safari_extensions=$(echo -e \"User|Name|Id\\n$safari_extensions\")\r\n    fi\r\n    if [[ -n \"${chrome_extensions}\" ]]; then\r\n        chrome_extensions=$(echo -e \"User|Profile Name|Name|Id|Version\\n$chrome_extensions\")\r\n    fi\r\n    if [[ -n \"${firefox_addons}\" ]]; then\r\n        firefox_addons=$(echo -e \"User|Profile Name|Name|Id|Description\\n$firefox_addons\")\r\n    fi\r\n    if [[ -n \"${edge_extensions}\" ]]; then\r\n        edge_extensions=$(echo -e \"User|Profile Name|Name|Id|Version\\n$edge_extensions\")\r\n    fi\r\nfi\r\n\r\n# Checks if there is a multiline custom field set\r\nif [[ -n $_arg_multilineField ]]; then\r\n    echo \"\"\r\n    echo \"Attempting to set Custom Field '$_arg_multilineField'...\"\r\n\r\n    # Formats the extension data for the multiline custom field\r\n    multilineValue=\"\"\r\n    # Check if any browser extensions were found\r\n    if [[ -n \"$safari_title\" ]] &amp;&amp; [[ -n \"${safari_extensions}\" ]]; then\r\n        multilineValue+=$'\\n'\r\n        multilineValue+=\"$safari_title:\"\r\n        multilineValue+=$'\\n'\r\n        multilineValue+=$(\r\n            # Convert the safari_extensions string to a table format. Skip the first line as it is the header\r\n            echo \"$safari_extensions\" | tail -n +2 | while IFS='|' read -r user name id; do\r\n                printf \"User: %s, Name: %s, Id: %s\\n\" \"$user\" \"$name\" \"$id\"\r\n            done\r\n        )\r\n    fi\r\n    if [[ -n \"$chrome_title\" ]] &amp;&amp; [[ -n \"${chrome_extensions}\" ]]; then\r\n        multilineValue+=$'\\n'\r\n        multilineValue+=\"$chrome_title:\"\r\n        multilineValue+=$'\\n'\r\n        multilineValue+=$(\r\n            # Convert the chrome_extensions string to a table format. Skip the first line as it is the header\r\n            echo \"$chrome_extensions\" | tail -n +2 | while IFS='|' read -r user_name profileName name id version; do\r\n                if [[ -n \"$name\" ]]; then\r\n                    printf \"User: %s, Profile Name: %s, Name: %s, Id: %s, Version: %s\\n\" \"$user_name\" \"$profileName\" \"$name\" \"$id\" \"$version\"\r\n                fi\r\n            done\r\n        )\r\n    fi\r\n    if [[ -n \"$firefox_title\" ]] &amp;&amp; [[ -n \"${firefox_addons}\" ]]; then\r\n        multilineValue+=$'\\n'\r\n        multilineValue+=\"$firefox_title:\"\r\n        multilineValue+=$'\\n'\r\n        multilineValue+=$(\r\n            # Convert the firefox_addons string to a table format. Skip the first line as it is the header\r\n            echo \"$firefox_addons\" | tail -n +2 | while IFS='|' read -r user profileName name id description; do\r\n                if [[ -n \"$name\" ]]; then\r\n                    printf \"User: %s, Profile Name: %s, Name: %s, Id: %s, Description: %s\\n\" \"$user\" \"$profileName\" \"$name\" \"$id\" \"$description\"\r\n                fi\r\n            done\r\n        )\r\n    fi\r\n    if [[ -n \"$edge_title\" ]] &amp;&amp; [[ -n \"${edge_extensions}\" ]]; then\r\n        multilineValue+=$'\\n'\r\n        multilineValue+=\"$edge_title:\"\r\n        multilineValue+=$'\\n'\r\n        multilineValue+=$(\r\n            # Convert the edge_extensions string to a table format. Skip the first line as it is the header\r\n            echo \"$edge_extensions\" | tail -n +2 | while IFS='|' read -r user_name profileName name id version; do\r\n                if [[ -n \"$name\" ]]; then\r\n                    printf \"User: %s, Profile Name: %s, Name: %s, Id: %s, Version: %s\\n\" \"$user_name\" \"$profileName\" \"$name\" \"$id\" \"$version\"\r\n                fi\r\n            done\r\n        )\r\n    fi\r\n    # if all multilineValue is empty, set it to \"No browser extensions found\"\r\n    if [[ -z \"$multilineValue\" ]]; then\r\n        multilineValue=\"No browser extensions found\"\r\n    fi\r\n\r\n    # Tries to set the multiline custom field using ninjarmm-cli and captures the output\r\n    if ! output=$(printf '%b' \"$multilineValue\" | \/Applications\/NinjaRMMAgent\/programdata\/ninjarmm-cli set --stdin \"$_arg_multilineField\" 2&gt;&amp;1); then\r\n        echo \"[Error] $output\" &gt;&amp;2\r\n        EXITCODE=1\r\n    else\r\n        echo \"[Info] Successfully set Custom Field '$_arg_multilineField'!\"\r\n    fi\r\nfi\r\n\r\n# Checks if there is a WYSIWYG custom field set\r\nif [[ -n $_arg_wysiwygField ]]; then\r\n    echo \"\"\r\n    echo \"Attempting to set Custom Field '$_arg_wysiwygField'...\"\r\n\r\n    # Initializes an HTML formatted string with headers and extension details\r\n    # Check if any browser extensions were found\r\n    if [[ -n \"$safari_title\" ]] &amp;&amp; [[ -n \"${safari_extensions}\" ]]; then\r\n        htmlObject+=\"&lt;h2&gt;$safari_title&lt;\/h2&gt;\"\r\n        htmlObject+=$(echo \"$safari_extensions\" | convertToHTMLTable --delimiter '|')\r\n    fi\r\n    if [[ -n \"$chrome_title\" ]] &amp;&amp; [[ -n \"${chrome_extensions}\" ]]; then\r\n        htmlObject+=\"&lt;h2&gt;$chrome_title&lt;\/h2&gt;\"\r\n        htmlObject+=$(echo \"$chrome_extensions\" | convertToHTMLTable --delimiter '|')\r\n    fi\r\n    if [[ -n \"$firefox_title\" ]] &amp;&amp; [[ -n \"${firefox_addons}\" ]]; then\r\n        htmlObject+=\"&lt;h2&gt;$firefox_title&lt;\/h2&gt;\"\r\n        htmlObject+=$(echo \"$firefox_addons\" | convertToHTMLTable --delimiter '|')\r\n    fi\r\n    if [[ -n \"$edge_title\" ]] &amp;&amp; [[ -n \"${edge_extensions}\" ]]; then\r\n        htmlObject+=\"&lt;h2&gt;$edge_title&lt;\/h2&gt;\"\r\n        htmlObject+=$(echo \"$edge_extensions\" | convertToHTMLTable --delimiter '|')\r\n    fi\r\n    # if all htmlObject is empty, set it to \"No browser extensions found\"\r\n    if [[ -z \"$htmlObject\" ]]; then\r\n        htmlObject=\"&lt;p&gt;No browser extensions found&lt;\/p&gt;\"\r\n    fi\r\n    # Replace &lt;table&gt; with &lt;table style='white-space:nowrap;'&gt;\r\n    htmlObject=${htmlObject\/\/&lt;table&gt;\/&lt;table style=\\'white-space:nowrap;\\'&gt;}\r\n    # Tries to set the WYSIWYG custom field using ninjarmm-cli and captures the output\r\n    if ! output=$(printf '%b' \"$htmlObject\" | \/Applications\/NinjaRMMAgent\/programdata\/ninjarmm-cli set --stdin \"$_arg_wysiwygField\" 2&gt;&amp;1); then\r\n        echo \"[Error] $output\" &gt;&amp;2\r\n        EXITCODE=1\r\n    else\r\n        echo \"[Info] Successfully set Custom Field '$_arg_wysiwygField'!\"\r\n    fi\r\nfi\r\n\r\n# If both _arg_multilineField and _arg_wysiwygField are not set, or if there is an error saving to the custom fields, print the results\r\nif [[ -z $_arg_multilineField &amp;&amp; -z $_arg_wysiwygField ]] || [[ $EXITCODE -ne 0 ]]; then\r\n    echo \"\"\r\n    echo \"$safari_title:\"\r\n    echo \"$safari_extensions\" | while IFS='|' read -r user name id; do\r\n        if [[ -n \"$name\" ]]; then\r\n            printf \"User: %s, Name: %s, Id: %s\\n\" \"$user\" \"$name\" \"$id\"\r\n        fi\r\n    done\r\n    echo \"\"\r\n    echo \"$chrome_title:\"\r\n    echo \"$chrome_extensions\" | while IFS='|' read -r user profileName name id version; do\r\n        if [[ -n \"$name\" ]]; then\r\n            printf \"User: %s, Profile Name: %s, Name: %s, Id: %s, Version: %s\\n\" \"$user\" \"$profileName\" \"$name\" \"$id\" \"$version\"\r\n        fi\r\n    done\r\n    echo \"\"\r\n    echo \"$firefox_title:\"\r\n    echo \"$firefox_addons\" | while IFS='|' read -r user profileName name id description; do\r\n        if [[ -n \"$name\" ]]; then\r\n            printf \"User: %s, Profile Name: %s, Name: %s, Id: %s, Description: %s\\n\" \"$user\" \"$profileName\" \"$name\" \"$id\" \"$description\"\r\n        fi\r\n    done\r\n    echo \"\"\r\n    echo \"$edge_title:\"\r\n    echo \"$edge_extensions\" | while IFS='|' read -r user profileName name id version; do\r\n        if [[ -n \"$name\" ]]; then\r\n            printf \"User: %s, Profile Name: %s, Name: %s, Id: %s, Version: %s\\n\" \"$user\" \"$profileName\" \"$name\" \"$id\" \"$version\"\r\n        fi\r\n    done\r\n    # If no extensions are found, print a message\r\n    if [[ -z \"$safari_extensions\" ]] &amp;&amp; [[ -z \"$chrome_extensions\" ]] &amp;&amp; [[ -z \"$firefox_addons\" ]] &amp;&amp; [[ -z \"$edge_extensions\" ]]; then\r\n        echo \"[Info] No Browser Extensions Found\"\r\n    fi\r\nfi\r\n\r\n# Checks if an error code is set and exits the script with that code\r\nif [[ -n $EXITCODE ]]; then\r\n    echo \"[Error] Failed to save browser extensions to custom field '$_arg_multilineField' or '$_arg_wysiwygField'.\"\r\n    exit \"$EXITCODE\"\r\nfi<\/pre>\n<p>&nbsp;<\/p>\n\n<div class=\"in-context-cta\"><p>Greifen Sie auf \u00fcber 300 Skripte im NinjaOne Dojo zu.<\/p>\n<p><a href=\"https:\/\/www.ninjaone.com\/freetrialform\/\">Zugang erhalten<\/a><\/p>\n<\/div>\n<h2>Detailansicht<\/h2>\n<p>Das Skript beginnt mit einer Definition seines Zwecks und seiner Verwendung, einer klaren Beschreibung und einer Beispielausgabe. Anschlie\u00dfend wird verifiziert, ob Hilfsargumente vorhanden sind, und es werden Werte f\u00fcr benutzerdefinierte Felder mit Hilfe von ninjarmm-cli gesetzt, einem Tool zur Verwaltung benutzerdefinierter Felder in NinjaOne RMM.<\/p>\n<h3>1. Initialisierung und Argumentbehandlung<\/h3>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:1440,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" data-aria-posinset=\"1\" data-aria-level=\"2\">Bei der Initialisierung des Skripts wird gepr\u00fcft, ob Hilfe-Argumente (&#8211;help oder -h) angegeben wurden. Ist dies der Fall, erscheinen die Verwendungshinweise und das Skript beendet sich.<\/li>\n<\/ul>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:1440,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" data-aria-posinset=\"2\" data-aria-level=\"2\">Es definiert eine Funktion &#8218;GetCustomField&#8216; zum Abrufen von Werten der benutzerdefinierten Felder mit ninjarmm-cli.<\/li>\n<\/ul>\n<h3>2. \u00dcberpr\u00fcfungen von Umgebungsvariablen<\/h3>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:1440,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" data-aria-posinset=\"3\" data-aria-level=\"2\">Das Skript \u00fcberpr\u00fcft, ob &#8218;multilineCustomFieldName&#8216; und &#8218;wysiwygCustomFieldName&#8216; als Umgebungsvariablen gesetzt sind und aktualisiert die Argumente des Skripts dementsprechend.<\/li>\n<\/ul>\n<h3>3. Identifikation des Benutzerverzeichnisses<\/h3>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:1440,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" data-aria-posinset=\"4\" data-aria-level=\"2\">Es identifiziert die Benutzerverzeichnisse in \/Users, mit Ausnahme des Verzeichnisses &#8218;Shared&#8216;, und sammelt alle Benutzerkonten auf dem System.<\/li>\n<\/ul>\n<h3>4. Safari-Erweiterungen<\/h3>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:1440,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" data-aria-posinset=\"5\" data-aria-level=\"2\">F\u00fcr jeden Benutzer sucht das Skript nach plist-Dateien der Safari-Erweiterungen und extrahiert mithilfe regul\u00e4rer Ausdr\u00fccke Details.<\/li>\n<\/ul>\n<h3>5. Erweiterungen f\u00fcr Chrome und Edge<\/h3>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:1440,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" data-aria-posinset=\"6\" data-aria-level=\"2\">Das Skript verwendet die Funktion &#8218;createExtList&#8216;, um Chrome- und Edge-Erweiterungen zu finden und aufzulisten. Es analysiert manifest.json-Dateien in den Erweiterungsverzeichnissen des Browsers und extrahiert Erweiterungsnamen, IDs und Versionen.<\/li>\n<\/ul>\n<h3>6. Firefox-Erweiterungen<\/h3>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:1440,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" data-aria-posinset=\"7\" data-aria-level=\"2\">F\u00fcr Firefox analysiert das Skript die Dateien profiles.ini und addons.json, um installierte Addons aufzulisten, einschlie\u00dflich Namen, IDs und Beschreibungen.<\/li>\n<\/ul>\n<h3>7. Einstellung der benutzerdefinierten Felder und Ausgabe<\/h3>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:1440,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" data-aria-posinset=\"8\" data-aria-level=\"2\">Wenn benutzerdefinierte Felder gesetzt sind, formatiert das Skript die gesammelten Daten in HTML-Tabellen oder Plain-Text und versucht dann, diese Felder mit ninjarmm-cli einzurichten. Wenn die Einrichtung der Felder fehlschl\u00e4gt, werden die gesammelten Daten auf der Konsole ausgegeben.<\/li>\n<\/ul>\n<p>Dieser strukturierte Ansatz gew\u00e4hrleistet eine gr\u00fcndliche Abdeckung aller wichtigen Browser und bietet ein klares und detailliertes Inventar durch das Auflisten von Browsererweiterungen unter macOS.<\/p>\n<h2>Potenzielle Anwendungsf\u00e4lle<\/h2>\n<p>Stellen Sie sich einen MSP vor, der daf\u00fcr sorgen soll, dass alle Kunden-Computer sicher sind. Mit diesem Skript kann der MSP schnell eine Liste aller Browsererweiterungen erstellen, die auf den macOS-Systemen der Kunden installiert sind. Wird beispielsweise eine Sicherheitsschwachstelle in einer bestimmten Erweiterung entdeckt, kann der MSP mithilfe des Skripts feststellen, auf welchen Clients die Erweiterung installiert ist, und entsprechende Ma\u00dfnahmen zur Risikominimierung ergreifen.<\/p>\n<h2>Vergleiche<\/h2>\n<p>Andere Methoden zum Auflisten von Browsererweiterungen unter macOS bestehen in der Regel in manuellen \u00dcberpr\u00fcfungen oder der Verwendung browserspezifischer Tools, was zeitaufw\u00e4ndig und fehleranf\u00e4llig sein kann. Dieses Skript bietet eine einheitliche, automatisierte L\u00f6sung, die in mehreren Browsern funktioniert, Zeit spart und die Wahrscheinlichkeit eines Fl\u00fcchtigkeitsfehlers verringert. Dar\u00fcber hinaus erm\u00f6glicht die Integration mit NinjaOne RMM eine zentralisierte Verwaltung und Berichterstattung, die mit manuellen Methoden nicht m\u00f6glich ist.<\/p>\n<h2>FAQs<\/h2>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" data-aria-posinset=\"2\" data-aria-level=\"1\"><strong>Wie geht das Skript mit verschiedenen Benutzerprofilen um?<\/strong><br \/>\nDas Skript durchl\u00e4uft jedes Benutzerverzeichnis in \/Users und verarbeitet jedes in den jeweiligen Browserverzeichnissen gefundene Profil.<\/li>\n<\/ul>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" data-aria-posinset=\"3\" data-aria-level=\"1\"><strong>Was passiert, wenn das Skript nicht auf ein Benutzerverzeichnis zugreifen kann?<\/strong><br \/>\nDas Skript warnt, dass es m\u00f6glicherweise Root-Zugriff ben\u00f6tigt, um alle Benutzerverzeichnisse zu lesen. Wenn Sie das Skript mit Root-Rechten ausf\u00fchren, haben Sie umfassenden Zugriff.<\/li>\n<\/ul>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" data-aria-posinset=\"4\" data-aria-level=\"1\"><strong>Kann das Skript auch auf Nicht-macOS-Systemen verwendet werden?<\/strong><br \/>\nNein, dieses Skript ist aufgrund der verwendeten Pfade und Tools speziell f\u00fcr macOS konzipiert.<\/li>\n<\/ul>\n<h2>Folgen<\/h2>\n<p>Die Ergebnisse dieses Skripts bieten wichtige Einblicke in die in mehreren Browsern installierten Erweiterungen und weisen auf <a href=\"https:\/\/www.ninjaone.com\/de\/blog\/sicherheitsbedrohungen-besiegen\/\" target=\"_blank\" rel=\"noopener\">potenzielle Sicherheitsrisiken<\/a> hin. Durch eine klare Inventarisierung k\u00f6nnen IT-Experten die Einhaltung von Sicherheitsrichtlinien sicherstellen, nicht autorisierte Erweiterungen erkennen und Schwachstellen umgehend beheben.<\/p>\n<h2>Empfehlungen<\/h2>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" data-aria-posinset=\"5\" data-aria-level=\"1\"><strong>F\u00fchren Sie das Skript als mit Root-Rechten aus<\/strong>, um den Zugriff auf alle Benutzerverzeichnisse zu gew\u00e4hrleisten.<\/li>\n<\/ul>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" data-aria-posinset=\"6\" data-aria-level=\"1\"><strong>\u00dcberpr\u00fcfen Sie regelm\u00e4\u00dfig die Erweiterungslisten<\/strong>, um unn\u00f6tige oder potenziell sch\u00e4dliche Erweiterungen zu identifizieren und zu entfernen.<\/li>\n<\/ul>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" data-aria-posinset=\"7\" data-aria-level=\"1\"><strong>Integrieren Sie das Skript in ein \u00dcberwachungs-Tool<\/strong> wie NinjaOne RMM f\u00fcr kontinuierliche Verwaltung und Berichterstellung.<\/li>\n<\/ul>\n<h2>Abschlie\u00dfende \u00dcberlegungen<\/h2>\n<p>Die Verwaltung von Browser-Erweiterungen ist ein wichtiger Aspekt bei der Aufrechterhaltung einer sicheren IT-Umgebung. Dieses Skript bietet eine leistungsstarke, automatisierte L\u00f6sung zum Auflisten von Browsererweiterungen unter macOS und ist damit ein unsch\u00e4tzbares Tool f\u00fcr IT-Experten und MSPs. Durch die Integration von <a href=\"https:\/\/www.ninjaone.com\/de\/\" target=\"_blank\" rel=\"noopener\">NinjaOne<\/a> k\u00f6nnen Sie Ihre M\u00f6glichkeiten zur \u00dcberwachung und Verwaltung von Browsererweiterungen verbessern und so f\u00fcr eine <a href=\"https:\/\/www.ninjaone.com\/de\/blog\/sicherheitsbedrohungen-besiegen\/\" target=\"_blank\" rel=\"noopener\">sichere<\/a> und Compliance-konforme Computerumgebung sorgen.<\/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":"no","_lmt_disable":""},"operating_system":[4210],"use_cases":[4307],"class_list":["post-381851","script_hub","type-script_hub","status-publish","hentry","script_hub_category-macos"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.ninjaone.com\/de\/wp-json\/wp\/v2\/script_hub\/381851","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.ninjaone.com\/de\/wp-json\/wp\/v2\/script_hub"}],"about":[{"href":"https:\/\/www.ninjaone.com\/de\/wp-json\/wp\/v2\/types\/script_hub"}],"author":[{"embeddable":true,"href":"https:\/\/www.ninjaone.com\/de\/wp-json\/wp\/v2\/users\/35"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ninjaone.com\/de\/wp-json\/wp\/v2\/comments?post=381851"}],"wp:attachment":[{"href":"https:\/\/www.ninjaone.com\/de\/wp-json\/wp\/v2\/media?parent=381851"}],"wp:term":[{"taxonomy":"script_hub_category","embeddable":true,"href":"https:\/\/www.ninjaone.com\/de\/wp-json\/wp\/v2\/operating_system?post=381851"},{"taxonomy":"use_cases","embeddable":true,"href":"https:\/\/www.ninjaone.com\/de\/wp-json\/wp\/v2\/use_cases?post=381851"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}