Forum Discussion

Tomcat456's avatar
Tomcat456
Copper Contributor
Aug 19, 2025

Error setting profile for interface Primary LAN Interface

Hi all

I have a problem with this script. It says "Error setting profile for interface Primary LAN Interface: The network connection profile is corrupted". I need to set the Network card Protected EAP Properties to "Smartcard or other certificate" and set the Trusted Root Certification Autorities to use our Root certificate.  Is there any other way to automate this or can you help me finding the problem in this script?

Thanks for your help!


Powershell Script:


# ================================
# 802.1X PEAP (EAP-TLS) for Wired
# Interface: "Primary LAN Interface"
# Root CA can be selected by Thumbprint or Subject Match
# Run as Administrator
# ================================

$InterfaceName = "Primary LAN Interface"     # Target NIC display name
$ProfileName   = "Network"          # Wired profile name to manage
$TempFolder    = "D:\iltis\tools\Temp\LanProfile"

# Root CA selection (choose ONE approach)
$RootCAThumbprint = "96f2bf58b39db8b704a4dda8c5df456c725fce24"                        # e.g. "AB12CD34EF56..."; leave blank to use subject search
$RootCASubjectLike = "Root"         # Used only if $RootCAThumbprint is blank

# ---------- Helpers ----------
function Ensure-Folder($path) {
    if (-not (Test-Path $path)) { New-Item -ItemType Directory -Path $path | Out-Null }
}

function Get-RootCAThumbprint {
    param(
        [string]$Thumbprint,
        [string]$SubjectLike
    )
    if ($Thumbprint -and $Thumbprint.Trim() -ne "") {
        return ($Thumbprint -replace "\s","").ToUpper()
    }

    $match = Get-ChildItem Cert:\LocalMachine\Root |
        Where-Object { $_.Subject -like "*$SubjectLike*" } |
        Select-Object -First 1

    if (-not $match) { throw "Root CA with subject like '$SubjectLike' not found in LocalMachine\Root." }
    return ($match.Thumbprint -replace "\s","").ToUpper()
}

function Start-WiredAutoConfig {
    $svc = Get-Service -Name dot3svc -ErrorAction SilentlyContinue
    if (-not $svc) { throw "Wired AutoConfig (dot3svc) service not found." }
    if ($svc.StartType -ne 'Automatic') { Set-Service dot3svc -StartupType Automatic }
    if ($svc.Status -ne 'Running') { Start-Service dot3svc }
}

function Get-NicOrThrow {
    param([string]$Name)
    $nic = Get-NetAdapter -Name $Name -ErrorAction SilentlyContinue
    if (-not $nic) { throw "Network adapter '$Name' not found. Use Get-NetAdapter to confirm the exact name." }
    if ($nic.Status -ne 'Up') { Write-Warning "Adapter '$Name' is not Up (status: $($nic.Status)). Continuing anyway." }
    return $nic
}

# Minimal valid LAN profile XML with EAPHostConfig placeholder (we’ll inject the Root CA thumbprint).
function New-LanProfileXml {
param([string]$ProfName)
@"
<?xml version="1.0"?>
<LANProfile xmlns="http://www.microsoft.com/networking/LAN/profile/v1">
  <name>$ProfName</name>
  <MSM>
    <security>
      <OneX xmlns="http://www.microsoft.com/networking/OneX/v1">
        <authMode>userOrComputer</authMode>
        <EAPConfig>
          <EapHostConfig xmlns="http://www.microsoft.com/provisioning/EapHostConfig">
            <EapMethod>
              <Type xmlns="http://www.microsoft.com/provisioning/EapCommon">25</Type>
              <AuthorId xmlns="http://www.microsoft.com/provisioning/EapCommon">0</AuthorId>
            </EapMethod>
            <Config xmlns="http://www.microsoft.com/provisioning/EapHostConfig">
              <Eap xmlns="http://www.microsoft.com/provisioning/BaseEapConnectionPropertiesV1">
                <Type>13</Type>
                <EapType xmlns="http://www.microsoft.com/provisioning/EapTlsConnectionPropertiesV1">
                  <CredentialsSource>
                    <CertificateStore>
                      <SimpleCertSelection>true</SimpleCertSelection>
                    </CertificateStore>
                  </CredentialsSource>
                  <ServerValidation>
                    <DisableUserPromptForServerValidation>true</DisableUserPromptForServerValidation>
                    <ServerNames></ServerNames>
                    <TrustedRootCA>__ROOT_CA_THUMBPRINT__</TrustedRootCA>
                  </ServerValidation>
                  <DifferentUsername>false</DifferentUsername>
                </EapType>
              </Eap>
            </Config>
          </EapHostConfig>
        </EAPConfig>
      </OneX>
    </security>
  </MSM>
</LANProfile>
"@
}

