dk-one

Probleme beim Erstellen eines Device Tunnels für Always ON VPN ohne MDM-Provider

Für eine Windows 2019-Domäne möchte ich Always ON VPN konfigurieren. Ich möchte AOVPN (IKEv2 mit Maschinenzertifikat) ausrollen. Ziel ist ein echter Device Tunnel (AlwaysOn + DeviceTunnel)damit Geräte schon vor Benutzer-Logon Domänen-Konnektivität haben (DCDNSSkripteGPOsSoftwareverteilung).

  • VPN-Gateway: vpn.example.com
  • Interner DNS-Suffix: corp.local
  • Beispielroute: 10.0.0.0/24
  • Clients: Windows 10/11 (Domänenmitglied)

Was ich versucht habe (chronologisch)

1) CSP direkt (ohne MDM) – kurzfristig sichtbardann gelöscht

Ich habe das VPNv2-Profil per CSP unter ./Vendor/MSFT/VPNv2/DeviceTunnel-… erzeugt (WCD/ProfileXML bzw. API).
Ergebnis: Das Profil taucht kurz aufwird aber wieder entfernt. Im Eventlog (DeviceManagement-Enterprise-Diagnostics-Provider/Admin) sehe ich:

Id 601 – MDM ResourceManager: DeleteResource
URI: ./Vendor/MSFT/VPNv2/DeviceTunnel-…

Scheinbar: Windows akzeptiert die CSP-Objekte nurwenn eine gültige Policy-Quelle (EnrollmentID) existiert. Ohne MDM-Quelle stuft Windows das Objekt als „verwaist“ ein → Cleanup (Event 601).
(Die vielen Event-IDs 813 in dem Kontext waren nur Power-Policy-Initirrelevant.)

2) „Offline-MDM“ mit WCD (Windows Configuration Designer) – GUI

  • Store-WCD: hatte bei mir keine UI für „Accounts → Enrollments → MDM“.
  • ADK-WCD: bietet den MDM-Knoten. Dort habe ich ein lokales MDM-Enrollment (Dummy) angelegt:
      • Enrollment service URL: https://mdm.example.local
      • Provider name: beliebig
      • Provider ID: GUID
      • Target: Device

Anschließend unter Network → VPNv2 ein ProfileXML mit <AlwaysOn>true</AlwaysOn><DeviceTunnel>true</DeviceTunnel>IKEv2/MachineCert/Routen/NRPT hinterlegt und ein PPKG gebaut.

Ergebnis: Auch hier wurde der Eintrag wieder bereinigt (Event 601). Das „Offline-Enrollment“ via PPKG reichte in meinem Setup nicht ausum eine stabile EnrollmentID/Policy-Quelle zu hinterlegendie Windows dauerhaft respektiert.

3) PPKG per PowerShell/PSD1 (ohne GUI)

Plan: New-ProvisioningPackage mit einer .psd1die Enrollment + VPNv2-CSP beschreibt.
Problem: Auf einem frischen System gab es weder das Modul WindowsProvisioning noch das Cmdlet New-ProvisioningPackage. Die Datei Microsoft.Windows.Provisioning.Commands.dll war systemweit nicht vorhanden.

  • Ich habe das ADK inkl. „Imaging and Configuration Designer (ICD)“ installiert.
  • Trotzdem ergab die Suche innerhalb C:\Program Files (x86)\Windows Kits\10\… keinen Treffer für diese DLL.
  • Ergebnis: Mit aktuellen Windows-11-ADK-Builds scheint das PowerShell-Modul nicht mehr ausgeliefert zu werden. Workaround wäre wohl ein Windows-10-ADK (22H2) parallel — das habe ich an der Stelle nicht weiterverfolgtweil ich erst den GUI-Weg verifizieren wollte.

Zwischenfazit:

  • Ohne echtes MDM-Enrollment löscht Windows den Device-Tunnel (MDM ResourceManagerEvent 601).
  • Das „Offline-Enrollment“ via PPKG (WCD) hat bei mir keinen persistierenden Gerätekontext erzeugt.
  • Der PowerShell-Weg scheiterte an fehlenden Cmdlets/Modulen im aktuellen ADK; die besagte DLL war nicht vorhanden.

