My script uses PSADT 3.10.1 so it is a little bit different than v4.0.x. but the logic is still roughly the same, with v3.x I made customisations to the AppDeployToolkitConfig.xml to customise the Messaging showing in the Show-InstallationWelcome dialog
Here is my function (TBH I prefer the idea of yours as it determines if the VPN is connected by expanding the āIPEnabledā item to determine if itās connected (or not) where as mine checks if it has a valid network address allocated - although both will work, the only change Iād make to yours is use Get-CIMInstance instead of Get-WMIObject as there are security issues with WMI that Microsoft have now blocked in āmodernā PowerShell Core (So you canāt use Get-WMIObject calls in modern Powershell)
For my method to work, you just need to update your network range (or ranges). The reason I like your route means the network range is unimportant.
function Get-VPNStatus {
[CmdletBinding()]
param ()
$VPNAdapters = Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration -f:"Description like '%Cisco AnyConnect%'"
[bool]$vpnCheck = $false
foreach ($VPNAdapter in $VPNAdapters) {
Write-Log -Message " VPN Adapter with Service Name $($($VPNAdapter).ServiceName) detected"
$IPAddresses = $VPNAdapter.IPAddress
If ((($IPAddresses) -like "192.168.50.*") -or (($IPAddresses) -like "192.168.54.*")) {
Write-Log -Message " WARNING: Device appears to be connected to the User VPN, Will retry later, Pausing for 2 minutes" -Severity 2
$vpnCheck = $true
break
#Start-Sleep 120
#exit 1618
} Else {
Write-Log -Message " INFORMATION: Device appears not to be connected to the User VPN, can continue"
$vpnCheck = $false
break
}
}
return $vpnCheck
}
Then during the Install (or Uninstall) phase of the script I can call the function to check if the VPN is in use (Connected)
$VPNRunningInitially = $false
# Determine initial status of VPN, in order to decide if messaging is required
If (Get-VPNStatus) {
$VPNRunningInitially = $true
}
With the Cisco Secure Client you do not need to close (or stop) any apps, so you donāt āneedā to close any apps as you are doing (TBH it may not work for some of the apps / components due to the way they are loaded during the kernel) what we know (from experience) if you use the Network Access Module you do need to trigger a restart once NAM has installed (or upgraded), but you can silence this in the MSI command line and then get PSADT to prompt the user at the end to restart (as we did before we got rid of NAM and moved to use the native Microsoft 802.1x control with the Cisco VPN).
This shows you our v3.10.1 version of what you could do
If ($deploymentType -ine 'Uninstall' -and $deploymentType -ine 'Repair') {
##*===============================================
##* PRE-INSTALLATION
##*===============================================
[String]$installPhase = 'Pre-Installation'
$DefaultMessage = "Installing $($appVendor) $($appName) v$($appVersion).`n`n"
If ($VPNRunningInitially) {
# Show Deferal message only if VPN was connected when install lands
## Show Welcome Message, close Internet Explorer if required, allow up to 3 deferrals, verify there is enough disk space to complete the install, and persist the prompt
Show-InstallationWelcome -MinimizeWindows $false -AllowDefer -DeferTimes 3 -CheckDiskSpace -PersistPrompt -TopMost $true
## Show Progress Message (with the default message)
Show-InstallationProgress -StatusMessage "$($DefaultMessage)Please Wait...`n`n`n"
Start-Sleep -Seconds 10
}
## <Perform Pre-Installation tasks here>
#'PreInstallVariable'
##*===============================================
##* INSTALLATION
##*===============================================
[String]$installPhase = 'Installation'
## Handle Zero-Config MSI Installations
If ($useDefaultMsi) {
[Hashtable]$ExecuteDefaultMSISplat = @{ Action = 'Install'; Path = $defaultMsiFile }; If ($defaultMstFile) {
$ExecuteDefaultMSISplat.Add('Transform', $defaultMstFile)
}
Execute-MSI @ExecuteDefaultMSISplat; If ($defaultMspFiles) {
$defaultMspFiles | ForEach-Object { Execute-MSI -Action 'Patch' -Path $_ }
}
}
## <Perform Installation tasks here>
Write-Log -Message "====================================================== "
Write-Log -Message "$($appVendor) $($appName) installation PowerShell script "
Write-Log -Message "====================================================== "
# we want to make sure we only proceed if the previous MSI installed correctly.
#
# So we need to get and inspect the Exit Code to see if it worked. This is the most elegant construct:
# $Result = (Start-Process -FilePath "msiexec.exe" -ArgumentList "<<whatever>>" -Wait -Passthru).ExitCode
Write-Log -Message "============================================= "
Write-Log -Message "Installing $($appVendor) $($appName) components "
Write-Log -Message "============================================= "
Write-Log -Message "$($appVendor) $($appName) version $($appVersion)"
If ($VPNRunningInitially) {
# Exit with Retry code (1618) if the VPN is up
Write-Log -Message " - Searching for AnyConnect VPN Adapters..."
Show-InstallationProgress -StatusMessage "$($DefaultMessage)Checking if VPN is connected...`n`n`n"
Start-Sleep -Seconds 2
While (Get-VPNStatus) {
# Warn that VPN needs to be disconnected
Show-InstallationProgress -StatusMessage "WARNING: The VPN is connected`nPlease close App 1, App 2, App 3, App 4 and then disconnect the VPN so this upgrade can continue"
}
Write-Log -Message " PROCEEDING: User VPN appears to be disconnected"
Show-InstallationProgress -StatusMessage "$($DefaultMessage)VPN is not connected...`nProceeding with Install`n`n"
Start-Sleep -Seconds 2
# Install the Cisco Secure Client
Show-InstallationProgress -StatusMessage "$($DefaultMessage)Installing the Core/VPN package...`n`n`n"
Start-Sleep -Seconds 2
}
Write-Log -Message " - Installing the Core/VPN package..."
if (!(Test-Path -Path "$($dirFiles)\$($CoreVPNmsiPath)")) {
Write-Log -Message " WARNING: `""$($dirFiles)\$($CoreVPNmsiPath)"`" does not exist" -Severity 2
} else {
$ArgList = "/norestart /quiet"
[psobject]$Result = (Execute-MSI -Action Install -Path "$($dirFiles)\$($CoreVPNmsiPath)" -Parameters $($ArgList) -ContinueOnError $False -LogName "Cisco-SecureClient-core-vpn_MSI" -Passthru).ExitCode
if (! ( ($Result -eq 0) -or ($Result -eq 1707) -or ($Result -eq 3010) -or ($Result -eq 1641) -or ($Result -eq 1638) ) ) {
Write-Log -Message " There was an error installing the Core/VPN package : $Result" -Severity 3
Write-Log -Message " Exiting..." -Severity 3
Write-Log -Message $Result
exit $Result
}
}
If ($VPNRunningInitially) {
Show-InstallationProgress -StatusMessage "$($DefaultMessage)Installing the Core/VPN package...Done!`n`n`n"
Start-Sleep -Seconds 2
}
Write-Log -Message " OK"
If ($VPNRunningInitially) {
Show-InstallationProgress -StatusMessage "$($DefaultMessage)Installing the Core/VPN package...Done!`nInstalling the DaRT package...`n`n"
Start-Sleep -Seconds 2
}
Write-Log -Message " - Installing the DaRT package..."
if (!(Test-Path -Path "$($dirFiles)\$($DaRTmsiPath)")) {
Write-Log -Message " WARNING: `""$($dirFiles)\$($DaRTmsiPath)"`" does not exist" -Severity 2
} else {
$ArgList = "/norestart /quiet"
[psobject]$Result = (Execute-MSI -Action Install -Path "$($dirFiles)\$($DaRTmsiPath)" -Parameters $($ArgList) -ContinueOnError $False -LogName "Cisco-SecureClient-DaRT_MSI" -Passthru).ExitCode
if (! ( ($Result -eq 0) -or ($Result -eq 1707) -or ($Result -eq 3010) -or ($Result -eq 1641) -or ($Result -eq 1638) ) ) {
Write-Log -Message " There was an error installing the DART package : $Result" -Severity 3
Write-Log -Message " Exiting..." -Severity 3
Write-Log -Message $Result
exit $Result
}
}
If ($VPNRunningInitially) {
Show-InstallationProgress -StatusMessage "$($DefaultMessage)Installing the Core/VPN package...Done!`nInstalling the DaRT package...Done!`n`n"
Start-Sleep -Seconds 2
}
Write-Log -Message " OK"
If ($VPNRunningInitially) {
Start-Sleep -Seconds 2
Show-InstallationProgress -StatusMessage "$($DefaultMessage)Transferring configuration files...`n`n`n"
Start-Sleep -Seconds 2
}
Write-Log -Message " - Copying in configuration files..."
# Copy VPN config to 'C:\ProgramData\Cisco\Cisco Secure Client\VPN\Profile\'
$Source = $($VPNConfigFile)
$Target = "$($env:ProgramData)\Cisco\Cisco Secure Client\VPN\Profile"
If ($VPNRunningInitially) {
Show-InstallationProgress -StatusMessage "$($DefaultMessage)Transferring configuration files...`nVPN Config...`n`n"
Start-Sleep -Seconds 2
}
if (!(Test-Path -Path "$($dirFiles)\$($Source)")) {
Write-Log -Message " WARNING: VPN Config File `"$($Source)`" does not exist in `"$($dirFiles)\`"" -Severity 2
} else {
if (Test-Path -Path "$($Target)") {
Write-Log -Message " Copying VPN profile to $($Target)\$($Source)..."
Copy-Item "$($dirFiles)\$($Source)" -Destination "$($Target)" -Force -Verbose | Write-Log
} else {
Write-Log -Message " WARNING: VPN profile target folder $($Target) does not exist" -Severity 2
}
}
If ($VPNRunningInitially) {
Show-InstallationProgress -StatusMessage "$($DefaultMessage)Transferring configuration files...`nVPN Config...Done!`n`n"
Start-Sleep -Seconds 2
Show-InstallationProgress -StatusMessage "$($DefaultMessage)Transferring configuration files...`nVPN Config...Done!`nManagement Tunnel Config...`n"
Start-Sleep -Seconds 2
}
# Copy management tunnel config to 'C:\ProgramData\Cisco\Cisco Secure Client\VPN\Profile\MgmtTun\'
$Source = $($MgmtTunnelFile)
$Target = "$($env:ProgramData)\Cisco\Cisco Secure Client\VPN\Profile\MgmtTun"
if (!(Test-Path -Path "$($dirFiles)\$($Source)")) {
Write-Log -Message " WARNING: Management Tunnel Config File `"$($Source)`" does not exist in `"$($dirFiles)\`"" -Severity 2
} else {
if (Test-Path -Path "$($Target)") {
Write-Log -Message " Copying MgmtTun profile to $($Target)\$($Source)..."
Copy-Item "$($dirFiles)\$($Source)" -Destination "$($Target)" -Force -Verbose | Write-Log
} else {
Write-Log -Message " WARNING: MgmtTun target folder $($Target) does not exist" -Severity 2
}
}
If ($VPNRunningInitially) {
Show-InstallationProgress -StatusMessage "$($DefaultMessage)Transferring configuration files...`nVPN Config...Done!`nManagement Tunnel Config...Done!`n"
Start-Sleep -Seconds 10
Show-InstallationProgress -StatusMessage "$($DefaultMessage)Transferring configuration files...Done!`n`n`n"
Start-Sleep -Seconds 2
}
Write-Log -Message " Done."
Write-Log -Message "Result: $($Result)"
#endregion
##*===============================================
##* POST-INSTALLATION
##*===============================================
[String]$installPhase = 'Post-Installation'
## <Perform Post-Installation tasks here>
## Display a message at the end of the install
If (-not $useDefaultMsi) {
# Show-InstallationRestartPrompt -Countdownseconds 305 -CountdownNoHideSeconds 60
}
}
In Summary what my script does is:
- Check if the VPN is connected initially
- If it is, then notify the user we are deploying the software with a Warning they will need to close any of the business apps our users require the VPN for before clicking continue (or Defer if itās not convenient)
- Commence the install, if the VPN is found to still be connected, again prompt them to close the business apps and disconnect the VPN before the install will proceed (in the
While (Get-VPNStatus) loop
- Installs the Core/VPN package (with
/norestart / quiet Arguments)
- Installs the DaRT package (with
/norestart / quiet Arguments)
- Copy in VPN Profile
- Copy in Management Tunnel Profile
Without NAM there is no requirement to restart the machine, but if using NAM, you would need to include a final restart prompt (Which Iād recommend you alert users of this requirement at the start)
Unsure if this really answers your actual question, but hope my solution goes some way to assist?
EDIT: Just realised, you need to include the definition for a couple of variables I have called.
Add these in the ##* VARIABLE DECLARATION section:
# Installers
[String]$CoreVPNmsiPath = "cisco-secure-client-win-$($appVersion)-core-vpn-predeploy-k9.msi"
[String]$DaRTmsiPath = "cisco-secure-client-win-$($appVersion)-dart-predeploy-k9.msi"
# Configuration Files
[String]$VPNConfigFile = "dfac_vpn_off.xml"
[String]$MgmtTunnelFile = "VpnMgmtTunProfile.xml"
#