Relevance Substitution Error with Cisco Secure Client

Attempting to deploy Cisco Secure Client & Umbrella which has been a royal pain. There is an issue with upgrading to a newer version when the current version is missing the original installation files. When updating the action script, it now encounters a relevance substitution error when deploying to endpoints. I believe the issue is under the comment:

// If Secure Client VPN install failed, attempt to remove broken old version then reinstall

These reinstall sections were newly added and seemed to work in a vacuum when tested with Fixlet Debugger but now my script runs into that relevance substitution error after adding it.

Godspeed to whoever decides to parse this forsaken action script.

prefetch ae1f40580b2a4ff2453e35e11afae425efb8d14e sha1:ae1f40580b2a4ff2453e35e11afae425efb8d14e size:24720340 http://[siteurl] sha256:c2cf3ff8e46f700f885a40c23ae1ccc9121842aa6fff88fb6b9f00268aecee2b
extract ae1f40580b2a4ff2453e35e11afae425efb8d14e

// Parmeters needed for action script
parameter "CoreMsi"     = "cisco-secure-client-win-5.1.10.233-core-vpn-predeploy-k9.msi"
parameter "UmbrellaMsi" = "cisco-secure-client-win-5.1.10.233-umbrella-predeploy-k9.msi"
parameter "UmbrellaDir" = "C:\ProgramData\Cisco\Cisco Secure Client\Umbrella"
parameter "JsonPath"    = "{parameter "UmbrellaDir"}\OrgInfo.json"
parameter "RegPath"     = "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Cisco Secure Client - AnyConnect VPN"
parameter "Version"     = "5.1.10.233"

// Disable 64-bit > 32-bit redirection
action uses wow64 redirection {not x64 of operating system}

// Check if computer is on VPN
if {exists addresses whose (it as string starts with "10.9.") of ip interfaces of network}
	parameter "OnVpn" = "True"
else
	parameter "OnVpn" = "False"
endif

// Disconnect VPN session
if {exists file "C:\Program Files (x86)\Cisco\Cisco Secure Client\vpncli.exe"}
	waithidden "C:\Program Files (x86)\Cisco\Cisco Secure Client\vpncli.exe" disconnect
endif

// End VPN process
if {exists (names of it) of processes whose (name of it contains "csc_ui.exe")}
	waithidden taskkill /f /im csc_ui.exe
endif

// If downgrading VPN versions, uninstall current version first
if {exists key (parameter "RegPath") whose (value "DisplayVersion" of it as string as version > (parameter "Version") as version) of native registry}
	waithidden "C:\Program Files (x86)\Cisco\Cisco Secure Client\Uninstall.exe" -remove -silent
	pause while {exists processes whose (name of it contains "Cisco Secure Client0Uninstall")}
elseif {exists keys whose (value "DisplayName" of it as string starts with "Cisco Secure Client - Umbrella" and value "DisplayVersion" of it as string as version > (parameter "Version") as version) of keys "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" of (x64 registries; x32 registries)}
	wait msiexec /qn /norestart /x {names of keys whose (value "DisplayName" of it as string starts with "Cisco Secure Client - Umbrella" of it and value "UninstallString" of it as string as lowercase contains "msiexec") of keys "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" of (x32 registries; x64 registries)}
endif

// Install Secure Client VPN
parameter "VpnLog" = "C:\Windows\SystemTemp\cisco-vpn-install.log"
waithidden msiexec /qn /norestart /i "{(pathname of client folder of current site) & "\__Download\" & (parameter "CoreMsi")}" /lvx* "{parameter "VpnLog"}"

// If Secure Client VPN install failed, attempt to remove broken old version then reinstall
if {exists keys whose (value "DisplayName" of it as string starts with "Cisco Secure Client - AnyConnect VPN" and value "DisplayVersion" of it as string as version < (parameter "Version") as version) of keys "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" of (x32 registries; x64 registries)}
	// Uninstall VPN
	wait "C:\Program Files (x86)\Cisco\Cisco Secure Client\Uninstall.exe" -remove -silent
	pause while {exists processes whose (name of it contains "Cisco Secure Client0Uninstall")}
	wait msiexec /qn /norestart /x {names of keys whose (value "DisplayName" of it as string starts with "Cisco Secure Client - AnyConnect VPN" of it and value "UninstallString" of it as string as lowercase contains "msiexec") of keys "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" of (x32 registries; x64 registries)}

	// Remove bad registry key
	if {exists lines whose (it contains "Warning: Local cached package" and it ends with "is missing.") of file (parameter "VpnLog")}
		parameter "BadKeyVpn" = "{"HKEY_CLASSES_ROOT\Installer\Products\" & (following text of first "product: " of (tuple string item (number of tuple string items of it - 1) of tuple string of lines containing "Using cached product context: machine assigned for product:" of file (parameter "VpnLog")))}"
		
		if {exists key (parameter "BadKeyVpn") of native registry}
			waithidden reg delete "{parameter "BadKeyVpn"}" /f
		endif
	endif
	
	// Reinstall VPN
	waithidden msiexec /qn /norestart /i "{(pathname of client folder of current site) & "\__Download\" & (parameter "CoreMsi")}" /lvx* "{parameter "VpnLog"}"