Mein Verständnis (warum das passiert)

  • Device Tunnel ist eine MDM-Policy-Funktion (CSP ./Vendor/MSFT/VPNv2).
  • Jeder Eintrag trägt eine EnrollmentID als Policy-Quelle.
  • Fehlt die Quelle (kein echtes MDM oder „Offline-Enrollment“ wird nicht als gültig anerkannt)dann greift MDM ResourceManager → DeleteResource (601).
  • Ergebnis: Kein persistenter Device-Tunnel ohne echtes MDM.
  • Das deckt sich mit Hinweisen in Dokus/Blogsaber die Aussagen zu „PPKG simuliert MDM“ sind in der Praxis (Win10/Win11aktuelle Builds) inkonsistent.

Offene Fragen an die Community

1 Hat jemand ein „Offline-MDM/PPKG“ (WCD/ADK) unter Win10/11 stabil zum Laufen gebrachtso dass der Device-Tunnel persistiert und nicht per Event 601 gelöscht wird?
  • Falls ja: Welche ADK/WCD-Versionenwelche Felder in Enrollments → MDM waren entscheidend (URL/ProviderID/Auth)?
  • Musste zusätzlich ein Root-CA-Zertifikat gebündelt werden?
  • Wurden 801/803/1130 geloggt ohne nachfolgenden 601?
2 PowerShell-PPKG-Build:
  • Bestätigungdass die Win11-ADK-Builds die DLL Microsoft.Windows.Provisioning.Commands.dll nicht mehr enthalten?
  • Nutzt jemand als Workaround das Win10-ADK (22H2) parallel? Irgendwelche Nebenwirkungen?
Auf Facebook teilen
Auf X (Twitter) teilen
Auf Reddit teilen
Auf Linkedin teilen

Content-ID: 674412

Url: https://administrator.de/forum/device-tunnel-vpn-windows-mdm-674412.html

Ausgedruckt am: 10.02.2026 um 01:02 Uhr

Vision2015
Vision2015 22.08.2025 um 06:47:39 Uhr
Moin,

Ziel ist ein echter Device Tunnel (AlwaysOn + DeviceTunnel)damit Geräte schon vor Benutzer-Logon Domänen-Konnektivität haben
das würde ich aber nicht auf einen. DC / Windows Server machensondern über VPN RouterFWUDM etc...
selbst MS Supportet Always On VPN nicht mehrdas war 2016/2018 mal in.....

das ausrollen der IKE2 ist heher kein Problem.
Verwendung von Gruppenrichtlinien zur Remoteinstallation von Software

Frank
UnbekannterNR1
UnbekannterNR1 22.08.2025 um 08:48:18 Uhr
Also ich rolle die auch komplett ohne MDM oder ähnlich mit PowerShell aus.
Ich würde an dieser Stelle auf directaccess.richardhicks.com/2017/12/11/always-on-vpn-windows-1 ... Verweisen.

Um das hervorzuheben: Wichtig ist natürlichdasswenn du einen Tunnel in das Gerät schreiben willstdieser Prozess als SYSTEM laufen muss. Andernfalls hängt er – wie beschrieben – möglicherweise an einem normalen User oder Admin fest und funktioniert nicht.
aqui
aqui 22.08.2025 um 10:56:54 Uhr
Ein VPN gehört aus guten Gründen niemals auf einen lokalen Server sondern immer auf die Peripherie wie Router oder Firewall.
IPsec IKEv2 VPN für mobile Benutzer auf der pfSense oder OPNsense Firewall einrichten
IKEv2 VPN Server für Windows und Apple Clients mit Raspberry Pi
Usw. usw...
dk-one
dk-one 22.08.2025 um 11:56:38 Uhr
Always VPN On wurde zwar mit Windows Server 2016 und Windows 10 eingeführtwird aber immer noch von M$ supportet. Du meinst vermutlich DirectAccessdas in der Tat nicht mehr supportet wird.
dk-one
dk-one 22.08.2025 um 12:00:04 Uhr
Meinst Du aber auch tatsächlich den Device Tunnel? Oder den User Tunnel?

