The Beginning…

I would first, like to give thanks to Ben R. of Powers Hell who led me down this path of enlightenment.

Set your Azure VPN connections to “Connect Automatically” with PowerShell | Powers Hell (powers-hell.com)

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 Scheduled Task

  1. Create a batch file to call up the PowerShell script from within Task Scheduler.
    The contents of the batch file should include the following:
@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.

  1. Add the batch file (NameYourBatch.bat), and PowerShell script (NameYourPowerShellScript.ps1) in the same folder. I used C:\temp\scripts
    Configure Task Scheduler as follows:
    a. General – Selected Built-In Users Group, Run with highest privileges
    b. Triggers – At log on, Any User, Enabled & At System Startup, Enabled
    c.  Actions – Start a program, Program/Script >cmd.exe, Add arguments >/C C:\temp\scripts\NameOfYourBatch.bat
    d. Conditions – leave blank
    e. Settings – Allow task to be run on demand, Run task as soon as possible after a scheduled start is missed, If the task fails, restart every 1 minute, If the running task does not end when requested, force it to stop, and finally, Stop the existing instance from the dropdown. 

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:

The Intune Deployment

  1. Export the scheduled task. This will export the XML file needed for Intune.
  2. Create an install.ps1 script to copy the files to the local machine (including the xml file) and register the scheduled task. See below…
    # Copy the XML file, batch file, and PowerShell script to the C:\temp\scripts folder, and created log directory
$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 "/"

Create uninstall.ps1 to remove the scheduled task, log and scripts directory and contents.

$taskExists = Get-ScheduledTask | Where-Object {$_.TaskName -like "NameOfScheduledTask"}
if($taskExists) {
Write-Host "Success"
Exit 0
} else {
Exit 1}
  1. Place all files in a folder of your choice.
  2. Create intunewin file from install.ps1 PowerShell script.
  3. Create Win32App in Intune

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!

Leave a Reply

Your email address will not be published. Required fields are marked *