Untitled

mail@pastecode.io avatar
unknown
sh
a year ago
8.5 kB
4
Indexable
Never
#!/bin/bash
export PATH=/usr/bin:/bin:/usr/sbin:/sbin

########################################################################################################
#
# Jamf Self Service Script to check user's OneDrive folder for illegal
# characters, leading or trailing spaces and corrects them to
# allow smooth synchronization.
#
########################################################################################################

# Global variables
COMPANY="X"
JAMFBIN="/usr/local/jamf/bin/jamf"
NOTIFY="/Applications/Utilities/Notifier.app/Contents/MacOS/Notifier"
ONEDRIVE="/Applications/OneDrive.app"
LOG="/private/var/log/OneDriveFixLog.log"

USER=$( /usr/sbin/scutil <<< "show State:/Users/ConsoleUser" | /usr/bin/awk -F': ' '/[[:space:]]+Name[[:space:]]:/ { if ( $2 != "loginwindow" ) { print $2 }}' )
ONEDRIVE_FOLDER="/Users/$USER/Library/CloudStorage/OneDrive-$COMPANY"


# Logging function
# $1 = msg
logd() {
	echo "[$(date +'%m.%d.%Y %I:%M:%S')]: $1" >> "$LOG"
}


# Cleanup function, removes temp files and restarts OneDrive
finish() {

	[[ -z "$fixchars" ]] || rm -f "$fixchars" 2>> "$LOG"
	[[ -z "$fixtrail" ]] || rm -f "$fixtrail" 2>> "$LOG"
	[[ -z "$fixlead" ]] || rm -f "$fixlead" 2>> "$LOG"

	[[ $(pgrep -x "OneDrive") ]] || open -gj "$ONEDRIVE" 2>> "$LOG"

	# Headache
	logd "<\3 Coffee"
	kill "$caffeinatepid" 2>> "$LOG"

	logd "Clean up complete."

}
# Removed due to errors
# trap finish HUP INT QUIT TERM


# Filename correction functions
fix_trailing_chars() {

	local linecount counter line name path fixedname
	linecount="$(wc -l "$fixtrail" | awk '{print $1}')"
	counter="$linecount"

	while ! [ "$counter" -eq 0 ]; do

		line="$(sed -n "${counter}"p "$fixtrail")"
		name="$(basename "$line")"
		path="$(dirname "$line")"
		fixedname="$(echo "$name" | tr '.' '-' | awk '{sub(/[ \t]+$/, "")};1')"

		if [[ -f "$path"'/'"$fixedname" ]] || [[ -d "$path"'/'"$fixedname" ]]; then
			mv -vf "$line" "$path"'/'"$fixedname"'-'"$(jot -nr 1 100000 999999)" 2>> "$LOG"
		else
			mv -vf "$line" "$path"'/'"$fixedname" 2>> "$LOG"
		fi

		((counter = counter - 1))
	done
}


fix_leading_spaces() {

	local linecount counter line name path fixedname
	linecount="$(wc -l "$fixlead" | awk '{print $1}')"
	counter="$linecount"
	while ! [ "$counter" -eq 0 ]; do

		line="$(sed -n "${counter}"p "$fixlead")"
		name="$(basename "$line")"
		path="$(dirname "$line")"
		fixedname="$(echo "$name" | sed -e 's/^[ \t]*//')"

		if [[ -f "$path"'/'"$fixedname" ]] || [[ -d "$path"'/'"$fixedname" ]]; then
			mv -vf "$line" "$path"'/'"$fixedname"'-'"$(jot -nr 1 100000 999999)" 2>> "$LOG"
		else
			mv -vf "$line" "$path"'/'"$fixedname" 2>> "$LOG"
		fi

		((counter = counter - 1))
	done
}