Kannst Du mir ein Dummy XML-Profil und das PowerShell mal zukommen lassen? Das von Dir verlinkte Beispiel Profile + PowerShell-Script habe ich als SYSTEM laufen lassen und es bricht mit einem Fehler ab,
dk-one
dk-one 22.08.2025 um 13:49:28 Uhr
Ein Device Tunnel MUSS auf einem Windows Server terminiert werden.
Vision2015
Vision2015 22.08.2025 um 16:50:36 Uhr
Moin...
Zitat von @dk-one:

Ein Device Tunnel MUSS auf einem Windows Server terminiert werden.

jaaber wer macht so wasund warum?

Frank
Dani
Dani 22.08.2025 um 23:15:43 Uhr
Moin,
Kannst Du mir ein Dummy XML-Profil und das PowerShell mal zukommen lassen? Das von Dir verlinkte Beispiel Profile + PowerShell-Script habe ich als SYSTEM laufen lassen und es bricht mit einem Fehler ab,
steht doch alles in dem Link welcher Kollege @UnbekannterNR1 genannt hat. Einfacher wird es nicht mehr...

jaaber wer macht so wasund warum?
wir haben die Lösung seit 5 Jahren flächendeckend im Einsatz. Die Server stehen in der DMZ. Die Lösung kostet uns erst einmal nicht mehr als andere Lösungen. Das passende Betriebsteam brauche ich so oder so. Passt perfekt ins Microsoft Ökosystem. Skaliert recht gut im Kombination mit Geo LocationLoad BalancingFailover.

@aqui
Ein VPN gehört aus guten Gründen niemals auf einen lokalen Server sondern immer auf die Peripherie wie Router oder Firewall.
Ausnahmen bestätigen die Regel. Ich will mal 40.000 oder 100.000 VPN Profile auf einer Firewall/Router sehen. Das wird niemals gut gehen... hab ich in 20 Jahren auch noch nie so gesehen. Aber du wirst mich evtl. korrigieren. 😉

Gruß,
Dani
dk-one
dk-one 23.08.2025 aktualisiert um 03:09:01 Uhr
Du hast nicht sauber gelesenDani.

Das von Dir verlinkte Beispiel Profile + PowerShell-Script habe ich als SYSTEM laufen lassen und es bricht mit einem Fehler ab,

Ich kann das Profile für den Device Tunnel nicht erstellen. Nicht mit meinem Script und nicht mit dem von UnbekannterNR1 verlinkten Beispiel-Scripten. Den genauen Fehler habe ich oben bereits benannt.

Und die Frage warob ich ein Profil für einen Device Tunnel mit CSP ./Vendor/MSFT/VPNv2 NUR erstellen kannwenn ich ein MDM-Enrollment (IntuneNinja etc.) einsetze. Auch der AutorRichard Hicksbenutzt ein MDM-Enrollment. Ich habe es 2 Tage versuchtsogar mithilfe der KIaber es wollte nicht funktionieren. Alle Prerequisites sind erfüllt. Oder eben auch nicht.
Dani
Dani 23.08.2025 um 11:27:21 Uhr
Moin,
in dem Fall poste deine XMLdeine Befehle und deren Output. Letzteres gerne als Screenshots. Damit wir sehenwas du ausführst und welche Output generiert wird.

Ich kann das Profile für den Device Tunnel nicht erstellen. Nicht mit meinem Script und nicht mit dem von UnbekannterNR1 verlinkten Beispiel-Scripten.
Grundsätzlich funktioniert es. Wir deployen (mit Hilfe des Artikels) über ein UEM diese Tunnelart auf mehreren Tausend Geräten erfolgreich. Wir sind allerdings auf Windows Server 2019 und Windows 11 Enterprise.