endif

// Install Umbrella
parameter "UmbrellaLog" = "C:\Windows\SystemTemp\cisco-umbrella-install.log"
waithidden msiexec /qn /norestart /i "{(pathname of client folder of current site) & "\__Download\" & (parameter "UmbrellaMsi")}" /lvx* "{parameter "UmbrellaLog"}"

// If Umbrella install failed, attempt to remove broken old version then reinstall
if {exists keys whose (value "DisplayName" of it as string starts with "Cisco Secure Client - Umbrella" and value "DisplayVersion" of it as string as version < (parameter "Version") as version) of keys "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" of (x32 registries; x64 registries)}
	// Uninstall Umbrella
	wait msiexec /qn /norestart /x {names of keys whose (value "DisplayName" of it as string starts with "Cisco Secure Client - AnyConnect VPN" of it and value "UninstallString" of it as string as lowercase contains "msiexec") of keys "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" of (x32 registries; x64 registries)}
	
	// Remove bad registry key
	if {exists lines whose (it contains "Warning: Local cached package" and it ends with "is missing.") of file (parameter "UmbrellaLog")}
		parameter "BadKeyUmbrella" = "{"HKEY_CLASSES_ROOT\Installer\Products\" & (following text of first "product: " of (tuple string item (number of tuple string items of it - 1) of tuple string of lines containing "Using cached product context: machine assigned for product:" of file (parameter "UmbrellaLog")))}"
		
		if {exists key (parameter "BadKeyUmbrella") of native registry}
			waithidden reg delete "{parameter "BadKeyUmbrella"}" /f
		endif
	endif
	
	// Reinstall Umbrella
	waithidden msiexec /qn /norestart /i "{(pathname of client folder of current site) & "\__Download\" & (parameter "UmbrellaMsi")}" /lvx* "{parameter "UmbrellaLog"}"
endif

// Verify VPN & Umbrella were installed
continue if {exists key (parameter "RegPath") whose (value "DisplayVersion" of it as string as version = (parameter "Version") as version) of native registry}
continue if {exists keys whose (value "DisplayName" of it as string starts with "Cisco Secure Client - Umbrella" and value "DisplayVersion" of it as string as version = (parameter "Version") as version) of keys "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" of (x32 registries; x64 registries)}

// Remove existing Umbrella profile if detected
if {exists file (parameter "JsonPath")}
	delete "{(parameter "JsonPath")}"
endif

// Move Umbrella profile
if {not exists folder (parameter "UmbrellaDir")}
	folder create "{parameter "UmbrellaDir"}"
endif

move "__Download\OrgInfo.json" "{(parameter "JsonPath")}"

// Restart Cisco VPN service
if {exists service "csc_vpnagent"}
	waithidden net stop csc_vpnagent
	waithidden net start csc_vpnagent
endif

// Require restart if Cisco VPN service does not exist or is not running
if {not exists service "csc_vpnagent" whose (state of it = "Running")} 
	action requires restart "ae1f40580b2a4ff2453e35e11afae425efb8d14e"
else
	action may require restart
endif

// Enable WiFi if it's disabled
if {not exists adapters whose (friendly name of it contains "Wi-Fi") of networks}
	waithidden powershell -Command "Get-NetAdapter | Where-Object {{ $_.Name -match 'Wi-Fi' } | Enable-NetAdapter -Confirm:$false"
endif

// Start Cisco Secure Client; show UI if on VPN, silent if not on VPN
if {(exists logged on user) and (not exists process whose (name of it = "csc_ui.exe"))}
	if {(parameter "OnVpn") = "True"}
		override run
		runas = currentuser
		run "C:\Program Files (x86)\Cisco\Cisco Secure Client\UI\csc_ui.exe"
	else
		override run
		runas = currentuser
		run "C:\Program Files (x86)\Cisco\Cisco Secure Client\UI\csc_ui.exe" -autolaunched
	endif
endif

Is this the section that fails with relevance substitution error?

If so, the one thing that I would look into is the relevance in the mesiexec command:

  1. Are you sure you are getting back a single entry? If for example there are multiple it may be messing up the command/substituion.
  2. Names of the keys under Uninstall reg key sometimes are of format {GUID}, and if that is what you are getting back not sure whether the curly bracket itself won’t need to be escaped even though it comes from relevance evaluation itself…
2 Likes

When I check an endpoint’s action info, this is the line it’s showing as failed.

if {exists lines whose (it contains "Warning: Local cached package" and it ends with "is missing.") of file (parameter "VpnLog")}

When running in Fixlet Debugger I get no issues.

EDIT: The VPN log file isn’t generated on the computer until the msiexec commands run. I noticed that action script has a relevance error if the log file doesn’t exist. I’m guessing I either need to do a prefetch block or change the line to the following:

if {(exists file (parameter "VpnLog")) and exists lines whose (it contains "Warning: Local cached package" and it ends with "is missing.") of file (parameter "VpnLog")}
2 Likes