# ---------- Main ----------
try {
    Write-Host "Preparing environment..." -ForegroundColor Cyan
    Ensure-Folder $TempFolder
    Start-WiredAutoConfig
    $null = Get-NicOrThrow -Name $InterfaceName

    $thumb = Get-RootCAThumbprint -Thumbprint $RootCAThumbprint -SubjectLike $RootCASubjectLike
    Write-Host "Using Root CA Thumbprint: $thumb" -ForegroundColor Green

    # Try to export existing profile for this interface+name; if missing, build a fresh one.
    $exported = $false
    Write-Host "Exporting existing wired profile (if present)..." -ForegroundColor Cyan
    $null = netsh lan export profile folder="$TempFolder" interface="$InterfaceName" name="$ProfileName" 2>$null

    $ProfilePath = Join-Path $TempFolder "$ProfileName.xml"
    if (Test-Path $ProfilePath) { $exported = $true }

    if (-not $exported) {
        Write-Host "No existing profile named '$ProfileName' found. Creating a new one..." -ForegroundColor Yellow
        $xmlText = New-LanProfileXml -ProfName $ProfileName
        $xmlText = $xmlText -replace "__ROOT_CA_THUMBPRINT__", $thumb
        $xmlText | Set-Content -Path $ProfilePath -Encoding UTF8
    } else {
        # Load existing, replace EAP host config with our desired PEAP->EAP-TLS block
        [xml]$xml = Get-Content $ProfilePath
        # Find any EapHostConfig node and replace its InnerXml with our config (PEAP 25 -> inner EAP-TLS 13)
        $ns = New-Object System.Xml.XmlNamespaceManager($xml.NameTable)
        $ns.AddNamespace("lp", "http://www.microsoft.com/networking/LAN/profile/v1")
        $ns.AddNamespace("ox", "http://www.microsoft.com/networking/OneX/v1")
        $eapConfigNode = $xml.SelectSingleNode("//lp:LANProfile/lp:MSM/lp:security/ox:OneX/ox:EAPConfig", $ns)
        if (-not $eapConfigNode) { throw "EAPConfig node not found in exported profile. Cannot proceed safely." }

        $newEap = New-LanProfileXml -ProfName $ProfileName
        # extract just the EAPHostConfig from the template
        [xml]$tmp = $newEap
        $tmpNs = New-Object System.Xml.XmlNamespaceManager($tmp.NameTable)
        $tmpNs.AddNamespace("lp", "http://www.microsoft.com/networking/LAN/profile/v1")
        $tmpNs.AddNamespace("ox", "http://www.microsoft.com/networking/OneX/v1")
        $eapHostConfig = $tmp.SelectSingleNode("//lp:LANProfile/lp:MSM/lp:security/ox:OneX/ox:EAPConfig/*", $tmpNs)

        # Replace placeholder with real thumbprint
        $eapHostConfigOuterXml = $eapHostConfig.OuterXml.Replace("__ROOT_CA_THUMBPRINT__", $thumb)

        # Replace EAPConfig contents
        $eapConfigNode.InnerXml = $eapHostConfigOuterXml

        # Save back
        $xml.Save($ProfilePath)
    }

    Write-Host "Importing wired 802.1X profile to '$InterfaceName'..." -ForegroundColor Cyan
    # Adds the profile and associates it with the specified interface
    netsh lan add profile filename="$ProfilePath" interface="$InterfaceName"

    # Optional: force 802.1X reauth/reconnect
    try { netsh lan reconnect interface="$InterfaceName" | Out-Null } catch {}

    Write-Host ""
    Write-Host "✅ Done." -ForegroundColor Green
    Write-Host "The adapter '$InterfaceName' is configured for PEAP with inner 'Smart Card or other certificate' (EAP-TLS) and trusts the specified Root CA." -ForegroundColor Green
    Write-Host "Profile name: $ProfileName"
    Write-Host ""
    Write-Host "Tip: If your NAC expects machine auth, make sure a valid machine certificate is present in LocalMachine\My." -ForegroundColor DarkGray
}
catch {
    Write-Error $_.Exception.Message
    exit 1
}

2 Replies

  • Bart_Pasmans's avatar
    Bart_Pasmans
    Copper Contributor

    Hi Tomcat456​,

    Though one, but I'll give it a shot non the less!

    can you validate;

     

    • The XML structure if everything is fine?
    • Might be an existing profile cache

    I know also that when copying thumbprints there is a 'hidden white' character at start of the line. You should check that one out as well (as this cost me a lot of time in the past)

     

    If you have a corrupted profile you can try removing that with:

    netsh lan delete profile name="Network" interface="Primary LAN Interface"

     

    Also check if the certificate can be fetched:

    Get-ChildItem Cert:\LocalMachine\Root | Where-Object { $_.Thumbprint -eq "96f2bf58b39db8b704a4dda8c5df456c725fce24" }

     

    And check for dot3svc service:

    Get-Service dot3svc (need to be running)

    • SivertSolem's avatar
      SivertSolem
      Iron Contributor
      It does appear like there's an issue with the XML indeed.
      
      First of all, <name> does not appear to be a property of <LanProfile>, so <name>$ProfName</name> should be removed entirely. (LAN_profile schema elements - Win32 apps | Microsoft Learn)
      
      Second, the <authMode>userOrComputer</authMode> is wrong.
      It should be "machineOrUser". (OneX element - Win32 apps | Microsoft Learn)
      
      
      
      You may also need the <PerformServerValidation>, <AcceptServerName>, and <TLSExtensions> tags as children of the <EAPType> tag.
      Compare with an export of a manually created and correct profile.

      I've wrapped everything in a code block because this site didn't like me using tags (invalid html)

Resources