Gruß,
Dani
dk-one
dk-one 23.08.2025 um 17:19:15 Uhr
Danke. Ich habe es jetzt hinbekommen. Es war ein Definitionsfehler im ProfileXML_Device.xml. Jetzt ist der Device Tunnel vorhanden.
UnbekannterNR1
UnbekannterNR1 23.08.2025 um 22:16:39 Uhr
Zitat von @dk-one:

Danke. Ich habe es jetzt hinbekommen. Es war ein Definitionsfehler im ProfileXML_Device.xml. Jetzt ist der Device Tunnel vorhanden.

Sehr gut! 👍
Zur Dokumentation hänge ich hier trotzdem noch meine PowerShell-Quelle an. Ich habe das Skript noch erweitertsodass ich meine AOVPN-Konfigurationsdatei bei Bedarf auch updaten kann. Dabei wird ein Registry-Key mit der Versionsnummer gespeichert – falls man mal etwas anpassen muss.

Und vor allem habe ich auch noch eine Frage:
Zitat von @dk-one:

in Device Tunnel MUSS auf einem Windows Server terminiert werden.

Gibt es dazu irgendwo eine verlässliche Quelle?
Ich habe die Tunnel aktuell auf einem separaten VPN-Host terminiertwürde aber ggf. auch noch ein Gateway dafür einsetzen.

Der Aufruf ist natürlich ebenfalls wichtig:
Ich lasse das Ganze beim Booten über eine geplante Aufgabe laufen. Die benötigten Dateien werden vorher (automatisch) auf den Client kopiertdamit sich das Skript bei einem Update nicht selbst aussperrt.

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe   
 Argumente  -Noninteractive -ExecutionPolicy Bypass -Noprofile -file c:\Windows\logs\AOVPN\new-aovpnconnection.ps1 -xmlFilePath .\devicetunnnel.xml 

<#
.SYNOPSIS
    Creates an Always On VPN device tunnel connection

.PARAMETER xmlFilePath
    Path to the ProfileXML configuration file

.PARAMETER ProfileName
    Name of the VPN profile to be created

.EXAMPLE
    .\New-AovpnDeviceTunnel.ps1 -xmlFilePath "C:\Temp\Device.xml" -ProfileName "Always On VPN Device Tunnel"  

.DESCRIPTION
    This script will create an Always On VPN device tunnel on supported Windows 10 devices

.LINK
    https://github.com/ConfigJon/AlwaysOnVPN/blob/master/New-AovpnDeviceTunnel.ps1

.NOTES
    Creation Date:      May 282019
    Last Updated:       August 172020
    Note:               This is a modified version of a script that Richard Hicks has on his GitHub
    Original Script:    https://github.com/richardhicks/aovpn/blob/master/New-AovpnDeviceConnection.ps1
#>

[CmdletBinding()]

Param(
    [Parameter(Mandatory = $TrueHelpMessage = 'Enter the path to the ProfileXML file.')]      
    [string]$xmlFilePath,
    [Parameter(Mandatory = $FalseHelpMessage = 'Enter a name for the VPN profile.')]          
    [string]$ProfileName = 'Always On VPN Device Tunnel'  
)

