Nine41 Consulting | How to Customize and Silently Deploy Cisco AnyConnect 4.x
apple, device management, dep, vpp, systems management, landesk, ivanti, lanrev, absolute, heat, mdm,
1292
post-template-default,single,single-post,postid-1292,single-format-standard,qode-quick-links-1.0,ajax_fade,page_not_loaded,,columns-3,qode-child-theme-ver-1.0.0,qode-theme-ver-11.0,qode-theme-bridge,wpb-js-composer js-comp-ver-5.1.1,vc_responsive
 

How to Customize and Silently Deploy Cisco AnyConnect 4.x

How to Customize and Silently Deploy Cisco AnyConnect 4.x

If you’re an existing 3.x consumer of Cisco AnyConnect you may be surprised when you load up the 4.x installer and find your users have a plethora of additional features; like Web Security, System Scan, Roaming Security and AMP Enabler.ciscoanyconnect-all

If these are features you’re planning on using, great, you’re all set.  If you were just hoping to leverage the VPN, well, all is not lost.  You can easily customize the installer, providing it a set of instructions indicating what modules you want installed and what modules you want blocked – and it’s all done via a simple PLIST file.

I’ve included the entire example PLIST I used to block everything but the VPN as well as the installer script for LANDESK on my GitHub site here.

Let’s discuss the PLIST first.  Here is an example of one of the dictionary objects found in the PLIST file, in this case it is for the VPN feature.

 <dict>
    <key>attributeSetting</key>
    <integer>1</integer>
    <key>choiceAttribute</key>
    <string>selected</string>
    <key>choiceIdentifier</key>
    <string>choice_vpn</string>
 </dict>

Basically we have a dictionary of values that define the module and tell the installer of whether it should be installed by setting the Integer value to 1.  If you want to block the given module, set the integer value to 0.  Look at the string value to figure out what module you’re enabling or disabling.

You shouldn’t need to adjust any of the other settings.  So go ahead and download the example PLIST file I have on my GitHub site and finish customizing it for your environment.  My PLIST file has everything disabled  outside of the VPN.  If you were to manually install the application, you’d see the window below.  manualinstallciscooptions

Now that you have your PLIST ready to go, you need to save it as ‘ChoiceChangesCiscoAnyConnect.plist’ so it can be properly referenced in our installer script.  If you save it as something else, just make sure you make the appropriate change in your installer script.

OK, we’re now ready to create the installer script.  For simplicity, I’m going to build my installer script to do both the downloading of the AnyConnect package file, the PLIST file we just created and then it’ll kick off the installer – all using SDClient so I can take advantage of the bandwidth and throttling settings.

The entire installer script is pasted below.  In your environment, you’ll likely only need to change the plistFilePath and packageFilePath variables.  The script copies everything to a folder titled CiscoAnyConnect inside of sdcache.  I  purposely chose to put everything in the sdcache folder as the script doesn’t purge anything when finished, letting the standard sdcache cleanup process take care of that at the appropriate time.

Once you have your paths set, you should be ready to go.  You’ll notice that SDClient is used, with several arguments, to download the files.  The -noinstall argument is quite obvious, it tells SDClient to just download and not do anything else.  The -package is telling SDClient where to obtain the file and the -destdir argument is telling SDClient where to copy the file to.

/Library/Application\ Support/LANDesk/bin/sdclient -noinstall -package "$packageToCopy" -destdir "$destinationLocation"

As mentioned before, the script copies down the PLIST file and the Cisco installer.  If you have a DMG version of the Cisco Installer, just mount it on a Mac and copy out the AnyConnect.pkg from the DMG.  I copied mine directly to my standard SWD file share.

Then the scripts wraps up by executing the AnyConnect.pkg installer with a few arguments as well.  We tell macOS we want it to run a pkg intsaller and point to where that file is.  In my example, it’s in the /Library/Application Support/LANDesk/sdcache/CiscoAnyConnect folder.  I leave the -target path empty, basically letting the installer put where it’s designed to.  I then add the flag -applyChoiceChangesXML so that it knows customization is to be performed and I supply the path to that name/file.