fix_names() {

	local linecount counter line name path fixedname
	linecount="$(wc -l "$fixchars" | awk '{print $1}')"
	counter="$linecount"
	while ! [ "$counter" -eq 0 ]; do

		line="$(sed -n "${counter}"p "$fixchars")"
		name="$(basename "$line")"
		path="$(dirname "$line")"
		fixedname="$(echo "$name" | tr ':' '-' | tr '\\' '-' | tr '?' '-' | tr '*' '-' | tr '"' '-' | tr '<' '-' | tr '>' '-' | tr '|' '-')"

		if [[ -f "$path"'/'"$fixedname" ]] || [[ -d "$path"'/'"$fixedname" ]]; then
			mv -vf "$line" "$path"'/'"$fixedname"'-'"$(jot -nr 1 100000 999999)" 2>> "$LOG"
		else
			mv -vf "$line" "$path"'/'"$fixedname" 2>> "$LOG"
		fi

		((counter = counter - 1))
	done
}


main() {
	old_log_dir="/var/log/onedrive-fixlogs"

	# Init log, remove old log
	if [[ ! -f "$LOG" ]]; then
	  touch "$LOG"
	  logd "Log Init"
		if [[ -d "$old_log_dir" ]]; then
			rm -drf "$old_log_dir" 2>> "$LOG"
		fi
	else
		echo "" >> "$LOG"
	fi

	# START
	logd "STARTING RUN"

	# Caffeinate
	logd "<3 Coffee"
	/usr/bin/caffeinate -d -i -m -u &
	caffeinatepid=$!

	logd "User: $USER"
	logd "OneDrive Folder Path: $ONEDRIVE_FOLDER"

	set -o pipefail
	unset fixchars fixtrail fixlead

	$NOTIFY --type alert --messagebutton "Close" --title "OneDrive Name Fix" --message "Running checks..." 2>> "$LOG"

	# # Get the user
	# local -r loggedinuser=$( /usr/sbin/scutil <<< "show State:/Users/ConsoleUser" | /usr/bin/awk -F': ' '/[[:space:]]+Name[[:space:]]:/ { if ( $2 != "loginwindow" ) { print $2 }}' )
	# 
	# # Set OneDrive folder name (specify onedrive folder name here)
	# local -r onedrivefolder="/Users/$loggedinuser/OneDrive - $COMPANY"

	# Get date
	local -r fixdate=$(date +'%Y.%m.%d-%H.%M')

	# Check if file system is APFS
	local apfscheck
	apfscheck="$(diskutil info / | awk '/Type \(Bundle\)/ {print $3}')"

	if [[ "$apfscheck" == "apfs" ]]; then
		logd "File system is APFS, the script may continue."
	else
		logd "File system not supported, aborting."

		$JAMFBIN displayMessage -message "The file system on this Mac is not supported, please contact IT." 2>> "$LOG"

		exit 1
	fi

	# Check if OneDrive folder is present
	# Make backup using APFS clonefile, prevent the backup from being indexed by Spotlight
	if [ -d "$ONEDRIVE_FOLDER" ]; then

		$NOTIFY --type alert --messagebutton "Close" --title "OneDrive Name Fix" --message "Making a backup..." 2>> "$LOG"

		logd "OneDrive directory is present. Stopping OneDrive."

		killall "OneDrive" || true 2>> "$LOG"

		beforefix_size=$(du -sk "$ONEDRIVE_FOLDER" | awk -F '\t' '{print $1}')
		readonly beforefix_size
		beforefix_filecount=$(find "$ONEDRIVE_FOLDER" | wc -l | sed -e 's/^ *//')
		readonly beforefix_filecount

		logd "The OneDrive folder is using $beforefix_size KB and the file count is $beforefix_filecount before fixing filenames."

		rm -drf "/Users/$USER/OD-Backup-"*"-"* 2>> "$LOG"
		mkdir -p "/Users/$USER/OD-Backup-$fixdate/$fixdate.noindex" 2>> "$LOG"
		chown "$USER":staff "/Users/$USER/OD-Backup-$fixdate" 2>> "$LOG"
		chown "$USER":staff "/Users/$USER/OD-Backup-$fixdate/$fixdate.noindex" 2>> "$LOG"
		touch "/Users/$USER/OD-Backup-$fixdate/$fixdate.noindex/.metadata_never_index" 2>> "$LOG"
		cp -cpR "$ONEDRIVE_FOLDER" "/Users/$USER/OD-Backup-$fixdate/$fixdate.noindex" 2>> "$LOG"

		logd "APFS clonefile backup created at /Users/$USER/OD-Backup-$fixdate/$fixdate.noindex."

	else

		logd "OneDrive directory not present, aborting."
		$JAMFBIN displayMessage -message "Cannot find the OneDrive folder. Ask IT to help set up OneDrive, or change the name of the folder" 2>> "$LOG"
		exit 1

	fi

	$NOTIFY --type alert --messagebutton "Close" --title "OneDrive Name Fix" --message "Hang tight. Running fixes..." 2>> "$LOG"

	# Fix directory filenames
	logd "Fixing illegal characters in directory names"
	fixchars="$(mktemp)"
	readonly fixchars
	find "${ONEDRIVE_FOLDER}" -type d -name '*[\\:*?"<>|]*' -print > "$fixchars" 2>> "$LOG"
	fix_names

	logd "Fixing trailing characters in directory names"
	fixtrail="$(mktemp)"
	readonly fixtrail
	find "${ONEDRIVE_FOLDER}" -type d -name "* " -print > "$fixtrail" 2>> "$LOG"
	find "${ONEDRIVE_FOLDER}" -type d -name "*." -print >> "$fixtrail" 2>> "$LOG"
	fix_trailing_chars

	logd "Fixing leading spaces in directory names"
	fixlead="$(mktemp)"
	readonly fixlead
	find "${ONEDRIVE_FOLDER}" -type d -name " *" -print > "$fixlead" 2>> "$LOG"
	fix_leading_spaces

	# Fix all other filenames
	logd "Fixing illegal characters in filenames"

	find "${ONEDRIVE_FOLDER}" -name '*[\\:*?"<>|]*' -print > "$fixchars" 2>> "$LOG"
	fix_names

	logd "Fixing trailing characters in filenames"
	find "${ONEDRIVE_FOLDER}" -name "* " -print > "$fixtrail" 2>> "$LOG"
	find "${ONEDRIVE_FOLDER}" -name "*." -print >> "$fixtrail" 2>> "$LOG"
	fix_trailing_chars

	logd "Fixing leading spaces in filenames"
	find "${ONEDRIVE_FOLDER}" -name " *" -print > "$fixlead" 2>> "$LOG"
	fix_leading_spaces

	# Check OneDrive directory size and filecount after applying name fixes
	afterfix_size=$(du -sk "$ONEDRIVE_FOLDER" | awk -F '\t' '{print $1}')
	readonly afterfix_size
	afterfix_filecount=$(find "$ONEDRIVE_FOLDER" | wc -l | sed -e 's/^ *//')
	readonly afterfix_filecount

	logd "The OneDrive folder is using $afterfix_size KB and the file count is $afterfix_filecount after fixing filenames. Restarting OneDrive."

	if [[ "$beforefix_filecount" -eq "$afterfix_filecount" ]]; then
		rm -drf "/Users/$USER/OD-Backup-"*"-"* 2>> "$LOG"
		$JAMFBIN displayMessage -message "File names have been successfully corrected. The backup has been removed." 2>> "$LOG"
	else
		$JAMFBIN displayMessage -message "Something went wrong. A backup has been placed in OD-Backup-$fixdate in your user folder. Ask IT to help restore the backup." 2>> "$LOG"
	fi
}

# Call main
main

# Cleanup
finish

exit 0  #Success
exit 1  #Failure