教學課程:部署 AlwaysOn VPN:設定適用於 Windows 10+ 用戶端的 AlwaysOn VPN 設定檔

適用於:Windows Server 2022、Windows Server 2019、Windows Server 2016、Windows Server 2012 R2、Windows 10、Windows 11

在本教學課程的最後一個部分中,您將了解如何使用 ProfileXML PowerShell 組態指令碼來設定 AlwaysOn VPN 設定,並建立用戶端連線的使用者通道。

如需關於組態服務提供者 (CSP) 的 Always on VPN 組態選項詳細資訊,請參閱 VPNv2 組態服務提供者

必要條件

完成教學課程:部署 AlwaysOn VPN:設定憑證授權單位範本

建立 AlwaysOn VPN 用戶端設定檔

在本節中,我們將建立 VPN 用戶端連線,以確認 VPN 測試用戶端可以建立成功的 VPN 連線。 藉此我們也可建立要在下一節匯出的 EAP 設定。

如需 EAP 設定的詳細資訊,請參閱 EAP 組態

  1. 以您在建立 Active Directory 測試使用者中所建立的 VPN 使用者身分,登入已加入網域的 VPN 用戶端電腦。

  2. 在 [開始] 功能表上,輸入 VPN 以選取 [VPN 設定]。 按 ENTER 鍵。

  3. 在詳細資料窗格中,選取 [新增 VPN 連線]。

  4. 針對 [VPN 提供者],選取 [Windows (內建)]。

  5. 針對 [連線名稱],輸入 Contoso VPN

  6. 針對 [伺服器名稱或位址],輸入 VPN 伺服器的外部 FQDN (例如:vpn.contoso.com)。

  7. 針對 [VPN 類型],選取 [IKEv2]。

  8. 針對 [登入資訊類型],選取 [憑證]。

  9. 選取 [儲存]。

  10. 在 [相關設定] 下方,選取 [變更介面卡選項]。

  11. 以滑鼠右鍵按一下 [Contoso VPN],然後選取 [內容]。

  12. 在 [安全性] 索引標籤上,針對 [資料加密],選取 [最大強度加密]。

  13. 選取 [使用可延伸的驗證通訊協定 (EAP)]。 然後,針對 [使用可延伸的驗證通訊協定 (EAP)],選取 [Microsoft:受保護的 EAP (PEAP) (已啟用加密)]。

  14. 選取 [內容] 以開啟 [受保護的 EAP 內容],然後完成下列步驟:

    1. 針對 [連線到這些伺服器],輸入 NPS 伺服器的名稱。

    2. 針對 [受信任的根憑證授權單位],選取發出 NPS 伺服器憑證的 CA (例如 contoso-CA)。

    3. 針對 [連線前的通知],選取 [不要要求使用者授權新伺服器或受信任的 CA]。

    4. 針對 [選取驗證方法],選取 [智慧卡或其他憑證]。

    5. 選取設定

      1. 選取 [使用這台電腦上的憑證]。

      2. 針對 [連線到這些伺服器],輸入 NPS 伺服器的名稱。

      3. 針對 [受信任的根憑證授權單位] 下,選取發出 NPS 伺服器憑證的 CA。

      4. 選取 [不提示使用者授權新伺服器或受信任的憑證授權單位]。

      5. 選取 [確定] 以關閉 [智慧卡或其他憑證內容]。

      6. 選取 [確定] 以關閉 [受保護的 EAP 內容]。

    6. 選取 [確定] 以關閉 [Contoso VPN 內容]。

  15. 關閉 [網路連線] 視窗。

  16. 在 [設定] 中,選取 [Contoso VPN],然後選取 [連線]。

重要

請確定範本 VPN 已成功連線至 VPN 伺服器。 這麼做可先確保 EAP 設定正確無誤,再於下一個步驟中使用這些設定。 您必須至少連線一次再繼續;否則,設定檔不會包含要連線到 VPN 所需的所有資訊。