installer -pkg "$destinationLocation"/"$packageName" -target / -applyChoiceChangesXML "$destinationLocation"/"$plistName"

And that’s it.  You now have everything you need to deploy your package.  Save out your installer script, I named mine ciscoAnyConnect4.3Deploy.sh but you can name yours whatever you want.

As always, once saved, make sure you give the script the execution permissions by opening Terminal and running:

sudo chmod +x /path/to/script.sh

Now copy your installer script to your LANDESK SWD file share.  I used the same path for my script, PLIST file and AnyConnect.pkg installer.

Once you’ve copied up your script, you just need to create your LANDESK Mac package so you can target and silently deploy Cisco AnyConnect with all of your customizations.

Creating LANDESK Management Suite Mac Packages

  1. Open the LANDESK Console
  2. Navigate to the top menu bar, select Tools > Distribution > Distribution Packages.
  3. In the lower left menu tree, highlight My Packages or Public Packages from within the Distribution Packages window
  4. On the Distribution menu bar, press the New Package button and select New Macintosh Agent package.
  5. Give the package a name
  6. Provide a description as well as any metadata information desired
  7. Set the primary file to the script file you previously transferred to your package share
  8. Fill out the Metadata details if desired, specifically supplying a logo so it shows up properly in the portal
  9. Save the package

Creating a Scheduled Mac Software Distribution Task

  1. Right click on the Mac software distribution package created and select Create Scheduled Task
  2. From the network view, select and drag the desired machine(s), user(s) or query(ies) and drop them onto the task
  3. Now, right click on the task and select properties
  4. Set the desired Task type under Task Settings as to whether you want a push, a policy or a hybrid of the two types in a policy-supported push
  5. Set the radio button in the Portal Settings to either Recommended or Optional if you desire to put the package into Workspaces.  If you’d like to automatically deploy the app, select Run automatically
  6. Change the Reboot Settings or Distribution and Patch settings if desired
  7. Set the schedule task settings with the appropriate start time

PLIST File

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
 <dict>
 <key>attributeSetting</key>
 <integer>1</integer>
 <key>choiceAttribute</key>
 <string>selected</string>
 <key>choiceIdentifier</key>
 <string>choice_vpn</string>
 </dict>
 <dict>
 <key>attributeSetting</key>
 <integer>0</integer>
 <key>choiceAttribute</key>
 <string>selected</string>
 <key>choiceIdentifier</key>
 <string>choice_websecurity</string>
 </dict>
 <dict>
 <key>attributeSetting</key>
 <integer>0</integer>
 <key>choiceAttribute</key>
 <string>selected</string>
 <key>choiceIdentifier</key>
 <string>choice_fireamp</string>
 </dict>
 <dict>
 <key>attributeSetting</key>
 <integer>0</integer>
 <key>choiceAttribute</key>
 <string>selected</string>
 <key>choiceIdentifier</key>
 <string>choice_dart</string>
 </dict>
 <dict>
 <key>attributeSetting</key>
 <integer>0</integer>
 <key>choiceAttribute</key>
 <string>selected</string>
 <key>choiceIdentifier</key>
 <string>choice_posture</string>
 </dict>
 <dict>
 <key>attributeSetting</key>
 <integer>0</integer>
 <key>choiceAttribute</key>
 <string>selected</string>
 <key>choiceIdentifier</key>
 <string>choice_iseposture</string>
 </dict>
 <dict>
 <key>attributeSetting</key>
 <integer>0</integer>
 <key>choiceAttribute</key>
 <string>selected</string>
 <key>choiceIdentifier</key>
 <string>choice_nvm</string>
 </dict>
 <dict>
 <key>attributeSetting</key>
 <integer>0</integer>
 <key>choiceAttribute</key>
 <string>selected</string>
 <key>choiceIdentifier</key>
 <string>choice_umbrella</string>
 </dict>
</array>
</plist>

Installer Script

#!/bin/sh

# ciscoAnyConnect4.3Deploy.sh
# Created by Bennett Norton on 11/30/16.


