MAC OS script

🧩 Syntax:
#!/bin/bash

# Get system hostname and timestamp
HOSTNAME=$(hostname)
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
LOCAL_FOLDER="$HOME/Downloads/${HOSTNAME}_${TIMESTAMP}"
mkdir -p "$LOCAL_FOLDER"

# File paths
APP_FILE="$LOCAL_FOLDER/${HOSTNAME}_InstalledApplications.csv"
SYSDETAILS_FILE="$LOCAL_FOLDER/${HOSTNAME}_systemdetails.csv"
LOG_FILE="$LOCAL_FOLDER/${HOSTNAME}_copy_status.log"

# Network share path (direct UNC access - no mounting)
NETWORK_SHARE="/Volumes/samaudit/MAC OS"
UNC_PATH="//10.250.10.92/samaudit/MAC OS"

# Function to test network share access (simple approach)
test_network_access() {
    echo "$(date): Testing network share access..." >> "$LOG_FILE"

    # Test basic connectivity
    echo "$(date): Testing ping to 10.250.10.92..." >> "$LOG_FILE"
    if ping -c 2 10.250.10.92 >/dev/null 2>&1; then
        echo "$(date): Server is reachable" >> "$LOG_FILE"
    else
        echo "$(date): Server ping failed" >> "$LOG_FILE"
        return 1
    fi

    # Test if we can access the network path (it might auto-mount in /Volumes)
    echo "$(date): Checking network share accessibility..." >> "$LOG_FILE"

    # Try to list the share contents to test access
    if ls "$UNC_PATH" >/dev/null 2>&1 || ls "$NETWORK_SHARE" >/dev/null 2>&1; then
        echo "$(date): Network share is accessible" >> "$LOG_FILE"
        return 0
    else
        echo "$(date): Network share not directly accessible, will try copy anyway" >> "$LOG_FILE"
        return 0  # Continue anyway as the copy might work
    fi
}

