Set Up Policy Banners on macOS Devices
This comprehensive guide demonstrates how to create, manage, and deploy interactive policy banners on macOS devices for organizational compliance and policy communication.
Overview
Policy banners are interactive messages that appear at the login screen, requiring users to acknowledge organizational policies, agreements, or guidelines before accessing the device. They serve as an essential compliance tool for:
- Legal compliance: Displaying terms of use and acceptable use policies
- Security awareness: Communicating security policies and best practices
- Regulatory requirements: Meeting industry-specific compliance standards
- Corporate governance: Ensuring users acknowledge company policies
- Asset protection: Establishing legal framework for device usage
Basic Policy Banner Implementation
Simple Policy Banner Script
Create a basic policy banner with custom messaging:
#!/bin/bash
# Basic policy banner setup script
# Usage: ./create_policy_banner.sh "Your policy message"
create_policy_banner() {
local message="$1"
# Default message if none provided
if [ -z "$message" ]; then
message="This computer system is for authorized use only. By accessing this system, you agree to comply with all applicable policies and regulations."
fi
# Create the policy banner file
sudo tee /Library/Security/PolicyBanner.txt <<EOF > /dev/null
$message
EOF
# Set appropriate permissions
sudo chmod 644 /Library/Security/PolicyBanner.txt
sudo chown root:wheel /Library/Security/PolicyBanner.txt
echo "Policy banner created successfully."
echo "Message: $message"
}
# Main execution
if [ $# -eq 0 ]; then
echo "Usage: $0 \"Your policy message\""
echo "Example: $0 \"This system is monitored for security purposes.\""
create_policy_banner
else
create_policy_banner "$1"
fi
Enhanced Policy Banner with Validation
#!/bin/bash
# Enhanced policy banner setup with validation and logging
# Usage: ./enhanced_policy_banner.sh
setup_policy_banner() {
local banner_file="/Library/Security/PolicyBanner.txt"
local log_file="/var/log/macfleet_policy_banner.log"
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
# Check if running as root
if [ "$EUID" -ne 0 ]; then
echo "Error: This script must be run as root"
exit 1
fi
# Create log directory if it doesn't exist
mkdir -p /var/log
# Log the operation
echo "[$timestamp] Starting policy banner setup on $(hostname)" >> "$log_file"
# Create policy banner content
cat > "$banner_file" << 'EOF'
AUTHORIZED USE ONLY
This computer system is the property of MacFleet Organization and is intended for authorized business use only. By continuing, you acknowledge that:
• You have read and agree to comply with all applicable policies
• Your activities may be monitored and recorded for security purposes
• Unauthorized access or use is prohibited and may result in criminal prosecution
• You understand that personal use may be restricted or prohibited
Click "Accept" to acknowledge these terms and continue.
EOF
# Set proper permissions
chmod 644 "$banner_file"
chown root:wheel "$banner_file"
# Validate the banner file
if [ -f "$banner_file" ]; then
echo "[$timestamp] Policy banner created successfully at $banner_file" >> "$log_file"
echo "Policy banner setup completed successfully."
# Display current content
echo "Current policy banner content:"
echo "================================"
cat "$banner_file"
echo "================================"
else
echo "[$timestamp] ERROR: Failed to create policy banner file" >> "$log_file"
echo "Error: Failed to create policy banner file"
exit 1
fi
# Update preboot volume for FileVault compatibility
echo "[$timestamp] Updating preboot volume for FileVault compatibility" >> "$log_file"
if diskutil apfs updatePreboot / 2>/dev/null; then
echo "[$timestamp] Preboot volume updated successfully" >> "$log_file"
echo "Preboot volume updated for FileVault compatibility."
else
echo "[$timestamp] Warning: Failed to update preboot volume" >> "$log_file"
echo "Warning: Could not update preboot volume. Banner may not appear on FileVault-enabled devices."
fi
}
# Execute setup
setup_policy_banner
Advanced Policy Banner Management
Multi-Language Policy Banner
#!/bin/bash
# Multi-language policy banner setup
# Usage: ./multilang_policy_banner.sh [language_code]
setup_multilang_banner() {
local language=${1:-"en"}
local banner_file="/Library/Security/PolicyBanner.txt"
# Check if running as root
if [ "$EUID" -ne 0 ]; then
echo "Error: This script must be run as root"
exit 1
fi
case $language in
"en")
create_english_banner
;;
"fr")
create_french_banner
;;
"es")
create_spanish_banner
;;
"de")
create_german_banner
;;
*)
echo "Unsupported language: $language"
echo "Supported languages: en, fr, es, de"
exit 1
;;
esac
# Set proper permissions
chmod 644 "$banner_file"
chown root:wheel "$banner_file"
# Update preboot volume
diskutil apfs updatePreboot / 2>/dev/null
echo "Multi-language policy banner ($language) created successfully."
}
create_english_banner() {
cat > "/Library/Security/PolicyBanner.txt" << 'EOF'
AUTHORIZED ACCESS ONLY
This computer system is owned by MacFleet Organization and is provided for authorized business use only.
By proceeding, you acknowledge that:
• You are an authorized user with legitimate business purpose
• All activities are subject to monitoring and logging
• Unauthorized access, use, or disclosure is prohibited
• Violations may result in disciplinary action and legal prosecution
• Personal use may be restricted per company policy
Your continued use constitutes acceptance of these terms.
Click "Accept" to proceed.
EOF
}
create_french_banner() {
cat > "/Library/Security/PolicyBanner.txt" << 'EOF'
ACCÈS AUTORISÉ SEULEMENT
Ce système informatique appartient à l'organisation MacFleet et est fourni uniquement pour un usage professionnel autorisé.
En continuant, vous reconnaissez que :
• Vous êtes un utilisateur autorisé avec un objectif commercial légitime
• Toutes les activités sont sujettes à surveillance et enregistrement
• L'accès, l'utilisation ou la divulgation non autorisés sont interdits
• Les violations peuvent entraîner des mesures disciplinaires et des poursuites légales
• L'usage personnel peut être restreint selon la politique de l'entreprise
Votre utilisation continue constitue l'acceptation de ces termes.
Cliquez sur "Accepter" pour continuer.
EOF
}
create_spanish_banner() {
cat > "/Library/Security/PolicyBanner.txt" << 'EOF'
SOLO ACCESO AUTORIZADO
Este sistema informático es propiedad de la Organización MacFleet y se proporciona únicamente para uso comercial autorizado.
Al continuar, usted reconoce que:
• Es un usuario autorizado con un propósito comercial legítimo
• Todas las actividades están sujetas a monitoreo y registro
• El acceso, uso o divulgación no autorizados están prohibidos
• Las violaciones pueden resultar en acción disciplinaria y enjuiciamiento legal
• El uso personal puede estar restringido según la política de la empresa
Su uso continuado constituye la aceptación de estos términos.
Haga clic en "Aceptar" para continuar.
EOF
}
create_german_banner() {
cat > "/Library/Security/PolicyBanner.txt" << 'EOF'
NUR AUTORISIERTER ZUGANG
Dieses Computersystem gehört der MacFleet Organisation und wird nur für autorisierten geschäftlichen Gebrauch bereitgestellt.
Durch Fortfahren erkennen Sie an, dass:
• Sie ein autorisierter Benutzer mit legitimen geschäftlichen Zweck sind
• Alle Aktivitäten der Überwachung und Protokollierung unterliegen
• Unbefugter Zugang, Gebrauch oder Offenlegung verboten ist
• Verstöße zu Disziplinarmaßnahmen und rechtlicher Verfolgung führen können
• Persönlicher Gebrauch gemäß Firmenrichtlinie beschränkt sein kann
Ihre fortgesetzte Nutzung stellt die Annahme dieser Bedingungen dar.
Klicken Sie "Akzeptieren" um fortzufahren.
EOF
}
# Main execution
setup_multilang_banner "$1"
Dynamic Policy Banner Generator
#!/bin/bash
# Dynamic policy banner generator with template support
# Usage: ./dynamic_banner.sh [template_name]
generate_dynamic_banner() {
local template=${1:-"corporate"}
local banner_file="/Library/Security/PolicyBanner.txt"
local config_file="/etc/macfleet/banner_config.conf"
# Check if running as root
if [ "$EUID" -ne 0 ]; then
echo "Error: This script must be run as root"
exit 1
fi
# Create configuration directory
mkdir -p /etc/macfleet
# Load or create configuration
if [ -f "$config_file" ]; then
source "$config_file"
else
create_default_config
source "$config_file"
fi
# Generate banner based on template
case $template in
"corporate")
generate_corporate_banner
;;
"government")
generate_government_banner
;;
"healthcare")
generate_healthcare_banner
;;
"education")
generate_education_banner
;;
"financial")
generate_financial_banner
;;
*)
echo "Unknown template: $template"
echo "Available templates: corporate, government, healthcare, education, financial"
exit 1
;;
esac
# Apply configuration
chmod 644 "$banner_file"
chown root:wheel "$banner_file"
diskutil apfs updatePreboot / 2>/dev/null
echo "Dynamic policy banner ($template) generated successfully."
}
create_default_config() {
cat > "/etc/macfleet/banner_config.conf" << 'EOF'
# MacFleet Policy Banner Configuration
ORGANIZATION_NAME="MacFleet Organization"
CONTACT_EMAIL="support@macfleet.com"
CONTACT_PHONE="1-800-MACFLEET"
COMPLIANCE_OFFICER="Compliance Team"
EFFECTIVE_DATE="2025-01-01"
MONITORING_ENABLED="true"
PERSONAL_USE_POLICY="restricted"
EOF
}
generate_corporate_banner() {
cat > "$banner_file" << EOF
$ORGANIZATION_NAME
AUTHORIZED USE POLICY
This computer system is provided for authorized business use only.
TERMS OF USE:
• Access is restricted to authorized personnel only
• All activities are monitored and logged for security purposes
• Unauthorized access or misuse is prohibited
• Personal use is $PERSONAL_USE_POLICY per company policy
• Users must comply with all applicable laws and regulations
MONITORING NOTICE:
By using this system, you consent to monitoring and recording of your activities.
This includes but is not limited to: network traffic, file access, and application usage.
For questions or concerns, contact:
$COMPLIANCE_OFFICER at $CONTACT_EMAIL or $CONTACT_PHONE
Effective Date: $EFFECTIVE_DATE
Your continued use constitutes acceptance of these terms.
EOF
}
generate_government_banner() {
cat > "$banner_file" << EOF
$ORGANIZATION_NAME
OFFICIAL USE ONLY
WARNING: This is a U.S. Government computer system for official use only.
By accessing this system, you agree to the following:
• This system is for authorized government business only
• All activities are subject to monitoring and recording
• Unauthorized access is a violation of federal law
• Evidence of criminal activity will be reported to law enforcement
• Personal use is strictly prohibited
PRIVACY NOTICE:
Users have no expectation of privacy when using this system.
All information stored or transmitted may be monitored or recorded.
Unauthorized use may result in:
• Criminal prosecution under 18 USC 1030
• Civil liability
• Administrative action including termination
For official use authorization, contact: $CONTACT_EMAIL
Effective Date: $EFFECTIVE_DATE
EOF
}
generate_healthcare_banner() {
cat > "$banner_file" << EOF
$ORGANIZATION_NAME
HIPAA COMPLIANCE NOTICE
This system contains Protected Health Information (PHI) subject to HIPAA regulations.
ACCESS REQUIREMENTS:
• Access is restricted to authorized healthcare personnel only
• Users must have legitimate business need for PHI access
• All PHI access is logged and monitored for compliance
• Unauthorized access may result in HIPAA violations
PRIVACY AND SECURITY:
• All activities are monitored for HIPAA compliance
• PHI must be handled according to organization policies
• Report suspected privacy breaches immediately
• Personal use of this system is prohibited
COMPLIANCE OBLIGATIONS:
• Users must complete required HIPAA training
• Passwords must meet complexity requirements
• Workstations must be locked when unattended
• PHI must not be disclosed to unauthorized persons
For HIPAA compliance questions: $CONTACT_EMAIL
Effective Date: $EFFECTIVE_DATE
Your access confirms your understanding of these obligations.
EOF
}
generate_education_banner() {
cat > "$banner_file" << EOF
$ORGANIZATION_NAME
EDUCATIONAL TECHNOLOGY POLICY
This computer system is provided for educational purposes and authorized use only.
ACCEPTABLE USE:
• Access is limited to students, faculty, and authorized staff
• Use must support educational objectives and institutional mission
• All activities are monitored to ensure appropriate use
• Personal use is limited and subject to institutional policy
STUDENT PRIVACY:
• Student records are protected under FERPA regulations
• Access to student information requires legitimate educational interest
• Unauthorized disclosure of student information is prohibited
• Report suspected privacy violations immediately
PROHIBITED ACTIVITIES:
• Accessing, copying, or sharing inappropriate content
• Violating copyright or intellectual property rights
• Harassment, bullying, or discriminatory behavior
• Installing unauthorized software or applications
For technology support: $CONTACT_EMAIL
For policy questions: $COMPLIANCE_OFFICER
Effective Date: $EFFECTIVE_DATE
Your use indicates acceptance of these terms.
EOF
}
generate_financial_banner() {
cat > "$banner_file" << EOF
$ORGANIZATION_NAME
FINANCIAL SERVICES COMPLIANCE
This system processes financial data subject to regulatory oversight.
REGULATORY COMPLIANCE:
• Access restricted to authorized financial services personnel
• All transactions are monitored for compliance with:
- SOX (Sarbanes-Oxley Act)
- GLBA (Gramm-Leach-Bliley Act)
- PCI DSS (Payment Card Industry Data Security Standard)
• Financial data must be protected according to regulatory requirements
SECURITY REQUIREMENTS:
• Strong authentication is required for all access
• Financial data must not be stored on local devices
• All access is logged and subject to audit
• Suspicious activity will be reported to regulators
CONFIDENTIALITY:
• Customer financial information is strictly confidential
• Access requires legitimate business purpose
• Unauthorized disclosure may result in regulatory action
• Personal use of this system is prohibited
For compliance questions: $COMPLIANCE_OFFICER
For technical support: $CONTACT_EMAIL
Effective Date: $EFFECTIVE_DATE
Your access confirms compliance with these requirements.
EOF
}
# Execute generator
generate_dynamic_banner "$1"
Enterprise Policy Banner Management
Centralized Banner Deployment
#!/bin/bash
# Centralized policy banner deployment for Mac fleet
# Usage: ./enterprise_banner_deploy.sh
deploy_enterprise_banner() {
local deployment_id="$(date +%Y%m%d_%H%M%S)"
local log_file="/var/log/macfleet_banner_deployment.log"
local config_server="https://config.macfleet.com"
local device_id=$(system_profiler SPHardwareDataType | grep "Hardware UUID" | awk '{print $3}')
# Check if running as root
if [ "$EUID" -ne 0 ]; then
echo "Error: This script must be run as root"
exit 1
fi
# Create log entry
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Starting enterprise banner deployment (ID: $deployment_id)" >> "$log_file"
# Get device information
local computer_name=$(scutil --get ComputerName)
local os_version=$(sw_vers -productVersion)
local build_version=$(sw_vers -buildVersion)
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Device: $computer_name ($device_id)" >> "$log_file"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] OS: macOS $os_version ($build_version)" >> "$log_file"
# Fetch organization-specific banner configuration
fetch_banner_config
# Deploy banner based on configuration
if [ -f "/tmp/banner_config.json" ]; then
parse_and_deploy_banner
else
deploy_default_banner
fi
# Validate deployment
validate_banner_deployment
# Report deployment status
report_deployment_status "$deployment_id"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Enterprise banner deployment completed (ID: $deployment_id)" >> "$log_file"
}
fetch_banner_config() {
local config_url="$config_server/api/banner/config"
local headers="X-Device-ID: $device_id"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Fetching banner configuration from: $config_url" >> "$log_file"
# Attempt to fetch configuration (simulated - replace with actual API call)
# curl -s -H "$headers" "$config_url" -o "/tmp/banner_config.json"
# Create mock configuration for demonstration
cat > "/tmp/banner_config.json" << 'EOF'
{
"organization": "MacFleet Enterprise",
"template": "corporate",
"language": "en",
"custom_message": "",
"monitoring_enabled": true,
"contact_info": {
"email": "compliance@macfleet.com",
"phone": "1-800-MACFLEET"
},
"compliance_requirements": [
"SOX", "HIPAA", "PCI-DSS"
],
"effective_date": "2025-07-07"
}
EOF
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Configuration fetched successfully" >> "$log_file"
}
parse_and_deploy_banner() {
local config_file="/tmp/banner_config.json"
# Parse JSON configuration (requires jq or manual parsing)
local organization=$(grep -o '"organization"[^,]*' "$config_file" | cut -d'"' -f4)
local template=$(grep -o '"template"[^,]*' "$config_file" | cut -d'"' -f4)
local language=$(grep -o '"language"[^,]*' "$config_file" | cut -d'"' -f4)
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Deploying banner for $organization (template: $template, language: $language)" >> "$log_file"
# Create banner based on configuration
cat > "/Library/Security/PolicyBanner.txt" << EOF
$organization
ENTERPRISE POLICY BANNER
This computer system is owned by $organization and is provided for authorized business use only.
By accessing this system, you acknowledge and agree to:
• Comply with all applicable corporate policies and procedures
• Submit to monitoring and logging of all system activities
• Respect the confidentiality of proprietary information
• Report security incidents immediately to IT security team
• Use the system only for legitimate business purposes
MONITORING NOTICE:
All activities on this system are subject to monitoring and recording.
This includes but is not limited to network traffic, file access, email, and application usage.
COMPLIANCE REQUIREMENTS:
This system must comply with applicable regulations including SOX, HIPAA, and PCI-DSS.
Users are responsible for maintaining compliance with all applicable standards.
For questions or to report security incidents:
Email: compliance@macfleet.com
Phone: 1-800-MACFLEET
Effective Date: 2025-07-07
Your continued use constitutes acceptance of these terms and conditions.
EOF
# Set proper permissions
chmod 644 "/Library/Security/PolicyBanner.txt"
chown root:wheel "/Library/Security/PolicyBanner.txt"
# Clean up temporary files
rm -f "/tmp/banner_config.json"
}
deploy_default_banner() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Deploying default banner (configuration not available)" >> "$log_file"
cat > "/Library/Security/PolicyBanner.txt" << 'EOF'
MacFleet Organization
AUTHORIZED USE ONLY
This computer system is provided for authorized business use only.
By proceeding, you acknowledge that:
• You are an authorized user with legitimate business access
• All activities are monitored and logged for security purposes
• Unauthorized access or misuse is strictly prohibited
• Personal use may be restricted per company policy
• You agree to comply with all applicable policies and regulations
Your continued use constitutes acceptance of these terms.
For questions: support@macfleet.com
EOF
chmod 644 "/Library/Security/PolicyBanner.txt"
chown root:wheel "/Library/Security/PolicyBanner.txt"
}
validate_banner_deployment() {
local banner_file="/Library/Security/PolicyBanner.txt"
if [ -f "$banner_file" ]; then
local file_size=$(stat -f%z "$banner_file")
local file_perms=$(stat -f%p "$banner_file")
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Banner validation: File exists, size: $file_size bytes, permissions: $file_perms" >> "$log_file"
# Update preboot volume
if diskutil apfs updatePreboot / 2>/dev/null; then
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Preboot volume updated successfully" >> "$log_file"
else
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Warning: Failed to update preboot volume" >> "$log_file"
fi
return 0
else
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Error: Banner file not found after deployment" >> "$log_file"
return 1
fi
}
report_deployment_status() {
local deployment_id="$1"
local status_url="$config_server/api/banner/status"
# Create status report
cat > "/tmp/deployment_status.json" << EOF
{
"deployment_id": "$deployment_id",
"device_id": "$device_id",
"computer_name": "$computer_name",
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"status": "completed",
"os_version": "$os_version",
"banner_deployed": true
}
EOF
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Deployment status prepared for reporting" >> "$log_file"
# Send status report (simulated)
# curl -s -X POST -H "Content-Type: application/json" -d @"/tmp/deployment_status.json" "$status_url"
# Clean up
rm -f "/tmp/deployment_status.json"
}
# Execute deployment
deploy_enterprise_banner
Policy Banner Monitoring and Compliance
#!/bin/bash
# Policy banner monitoring and compliance checking
# Usage: ./banner_compliance_check.sh
check_banner_compliance() {
local log_file="/var/log/macfleet_banner_compliance.log"
local banner_file="/Library/Security/PolicyBanner.txt"
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
local device_id=$(system_profiler SPHardwareDataType | grep "Hardware UUID" | awk '{print $3}')
echo "[$timestamp] Starting policy banner compliance check on device: $device_id" >> "$log_file"
# Check if banner file exists
if [ ! -f "$banner_file" ]; then
echo "[$timestamp] COMPLIANCE VIOLATION: Policy banner file not found" >> "$log_file"
echo "VIOLATION: Policy banner not deployed"
return 1
fi
# Check file permissions
local file_perms=$(stat -f%p "$banner_file")
local expected_perms="100644"
if [ "$file_perms" != "$expected_perms" ]; then
echo "[$timestamp] COMPLIANCE WARNING: Banner file permissions incorrect (found: $file_perms, expected: $expected_perms)" >> "$log_file"
echo "WARNING: Incorrect file permissions detected"
# Attempt to fix permissions
chmod 644 "$banner_file"
chown root:wheel "$banner_file"
echo "[$timestamp] Permissions corrected automatically" >> "$log_file"
fi
# Check file ownership
local file_owner=$(stat -f%u:%g "$banner_file")
local expected_owner="0:0"
if [ "$file_owner" != "$expected_owner" ]; then
echo "[$timestamp] COMPLIANCE WARNING: Banner file ownership incorrect (found: $file_owner, expected: $expected_owner)" >> "$log_file"
echo "WARNING: Incorrect file ownership detected"
# Attempt to fix ownership
chown root:wheel "$banner_file"
echo "[$timestamp] Ownership corrected automatically" >> "$log_file"
fi
# Check banner content
local file_size=$(stat -f%z "$banner_file")
if [ "$file_size" -lt 100 ]; then
echo "[$timestamp] COMPLIANCE WARNING: Banner file appears to be empty or too small ($file_size bytes)" >> "$log_file"
echo "WARNING: Banner content may be insufficient"
fi
# Check for required keywords
local required_keywords=("AUTHORIZED" "MONITORING" "PROHIBITED" "POLICY")
local missing_keywords=()
for keyword in "${required_keywords[@]}"; do
if ! grep -q "$keyword" "$banner_file" 2>/dev/null; then
missing_keywords+=("$keyword")
fi
done
if [ ${#missing_keywords[@]} -gt 0 ]; then
echo "[$timestamp] COMPLIANCE WARNING: Missing required keywords: ${missing_keywords[*]}" >> "$log_file"
echo "WARNING: Banner may not meet compliance requirements"
fi
# Check banner age
local banner_age=$(( $(date +%s) - $(stat -f%m "$banner_file") ))
local max_age=7776000 # 90 days in seconds
if [ "$banner_age" -gt "$max_age" ]; then
echo "[$timestamp] COMPLIANCE NOTICE: Banner is older than 90 days (age: $((banner_age/86400)) days)" >> "$log_file"
echo "NOTICE: Banner may need updating"
fi
# Generate compliance report
generate_compliance_report
echo "[$timestamp] Compliance check completed" >> "$log_file"
echo "Policy banner compliance check completed."
}
generate_compliance_report() {
local report_file="/tmp/banner_compliance_report.txt"
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
cat > "$report_file" << EOF
MacFleet Policy Banner Compliance Report
Generated: $timestamp
Device: $(scutil --get ComputerName)
Device ID: $device_id
COMPLIANCE STATUS:
$([ -f "$banner_file" ] && echo "✓ Policy banner deployed" || echo "✗ Policy banner missing")
$([ "$(stat -f%p "$banner_file" 2>/dev/null)" = "100644" ] && echo "✓ Correct file permissions" || echo "✗ Incorrect file permissions")
$([ "$(stat -f%u:%g "$banner_file" 2>/dev/null)" = "0:0" ] && echo "✓ Correct file ownership" || echo "✗ Incorrect file ownership")
BANNER CONTENT ANALYSIS:
File size: $(stat -f%z "$banner_file" 2>/dev/null || echo "N/A") bytes
Last modified: $(stat -f%Sm "$banner_file" 2>/dev/null || echo "N/A")
Content preview:
$(head -3 "$banner_file" 2>/dev/null || echo "No content available")
RECOMMENDATIONS:
• Review banner content regularly for policy updates
• Ensure banner meets organizational compliance requirements
• Monitor banner deployment across all managed devices
• Update banner when policies change
Report saved to: $report_file
EOF
echo "Compliance report generated: $report_file"
}
# Execute compliance check
check_banner_compliance
Policy Banner Removal and Management
Safe Banner Removal
#!/bin/bash
# Safe policy banner removal with backup
# Usage: ./remove_policy_banner.sh
remove_policy_banner() {
local banner_file="/Library/Security/PolicyBanner.txt"
local backup_dir="/var/backups/macfleet"
local timestamp=$(date '+%Y%m%d_%H%M%S')
local log_file="/var/log/macfleet_banner_removal.log"
# Check if running as root
if [ "$EUID" -ne 0 ]; then
echo "Error: This script must be run as root"
exit 1
fi
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Starting policy banner removal" >> "$log_file"
# Check if banner exists
if [ ! -f "$banner_file" ]; then
echo "No policy banner found to remove."
echo "[$(date '+%Y-%m-%d %H:%M:%S')] No policy banner found" >> "$log_file"
return 0
fi
# Create backup directory
mkdir -p "$backup_dir"
# Backup current banner
cp "$banner_file" "$backup_dir/PolicyBanner_backup_$timestamp.txt"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Banner backed up to $backup_dir/PolicyBanner_backup_$timestamp.txt" >> "$log_file"
# Remove banner file
rm -f "$banner_file"
# Verify removal
if [ ! -f "$banner_file" ]; then
echo "Policy banner removed successfully."
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Policy banner removed successfully" >> "$log_file"
# Update preboot volume
if diskutil apfs updatePreboot / 2>/dev/null; then
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Preboot volume updated" >> "$log_file"
echo "Preboot volume updated."
else
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Warning: Failed to update preboot volume" >> "$log_file"
echo "Warning: Could not update preboot volume."
fi
else
echo "Error: Failed to remove policy banner."
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Error: Failed to remove policy banner" >> "$log_file"
return 1
fi
}
# Execute removal
remove_policy_banner
Banner Management Dashboard
#!/bin/bash
# Interactive policy banner management dashboard
# Usage: ./banner_dashboard.sh
banner_management_dashboard() {
local banner_file="/Library/Security/PolicyBanner.txt"
while true; do
clear
echo "=================================="
echo "MacFleet Policy Banner Management"
echo "=================================="
echo ""
# Display current status
if [ -f "$banner_file" ]; then
echo "Status: Policy banner is ACTIVE"
echo "Size: $(stat -f%z "$banner_file") bytes"
echo "Modified: $(stat -f%Sm "$banner_file")"
echo "Permissions: $(stat -f%p "$banner_file")"
else
echo "Status: No policy banner deployed"
fi
echo ""
echo "Available Actions:"
echo "1. View current banner"
echo "2. Create new banner"
echo "3. Edit existing banner"
echo "4. Remove banner"
echo "5. Check compliance"
echo "6. Export banner"
echo "7. Import banner"
echo "8. View logs"
echo "9. Exit"
echo ""
read -p "Select an option (1-9): " choice
case $choice in
1)
view_current_banner
;;
2)
create_new_banner
;;
3)
edit_existing_banner
;;
4)
remove_banner
;;
5)
check_compliance
;;
6)
export_banner
;;
7)
import_banner
;;
8)
view_logs
;;
9)
echo "Exiting banner management dashboard."
exit 0
;;
*)
echo "Invalid option. Please try again."
;;
esac
echo ""
read -p "Press Enter to continue..."
done
}
view_current_banner() {
echo "=================================="
echo "Current Policy Banner Content"
echo "=================================="
if [ -f "$banner_file" ]; then
cat "$banner_file"
else
echo "No policy banner is currently deployed."
fi
}
create_new_banner() {
echo "=================================="
echo "Create New Policy Banner"
echo "=================================="
echo "Enter your policy banner text (end with Ctrl+D):"
cat > "$banner_file"
# Set proper permissions
chmod 644 "$banner_file"
chown root:wheel "$banner_file"
# Update preboot volume
diskutil apfs updatePreboot / 2>/dev/null
echo "New policy banner created successfully."
}
edit_existing_banner() {
echo "=================================="
echo "Edit Existing Policy Banner"
echo "=================================="
if [ ! -f "$banner_file" ]; then
echo "No existing banner found. Create a new one first."
return
fi
# Create backup
cp "$banner_file" "$banner_file.backup"
echo "Current banner content:"
cat "$banner_file"
echo ""
echo "Enter new banner text (end with Ctrl+D):"
cat > "$banner_file"
# Set proper permissions
chmod 644 "$banner_file"
chown root:wheel "$banner_file"
# Update preboot volume
diskutil apfs updatePreboot / 2>/dev/null
echo "Policy banner updated successfully."
}
remove_banner() {
echo "=================================="
echo "Remove Policy Banner"
echo "=================================="
if [ ! -f "$banner_file" ]; then
echo "No policy banner found to remove."
return
fi
read -p "Are you sure you want to remove the policy banner? (y/N): " confirm
if [ "$confirm" = "y" ] || [ "$confirm" = "Y" ]; then
# Create backup
cp "$banner_file" "/tmp/PolicyBanner_removed_$(date +%Y%m%d_%H%M%S).txt"
# Remove banner
rm -f "$banner_file"
# Update preboot volume
diskutil apfs updatePreboot / 2>/dev/null
echo "Policy banner removed successfully."
else
echo "Operation cancelled."
fi
}
check_compliance() {
echo "=================================="
echo "Policy Banner Compliance Check"
echo "=================================="
# Run compliance check (reuse function from earlier)
check_banner_compliance
}
export_banner() {
echo "=================================="
echo "Export Policy Banner"
echo "=================================="
if [ ! -f "$banner_file" ]; then
echo "No policy banner found to export."
return
fi
local export_file="/tmp/PolicyBanner_export_$(date +%Y%m%d_%H%M%S).txt"
cp "$banner_file" "$export_file"
echo "Policy banner exported to: $export_file"
}
import_banner() {
echo "=================================="
echo "Import Policy Banner"
echo "=================================="
read -p "Enter the full path to the banner file to import: " import_file
if [ ! -f "$import_file" ]; then
echo "Error: File not found: $import_file"
return
fi
# Copy imported file
cp "$import_file" "$banner_file"
# Set proper permissions
chmod 644 "$banner_file"
chown root:wheel "$banner_file"
# Update preboot volume
diskutil apfs updatePreboot / 2>/dev/null
echo "Policy banner imported successfully."
}
view_logs() {
echo "=================================="
echo "Policy Banner Logs"
echo "=================================="
local log_files=(
"/var/log/macfleet_policy_banner.log"
"/var/log/macfleet_banner_deployment.log"
"/var/log/macfleet_banner_compliance.log"
"/var/log/macfleet_banner_removal.log"
)
for log_file in "${log_files[@]}"; do
if [ -f "$log_file" ]; then
echo "--- $log_file ---"
tail -10 "$log_file"
echo ""
fi
done
}
# Check if running as root
if [ "$EUID" -ne 0 ]; then
echo "Error: This script must be run as root"
exit 1
fi
# Start dashboard
banner_management_dashboard
Troubleshooting and Best Practices
Common Issues and Solutions
1. Banner Not Appearing
# Check file permissions
ls -la /Library/Security/PolicyBanner.txt
# Fix permissions if needed
sudo chmod 644 /Library/Security/PolicyBanner.txt
sudo chown root:wheel /Library/Security/PolicyBanner.txt
# Update preboot volume
sudo diskutil apfs updatePreboot /
2. FileVault Compatibility
# For FileVault-enabled devices, ensure preboot volume is updated
sudo diskutil apfs updatePreboot /
# Check FileVault status
sudo fdesetup status
3. Banner Content Issues
# Check file encoding
file /Library/Security/PolicyBanner.txt
# Ensure proper line endings
dos2unix /Library/Security/PolicyBanner.txt
Best Practices for Policy Banner Management
- Regular Updates: Review and update policy banners regularly to reflect current policies
- Compliance Documentation: Maintain records of banner deployments for audit purposes
- User Training: Ensure users understand the importance of policy acknowledgment
- Monitoring: Implement monitoring to ensure banners remain deployed across all devices
- Backup Management: Maintain backups of all policy banner configurations
- Testing: Test banner deployments in a controlled environment before enterprise rollout
Security Considerations
- File Integrity: Monitor banner files for unauthorized modifications
- Access Control: Restrict banner management to authorized administrators only
- Audit Trail: Maintain logs of all banner management activities
- Encryption: Consider encrypting banner content for sensitive environments
Conclusion
Policy banners are essential tools for organizational compliance and security awareness. This comprehensive guide provides enterprise-grade solutions for deploying, managing, and monitoring policy banners across Mac fleets. The scripts and procedures outlined ensure consistent policy communication while maintaining security and compliance standards.
Remember to test all scripts in a controlled environment before deploying to production systems, and always maintain proper backups of your policy configurations. Regular monitoring and updates ensure that your policy banners remain effective and compliant with organizational requirements.