Apple automation intune macOS

Application Inventory: The Unsung Hero of macOS Security

In the ever-evolving threat landscape, keeping your organization's macOS devices secure is paramount. While Mobile Device Management (MDM) solutions offer a valuable layer of control, a critical piece of the puzzle often gets overlooked: application inventory. This blog post dives into the importance of a comprehensive application inventory

6 min read
Application Inventory: The Unsung Hero of macOS Security

In the ever-evolving threat landscape, keeping your organization's macOS devices secure is paramount. While Mobile Device Management (MDM) solutions offer a valuable layer of control, a critical piece of the puzzle often gets overlooked: application inventory.

This blog post dives into the importance of a comprehensive application inventory for macOS devices, explores the limitations of MDM reporting, and highlights the security benefits gained from improved application visibility.


The Silent Threat: Unseen Applications

Imagine a blind spot in your home security system. That's essentially what an incomplete application inventory creates for your macOS environment. MDM solutions often focus on device details and pre-approved applications.However, this leaves a gap for unauthorized applications, potentially exposing your network to vulnerabilities.

Malware can disguise itself as legitimate applications, making it crucial to have a complete picture of everything running on your Macs. Additionally, outdated or unmaintained software can pose security risks.

Beyond Pre-Approved Apps

While mostly all MDM excels at managing pre-approved applications, it often felt like a shortcoming when it comes to comprehensive application discovery. Here are some limitations to consider:

The Power of Application Inventory

A robust application inventory solution fills the gaps left by MDM, offering significant security benefits:


Beyond Security: The Added Value of Application Inventory

The benefits of application inventory extend beyond just security. It empowers you to:


Taking Control: Building a Comprehensive Inventory with Intune and Azure Log Analytics

Traditionally, building a comprehensive application inventory required additional tools. However, by leveraging Microsoft Intune and Azure Log Analytics, you can achieve this with a custom script.

The Power of Automation:

The script utilizes a bash script running on macOS devices enrolled in Intune. This script gathers application data and sends it securely to your Azure Log Analytics workspace for centralized analysis.

Benefits of this Approach:

Building the macOS Application Inventory Script

