Posted on 02-04-2019 09:20 AM
Need to find out who in my company has this turned on. Don't seemed to see any search criteria for that specifically...
Any help appreciated.
Posted on 02-27-2019 10:23 AM
Anyone. I can't believe this isn't a problem. There has to be a solution.
Thanks.
Posted on 02-27-2019 10:41 AM
I just started poking around in the Finder plist file and found FXICloudDriveDesktop. I'm not sure what that is, and Google is unrevealing so far, but it is TRUE for me, so it might be worth checking into.
Posted on 02-27-2019 10:58 AM
We're using this EA to find that info. I think I grabbed this from a similar Jamf Nation post...
#!/bin/bash
# Purpose: to grab iCloud Drive Desktop and Document Sync status.
# If Drive has been setup previously then values should be: "false" or "true"
# If Drive has NOT been setup previously then values will be: "iCloud Account Enabled, Drive Not Enabled" or "iCloud Account Disabled"
#Variable to determine major OS version
OSver="$(/usr/bin/sw_vers -productVersion | /usr/bin/cut -d . -f 2)"
#Determine OS is 10.12 or greater as Doc Sync is only available on 10.12+
if [ "$OSver" -ge "12" ]; then
#Path to PlistBuddy
plistBud="/usr/libexec/PlistBuddy"
#Determine logged in user
loggedInUser=$(python -c 'from SystemConfiguration import SCDynamicStoreCopyConsoleUser; import sys; username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]; username = [username,""][username in [u"loginwindow", None, u""]]; sys.stdout.write(username + "
");')
#Determine whether user is logged into iCloud
if [[ -e "/Users/$loggedInUser/Library/Preferences/MobileMeAccounts.plist" ]]; then
iCloudStatus=$("$plistBud" -c "print :Accounts:0:LoggedIn" /Users/$loggedInUser/Library/Preferences/MobileMeAccounts.plist 2> /dev/null )
#Determine whether user has enabled Drive enabled. Value should be either "false" or "true"
if [[ "$iCloudStatus" = "true" ]]; then
DriveStatus=$("$plistBud" -c "print :Accounts:0:Services:2:Enabled" /Users/$loggedInUser/Library/Preferences/MobileMeAccounts.plist 2> /dev/null )
if [[ "$DriveStatus" = "true" ]]; then
if [[ -e "/Users/$loggedInUser/Library/Mobile Documents/com~apple~CloudDocs/Desktop" ]] && [[ -e "/Users/$loggedInUser/Library/Mobile Documents/com~apple~CloudDocs/Documents" ]] && [[ $(ls -la "/Users/$loggedInUser/Library/Mobile Documents/com~apple~CloudDocs/" | grep "->") ]]; then
DocSyncStatus="true"
else
DocSyncStatus="false"
fi
fi
if [[ "$DriveStatus" = "false" ]] || [[ -z "$DriveStatus" ]]; then
DocSyncStatus="iCloud Account Enabled, Drive Not Enabled"
fi
fi
if [[ "$iCloudStatus" = "false" ]] || [[ -z "$iCloudStatus" ]]; then
DocSyncStatus="iCloud Account Disabled"
fi
else
DocSyncStatus="iCloud Account Disabled"
fi
else
DocSyncStatus="OS Not Supported"
fi
/bin/echo "<result>$DocSyncStatus</result>"
Posted on 04-05-2019 12:50 PM
I am getting a "False" result on both machines. One with it turned on and one that does not have it turned on.
Not sure what I am doing wrong....
Posted on 08-15-2019 02:33 PM
<deleted>
Posted on 08-15-2019 03:04 PM
Hi @ktermin.
I don't know if you're still in need of a solution to your original post. However, I'm working on implementing the script posted by @mottertektura within my own environment, and I think I may have figured out at least one reason why you're seeing false negative results.
One of the conditional statements in the script requires three separate, individual checks all to be true:
/Users/<current_user>/Library/Mobile Documents/com~apple~CloudDocs/Desktop
exist?/Users/<current_user>/Library/Mobile Documents/com~apple~CloudDocs/Documents
exist?->
within the /Users/<current_user>/Library/Mobile Documents/com~apple~CloudDocs/
directory?If all three of these checks are true, then the result of the script is "True". However, if any of these three checks returns as false, then the result of the script is "False". I got a false negative ("False") result on a machine where iCloud Desktop & Documents was clearly enabled. Here's the problem as I understand it:
On my test machine I logged into my own personal iCloud account and enabled iCloud Desktop & Documents. Now, I don't normally use this feature because reasons. That being the case, there was no already-existing Desktop or Documents folder within my iCloud Drive. So, when I logged into my iCloud account, the symbolic links pointing to the local user's Desktop and Documents folders didn't exist and had to be created. The Documents symlink seemed to create itself just fine, but none existed for the Desktop folder. Thus, when I ran the policy pointing to this script (I modified it to be able to run as a policy and write the result into a text field style EA via an API call), I got a "False" result. I then randomly created an empty folder on the Desktop on the test machine in the process of doing something else. Later, when I ran the policy again, I got a "True" result. I went back and looked in the /Users/<current_user>/Library/Mobile Documents/com~apple~CloudDocs/
directory, and now there was a symlink pointing to the local Desktop folder. So, at that point, all three criteria for the check were true, so I got a positive result.
It seems to me that the three-way check is pretty fragile. I'm not 100% sold that all three need to be true, and I'm frankly kind of baffled by the need for the third one, as it's really only checking whether there exists any symlink at the top level of the /Users/<current_user>/Library/Mobile Documents/com~apple~CloudDocs/
directory, regardless of whether it's either of the ones we're interested in (Desktop or Documents). I just haven't yet been able to wrap my head around the need for that particular check, though I'm sure there was a reason that was clear to the original author.
I'm currently researching whether there's a more robust and reliable method to determine if iCloud Desktop & Documents is enabled. If I find one and get the modified script working, I'll post it back here.
Posted on 08-16-2019 02:37 PM
I figured it out.
In /Users/<current_user>/Library/Preferences/com.apple.finder.plist
, there are a few key/value pairs that safely identify whether iCloud Desktop & Documents is enabled. We only need to check one of them.
In the original script we have this conditional check:
if [[ -e "/Users/$loggedInUser/Library/Mobile Documents/com~apple~CloudDocs/Desktop" ]] && [[ -e "/Users/$loggedInUser/Library/Mobile Documents/com~apple~CloudDocs/Documents" ]] && [[ $(ls -la "/Users/$loggedInUser/Library/Mobile Documents/com~apple~CloudDocs/" | grep "->") ]]; then
DocSyncStatus="true"
else
DocSyncStatus="false"
fi
This is not a reliable check, because it requires all three of those conditions to be true, and in testing I've found that if there is nothing on the Desktop when iCloud Desktop & Documents gets turned on, the [[ -e "/Users/$loggedInUser/Library/Mobile Documents/com~apple~CloudDocs/Desktop" ]]
part of that three-way conditional check will fail, thus giving a false negative result. The symlink to the Desktop only gets created once any item is added to the Desktop. Now, I understand that it's probably pretty safe to assume users will have things on their Desktops, so the symlink will be there. I'm just not that comfortable using code which relies on people behaving in a certain way; I don't want to risk missing someone who keeps a pristine Desktop, only to be siphoning company data out via their Documents folder.
In place of that, I'm now doing two things. First, I define a variable to contain the results of checking the status of iCloud Desktop & Docs:
iCloudDesktop=$(defaults read /Users/$loggedInUser/Library/Preferences/com.apple.finder.plist FXICloudDriveDesktop)
And then, the actual conditional check becomes much simpler:
if [[ "$iCloudDesktop" = "1" ]]; then
DocSyncStatus="Enabled"
else
DocSyncStatus="Not Enabled"
fi
Since I'm doing a simple check inside that plist file, I saw no need to use PlistBuddy and instead chose to use a simple defaults read command to get the value of the key I'm interested in. There are two keys we could use:
FXICloudDriveDesktop
FXICloudDriveDocuments
I chose the first one, just because. In fact, the more I look at that com.apple.finder.plist
file, the more I think this whole script could be somewhat simplified, since there also are these two keys:
FXICloudDriveEnabled
FXICloudDriveLoggedIn
Hmmm... I'll have to think on that some more.
At any rate, here's the working script with my changes:
#!/bin/bash
# Purpose: to grab iCloud Drive Desktop and Document Sync status.
# If Drive has been setup previously then values should be: "Enabled" or "Not Enabled"
# If Drive has NOT been set up previously then values will be: "iCloud Account Enabled, Drive Not Enabled" or "iCloud Account Disabled"
#Variable to determine major OS version
OSver="$(/usr/bin/sw_vers -productVersion | /usr/bin/cut -d . -f 2)"
#Determine OS is 10.12 or greater as Doc Sync is only available on 10.12+
if [ "$OSver" -ge "12" ]; then
#Path to PlistBuddy
plistBud="/usr/libexec/PlistBuddy"
#Determine logged in user
loggedInUser=$(python -c 'from SystemConfiguration import SCDynamicStoreCopyConsoleUser; import sys; username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]; username = [username,""][username in [u"loginwindow", None, u""]]; sys.stdout.write(username + "
");')
#Variable to determine status of iCloud Drive Desktop & Documents setting
iCloudDesktop=$(defaults read /Users/$loggedInUser/Library/Preferences/com.apple.finder.plist FXICloudDriveDesktop)
#Determine whether user is logged into iCloud
if [[ -e "/Users/$loggedInUser/Library/Preferences/MobileMeAccounts.plist" ]]; then
iCloudStatus=$("$plistBud" -c "print :Accounts:0:LoggedIn" /Users/$loggedInUser/Library/Preferences/MobileMeAccounts.plist 2> /dev/null )
#Determine whether user has iCloud Drive enabled. Value should be either "False" or "True"
if [[ "$iCloudStatus" = "true" ]]; then
DriveStatus=$("$plistBud" -c "print :Accounts:0:Services:2:Enabled" /Users/$loggedInUser/Library/Preferences/MobileMeAccounts.plist 2> /dev/null )
if [[ "$DriveStatus" = "true" ]]; then
if [[ "$iCloudDesktop" = "1" ]]; then
DocSyncStatus="Enabled"
else
DocSyncStatus="Not Enabled"
fi
fi
if [[ "$DriveStatus" = "false" ]] || [[ -z "$DriveStatus" ]]; then
DocSyncStatus="iCloud Account Enabled, Drive Not Enabled"
fi
fi
if [[ "$iCloudStatus" = "false" ]] || [[ -z "$iCloudStatus" ]]; then
DocSyncStatus="iCloud Account Disabled"
fi
else
DocSyncStatus="iCloud Account Disabled"
fi
else
DocSyncStatus="OS Not Supported"
fi
#Update the iCloud Desktop & Documents Status extension attribute with discovered value of $DocSyncStatus
/usr/bin/curl -H "Content-Type: application/xml" -sfku $4:$5 https://jamf-pro.server.address:8443/JSSResource/computers/name/$2 -d
"<computer><extension_attributes><extension_attribute><id>$6</id><value>$DocSyncStatus</value></extension_attribute></extension_attributes></computer>" -X PUT
Remember that I mentioned I modified the script so that it can run as a policy payload which writes its result back to a Text Field style Extension Attribute. Since this identifies a potentially pretty big security risk, I didn't want to wait as long as computers checking in with recon results usually takes. There are times I like to get EA data much more quickly, so I implement them this way.
Anyway, I hope this helps someone.
Posted on 12-06-2021 03:42 PM
Is there anything that needs to be done to make this now work in Big Sur and Monterey? We know for a fact one of our lab machines has iCloud signed in and Desktop and Document syncing on but it shows OS is not supported. We tried tweaking this and figured some stuff out but now all we get is "iCloud Account Enabled, Drive Not Enabled"
Posted on 10-09-2019 02:14 PM
@andy.granger is this script still working for you? I tried using it the other day but haven't had success getting any results.
Posted on 10-21-2019 10:29 AM
Hi @daniel_ross,
Yes, it's working fine for me.
Have you deployed the script as a policy payload? What is your policy trigger? Have you configured a String/Text Field style EA to receive the script result? Have you set up a user in Jamf Pro that only has access to make API calls, and are you using its credentials?
Attached are some screenshots showing how I have my script/policy/EA combination set up. The Extension Attribute ID script parameter field in the 1st screenshot needs to contain the ID number of the EA that is shown in the 3rd screenshot.
Lastly, I'm sure I don't have to mention this but I will for the sake of completeness: make sure to enter your own JSS URL and port number in the API call at the end of the script. I sanitized the script for my own privacy before posting it to JamfNation.
https://jamf-pro.server.address:8443
Posted on 12-06-2021 04:56 PM
Can this be used without the API connection?
Posted on 03-24-2022 05:11 PM
Yes, and you should plan to do this when Jamf deprecates the use of Basic Auth in Summer 2022. You'll have to generate a "Token" to call the API, and these will only be good for 30 minutes. They also require you to authenticate with user/pass to generate said API token, which makes them wholly unsuitable for use in Extension Attributes.
Your non-daily policy script should write a reverse extension attribute that leaves a text file in a special folder that users can't access.
Many orgs will use locations like /var/acmeinc, or /etc/pretendco.
These folders are good candidates for four reasons:
*while /var/tmp is not wiped on reboot, /tmp is definitely wiped every startup. Don't store important things there.
Your secret folder should be owned by root/wheel, and the permission should be 500 (r-x --- ---), or 755 (rwx r-x r-x) if you don't mind other users casually exploring their contents.
Permissions for files in this secret folder should be 400 (r-- --- ---), owned by root/wheel, or 644 (rw- r-- r--) if you don't care about perusal by others.
Jamf, the root user, and system extensions will always be able to read these files.
The data in such files needs to be read by your daily Extension Attributes. If you're super paranoid, encrypt the local data with a known hash that only your team knows, and decrypt in the EA at runtime. This is potentially risky, as it can leave you with a lot of useless EA data if the hash source is forgotten.
Posted on 02-27-2020 09:33 AM
Hey all, just wanted to share something I came up with for our environment. It's a modification of what @iJake came up with on this thread:
https://www.jamf.com/jamf-nation/discussions/21993/find-computers-using-icloud-drive
And the above script posted by @mottertektura
#!/bin/sh
iCloudDrivePath="/Library/Mobile Documents/com~apple~CloudDocs"
# It was discovered that Catalina at one point moved the iCloud drive folder
# On macs upgraded to 10.15 the folder is still 'Mobile Documents'.
# If discovered that some 10.15 macs have it moved to CloudStorage
# Then uncomment out the lines below.
# OSver="$(/usr/bin/sw_vers -productVersion | /usr/bin/cut -d . -f 2)"
# if [ "$OSver" -ge "15" ]; then
# iCloudDrivePath="/Library/CloudStorage/iCloud Drive";
# else iCloudDrivePath="/Library/Mobile Documents/com~apple~CloudDocs" echo 'not cat';
# fi
# Get the logged in user and their home folder
grabConsoleUserAndHome()
{
currentUser=$(stat -f %Su "/dev/console")
homeFolder=$(dscl . read "/Users/$currentUser" NFSHomeDirectory | cut -d: -f 2 | sed 's/^ *//'| tr -d '
')
case "$homeFolder" in
* * )
homeFolder=$(printf %q "$homeFolder")
;;
*)
;;
esac
}
grabConsoleUserAndHome
if [[ "$currentUser" == "root" ]]
then
exit
fi
# Checks if the drive path and file exists
if [[ -e "$homeFolder""$iCloudDrivePath" ]]
then
# Checks status of iCloud Drive Desktop and Documents setting
iCloudDesktop=$(defaults read /Users/$currentUser/Library/Preferences/com.apple.finder.plist FXICloudDriveDesktop)
if [[ "$iCloudDesktop" = 1 ]];
then
echo 'iCloud Desktop Enabled';
echo "<result>true</result>"
else
echo 'Drive enabled, Desktop Disabled';
echo "<result>false</result>"
fi;
else
echo "User does not have iCloud Drive setup"
echo "<result>false</result>"
fi
exit 0
Although mottertektura's script works great as is, and so does iJake's, I wanted to have a simple version that did both.
Additionally, I would like to add the ability to check if the signed-in iCloud account is from our domain or a personal, but I haven't gotten that far yet; this is good enough for now.
Also, If someone could confirm or deny the commented out line about the iCloud Drive folder location on Catalina, that would be much appreciated. It's in the "/Library/Mobile Documents/com~apple~CloudDocs" for me (10.15.3), but I've seen it in "/Library/CloudStorage/iCloud Drive" on a few 10.15 machines in the past. Just need clarification.
Posted on 10-08-2021 11:32 AM
I set this up and my computer shows 0 as the output. Any idea why that would be?
Posted on 12-06-2021 11:43 AM
Ditto here except ours is blank?
Posted on 07-08-2020 06:01 AM
@andy.granger sorry but how can I see the result of your script ?
Posted on 08-08-2020 12:33 PM
Hi @Mkh.
The results of the script get written to a "text field" type computer Extension Attribute, so you have to make sure you've created such an EA to receive the script results. If you have everything set up correctly, then you can view the results within any individual computer record, in the section where you set up your EA to be displayed. What's great is that you can then set up a Smart Computer Group which will always give you a running list of machines that have the value of the EA you've set for its criteria.
Please let me know if you need further clarification.
Posted on 11-30-2022 05:18 AM
I had an issue with com.apple.finder.plist where FXICloudDriveDesktop wasn't 1 when Documents and Desktop sync was active. I enabled it to fast after turning on iCloud Drive and something broke. I tried to turn it on and off without help. Reboot didn't do anything either. Turning off iCloud Drive fixed the problem.
This means that FXICloudDriveDesktop may not be 100% reliable.
The problem was on a 2020 M1 MacBook Pro