# Function to escape CSV fields
escape_csv() {
    local field="$1"
    if [[ "$field" == *[,\"]* ]] || [[ "$field" == *$'\n'* ]]; then
        field="${field//\"/\"\"}"
        echo "\"$field\""
    else
        echo "$field"
    fi
}

# Write CSV header for applications
echo "Application Name,Version,Vendor,Installation Date" > "$APP_FILE"

# Check if jq is available for JSON parsing
if command -v jq &> /dev/null; then
    system_profiler SPApplicationsDataType -json | jq -r '.SPApplicationsDataType[] | [._name // "N/A", .version // "N/A", .obtained_from // "N/A", .lastModified // "N/A"] | @csv' >> "$APP_FILE"
else
    system_profiler SPApplicationsDataType | awk -v OFS=',' '
    /^ *Location:/ {location=$2}
    /^ *Version:/ {version=$2}
    /^ *Obtained from:/ {vendor=$3}
    /^ *Last Modified:/ {install_date=$3}
    /^ *Name:/ {
        name=$2
        gsub(/:$/, "", name)
        print name, version, vendor, install_date
        version="N/A"; vendor="N/A"; install_date="N/A"
    }' >> "$APP_FILE"
fi

# Collect Homebrew-installed applications (if brew is available)
if command -v brew &> /dev/null; then
    if command -v jq &> /dev/null; then
        brew info --json=v2 --installed 2>/dev/null | jq -r '.formulae[]? | [.name // "N/A", (.installed[0].version // "N/A"), (.tap // "Homebrew"), (.installed[0].installed_time // "N/A")] | @csv' >> "$APP_FILE"
    else
        brew list --versions 2>/dev/null | while read -r line; do
            if [[ -n "$line" ]]; then
                name=$(echo "$line" | awk '{print $1}')
                version=$(echo "$line" | awk '{print $2}')
                vendor="Homebrew"
                install_date="N/A"
                echo "$(escape_csv "$name"),$(escape_csv "$version"),$(escape_csv "$vendor"),$(escape_csv "$install_date")" >> "$APP_FILE"
            fi
        done
    fi
fi

# Write CSV header for system details
echo "Hostname,Serial Number,IP Address,MAC Address,OS Name,OS Install Date,OS Version,Manufacturer,Model Type,Currently Logged-On User,Domain_Workgroup,Processor Type,Processor Count,Core Count,Logical Processor Count" > "$SYSDETAILS_FILE"

# Collect system information
SERIAL=$(system_profiler SPHardwareDataType | awk '/Serial Number/{print $NF}')
IP=$(ipconfig getifaddr en0 2>/dev/null || echo "N/A")
MAC=$(ifconfig en0 2>/dev/null | awk '/ether/{print $2}' || echo "N/A")
OS_NAME=$(sw_vers -productName 2>/dev/null || echo "N/A")
OS_VERSION=$(sw_vers -productVersion 2>/dev/null || echo "N/A")
OS_INSTALL_DATE=$(ls -l /var/db/.AppleSetupDone 2>/dev/null | awk '{print $6,$7,$8}' || echo "N/A")
MANUFACTURER="Apple"
MODEL=$(system_profiler SPHardwareDataType | awk -F": " '/Model Name/{print $2}' || echo "N/A")
USER=$(whoami)
DOMAIN=$(scutil --get ComputerName 2>/dev/null || echo "N/A")
PROCESSOR_TYPE=$(sysctl -n machdep.cpu.brand_string 2>/dev/null || echo "N/A")
PROCESSOR_COUNT=$(sysctl -n hw.packages 2>/dev/null || echo "N/A")
CORE_COUNT=$(sysctl -n hw.physicalcpu 2>/dev/null || echo "N/A")
LOGICAL_COUNT=$(sysctl -n hw.logicalcpu 2>/dev/null || echo "N/A")

# Write system details to CSV
echo "$(escape_csv "$HOSTNAME"),$(escape_csv "$SERIAL"),$(escape_csv "$IP"),$(escape_csv "$MAC"),$(escape_csv "$OS_NAME"),$(escape_csv "$OS_INSTALL_DATE"),$(escape_csv "$OS_VERSION"),$(escape_csv "$MANUFACTURER"),$(escape_csv "$MODEL"),$(escape_csv "$USER"),$(escape_csv "$DOMAIN"),$(escape_csv "$PROCESSOR_TYPE"),$(escape_csv "$PROCESSOR_COUNT"),$(escape_csv "$CORE_COUNT"),$(escape_csv "$LOGICAL_COUNT")" >> "$SYSDETAILS_FILE"

# Function to copy files to network share (simple approach like Windows)
copy_files_to_share() {
    local max_retries=3
    local retry_delay=5
    local copy_success=true

    echo "$(date): Starting file upload to network share..." >> "$LOG_FILE"

    for FILE in "$APP_FILE" "$SYSDETAILS_FILE"; do
        local basename=$(basename "$FILE")
        local attempt=1
        local file_copied=false

        echo "$(date): Copying $basename..." >> "$LOG_FILE"

        while [ $attempt -le $max_retries ] && [ "$file_copied" = "false" ]; do
            if [ $attempt -gt 1 ]; then
                echo "$(date): Retry attempt $attempt for $basename" >> "$LOG_FILE"
                sleep $retry_delay
            fi

            # Try different target paths
            local target_paths=("$NETWORK_SHARE/$basename" "$UNC_PATH/$basename")

            for target_path in "${target_paths[@]}"; do
                echo "$(date): Attempting copy to: $target_path" >> "$LOG_FILE"

                # Simple cp command (like Windows Copy-Item)
                if cp "$FILE" "$target_path" 2>>"$LOG_FILE"; then
                    # Verify the file was copied
                    if [ -f "$target_path" ] && [ -s "$target_path" ]; then
                        echo "$(date): Successfully copied $basename to network share" >> "$LOG_FILE"
                        file_copied=true
                        break
                    else
                        echo "$(date): File copy verification failed for $basename" >> "$LOG_FILE"
                    fi
                else
                    echo "$(date): Copy command failed for target: $target_path" >> "$LOG_FILE"
                fi
            done

            if [ "$file_copied" = "true" ]; then
                break
            fi

            attempt=$((attempt + 1))
        done

        if [ "$file_copied" = "false" ]; then
            echo "$(date): FINAL FAILURE - Could not copy $basename after $max_retries attempts" >> "$LOG_FILE"
            copy_success=false
        fi
    done

    echo "$copy_success"
}

# Test network share access and copy files
NETWORK_ACCESS_SUCCESS=false
if test_network_access; then
    NETWORK_ACCESS_SUCCESS=true
    COPY_SUCCESS=$(copy_files_to_share)
else
    COPY_SUCCESS=false
    echo "$(date): Skipping file upload due to network access failure" >> "$LOG_FILE"
fi

# Final status log
if [ "$NETWORK_ACCESS_SUCCESS" = "true" ]; then
    if [ "$COPY_SUCCESS" = "true" ]; then
        echo "$(date): ✓ All files uploaded successfully to network share" >> "$LOG_FILE"
        echo "$(date): Network share location: $UNC_PATH" >> "$LOG_FILE"
    else
        echo "$(date): ✗ Upload failed - Files available locally only" >> "$LOG_FILE"
        echo "$(date): Local backup location: $LOCAL_FOLDER" >> "$LOG_FILE"
    fi
else
    echo "$(date): ✗ Network share access failed - Files saved locally only" >> "$LOG_FILE"
    echo "$(date): Check network connectivity to 10.250.10.92" >> "$LOG_FILE"
fi

# Generate summary report
APP_COUNT=$(( $(wc -l < "$APP_FILE") - 1 ))
echo "$(date): === AUDIT SUMMARY ===" >> "$LOG_FILE"
echo "$(date): Hostname: $HOSTNAME" >> "$LOG_FILE"
echo "$(date): Applications collected: $APP_COUNT" >> "$LOG_FILE"
echo "$(date): Local files: $LOCAL_FOLDER" >> "$LOG_FILE"
echo "$(date): Network upload: $([ "$COPY_SUCCESS" = "true" ] && echo "SUCCESS" || echo "FAILED")" >> "$LOG_FILE"
echo "$(date): Script completed" >> "$LOG_FILE"

# Console output summary
echo "=== System Audit Complete ==="
echo "Applications collected: $APP_COUNT"
echo "Local files saved in: $LOCAL_FOLDER"
if [ "$COPY_SUCCESS" = "true" ]; then
    echo "✓ Files uploaded to network share successfully"
else
    echo "✗ Network upload failed - files saved locally"
fi
echo "Detailed log: $LOG_FILE"