#Variables ============================================================================================================
$RegKey = "SOFTWARE\AOVPNVPnConfig"  
$RegValue = "AOVPNDeviceTunnelVersion"  
# $DeviceTunnelVersion = 2
$FullPath = "HKLM:\$RegKey"  
$DeviceTunnelVersion 
#Functions ============================================================================================================
Function New-RegistryValue
{
    [CmdletBinding()]
    param(   
        [String][parameter(Mandatory=$true)][ValidateNotNullOrEmpty()]$RegKey,
        [String][parameter(Mandatory=$true)][ValidateNotNullOrEmpty()]$Name,
        [String][parameter(Mandatory=$true)][ValidateSet('String','ExpandString','Binary','DWord','MultiString','Qword','Unknown')]$PropertyType 
        [String][parameter(Mandatory=$true)][ValidateNotNullOrEmpty()]$Value
    )
        
    #Create the registry key if it does not exist
    if(!(Test-Path $RegKey))
    {
        try{New-Item -Path $RegKey -Force | Out-Null}
        catch{throw "Failed to create $RegKey"}  
    }

    #Create the registry value
    try
    {
        New-ItemProperty -Path $RegKey -Name $Name -PropertyType $PropertyType -Value $Value -Force | Out-Null
    }
    catch
    {
        Write-LogEntry -Value "Failed to set $RegKey\$Name to $Value" -Severity 3  
        throw "Failed to set $RegKey\$Name to $Value"  
    }

    #Check if the registry value was successfully created
    $KeyCheck = Get-ItemProperty $RegKey
    if($KeyCheck.$Name -eq $Value)
    {
        Write-LogEntry -Value "Successfully set $RegKey\$Name to $Value" -Severity 1  
    }
    else
    {
        Write-LogEntry -Value "Failed to set $RegKey\$Name to $Value" -Severity 3  
        throw "Failed to set $RegKey\$Name to $Value"  
    }
}

