Get in Touch
Ready for Worry-Free IT? We can help.
I would first, like to give thanks to Ben R. of Powers Hell who led me down this path of enlightenment.
tabs-not-spaces (Ben R.) (github.com)
I figured since we could use the rasman registry entries to keep the Azure VPN alive while connected to the internal network, why not use rasdial to initiate the connection based on the state of your network?
In our case, we wanted an Always On VPN solution that would auto connect and disconnect based on conditions of your network connection. For instance, if you were connected to an external network (like from home working remotely), the Azure VPN would automatically connect. If you brought your laptop to work, and connected to the corporate network, the Azure VPN client would automatically disconnect and vice versa.
Granted there are various posts on how to accomplish this using Microsoft’s solution as described here or on various other posts.
Configure an Always-On VPN user tunnel – Azure VPN Gateway | Microsoft Learn
However, I created another much simpler solution based on the rasdial command without all the overhead. Therefore, with a little help from my buddy Ben R, a PowerShell script, Scheduled Task, and Intune deployment was devised. Here is the script:
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
# Define the VPN Connection name
$vpnConnectionName = "Name Azure VPN"
#Check for network connectivity and VPN connection status in a loop
while ($true) {
# Get the VPN connection status
$vpnStatus = Get-VpnConnection -Name $vpnConnectionName -ErrorAction SilentlyContinue
# Get the default gateway IP
$defaultGatewayIp = (Get-NetRoute | Where-Object { $_.DestinationPrefix -eq '0.0.0.0/0' }).NextHop
# Check if the default gateway IP corresponds to an internal network
$internalNetworks = @("IpAddress1", "IpAddress2", "IpAddress3", "IpAddress4", "IpAddress5", "IpAddress6", "IpAddress7")
# Get the connection profile name
$connectionProfileName = (Get-NetConnectionProfile).Name
# Log the network status and connection profile
Add-Content -Path "C:\temp\Log\Network_Status.log" -Value "Default Gateway IP: $defaultGatewayIp, Connection Profile: $connectionProfileName"
# Check conditions based on network statuses to connect or stay connected to the VPN
if ($internalNetworks -contains $defaultGatewayIp -and $connectionProfileName -eq 'DomainName') {
# If connected to an internal network and the VPN is connected, disconnect the VPN
Write-Host "Connected to an internal network. Disconnecting VPN..."
rasdial.exe $vpnConnectionName /disconnect
} elseif ($defaultGatewayIp -eq 'IpAddress1' -or $defaultGatewayIp -eq 'IpAddress2' -or $defaultGatewayIp -eq 'IpAddress3' -or $defaultGatewayIp -eq 'IpAddress4' -or $defaultGatewayIp -eq 'IpAddress5' -or $defaultGatewayIp -eq 'IpAddress6' -or $defaultGatewayIp -eq 'IpAddress7') {
# If default gateway is equal to any of the internal network addresses, disconnect the VPN
Write-Host "Connected to an internal network. Disconnecting VPN..."
rasdial.exe $vpnConnectionName /disconnect
} elseif ($vpnStatus -eq $null -or $vpnStatus.ConnectionStatus -ne 'Connected') {
# If the VPN is disconnected, connect the VPN
Write-Host "VPN is disconnected. Connecting..."
rasdial.exe $vpnConnectionName
}
# Adjust the sleep interval as needed
Start-Sleep -Seconds 10
Let’s break it down a bit for clarity.
The PowerShell script was vigorously tested to connect/disconnect the Azure VPN automatically by connecting to an external network, then connecting to an internal network, both wired and wirelessly, and the Azure VPN connected and disconnected as intended. The next step is to create a scheduled task for the PowerShell script to run when the user logs on, or at startup. To create the scheduled task:
@echo off
cd C:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -command "& {Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass -Force}"
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -WindowStyle Hidden -File "C:\temp\scripts\nameOfpowerShellScript.ps1" 1>C:\temp\log\vpn.log 2>&1
We tested running the PowerShell script directly from within Task Scheduler but got errors or it didn’t run as intended. Therefore, calling the PowerShell script from within a batch file worked flawlessly. The execution policy is necessary for task scheduler to run the PowerShell script from within the batch file using the Built-In Users group. It is also necessary to use absolute paths as opposed to relative paths in the batch file as well or you will get an error. See the logs for any errors.
Once the scheduled task has been created, and you copied the batch file and PowerShell script to the C:\temp\scripts (or any folder of your choice), the scheduled task is ready to run. You can now test the state of your connections by connecting to your internal or external network to confirm the Azure VPN client connects, disconnects, and remains connected/disconnected as needed. The next step was to deploy the scripts (copy files to local machine) and create the scheduled task via Intune.
To deploy the scheduled task and files via Intune:
$tempdir = "C:\temp\scripts"
$logdir = "C:\temp\log"
New-Item $tempdir -ItemType Directory -Force
New-Item $logdir -ItemType Directory -Force
Copy-Item ".\NameofYourXML.xml" "C:\temp\scripts" -Force
Copy-Item ".\NameofYourbatch.bat" "C:\temp\scripts" -Force
Copy-Item ".\NameofYourScript.ps1" "C:\temp\scripts" -Force
Register a new scheduled task using the exported XML.
Register-ScheduledTask -xml (Get-Content C:\temp\scripts\NameofYourXML.xml | Out-String) -TaskName "Name of your task" -TaskPath "/"
Unregister-ScheduledTask -TaskName "Auto Connect Azure VPN" -Confirm:$false
Remove-Item C:\temp\log -Recurse
Remove-Item C:\temp\scripts -Recurse
$taskExists = Get-ScheduledTask | Where-Object {$_.TaskName -like "NameOfScheduledTask"}
if($taskExists) {
Write-Host "Success"
Exit 0
} else {
Exit 1}
Use the following for install/uninstall commands:
Install Command:
Powershell.exe -ExecutionPolicy ByPass -File .\install.ps1
Uninstall Command:
Powershell.exe -ExecutionPolicy ByPass -File .\uninstall.ps1
4. Configure the Win32App to run under the system context.
5. Use a custom detection script (see below)
$taskExists = Get-ScheduledTask | Where-Object {$_.TaskName -like "Your VPN Name"}
if($taskExists) {
Write-Host "Success"
Exit 0
}else {
Exit 1
6. Assign to specified group(s) as Required.
NOTE: For Task Scheduler to run the batch file successfully on the local machine, it is necessary to use absolute paths, and the following had to be used to set the proper execution policy for the batch file to execute the PowerShell script using the Task Scheduler. >C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -Command “& {Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass -Force}”
ANOTHER NOTE: This solution will conflict with users working remotely, where their home network is set to use any of the gateways within your internal network. In this case, the Azure VPN will remain disconnected until their home network subnet is changed to anything other than any of your internal network IP Addresses.
That’s it. Now you have a working “Always On” (like) Azure VPN connection when working remotely that disconnects automatically when working at the office and vice versa, that can be deployed via Intune. I hope you found this article helpful or at least down the path of enlightenment as myself. Please click the like button below, and feel free to share. Happy scripting!
Ready for Worry-Free IT? We can help.