設定 Windows VPN 用戶端

在本節中,您將使用 PowerShell 指令碼手動設定 Windows VPN 用戶端。

  1. 以 VPN 使用者身分登入 VPN 用戶端電腦。

  2. 以系統管理員身分開啟 Windows PowerShell 整合式指令碼環境 (ISE)。

  3. 複製並貼上下列指令碼:

    
    # Define key VPN profile parameters
    # Replace with your own values
    
    $Domain = 'corp' # Name of the domain.
    
    $TemplateName = 'Contoso VPN' # Name of the test VPN connection you created in the tutorial. 
    
    $ProfileName = 'Contoso AlwaysOn VPN' # Name of the profile we are going to create.
    
    $Servers = 'aov-vpn.contoso.com' #Public or routable IP address or DNS name for the VPN gateway.
    
    $DnsSuffix = 'corp.contoso.com' # Specifies one or more commas separated DNS suffixes. 
    
    $DomainName = '.corp.contoso.com' #Used to indicate the namespace to which the policy applies. Contains `.` prefix.
    
    $DNSServers = '10.10.0.6' #List of comma-separated DNS Server IP addresses to use for the namespace.
    
    $TrustedNetwork = 'corp.contoso.com' #Comma-separated string to identify the trusted network.
    
    
    #Get the EAP settings for the current profile called $TemplateName
    
    $Connection = Get-VpnConnection -Name $TemplateName
    
    if(!$Connection)
    {
        $Message = "Unable to get $TemplateName connection profile: $_"
        Write-Host "$Message"
        exit
    }
    
    $EAPSettings= $Connection.EapConfigXmlStream.InnerXml
    
    $ProfileNameEscaped = $ProfileName -replace ' ', '%20'
    
    # Define ProfileXML
    $ProfileXML = @("
    <VPNProfile>
      <DnsSuffix>$DnsSuffix</DnsSuffix>
      <NativeProfile>
    <Servers>$Servers</Servers>
    <NativeProtocolType>IKEv2</NativeProtocolType>
    <Authentication>
      <UserMethod>Eap</UserMethod>
      <Eap>
        <Configuration>
        $EAPSettings
        </Configuration>
      </Eap>
    </Authentication>
    <RoutingPolicyType>SplitTunnel</RoutingPolicyType>
      </NativeProfile>
    <AlwaysOn>true</AlwaysOn>
    <RememberCredentials>true</RememberCredentials>
    <TrustedNetworkDetection>$TrustedNetwork</TrustedNetworkDetection>
      <DomainNameInformation>
    <DomainName>$DomainName</DomainName>
    <DnsServers>$DNSServers</DnsServers>
    </DomainNameInformation>
    </VPNProfile>
    ")
    
    #Output the XML for possible use in Intune
    $ProfileXML | Out-File -FilePath ($env:USERPROFILE + '\desktop\VPN_Profile.xml')
    
    # Escape special characters in the profile (<,>,")
    $ProfileXML = $ProfileXML -replace '<', '&lt;'
    $ProfileXML = $ProfileXML -replace '>', '&gt;'
    $ProfileXML = $ProfileXML -replace '"', '&quot;'
    
    # Define WMI-to-CSP Bridge properties
    $nodeCSPURI = "./Vendor/MSFT/VPNv2"
    $namespaceName = "root\cimv2\mdm\dmmap"
    $className = "MDM_VPNv2_01"
    
    try
    {
    
        # Determine user SID for VPN profile.
        $WmiLoggedOnUsers = (Get-WmiObject Win32_LoggedOnUser).Antecedent
        If($WmiLoggedOnUsers.Count -gt 1) { 
            $WmiLoggedOnUsers = $WmiLoggedOnUsers -match "Domain=""$Domain"""
        }
    
        $WmiUserValid = ($WmiLoggedOnUsers | Select-Object -Unique -First 1) -match 'Domain="([^"]+)",Name="([^"]+)"'
    
        If(-not $WmiUserValid){
            Throw "Returned object is not a valid WMI string"
        }
    
    
        $UserName = "$($Matches[1])\$($Matches[2])"
    
        $ObjUser = New-Object System.Security.Principal.NTAccount($UserName)
        $Sid = $ObjUser.Translate([System.Security.Principal.SecurityIdentifier])
        $SidValue = $Sid.Value
        $Message = "User SID is $SidValue."
    
        Write-Host "$Message"
    
    }
    catch [Exception] 
    {
    
        $Message = "Unable to get user SID. $_"
        Write-Host "$Message" 
        exit
    }
    
    try 
    {
        # Define WMI session.
        $session = New-CimSession
        $options = New-Object Microsoft.Management.Infrastructure.Options.CimOperationOptions
        $options.SetCustomOption("PolicyPlatformContext_PrincipalContext_Type", "PolicyPlatform_UserContext", $false)
        $options.SetCustomOption("PolicyPlatformContext_PrincipalContext_Id", "$SidValue", $false)
    
    }
    catch {
    
        $Message = "Unable to create new session for $ProfileName profile: $_"
        Write-Host $Message
        exit
    }
    
    try
    {
        #Detect and delete previous VPN profile.
        $deleteInstances = $session.EnumerateInstances($namespaceName, $className, $options)
    
        foreach ($deleteInstance in $deleteInstances)
        {
            $InstanceId = $deleteInstance.InstanceID
            if ("$InstanceId" -eq "$ProfileNameEscaped")
            {
                $session.DeleteInstance($namespaceName, $deleteInstance, $options)
                $Message = "Removed $ProfileName profile $InstanceId" 
                Write-Host "$Message"
            }
            else 
            {
                $Message = "Ignoring existing VPN profile $InstanceId"
                Write-Host "$Message"
            }
        }
    }
    catch [Exception]
    {
        $Message = "Unable to remove existing outdated instance(s) of $ProfileName profile: $_"
        Write-Host $Message
        exit
    
    }
    
    try
    {
        # Create the VPN profile.
        $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)
        $session.CreateInstance($namespaceName, $newInstance, $options)
    
        $Message = "Created $ProfileName profile."
        Write-Host "$Message"
    
    }
    catch [Exception]
    {
    
        $Message = "Unable to create $ProfileName profile: $_"
        Write-Host "$Message"
        exit
    }
    
    $Message = "Script Complete"
    Write-Host "$Message"
    
    
  4. 在指令碼最上方設定下列變數的值:$Domain$TemplateName$ProfileName$Servers$DnsSuffix$DomainName$DNSServers。 如需有關如何設定這些變數的詳細資訊,請參閱:VPNv2 CSP

  5. 按 ENTER 鍵執行指令碼。

  6. 在 Windows PowerShell ISE 中執行下列命令,確認指令碼是否成功:

        Get-CimInstance -Namespace root\cimv2\mdm\dmmap -ClassName MDM_VPNv2_01
    
  7. 您應該會看到下列輸出內容 (已截斷 ProfileXML 值以提高可讀性):

    
    AlwaysOn                : True
    ByPassForLocal          : 
    DeviceTunnel            : 
    DnsSuffix               : corp.contoso.com
    EdpModeId               : 
    InstanceID              : Contoso%20AlwaysOn%20VPN
    LockDown                : 
    ParentID                : ./Vendor/MSFT/VPNv2
    ProfileXML              : <VPNProfile>...</VPNProfile>
    RegisterDNS             : 
    RememberCredentials     : True
    TrustedNetworkDetection : corp.contoso.com
    PSComputerName          : 
    `
    

您現在已設定 Always On VPN 的使用者通道。 若要了解如何設定裝置通道,請參閱在 Windows 用戶端中設定 VPN 裝置通道

下一步