Posted on 03-10-2017 07:24 AM
So, odd use case I know, but here's my dilemma:
Our privileged wifi is allowed via certificates that are installed via configuration profile, and they authenticate based on the machine being bound to AD. Sometimes, our users take their laptops offsite for periods of time, during which their AD password changes. The next time the machine touches our network, it breaks the privileged wifi and puts the laptop on our general network.
The solution has been to delete the wifi profile, delete the keychain entry that our general wifi installs in the login keychain, and then reinstall the wifi profile.
I'd love to come up with a solution that a user can do from Self Service, but the issue becomes: how do i get the wifi certificate back on the machine if it doesn't have internet?
Would it be possible to use Composer to create a package that "installed" the wifi profile, cache it, and then create the Self Service profile that uninstalls the current profile, deletes the single keychain entry, and then install the cached "package" which will reinstall the profile?
Solved! Go to Solution.
Posted on 03-13-2017 09:38 AM
We have a mix of Config Profiles that are deployed directly from Jamf Pro over Apple's MDM framework, and some that are deployed and installed locally with a package or script, bypassing APNs.
What I found, like others posted here, is that there are some reliability issues with Profiles randomly getting removed or vanishing from machines and then being redeployed again when done over APNs. Where the issue comes in is if using an important profile, like one that adds an 802.1x Wi-FI profile, or, in our case, that adds an important Intermediate SSL Decryption Authority certificate, this creates big problems for us. We can't have those profiles disappearing from our Macs for no apparent reason or it creates problems for the end users, so for the most important ones, we deploy them with a script or a package/script combo. They tend to stick around much more reliably when done this way.
I wanted to just add though, that I found its pretty easy to deploy the Profile entirely in a script and bypass a package altogether. Here are the steps you can take to do this.
security cms -D -i /path/to/profilename.mobileconfig | xmllint --format -
#!/bin/bash
## Create the .mobileconfig file in /private/tmp/
cat << EOF > /private/tmp/profile.mobileconfig
*<paste the entire xml code for the configuration profile from step 3 and 4 here, unaltered>*
EOF
## Install the .mobileconfig with the profiles command
/usr/bin/profiles -I -F /private/tmp/profile.mobileconfig
if [ $? == 0 ]; then
echo "Successfully installed. Deleting local file..."
rm -f /private/tmp/profile.mobileconfig
exit 0
else
echo "Installation of profile failed. Deleting local file..."
rm -f /private/tmp/profile.mobileconfig
exit 1
fi
In this way, the profile can be contained in the script and deployed and installed without needing to create a separate package for it, which can sometimes work better. I've been using the above process for deploying some of our profiles and its working well.
Be sure also to create an Extension Attribute that captures the installed profile names or identifiers, so you can build Smart Groups for machines that should get it or not. This may be necessary even if just pushing the profile in a regular package install.
Posted on 03-10-2017 07:54 AM
Not exactly what you're asking, but you can package a .mobileconfig file (create file, then store it in a temp place like /private/var/profiles and create a package with just the .mobileconfig file in it).
Then use apple's profile command to install it (/usr/bin/profiles -I -F /private/var/profiles/wifi.mobileconfig). Then run a script to trash the /private/var/profiles/wifi.mobileconfig file.
That is how we install our wifi config profile at image time. I didn't want the JSS involved with pushing it because we have such weird random profile issues when pushing through jss.
We use 802.1x - but ours is machine auth so we don't have issues when users change password.
Edit: You might not want to create the .mobileconfig file in the JSS (like I did initially). if you do, you'll get a lot of errors of JSS trying to remove the profile and failing to be able to since the JSS doesn't install it. It was just more clutter in my db.
Posted on 03-13-2017 06:10 AM
Similar to what @CasperSally does,
We package up our wireless profile (including the cert for the network), install it into the Jamf folder inside a Wireless Profiles folder (owned by root) and then run the command to install it for all users.
We also don't like having the JSS control the Wifi profile since we have had problems in the past with it randomly removing it. So keeping it local is great. We also have posted this policy in self service so that if a tech assistant sees a problem with wifi, they can just plug into ethernet and run the add wireless policy, which makes it so convenient.
profiles -I -F /Library/Application Support/JAMF/Wireless Profiles/YourProfileHere.mobileconfig
I have this set as ongoing, and to run during enrollment complete for each computer. I also have various profiles for the different buildings/vlans
Gabe Shackney
Princeton Public Schools
Posted on 03-13-2017 09:38 AM
We have a mix of Config Profiles that are deployed directly from Jamf Pro over Apple's MDM framework, and some that are deployed and installed locally with a package or script, bypassing APNs.
What I found, like others posted here, is that there are some reliability issues with Profiles randomly getting removed or vanishing from machines and then being redeployed again when done over APNs. Where the issue comes in is if using an important profile, like one that adds an 802.1x Wi-FI profile, or, in our case, that adds an important Intermediate SSL Decryption Authority certificate, this creates big problems for us. We can't have those profiles disappearing from our Macs for no apparent reason or it creates problems for the end users, so for the most important ones, we deploy them with a script or a package/script combo. They tend to stick around much more reliably when done this way.
I wanted to just add though, that I found its pretty easy to deploy the Profile entirely in a script and bypass a package altogether. Here are the steps you can take to do this.
security cms -D -i /path/to/profilename.mobileconfig | xmllint --format -
#!/bin/bash
## Create the .mobileconfig file in /private/tmp/
cat << EOF > /private/tmp/profile.mobileconfig
*<paste the entire xml code for the configuration profile from step 3 and 4 here, unaltered>*
EOF
## Install the .mobileconfig with the profiles command
/usr/bin/profiles -I -F /private/tmp/profile.mobileconfig
if [ $? == 0 ]; then
echo "Successfully installed. Deleting local file..."
rm -f /private/tmp/profile.mobileconfig
exit 0
else
echo "Installation of profile failed. Deleting local file..."
rm -f /private/tmp/profile.mobileconfig
exit 1
fi
In this way, the profile can be contained in the script and deployed and installed without needing to create a separate package for it, which can sometimes work better. I've been using the above process for deploying some of our profiles and its working well.
Be sure also to create an Extension Attribute that captures the installed profile names or identifiers, so you can build Smart Groups for machines that should get it or not. This may be necessary even if just pushing the profile in a regular package install.
Posted on 03-14-2017 08:36 AM
@mm2270 This works really well! Not only does it solve my issue of needing to reinstall it should it become corrupted, but we can also use this script to install the profile to new computers and not disrupt the existing profile on currently deployed machines (something we were having an issue with when using it as a configuration profile)!
Posted on 03-14-2017 09:23 AM
@duffcalifornia Glad that helped out!
If you're interested, I also have a script that can use the JSS API to download any Configuration Profile that's in your JSS, directly from it and install it to the local machine. It's designed to use script parameters to pass the API account information as well as the Configuration Profile JSS ID. It will download the profile, convert it into the proper xml format and install it to the machine using the profiles
command. So it even bypasses the need to put the config profile data into the script. Its more flexible also since it can be used for any Configuration Profile simply by changing the parameter for the profile's ID you pass to the script at run time.
Posted on 03-14-2017 09:54 AM
@mm2270 How do you recommend creating an extension attribute? I am not very familiar with creating these from scratch. Our deployment of config profiles through the JSS has always been really unreliable and I am looking to deploy these through another method. Also, do you know how to remove these script-installed profiles? Do I need to copy the package to the machine to be able to remove it from the "profiles -R -p UUID (of the file in question)"?
Love the script! Thanks!
Posted on 03-14-2017 10:10 AM
Hi @monosodium Here are two Extension Attribute scripts. These aren't exactly what we use, but they're close and produce the same results either way
First one gathers just the installed Configuration Profile identifiers, which sometimes are not human readable because of how the JSS inserts a random UUID string into each one.
#!/bin/sh
installedProfiles=$(profiles -C | awk -F'profileIdentifier: ' '/attribute/{print $NF}')
echo "<result>$installedProfiles</result>"
This one gets the proper names for the profiles, which would be the display name you've given them when you created them in your JSS
#!/bin/sh
installedProfiles=$(profiles -Cv | awk -F'attribute: name: ' '/attribute: name:/{print $NF}')
echo "<result>$installedProfiles</result>"
Both of these could be fleshed out a bit more with some error checking, like making sure the variable contains some information before echoing it or something, but these should get you started at least. See how they work for you.
Posted on 04-20-2017 08:52 AM
@mm2270 , I would love to take a look at the script that you are using to pull down the Configuration Profiles directly from the JSS. Would you be willing to share that?
Thanks in advance,
Jim
Posted on 04-20-2017 09:10 AM
Posted on 04-20-2017 12:19 PM
Nice set of scripts!!
Posted on 04-20-2017 06:02 PM
i have a question.
I have a mobileconfig that will request a cert from Microsoft CA by using /usr/bin/profiles method.
Everytime the script runs, it will create a new cert based on machine name. Is there a way to replace or delete the existing cert? this is mainly for certificate renewal or if i need to modify the config and re-deploy new cert.
thanks
Posted on 05-25-2017 03:35 PM
@khey I have a script that will remove all of the machine certificates. You can run this before the renewal process.
compname=dsconfigad -show | grep "Computer Account" | awk '{print $4}' | sed 's/.$//'
Certs="$compname.your.domain.here"
hashes=$(security find-certificate -c "$Certs" -a -Z|grep SHA-1|awk '{ print $NF }')
for hash in $hashes; do
echo deleting duplicate certs $hash
sudo security delete-certificate -Z $hash
done
Do you guys find that when you install profiles created from the JSS, but installed using profiles -I -F, you get a ton of messages in the JSS saying "Cannot remove profile 'AOFJ19284-9303-4CC5-9329-BB6314EAFF9' because it was not installed by the MDM server <MDMClientError:96>" ?
Posted on 07-07-2017 11:18 AM
@mm2270
I'm using your Install-configuration-profile script. Everything works great.
Just noticed an echo in the script "Single ID was passed. Running in single mode"
Does this mean I can run multiple ID's at one time? If so, how is this accomplished?
Really appreciate your script. Saved some major headaches.
Posted on 07-07-2017 12:59 PM
@jnice22 Yes, it does mean you can pass multiple Config Profile IDs at once and it will attempt to download and install all of them one at a time. You do this by simply passing multiple IDs with spaces between them. Since the IDs are simple integers, there's no need to quote them. It uses the space between each id to separate them out and loop over the entire list and run the download and install function for each one.
Note however, that if you pass a value to the rename flag to have the profiles renamed with a human readable name from the description in your JSS, it will do that for all of the ones passed to the script. You can't have it rename some profiles but not all of them.
Hope that helps.
Posted on 08-13-2017 07:14 PM
@bbot Thanks!
Posted on 08-13-2017 08:55 PM
Hoping to get some help here on a renewal process for certificates
We use computer auth 802.1x for our wifi.
Our config profile is currently set to deploy via a script that utilizes /usr/bin/profiles through Self Service. (works perfectly)
However, if we push the same exact script through Jamf, it'll request and generate a new machine certificate, but won't create the proper keychain entry in the login keychain... instead, the com.apple..network.eap.system.identity.wlan.ssid.SSID is created in the system keychain.
When ran through self service, com.apple.network.eap.user.identity.wlan.ssid.SSID is created in the login keychain. (this works.. note the USER in the keychain entry.
Just to add more info. The installation of the config profile is working, but I'm seeing two different behavior when running the script as the user through Self Service, and pushing the script through a policy at recurring check-in.
Posted on 01-30-2018 11:30 AM
Hey @mm2270 - When installing config profiles manually, how do you set up the profile in the JSS to a) Not offer the profile in self service and b) not try to remove it if that computer is not in scope. If I set it to install automatically and the computer is not in the scope, it will error out saying that it cannot remove the config profile. If I add all the computers to the scope it will try to push the config out to all of them.
Also, why do you suggest to un-sign the config profile? I thought that was to solve my issue above, but the unsigned profile that I have now installed still wants to still be removed from the JSS.
Posted on 01-30-2018 01:12 PM
@danshaw We had a similar issue. I found that if you modify the PayloadUUID in the script of the CP before you deploy it, it won't match the UUID that the JSS generated, thus avoiding the "Remove Configuration Profile" MDM failures in the JSS.
Here is what it looks like in the CP in your script:
<key>PayloadUUID</key>
<string>4B79E550-DEFB-4DAF-BECB-C62BE15A0966</string>
You can use a terminal command called uuidgen
and it'll poop out a new UUID everytime you run the command. Replace the UUID payloads in your CP and save and redeploy it. You'll have to remove the previous one because this new one won't replace the old one since the UUID's are different. Hope this helps. Thanks!
Posted on 01-30-2018 01:18 PM
Thanks @ssrussell ! I'll give this a shot. Did you also un-sign your CP's like talked about above. Curious to know if this is needed or not.
Posted on 01-30-2018 01:22 PM
@danshaw I'm not sure how to unsign a CP, but when I change the UUID and deploy it via the @mm2270 method it shows up as unsigned in SysPrefs > Profiles. I removed the Profiles Pane for all the student account in my school district and allow teachers/staff to remove the CP if they want. I know there is a bit you can flip in the CP to not allow removal, not sure if that works if it isn't signed or delivered from an MDM. I'll let someone else answer that who might be more familiar with that if that was your concern.
Posted on 01-30-2018 01:28 PM
@ssrussell is correct. If you change the unique identifier the Jamf Pro server won't see it as the same profile and won't try to remove it. Somehow I left that out of the older instructions above, but it's what I tend to do. Plus, you can use something identifiable and readable, like com.organization.profilename.setting
instead of a long uid string that doesn't mean anything to anyone but a computer. Can't tell you how many times I've run sudo profiles -P
on a machine, only to realize I can't tell which profile is which unless I throw in the -v
flag to give me verbose output and slog through the info to figure out what they actually are.
FWIW, in my script on github that pulls down the profiles and installs them, there is a flag to rename the UUID to something identifiable by using an organization substring and the display name of the profile with spaces replaced by dashes. If you use that, it prevents the JSS from trying to remove it. I should probably add something to the script that generates a new UUID using uuidgen and plugs that in place of the original, if the rename flag isn't set at run time.
Posted on 11-08-2018 01:14 PM
@ssrussell When I run your script, everything appears to work and I get an output. However, the output is empty. Looking at the logs I see this...
Stage 4: Scanning all policy scope details and creating report...
warning: failed to load external entity "/Users/xxx/Library/Application Support/_JSS_REPORT/_POLICY_DATA/.xml"
warning: failed to load external entity "/Users/xxx/Library/Application Support/_JSS_REPORT/_POLICY_DATA/.xml"
warning: failed to load external entity "/Users/xxx/Library/Application Support/_JSS_REPORT/_POLICY_DATA/.xml"
warning: failed to load external entity "/Users/xxx/Library/Application Support/_JSS_REPORT/_POLICY_DATA/.xml"
warning: failed to load external entity "/Users/xxx/Library/Application Support/_JSS_REPORT/_POLICY_DATA/.xml"
Any assistance?
Posted on 02-12-2020 03:32 PM
@mm2270 have been trying to get a user config profile top install via script or package. Both ways fail. My script errors and thinks I'm trying to install device profile but it's a user profile I downloaded it from my Jamf server and I did you steps listed in this thread. If you or anyone has an idea please let me know. Thank you.
Error..
Script result: profiles: verbose mode ON
profiles install profile /tmp/my.mobileconfig for user: (null)
profiles install for file:'/tmp/my.mobileconfig' and user:'root' returned 1 (An identity preference payload can only be included in a user profile.)
profiles: returned error: 1
Installation of profile failed. Deleting local file...
This only thing I'm doing different is the profiles command format.
/usr/bin/profiles install -path /private/tmp/my.mobileconfig -forced -verbose
Posted on 02-12-2020 03:41 PM
User profiles have to be installed as the current user logged in, not as root, or it assumes they are device profiles.
But to take a huge step back here, why is there a need to install profiles in this way now? Back when this thread was first spawned, it made more practical sense, but I can't say it does anymore. If you aren't installing profiles over an MDM like Jamf Pro, you're going to run into a lot of problems. Some profile payloads now can't even be installed on devices unless they specifically come from an MDM.
Posted on 02-13-2020 04:59 AM
Intersting @mm2270 , so I would need to call out the current user in the script. Okay, thank you.
The reason is that this profile delivers a user MFA cert using scep. I've been hearing of MFA certs disappearing once in a while and the user then looses all o365 access. I think the profile is disappearing once in a while if APNS is unreachable and removing the cert in the keychain as a result. I have not been able to verify this but it seems logical that the issue in this thread is happening to my users as well.
I'm open to suggestions. It's know that the networks of the affected users don't all have great APNS connectivity and no fixes will be coming anytime soon as they are migrating off old networks/vpn's.
Posted on 02-13-2020 06:32 AM
Hmm, I actually don't know with any degree of certainty if a bad or poor APNs connection would be removing profiles. I suppose it's possible, but I haven't seen anything like that happen to us in quite some time now.
But, if you're determined to go this route for now, I would suggest taking another look at the script I posted above on my GitHub page (found here), which has the necessary code to install User Level profiles as the current user. The relevant code starts on line 167. You'll see that I'm getting the logged in user and the logged in UID, and then on line 174, it installs the profile as the user. You could try to incorporate what I have there into your own script.
Unlike System Level profiles, User Level get installed to an account, not globally like System profiles.
Posted on 02-13-2020 06:41 AM
Thanks again. I don't want to go this route but support keeps getting tickets that the user loses o365 so I am hoping to have this available in self service for them. Just in case. I will be opening a ticket with Jamf support as well to discuss it. Maybe they can find the issue.
Posted on 02-10-2021 11:11 AM
delete
Posted on 02-23-2021 11:10 AM
FYI they removed the ability to install a profile with the command line profile command in osx 11.0
"profiles tool no longer supports installs. Use System Preferences Profiles to add configuration profiles."
see here:
https://www.alansiu.net/2021/01/06/semi-automating-profile-installation-in-big-sur/
so the method above wont work. I am happy that other people find the configuration wireless profile to be buggy as well. My macs are all losing their profile randomly sadly so i was looking for alternative methods to connect them up. I guess this wont be it. The open command referenced in the article does not do what i wanted.
i think we will move towards a certificate based install anyway and away from PSK. I dont supposed someone has a guide on that? well i am going to look around and research it now.