#File to copy
#change this to match your hosted path, it needs to be http
plistName="ChoiceChangesCiscoAnyConnect.plist"
packageName="AnyConnect.pkg"
plistFilePath="http://yourFileShareServer/Path/To/PLIST"
packageFilePath="http://yourFileShareServer/Path/To/CiscoAnyConnect"
packageToCopy="$packageFilePath"/"$packageName"
plistToCopy="$plistFilePath"/"$plistName"

#Location to copy file to
#change this to match your destination path
destinationLocation="/Library/Application Support/LANDesk/sdcache/CiscoAnyConnect"

#Download and execute command
#You shouldn't need to make any changes here
#-noinstall ensure the package does not get executed when downloaded
#-package is the source url path
#-destdir is the destination url path
/Library/Application\ Support/LANDesk/bin/sdclient -noinstall -package "$packageToCopy" -destdir "$destinationLocation"
/Library/Application\ Support/LANDesk/bin/sdclient -noinstall -package "$plistToCopy" -destdir "$destinationLocation"
installer -pkg "$destinationLocation"/"$packageName" -target / -applyChoiceChangesXML "$destinationLocation"/"$plistName"
17 Comments
  • Andy
    Posted at 12:11h, 12 January Reply

    Hi Bennett. This is very helpful but I’m having an issue. The package fails but it does download the .pkg, the .plist and the .sh file to the target machine. It just doesn’t install it.

    I ran the .sh manually on the machine and I get this: installer: choices file ‘/Library/Application Support/LANDesk/sdcache/CiscoAnyConnect/ChoiceChangesCiscoAnyConnect.plist’ either could not be found or was malformed.

    I verified the path and that the plist could be opened and even changed the permissions on it. Still doesn’t work though.

    Any thoughts? Thanks!

  • Andy
    Posted at 12:39h, 12 January Reply

    Thanks for the reply. I built it in Xcode. I tested using your method and it checks out fine. I couldn’t figure out how to actually download the one on your GitHub site so I copied it.

    • Bennett
      Posted at 13:22h, 12 January Reply

      OK, it may be a syntax error then in your shell script path. Try adding a backslash after Application. Example /Library/Application Support/LANDesk/sdcache/CiscoAnyConnect/ChoiceChangesCiscoAnyConnect.plist. If that doesn’t work, email me your plist and scripts and I’ll take a look.

  • Andy
    Posted at 16:24h, 12 January Reply

    So I had to change that line because is was creating a new folder called “Application Support” in the Library folder with the in at the end of Application instead of just putting it into the regular “Application Support” folder (the package failed that time too). Once I changed the script to ‘/Library/Application Support/LANDesk/sdcache/CiscoAnyConnect’ it put them into the normal directory. I’m happy to email you my shell script and plist file if you can provide your email address. Thanks again! I appreciate the help!

  • Bennett
    Posted at 11:25h, 13 January Reply

    OK, looks like the PLIST being used had some extra tags, something the Cisco installer wasn’t expecting and causing it to fail. These tags may have been caused by Xcode when generating the file.

  • Andy
    Posted at 13:45h, 13 January Reply

    Thanks again! It’s working great!

  • Maryann Trozzo
    Posted at 14:50h, 30 July Reply

    Bennett. I am trying to use your script and having issues. The software does install but in the process it is creating additional directories in the /Library folder. I’m seeing the following

    Application (locked folder)
    Application\
    Application\ Support

    Folders are named exactly as above. There is nothing under Application\ there is a LANDesk Folder under \Application\Support. My shell scripting Guru even looked t the script, was wondering what we are missing. I also have to install a related profile for the ISE Compliance Module.

    Thanks, Maryann

  • Maryann Trozzo
    Posted at 14:07h, 31 July Reply

    Bennett, I tried posting a comment yesterday but I’m not seeing it. I’m having issues with the script to customize the AnyConnect install. I edited as your documentation states and when AnyConnect installs LANDesk creates a number of blank or duplicate folders under /Library. They are as follows:

    Application (locked folder)
    Application\
    Application\ Support

    Folders are named exactly as above. There is nothing under Application\ there is a LANDesk Folder under \Application\Support.

    Any assistance would be appreciated.

  • Bennett Norton
    Posted at 22:03h, 31 July Reply

    Maryann,

    Good catch. I did not notice the duplicate folder structure being created. Turns out, sdclient will create the destination folder automatically for us, so we don’t even need to do a detect / create folder if needed. Go ahead and just remove that part of the script and add quotes around the destination directory. See below.

    #!/bin/sh

    # ciscoAnyConnect4.3Deploy.sh
    # Created by Bennett Norton on 11/30/16.

    #File to copy
    #change this to match your hosted path, it needs to be http
    plistName=”ChoiceChangesCiscoAnyConnect.plist”
    packageName=”AnyConnect.pkg”
    plistFilePath=”http://production.nine41.com/SoftwareDist/CiscoAnyConnect”
    packageFilePath=”http://production.nine41.com/SoftwareDist/CiscoAnyConnect”
    packageToCopy=”$packageFilePath”/”$packageName”
    plistToCopy=”$plistFilePath”/”$plistName”

    #Location to copy file to
    #change this to match your destination path
    destinationLocation=”/Library/Application Support/LANDesk/sdcache/CiscoAnyConnect”

    #Download and execute command
    #You shouldn’t need to make any changes here
    #-noinstall ensure the package does not get executed when downloaded
    #-package is the source url path
    #-destdir is the destination url path
    /Library/Application\ Support/LANDesk/bin/sdclient -noinstall -package “$packageToCopy” -destdir “$destinationLocation”
    /Library/Application\ Support/LANDesk/bin/sdclient -noinstall -package “$plistToCopy” -destdir “$destinationLocation”
    installer -pkg “$destinationLocation”/”$packageName” -target / -applyChoiceChangesXML “$destinationLocation”/”$plistName”

    • Maryann Trozzo
      Posted at 07:08h, 01 August Reply

      Bennet, thanks a lot. Hope all is well. Another question, I also need to install a separate ISE Compliance Module. Does this look right? In addition I need to copy a specific profile to /opt/cisco/anyconnect/profile folder. I wasn’t sure how to incorporate that into the script or just do a separate job to install.

      #!/bin/sh
      # ciscoAnyConnect4.4Deploy.sh
      # Created by Bennett Norton on 11/30/16.
      #File to copy

      #change this to match your hosted path, it needs to be http
      plistName=”ChoiceChangesCiscoAnyConnect.plist”
      packageName=”AnyConnect.pkg”
      isePackageName=”anyconnect-isecompliance-macosx-3.6.11017.2-web-deploy-k9.pkg”
      plistFilePath=”http://ourserver/packages/mac/Cisco/ISE”
      packageFilePath=”http://ourserver/packages/mac/Cisco/ISE”
      packageToCopy=”http://ourserver/packages/mac/Cisco/ISE/AnyConnect.pkg”
      isePackageToCopy=”http://ourserver/packages/mac/Cisco/”${isePackageName}
      plistToCopy=”http://ourserver/packages/mac/Cisco/ISE/ChoiceChangesCiscoAnyConnect.plist”

      #Location to copy file to
      #change this to match your destination path
      destinationLocation=’/Library/Application\ Support/LANDesk/sdcache’

      #Check to see if destination exists and if not, create it
      if [ ! -d “$destinationLocation” ]; then
      echo “Location doesn’t exist. Creating directory”
      mkdir $destinationLocation
      echo “$destinationLocation created”
      fi

      #Download and execute command
      #You shouldn’t need to make any changes here
      #-noinstall ensure the package does not get executed when downloaded
      #-package is the source url path
      #-destdir is the destination url path
      /Library/Application\ Support/LANDesk/bin/sdclient -noinstall -package “$packageToCopy” -destdir “$destinationLocation”
      /Library/Application\ Support/LANDesk/bin/sdclient -noinstall -package “$plistToCopy” -destdir “$destinationLocation”
      /Library/Application\ Support/LANDesk/bin/sdclient -noinstall -package ${isePackageToCopy} -destdir “$destinationLocation”
      installer -pkg “$destinationLocation”/”$packageName” -target / -applyChoiceChangesXML “$destinationLocation”/”$plistName”
      installer -pkg ${destinationLocation}/${isePackageName} -target /

      #Copy Custom Profile to /opt/cisco/anyconnect/profile

  • Maryann Trozzo
    Posted at 08:22h, 01 August Reply

    Bennet, I removed the section you mentioned and the job still creates those folders.

    • Bennett Norton
      Posted at 23:04h, 01 August Reply

      Maryann,

      Make sure you update the destinationLocation variable. It should be as follows: destinationLocation=”/Library/Application Support/LANDesk/sdcache/CiscoAnyConnect” Notice it has double quotes and no \ after Application.

      As for your additional items to download, you can totally do it within the same script, just change your variables to “$variableName” and not ${variableName}. Also, you’re going to want to update your ChoiceChangesCiscoAnyConnect.plist to install the Compliance Module.

      • Bennett Norton
        Posted at 08:58h, 02 August Reply

        Maryann, I should have clarified that using the {} vs “” on your variable is just fine, and will totally work. My suggestion for the change was for consistency throughout the script.

        • Maryann Trozzo
          Posted at 09:35h, 07 September Reply

          Hi Bennett, can you recommend the best way to prevent AnyConnect from being added too Login Items?? I did find the following command that removes it but was wondering if there is a way to suppress it?

          “osascript -e ‘tell application “System Events” to delete login item “Cisco AnyConnect Secure Mobility Client”‘

          • Bennett Norton
            Posted at 15:29h, 08 September

            I don’t know how to prevent it, or add in a flag to the customchoices.xml. What could be done is to create a second script with your “osascript -e ‘tell application “System Events” to delete login item “Cisco AnyConnect Secure Mobility Client” code. Then just deploy the bundle package.

      • Maryann Trozzo
        Posted at 14:21h, 07 August Reply

        Bennett, You mentioned I had to update the ChoiceChangesCiscoAnyConnect.plist. I did update so that the ISE Posture module that is part of the AnyConnect Install is enabled, that was working fine.. The Compliance Module is a separate application so I’m guessing I don’t have to edit the plist file. Am I wrong??

        Thanks, Maryann