#Write data to a CMTrace compatible log file. (Credit to SCConfigMgr - https://www.scconfigmgr.com/)
Function Write-LogEntry
{
	param(
		[parameter(Mandatory = $trueHelpMessage = "Value added to the log file.")]  
		[ValidateNotNullOrEmpty()]
		[string]$Value,
		[parameter(Mandatory = $trueHelpMessage = "Severity for the log entry. 1 for Informational2 for Warning and 3 for Error.")]  
		[ValidateNotNullOrEmpty()]
		[ValidateSet("1""2""3")]  
		[string]$Severity,
		[parameter(Mandatory = $falseHelpMessage = "Name of the log file that the entry will written to.")]  
		[ValidateNotNullOrEmpty()]
		[string]$FileName = "Install-AOVPN-Device.log"  
	)
    #Determine log file location
    $LogFilePath = Join-Path -Path $LogsDirectory -ChildPath $FileName
		
    #Construct time stamp for log entry
    if(-not(Test-Path -Path 'variable:global:TimezoneBias'))  
    {
        [string]$global:TimezoneBias = [System.TimeZoneInfo]::Local.GetUtcOffset((Get-Date)).TotalMinutes
        if($TimezoneBias -match "^-")  
        {
            $TimezoneBias = $TimezoneBias.Replace('-''+')  
        }
        else
        {
            $TimezoneBias = '-' + $TimezoneBias  
        }
    }
    $Time = -join @((Get-Date -Format "HH:mm:ss.fff")$TimezoneBias)  
		
    #Construct date for log entry
    $Date = (Get-Date -Format "MM-dd-yyyy")  
		
    #Construct context for log entry
    $Context = $([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)
		
    #Construct final log entry
    $LogText = "<![LOG[$($Value)]LOG]!><time=""$($Time)"" date=""$($Date)"" component=""Install-AOVPN"" context=""$($Context)"" type=""$($Severity)"" thread=""$($PID)"" file="""">"  
		
    #Add value to log file
    try
    {
        Out-File -InputObject $LogText -Append -NoClobber -Encoding Default -FilePath $LogFilePath -ErrorAction Stop
    }
    catch [System.Exception]
    {
        Write-Warning -Message "Unable to append log entry to $FileName file. Error message at line $($_.InvocationInfo.ScriptLineNumber): $($_.Exception.Message)"  
    }
}


#Main Program =========================================================================================================
#########################

$LogsDirectory = "$ENV:windir\logs\AOVPN"  


# Erste Zeile lesen (oder die komplette Datei und den Kommentar finden)
$firstLine = Get-Content $xmlFilePath -TotalCount 1

# Version aus Kommentar extrahieren
if ($firstLine -match '<!--\s*Version\s+([0-9.]+)\s*-->') {  
    $foundVersion = $matches[1] 
    $DeviceTunnelVersion = [int]($foundVersion.Split('.')[0])  
    Write-LogEntry -Value "Gefundene Version: $DeviceTunnelVersion" -Severity 1  
} else {
    Write-LogEntry -Value "Keine Versionsnummer gefunden" -Severity 2   
}


# Versuchden Wert auszulesen
try {
    $CurrentVersion = Get-ItemPropertyValue -Path $FullPath -Name $RegValue -ErrorAction Stop
} catch {
    #Write-Host "Registry-Wert nicht gefunden. Skript wird gestartet..."  
    $CurrentVersion = 0
    Write-LogEntry -Value "Registry-Wert nicht gefunden. Skript wird gestartet..."  -Severity 1  
}

# Vergleich und ggf. Skriptaufruf
if ($CurrentVersion -lt $DeviceTunnelVersion) {
    #Write-Host "Aktuelle Version ($CurrentVersion) ist kleiner als Zielversion ($DeviceTunnelVersion). Skript wird ausgeführt..."  
    #  & "C:\Windows\Logs\new-aovpn.ps1" -xmlpath ".\connection.xml" -version $DeviceTunnelVersion  
    Write-LogEntry -Value "Aktuelle Version ($CurrentVersion) ist kleiner als Zielversion ($DeviceTunnelVersion). Skript wird ausgeführt..."  -Severity 1  

###########################

if(!(Test-Path -PathType Container $LogsDirectory))
{
    New-Item -Path $LogsDirectory -ItemType "Directory" -Force | Out-Null  
}

Write-LogEntry -Value "START - Always On VPN Device Tunnel Script" -Severity 1  


#Script must be running in the context of the SYSTEM account to extract ProfileXML from a device tunnel connection. Validate userexit if not running as SYSTEM
Write-LogEntry -Value "Detect if the script is being run in the SYSTEM context" -Severity 1  
$CurrentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
$CurrentUserName = $CurrentPrincipal.Identities.Name

if($CurrentUserName -ne 'NT-AUTORITÄT\SYSTEM')  
{
    Write-LogEntry -Value "This script is not running in the SYSTEM context" -Severity 3  
    Write-LogEntry -Value "Use the Sysinternals tool Psexec.exe with the -i and -s parameters to run this script in the context of the local SYSTEM account." -Severity 3  
    throw "This script is not running in the SYSTEM context"  
}

#Check for existing connection and remove if found
Write-LogEntry -Value "Check for and remove old instances of the device tunnel" -Severity 1  
$Count = 0
while((Get-VpnConnection -Name $ProfileName -AllUserConnection -ErrorAction SilentlyContinue) -and ($Count -lt 20))
{
    Write-LogEntry -Value "Existing device tunnel detected. Attempt to disconnect and remove ($($Count + 1)/20)" -Severity 1  
    # Disconnect the tunnel
    rasdial.exe $ProfileName /disconnect | Out-Null
    # Delete the tunnel
    Get-VpnConnection -Name $ProfileName -AllUserConnection | Remove-VpnConnection -Force -ErrorAction SilentlyContinue
    Start-Sleep -Seconds 2
    $Count++
}

#Exit if the loop fails to delete the tunnel
if(Get-VpnConnection -Name $ProfileName -AllUserConnection -ErrorAction SilentlyContinue)
{
    $ErrorMessage = "Unable to remove existing outdated instance(s) of $ProfileName"  
    Write-LogEntry -Value $ErrorMessage -Severity 3
    throw $ErrorMessage
}

#Import the Profile XML
Write-LogEntry -Value "Import the device profile XML" -Severity 1  
$ProfileXML = Get-Content $xmlFilePath

#Escape spaces in the profile name
$ProfileNameEscaped = $ProfileName -replace ' ''%20'  
$ProfileXML = $ProfileXML -replace '<''<'  
$ProfileXML = $ProfileXML -replace '>''>'  
$ProfileXML = $ProfileXML -replace '"''"'  

#OMA URI information
$NodeCSPURI = './Vendor/MSFT/VPNv2'  
$NamespaceName = 'root\cimv2\mdm\dmmap'  
$ClassName = 'MDM_VPNv2_01'  

#Create a new CimSession
$Session = New-CimSession

#Create the device tunnel
$Error.Clear()
try
{
    Write-LogEntry -Value "Construct a new CimInstance object" -Severity 1  
    $NewInstance = New-Object Microsoft.Management.Infrastructure.CimInstance $ClassName$NamespaceName
    $Property = [Microsoft.Management.Infrastructure.CimProperty]::Create('ParentID'"$nodeCSPURI"'String''Key')  
    $NewInstance.CimInstanceProperties.Add($Property)
    $Property = [Microsoft.Management.Infrastructure.CimProperty]::Create('InstanceID'"$ProfileNameEscaped"'String''Key')  
    $NewInstance.CimInstanceProperties.Add($Property)
    $Property = [Microsoft.Management.Infrastructure.CimProperty]::Create('ProfileXML'"$ProfileXML"'String''Property')  
    $NewInstance.CimInstanceProperties.Add($Property)
    Write-LogEntry -Value "Create the new device tunnel" -Severity 1  
    $Session.CreateInstance($NamespaceName$NewInstance)
    Write-LogEntry -Value "Always On VPN device tunnel ""$ProfileName"" created successfully." -Severity 1  
}
catch [Exception]
{
    $ErrorMessage = "Unable to create $ProfileName profile: $_"  
    Write-LogEntry -Value $ErrorMessage -Severity 3
    throw $ErrorMessage
}

#Configure enchanced IKEv2 security settings
#Set-VpnConnectionIPsecConfiguration -ConnectionName $ProfileName -AuthenticationTransformConstants SHA256128 -CipherTransformConstants AES128 -DHGroup Group14 -EncryptionMethod AES128 -IntegrityCheckMethod SHA256 -PFSgroup PFS2048 -Force

#Create a registry key for detection
if(!($Error))
{
    Write-LogEntry -Value "Create the registry key to use for the detection method" -Severity 1  
    #Create a registry key for detection
    New-RegistryValue -RegKey "HKLM:\$($RegKey)" -Name $RegValue -PropertyType DWord -Value $DeviceTunnelVersion  
}
Write-LogEntry -Value "END - Always On VPN Device Tunnel Script" -Severity 1  

} else {
 #   Write-Host "Version ist aktuell ($CurrentVersion). Kein weiteres Vorgehen nötig."  
    Write-LogEntry -Value "Version ist ($CurrentVersion) aktutell. Kein weiteres Vorgehen nötig." -Severity 1  
}

Und die XML Dateiwichtig mit Versionsnummer passend zu dem Skript
<!-- Version 4 -->
<VPNProfile>
   <AlwaysOn>true</AlwaysOn>
   <DeviceTunnel>true</DeviceTunnel>
   <DnsSuffix>intern.firma.de</DnsSuffix>
   <TrustedNetworkDetection>intern.firma.de</TrustedNetworkDetection>
   <!-- The following settings are supported in Windows 11 22H2 and later. -->
   <DisableAdvancedOptionsEditButton>true</DisableAdvancedOptionsEditButton>
   <DisableDisconnectButton>true</DisableDisconnectButton>
   <NativeProfile>
      <!-- The VPN server is listed twice by design. This is required when deploying XML with Intune to Windows 11 devices. Details here: https://rmhci.co/48NTp3e -->
      <Servers>vpn.firma.de;vpn.firma.de</Servers>
      <!-- Only SplitTunnel routing policy is supported for the Always On VPN device tunnel. Force tunneling is explicitly not supported. -->
      <RoutingPolicyType>SplitTunnel</RoutingPolicyType>
      <!-- Only IKEv2 is supported for use with the Always On VPN device tunnel. -->
      <NativeProtocolType>IKEv2</NativeProtocolType>
      <!-- Only machine certificate authentication is supported for the Always On VPN device tunnel. -->
      <Authentication>
         <MachineMethod>Certificate</MachineMethod>
      </Authentication>
      <!-- The CryptographySuite setting is optional but recommended when using IKEv2. The default security settings for IKEv2 are extremely weak. Details here: https://rmhci.co/2Eou3Op. -->
      <!-- Enabling this setting requires the VPN server to use matching settings. A PowerShell script to configure Windows Server RRAS servers can be found here: https://rmhci.co/2WRpFgl. -->
      <!-- The cryptography settings defined below are recommended minimum security baselines. They can be changed to meet higher level security requirements as required. -->
      <!-- This setting is optional but recommended. -->
      <DisableClassBasedDefaultRoute>true</DisableClassBasedDefaultRoute>
   </NativeProfile>
   <!-- The Route setting is required when DisableClassBasedDefaultRoute is set to "true". --> 
   <!-- Host routes (/32 or /128) should be used to restrict access over the device tunnel to domain controllers. Using traffic filters is not recommended prior to Windows 10 2004 as it prevents outbound management. -->
   <Route>
      <Address>0.0.0.0</Address>
      <PrefixSize>0</PrefixSize>
      <Metric>1</Metric>
   </Route>
   <Route>
      <Address>128.0.0.0</Address>
      <PrefixSize>1</PrefixSize>
      <Metric>1</Metric>
   </Route>
   <!-- The RegisterDNS element is optional and used to register the IP address of the device tunnel VPN connection in internal DNS. If a user tunnel is deployed in conjunction with a device tunnelthis element should only be defined on the device tunnel. -->
   <RegisterDNS>true</RegisterDNS>   
   <!-- The following settings supported in Windows 11 24H2 and later -->
   <!-- Define Network Outage Time for IKEv2 -->
   <NetworkOutageTime>0</NetworkOutageTime>
   <!-- VPN tunnel interface metric settings -->
   <IPv4InterfaceMetric>3</IPv4InterfaceMetric>
   <!-- Recommend to set to 'false' on Entra-Join only endpoints --> 
   <UseRasCredentials>false</UseRasCredentials>
   <!-- PPP encryption setting -->   
   <DataEncryption>Max</DataEncryption>
   <!-- Enforce Private Windows firewall profile -->
   <!--  <PrivateNetwork>true</PrivateNetwork> -->
   <!-- Enable/Disable IKEv2 fragmentation - Recommended setting is 'false' --> 
   <DisableIKEv2Fragmentation>false</DisableIKEv2Fragmentation>
</VPNProfile>
Dani
Dani 23.08.2025 um 23:02:49 Uhr
Moin,
Ich habe die Tunnel aktuell auf einem separaten VPN-Host terminiertwürde aber ggf. auch noch ein Gateway dafür einsetzen.
was hast du für ein VPN Host im Einsatz?

Gruß,
Dani
UnbekannterNR1
UnbekannterNR1 23.08.2025 um 23:14:47 Uhr
TatsächlichWindows Server 2022 Datacenter halt als VM hinter meinem Sense-Konstruktweil esmit denen nicht zum Laufen bekommen habe. Mit Server 2025 gab es aber auch Problemebin gerade nicht ganz sicherdenn ich hatte mehrere unter anderen die Aktivierungweil unser KMS die noch nicht kannteaber ggf. auch was mit VPN lief nicht rund. Und ich hatte ehrlich keine Lustnachdem alles liefdie Server nochmal auf neuste Version zu ziehen.

Was Du ggf. noch Server seitig und auf den Clients aktivieren willstwäre die Fragmentierung von Paketen bzw. die MTU Größe von den VPN Paketen anpassengerade bei WLAN Netzen kann es sonst zu Problemen kommen. Beides hat der Godfahter of Always ON VPN Richard M. Hicks gut beschrieben.
Dani
Dani 23.08.2025 um 23:57:05 Uhr
Moin,
TatsächlichWindows Server 2022 Datacenter halt als VM hinter meinem Sense-Konstruktweil esmit denen nicht zum Laufen bekommen habe.
wäre mir neudass Always ON VPN mit anderen Produkten wie Windows Server als Endpunkt funktioniert.

Gruß,
Dani