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"