The following lines define variables for the CustomerId (your Azure Log Analytics workspace ID) and SharedKey (your workspace's primary key). These are placeholders; you'll need to replace them with your actual values before deployment.

#!/bin/bash

# Replace these with your actual Workspace ID and Primary Key
CustomerId="your_workspace_id"
SharedKey="your_primary_key"

The script retrieves the computer name using scutil --get ComputerName.

It then extracts the device serial number using system_profiler SPHardwareDataType and awk to filter the output for the line containing "Serial"

ComputerName=$(scutil --get ComputerName)
DeviceSerialNumber=$(system_profiler SPHardwareDataType | awk '/Serial/ {print $4}')

This section is the heart of application data collection:

Applications="["

IFS=$'\n'
for line in $(system_profiler SPApplicationsDataType); do
  if [[ "$line" =~ "Location:" ]]; then
    appName=$(basename "$line" .app)  # Extracts only the app name, removing path and .app extension
  elif [[ "$line" =~ "Version:" ]]; then
    appVersion=$(echo "$line" | awk -F": " '{print $2}')
    Applications+="{\"AppName\": \"$appName\", \"AppVersion\": \"$appVersion\", \"ComputerName\": \"$ComputerName\", \"DeviceSerialNumber\": \"$DeviceSerialNumber\"},"
  fi
done
IFS=$' \t\n'

# JSON format
Applications=$(echo $Applications | sed 's/,\]/\]/')

It passes the CustomerId (workspace ID), SharedKey (primary key), the prepared Applications JSON data (containing application details), and a log type identifier ("Mac_app_inventory_CL") for reference within Log Analytics.

# Send data
send_data "$CustomerId" "$SharedKey" "$Applications" "Mac_app_inventory_CL"

So, let's put together all the blocks and build our complete script:

#!/bin/bash

# Replace these with your actual Workspace ID and Primary Key
CustomerId="your_workspace_id"
SharedKey="your_primary_key"

# Function to create the authorization signature
function generate_signature() {
    local customerId="$1"
    local sharedKey="$2"
    local date="$3"
    local contentLength="$4"
    local method="$5"
    local contentType="$6"
    local resource="$7"
    
    local stringToHash="$method\n$contentLength\n$contentType\nx-ms-date:$date\n$resource"
    local decodedKey=$(echo "$sharedKey" | base64 -d | xxd -p -u -c 256)
    local hash=$(echo -ne "$stringToHash" | xxd -p -u -c 256 | xxd -r -p | openssl dgst -sha256 -mac HMAC -macopt hexkey:$decodedKey -binary | base64)
    
    echo "SharedKey $customerId:$hash"
}

# Function to send data to Log Analytics
function send_data() {
    local customerId="$1"
    local sharedKey="$2"
    local data="$3"
    local logType="$4"
    
    local method="POST"
    local contentType="application/json"
    local resource="/api/logs"
    local date=$(date -u +%a,\ %d\ %b\ %Y\ %H:%M:%S\ GMT)
    local contentLength=$(echo -n "$data" | wc -c | tr -d ' ')
    local signature=$(generate_signature "$customerId" "$sharedKey" "$date" "$contentLength" "$method" "$contentType" "$resource")
    local uri="https://$customerId.ods.opinsights.azure.com$resource?api-version=2016-04-01"
    
    response=$(curl --silent --location "$uri" \
         --header "Authorization: $signature" \
         --header "Log-Type: $logType" \
         --header "x-ms-date: $date" \
         --header "Content-Type: $contentType" \
         --data "$data")
    echo "$response"
}

# Main data collection and processing
ComputerName=$(scutil --get ComputerName)
DeviceSerialNumber=$(system_profiler SPHardwareDataType | awk '/Serial/ {print $4}')

# Collecting dynamic application data
Applications="["

appCount=0  # Initialize application count
IFS=$'\n'
for line in $(system_profiler SPApplicationsDataType); do
    if [[ "$line" =~ "Location:" ]]; then
        appName=$(basename "$line" .app)  # Extracts only the app name, removing path and .app extension
    elif [[ "$line" =~ "Version:" ]]; then
        appVersion=$(echo "$line" | awk -F": " '{print $2}')
        Applications+="{\"AppName\": \"$appName\", \"AppVersion\": \"$appVersion\", \"ComputerName\": \"$ComputerName\", \"DeviceSerialNumber\": \"$DeviceSerialNumber\"},"
        ((appCount++))  # Increment application count
    fi
done
IFS=$' \t\n'

# Remove the last comma for JSON format correctness
Applications=$(echo $Applications | sed 's/,\]/\]/')

# Debug output to check everything is captured correctly
echo "Debug: Prepared JSON Data: $Applications"

# Send data
send_data "$CustomerId" "$SharedKey" "$Applications" "Mac_app_inventory_CL"

# Print completion message
echo "Application inventory collected and uploaded to Azure Log Analytics workspace. The total count of apps discovered and uploaded are $appCount."

Deployment:

💡
It is advisable that you run the script locally on a test Mac to see the data before you push it to all production machines!

You need to deploy the script to all your Macs enrolled with Intune. Steps are as below: 


End Results

Once the script executes successfully, it transmits the collected data to your Azure Log Analytics workspace. This data will be stored in a new table named Mac_app_inventory_CL . Within this table, you'll find all the application inventory details gathered by the script from the device.


Conclusion

In conclusion, maintaining a comprehensive inventory of applications on Mac endpoints is crucial for several reasons. It enhances visibility into installed applications, aids in security compliance by ensuring all software is up-to-date, and helps IT departments manage resources more effectively. The limitations of standard MDM reporting functionalities often necessitate a more hands-on approach, as demonstrated through the use of our custom script.

The script not only automates the collection of application data but also seamlessly uploads this inventory to Azure Log Analytics. This integration provides a centralized and accessible location for monitoring and analysis, enabling organizations to make informed decisions based on accurate and up-to-date application usage data.

It empowers you to overcome the reporting limitations of MDM solutions by providing a deeper insight into the applications installed on your network's endpoints.

Next Steps:

Share This Post

Check out these related posts

Early Bird Gets the Worm: Testing iOS 18 & macOS 15 (Beta) Devices with Intune

Platform SSO for macOS: A Deep Dive into Configuration & Troubleshooting

Set Sail for Smooth Seas: Effortless Mac Enrollment with Intune