Posted on 01-25-2022 05:14 AM
Hi All,
I am curious if its possible to create a configuration profile using custom schema to modify the profile.xml settings?
I know we can package it with installer etc and that's what I am doing but i want to know if there is an easier way to update the profile.xml when there is changes in the connection name or server etc?
Thank you!
Solved! Go to Solution.
Posted on 01-25-2022 08:10 AM
Hi. If you're talking about using the Application and Custom Settings profile payload, then I don't think so. That payload is for creating custom Configuration Profiles, not for modifying or creating .xml files in other locations on disk.
What I'd consider is using a script to create the xml. Making XMLs, plists, Launchd's and other text based files is super easy within a script, and you can customize what it creates on the fly with the use of script parameters. This prevents the need to package and repackage the xml file every time there is a change to it.
Here's an example.
#!/bin/zsh
## Pass strings to the script parameters below to customize XML at creation time
xml_path="$4"
trusted_dns_domains="$5"
trusted_dns_servers="$6"
host_name="$7"
host_address="$8"
user_group="$9"
backup_address_1="${10}"
backup_address_2="${11}"
## Create the xml
/bin/cat << EOXML > "$xml_path"
<?xml version="1.0" encoding="UTF-8"?>
<AnyConnectProfile xmlns="http://schemas.xmlsoap.org/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.xmlsoap.org/encoding/ AnyConnectProfile.xsd">
<ClientInitialization>
<UseStartBeforeLogon UserControllable="false">true</UseStartBeforeLogon>
<AutomaticCertSelection UserControllable="false">true</AutomaticCertSelection>
<ShowPreConnectMessage>false</ShowPreConnectMessage>
<CertificateStore>Machine</CertificateStore>
<CertificateStoreMac>All</CertificateStoreMac>
<CertificateStoreOverride>true</CertificateStoreOverride>
<ProxySettings>Native</ProxySettings>
<AllowLocalProxyConnections>true</AllowLocalProxyConnections>
<AuthenticationTimeout>12</AuthenticationTimeout>
<AutoConnectOnStart UserControllable="false">false</AutoConnectOnStart>
<MinimizeOnConnect UserControllable="false">true</MinimizeOnConnect>
<LocalLanAccess UserControllable="false">false</LocalLanAccess>
<DisableCaptivePortalDetection UserControllable="false">false</DisableCaptivePortalDetection>
<ClearSmartcardPin UserControllable="false">false</ClearSmartcardPin>
<IPProtocolSupport>IPv4</IPProtocolSupport>
<AutoReconnect UserControllable="false">true
<AutoReconnectBehavior UserControllable="false">DisconnectOnSuspend</AutoReconnectBehavior>
</AutoReconnect>
<SuspendOnConnectedStandby>false</SuspendOnConnectedStandby>
<AutoUpdate UserControllable="false">false</AutoUpdate>
<RSASecurIDIntegration UserControllable="false">Automatic</RSASecurIDIntegration>
<WindowsLogonEnforcement>SingleLocalLogon</WindowsLogonEnforcement>
<LinuxLogonEnforcement>SingleLocalLogon</LinuxLogonEnforcement>
<WindowsVPNEstablishment>LocalUsersOnly</WindowsVPNEstablishment>
<LinuxVPNEstablishment>LocalUsersOnly</LinuxVPNEstablishment>
<AutomaticVPNPolicy>true
<TrustedDNSDomains>$trusted_dns_domains</TrustedDNSDomains>
<TrustedDNSServers>$trusted_dns_servers</TrustedDNSServers>
<TrustedNetworkPolicy>Disconnect</TrustedNetworkPolicy>
<UntrustedNetworkPolicy>Connect</UntrustedNetworkPolicy>
<AlwaysOn>true
<ConnectFailurePolicy>Closed
<AllowCaptivePortalRemediation>true
<CaptivePortalRemediationTimeout>5</CaptivePortalRemediationTimeout>
</AllowCaptivePortalRemediation>
<ApplyLastVPNLocalResourceRules>true</ApplyLastVPNLocalResourceRules>
</ConnectFailurePolicy>
<AllowVPNDisconnect>true</AllowVPNDisconnect>
</AlwaysOn>
</AutomaticVPNPolicy>
<PPPExclusion UserControllable="false">Disable
<PPPExclusionServerIP UserControllable="false"/>
</PPPExclusion>
<EnableScripting UserControllable="false">true
<TerminateScriptOnNextEvent>false</TerminateScriptOnNextEvent>
<EnablePostSBLOnConnectScript>false</EnablePostSBLOnConnectScript>
</EnableScripting>
<EnableAutomaticServerSelection UserControllable="false">false
<AutoServerSelectionImprovement>10</AutoServerSelectionImprovement>
<AutoServerSelectionSuspendTime>1</AutoServerSelectionSuspendTime>
</EnableAutomaticServerSelection>
<RetainVpnOnLogoff>false
</RetainVpnOnLogoff>
<CaptivePortalRemediationBrowserFailover>false</CaptivePortalRemediationBrowserFailover>
<AllowManualHostInput>false</AllowManualHostInput>
</ClientInitialization>
<ServerList>
<HostEntry>
<HostName>$host_name</HostName>
<HostAddress>$host_address</HostAddress>
<UserGroup>$user_group</UserGroup>
<BackupServerList>
<HostAddress>$backup_address_1</HostAddress>
<HostAddress>$backup_address_2</HostAddress>
</BackupServerList>
</HostEntry>
</ServerList>
</AnyConnectProfile>
EOXML
With the above, you can pass parameters to the script at execution time to change / customize the following values in the xml:
Trusted DNS Domains
Trusted DNS Servers
Host Name
Host Address
User Group
Backup Server 1 and 2
You would of course want to use your own Cisco AnyConnect VPN profile as the template and just replace the variables as needed. If you look at the XML closely, you'll see variables in places where those strings would go, such as $trusted_dns_domains, $host_name, $host_address, etc. The actual values get plugged in when the script creates the xml when it runs.
Posted on 01-25-2022 07:46 AM
Configuration profiles will not modify anything. They are more like a layer of managed preferences that are enforced when applied. If the profile is removed, the existing preferences come back to life.
My basic understanding of the profile.xml for Cisco AnyConnect is that you need to deploy that file to /opt/cisco/anyconnect/profile/profile.xml. You'll find a long thread about installing AnyConnect here. It may help.
https://community.jamf.com/t5/jamf-pro/installing-components-of-cisco-anyconnect-4-7/td-p/173802
Posted on 01-27-2022 12:52 AM
Thank you, was just looking if there was a way to do it on the fly and look's like the script options mentioned below will be helpful however I will also through the link given.
01-25-2022 07:57 AM - edited 01-25-2022 07:58 AM
I don't package Cisco AnyConnect anymore.
I just upload the AnyConnect installer package file to Jamf. Then I created a script in Jamf that creates the XML choice file into the Mac in the /private/tmp folder, use the installer command to install Cisco with XML choice file. Then I create the XML file with the VPN connection field into the /opt/cisco/anyconnect/profile folder. Once the installation completes, it deletes the AnyConnect installer package and XML choice file. I find creating a script is a lot easier to maintain than to keep updating a package and with a script, I can update it on the fly.
Posted on 01-27-2022 12:55 AM
That makes life alot easier when you can just avoid repacking it. I will look into creating something similar, thank you
Posted on 01-25-2022 08:10 AM
Hi. If you're talking about using the Application and Custom Settings profile payload, then I don't think so. That payload is for creating custom Configuration Profiles, not for modifying or creating .xml files in other locations on disk.
What I'd consider is using a script to create the xml. Making XMLs, plists, Launchd's and other text based files is super easy within a script, and you can customize what it creates on the fly with the use of script parameters. This prevents the need to package and repackage the xml file every time there is a change to it.
Here's an example.
#!/bin/zsh
## Pass strings to the script parameters below to customize XML at creation time
xml_path="$4"
trusted_dns_domains="$5"
trusted_dns_servers="$6"
host_name="$7"
host_address="$8"
user_group="$9"
backup_address_1="${10}"
backup_address_2="${11}"
## Create the xml
/bin/cat << EOXML > "$xml_path"
<?xml version="1.0" encoding="UTF-8"?>
<AnyConnectProfile xmlns="http://schemas.xmlsoap.org/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.xmlsoap.org/encoding/ AnyConnectProfile.xsd">
<ClientInitialization>
<UseStartBeforeLogon UserControllable="false">true</UseStartBeforeLogon>
<AutomaticCertSelection UserControllable="false">true</AutomaticCertSelection>
<ShowPreConnectMessage>false</ShowPreConnectMessage>
<CertificateStore>Machine</CertificateStore>
<CertificateStoreMac>All</CertificateStoreMac>
<CertificateStoreOverride>true</CertificateStoreOverride>
<ProxySettings>Native</ProxySettings>
<AllowLocalProxyConnections>true</AllowLocalProxyConnections>
<AuthenticationTimeout>12</AuthenticationTimeout>
<AutoConnectOnStart UserControllable="false">false</AutoConnectOnStart>
<MinimizeOnConnect UserControllable="false">true</MinimizeOnConnect>
<LocalLanAccess UserControllable="false">false</LocalLanAccess>
<DisableCaptivePortalDetection UserControllable="false">false</DisableCaptivePortalDetection>
<ClearSmartcardPin UserControllable="false">false</ClearSmartcardPin>
<IPProtocolSupport>IPv4</IPProtocolSupport>
<AutoReconnect UserControllable="false">true
<AutoReconnectBehavior UserControllable="false">DisconnectOnSuspend</AutoReconnectBehavior>
</AutoReconnect>
<SuspendOnConnectedStandby>false</SuspendOnConnectedStandby>
<AutoUpdate UserControllable="false">false</AutoUpdate>
<RSASecurIDIntegration UserControllable="false">Automatic</RSASecurIDIntegration>
<WindowsLogonEnforcement>SingleLocalLogon</WindowsLogonEnforcement>
<LinuxLogonEnforcement>SingleLocalLogon</LinuxLogonEnforcement>
<WindowsVPNEstablishment>LocalUsersOnly</WindowsVPNEstablishment>
<LinuxVPNEstablishment>LocalUsersOnly</LinuxVPNEstablishment>
<AutomaticVPNPolicy>true
<TrustedDNSDomains>$trusted_dns_domains</TrustedDNSDomains>
<TrustedDNSServers>$trusted_dns_servers</TrustedDNSServers>
<TrustedNetworkPolicy>Disconnect</TrustedNetworkPolicy>
<UntrustedNetworkPolicy>Connect</UntrustedNetworkPolicy>
<AlwaysOn>true
<ConnectFailurePolicy>Closed
<AllowCaptivePortalRemediation>true
<CaptivePortalRemediationTimeout>5</CaptivePortalRemediationTimeout>
</AllowCaptivePortalRemediation>
<ApplyLastVPNLocalResourceRules>true</ApplyLastVPNLocalResourceRules>
</ConnectFailurePolicy>
<AllowVPNDisconnect>true</AllowVPNDisconnect>
</AlwaysOn>
</AutomaticVPNPolicy>
<PPPExclusion UserControllable="false">Disable
<PPPExclusionServerIP UserControllable="false"/>
</PPPExclusion>
<EnableScripting UserControllable="false">true
<TerminateScriptOnNextEvent>false</TerminateScriptOnNextEvent>
<EnablePostSBLOnConnectScript>false</EnablePostSBLOnConnectScript>
</EnableScripting>
<EnableAutomaticServerSelection UserControllable="false">false
<AutoServerSelectionImprovement>10</AutoServerSelectionImprovement>
<AutoServerSelectionSuspendTime>1</AutoServerSelectionSuspendTime>
</EnableAutomaticServerSelection>
<RetainVpnOnLogoff>false
</RetainVpnOnLogoff>
<CaptivePortalRemediationBrowserFailover>false</CaptivePortalRemediationBrowserFailover>
<AllowManualHostInput>false</AllowManualHostInput>
</ClientInitialization>
<ServerList>
<HostEntry>
<HostName>$host_name</HostName>
<HostAddress>$host_address</HostAddress>
<UserGroup>$user_group</UserGroup>
<BackupServerList>
<HostAddress>$backup_address_1</HostAddress>
<HostAddress>$backup_address_2</HostAddress>
</BackupServerList>
</HostEntry>
</ServerList>
</AnyConnectProfile>
EOXML
With the above, you can pass parameters to the script at execution time to change / customize the following values in the xml:
Trusted DNS Domains
Trusted DNS Servers
Host Name
Host Address
User Group
Backup Server 1 and 2
You would of course want to use your own Cisco AnyConnect VPN profile as the template and just replace the variables as needed. If you look at the XML closely, you'll see variables in places where those strings would go, such as $trusted_dns_domains, $host_name, $host_address, etc. The actual values get plugged in when the script creates the xml when it runs.
Posted on 01-27-2022 01:01 AM
Thank you for the detailed explanation and yes that should do the work, just need to replace the XML details above. I will look into it in more detail and get it working.
Posted on 01-11-2023 07:38 AM
Is xml_path typically /opt/cisco/anyconnect/profile/AnyConnectProfile.xml ???
Posted on 10-19-2023 11:49 AM
This is great, thank you for sharing. Is there also a way to script which elements show up in the GUI (in my case I just need choice vpn and umbrella. I know I can create a custom pkg from the dmg that strips out the elements I do not want, but I am trying to solve having to build a new PKG whenever a new release is made.