Post A Comment

ARE YOU READY TO GET STARTED?
Please fill out your information, and a specialist will reach out to discuss our services in more details.
Your Information will never be shared with any third party.
        
Free Training Videos
Register to gain access to all of our free content.
YOUR PHONE
YOUR NAME
YOUR EMAIL
        
Get Started
Provide us your contact information and we will reach out as quickly as possible.
YOUR PHONE
YOUR NAME
YOUR EMAIL
        
Additional Questions?
Provide us your contact information and we will reach out as quickly as possible.
YOUR PHONE
YOUR NAME
YOUR EMAIL
        
Pay by PO?
Provide us your contact information and we will reach out to help you sign up by PO.
YOUR PHONE
YOUR NAME
YOUR EMAIL
Subscribe Now
Subscribing to our site gives you access to our Apple Admin 101 training videos as well as allowing us to notify you of each new blog post we release.
YOUR PHONE
YOUR NAME
YOUR EMAIL
Pay by PO
Send us your contact information and we will reach out to help you sign up by PO.
YOUR PHONE
YOUR NAME
YOUR EMAIL
Additional Questions?
Send us your contact information and your questions and we will reach out as quickly as possible.
YOUR PHONE
YOUR NAME
YOUR EMAIL
YOUR QUESTIONS
Get Started
Provide us your contact information and we will reach out as quickly as possible.
YOUR PHONE
YOUR NAME
YOUR EMAIL
Free Training Videos
Subscribing to our site gives you access to our Apple Admin 101 training videos as well as allowing us to notify you of each new blog post we release.
FIRST NAME
LAST NAME
PHONE
EMAIL
Subscribe Now
Subscribing to our site gives you access to our Apple Admin 101 training videos as well as allowing us to notify you of each new blog post we release.
FIRST NAME
LAST NAME
PHONE
EMAIL