Corrupt Local GPO Files

Published on Friday, May 8, 2015 in

A while ago I go I looked into a laptop not being able to access anything on the network. As this customer has Direct Access deployed I knew I had to start my troubleshooting with the following command: netsh dns show state


As you can tell from the screenshot above, the laptop thinks it’s outside the corporate network and has Direct Access configured and enabled. I tried pinging various resources (on the domain) but they all failed. That would make sense as the client is trying to build a Direct Access tunnel, but fails to do so. Besides that, the name resolution policy also kicks in. The result is that neither remote or local connectivity is working. In such a situation one should suspect an issue with the Network Location Service that is deployed on the network. However this was an isolated case as no other clients were showing similar issues…

The reason name resolution and thereby all other domain related tasks are failing is the fact that the Direct Access name resolution policies are in place and force all DNS requests for the domain zone to be resolved by the Direct Access DNS service. That one is not reachable as we don’t have a valid Direct Access Connection… In order to mitigate this I thought I’d kill the name resolution policies locally and see if I’d be able to get it talking to the domain again.


Delete both DA-…. keys. They can be found below HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient\DnsPolicyConfig. Reboot the client afterwards. In my case I could see connectivity (and name resolution) was now working again. But processing GPO’s still failed:


In the event log:


Event 1096: The processing of Group Policy failed. Windows could not apply the registry-based policy settings for the Group Policy object LocalGPO. Group Policy settings will not be resolved until this event is resolved. View the event details for more information on the file name and path that caused the failure.

Some googling led me the following information:

The instructions to fix this:

  • Rename (or delete) C:\Windows\System32\GroupPolicy\Machine\Registry.pol
  • Start > run > cmd (as admin)
  • Gpedit.msc
  • Below administrative templates change a (not matter which) setting and then revert it. This will trigger the creation of a new registry.pol file
  • gpupdate /force
  • Gpo’s should process correctly now.


Now you might wonder, how does this registry.pol gets in such a condition that group policy processing starts the fail? I stumbled across the following post:


In the comments section there’s a comment from Mike Niccum which seems to be very interesting. We checked our exclusions on our Endpoint Protection and as Mike explains we’re also seeing the missing antivirus exclusion. We added it and in the coming weeks we’ll see whether new issues will pop up or not.

  • Present (Wrong?) exclusion: C:\Windows\System32\GroupPolicy\Registry.pol
  • Missing exclusion: C:\Windows\System32\GroupPolicy\Machine\Registry.pol


Commvault REST API using PowerShell

Published on Sunday, April 26, 2015 in ,

A while ago I wrote a blog post about Connecting to the 3PAR WebAPI using PowerShell. Today I’m doing the same but now with the Commvault REST API. Connecting to that API is even easier! Commvault has a nice sandbox to get familiar with the REST API! This one is definately worth a look. It can be accessed at http://commvaultwebconsoleserver.contoso.com/webconsole/sandbox/ It looks like this:


Working with the API is similar to the 3PAR approach: first we authenticate and get a token. Then we use that token to call other services. In order to get this working I just looked at the c# sample code Commvault provides: Commvault Documentation: REST API - Getting Started Using C# Here’s how you can authenticate using PowerShell:


$username = "Contoso\s_apiuser" 
$password = P@$$w0rd 
#Commvault web console server
$SERVER = "srdccvws0001.rddcmgmt.local" 
$APIURL = "http://$($SERVER):81/SearchSvc/CVWebService.svc" 

$APIURLaction = "$APIURL/login" 
$passwordB64byte = [System.Text.Encoding]::UTF8.GetBytes($password) 
$encodedPassword = [System.Convert]::ToBase64String($passwordB64byte) 
$loginReq = "<DM2ContentIndexing_CheckCredentialReq mode=""Webconsole"" username=""$username"" password=""$encodedPassword"" />" 
$result = Invoke-WebRequest -Uri $APIURLaction -Method POST -Body $loginReq -UseBasicParsing       
$token = (([xml]$result.content).SelectSingleNode("/DM2ContentIndexing_CheckCredentialResp/@token")).value

The code might seem cryptic but is actually pretty straightforward: we need to call the /login service and pass it some parameters.The service requires the password to be base64 encoded. As you might guess this information goes across the wire… So I would definitely advise to use an account that only has permissions to the items it needs to access. Ideally we’d approach the service over SSL but I’m not sure if Commvault allows SSL to be configured for the services.

The username and encoded password have to be passed in a specific XML string that is passed as the body of the web request. The result is an XML string that contains a token value. We don’t need the whole string but only the part representing the token. Now that we managed to get a token we can start calling specific services. If I'm not mistaken this token will remain valid until there’s a period of inactivity (30’).

Here’s how you can get all Clients:


$service = "/client" 
$action = "GET" 
$APIURLaction = "$APIURL$service" 
$headers = @{} 
#default is XML
$headers["Accept"] = "application/json" 
$headers["Authtoken"] = $token 
$result = Invoke-WebRequest -Uri $APIURLaction -Headers $headers -Method $action -UseBasicParsing 
$clientInfo = ($result.content | ConvertFrom-Json).App_GetClientPropertiesResponse.clientProperties

If you go through the REST API documentation you’ll notice that some services are GET based and other are POST based. The /client service is GET based, the /jobdetails is POST based. You’ll also notice that we pass an XML string as the body for the request.


$jobID = "3040" 
$body = "<JobManager_JobDetailRequest jobId=""$jobID""/>" 
$service =  "/JobDetails" 
$action = "POST" 
$result = Invoke-WebRequest -Uri $APIURLaction -Headers $headers -Method $action -UseBasicParsing -Body $body 
$jobDetails = ($result.content | ConvertFrom-Json).JobManager_JobDetailResponse.job.jobDetail

I hope with these basic examples you can now successfully connect yourself. As you might see, the above code contains no error handling. Depending on how you will use scripts like that I would advise to add some logging and error handling. Try providing wrong credentials or entering a bad servername and see what happens.


Azure Virtual Machines: Event 257: Defrag: Slab Consolidation/ Slab Analysis

Published on Wednesday, March 4, 2015 in , ,

I’ve got a customer running some virtual machines on the Azure IAAS platform, and when doing a quick checkup I found the following recurring events in the event log:

  • The volume (C:) was not optimized because an error was encountered: Neither Slab Consolidation nor Slab Analysis will run if slabs are less than 8 MB. (0x8900002D)
  • The volume Temporary Storage (D:) was not optimized because an error was encountered: Neither Slab Consolidation nor Slab Analysis will run if slabs are less than 8 MB. (0x8900002D)
  • The volume Data (F:) was not optimized because an error was encountered: Neither Slab Consolidation nor Slab Analysis will run if slabs are less than 8 MB. (0x8900002D)

Sample event:


I’m aware that Windows does maintenance on a regular base all by itself. One of these tasks is a scheduled defrag:


You’ll probably see that there’s no trigger for this particular task, yet it runs regularly! That’s because there’s another scheduled task called “regular maintanance” who calls this specific task. An excellent writeup can be found here: DataToHelpThePeople: Maintenance at 3AM in the Morning

I did some googling and I quickly came accross this: KB2964429: Storage Optimizer memory use increases when it runs on thin provisioned LUNs

From that article: There's no need to run Storage Optimizer on thin provisioned LUNs that use an allocation size (also known as slab size) of less than 8 MB. Thin provisioned LUNs that have a smaller slab size manage space more efficiently, and the benefits of defragmenting them are not as great.

So that got me curious, how big is the allocation size on these volumes? We can find this information using diskpart:


After selecting a given volume, execute “filesystem”. In our example we have 4 MB which is, as the erorr states, less than 8 MB. Both the OS disk and the Temporary Disk have 4 MB which is the default I guess. My custom disk (F:) also has this value.


If we check the action of the scheduled task we can see that this is the command being executed: %windir%\system32\defrag.exe -c -h -k -g –$ If we execute that command manually, the same events are logged.


From defrag.exe /? I can tell that we could ommit –k in order to avoid slab analysis and consolidation. However upon executing the command I’m not really sure much happens in the background.


In the following screenshot you can clearly see that for each volume an event with ID 258 is logged: The storage optimizer succesfully completed retrim on XYZ. This events are NOT logged when I run the defrag command without the –k switch.


Your first reaction might be to disable this scheduled task all togehter. You might not care about fragmentation. But you might care about your billing statement… If you care check: fabriccontroller: Release unused space from your Windows Azure Virtual Hard Disks to reduce their billable size Bottom line: whenever this maintenance tasks finds unused storage it reclaims it and lowers the overall VHD size. Which means you pay less for your storage account!

I’m not really sure how to move forward. On the one hand I really detest recurring, safe to ignore, errors in events logs. But I don’t like changing system stuff like this without some official guidance. So if you got something to add, feel free to comment!


MaxTokenSize Implications for HTTP.SYS

Published on Thursday, November 13, 2014 in , , , , , , ,

One of my customers had problems with certain users being member of a lot of Active Directory groups. This resulted in several client side issues. There’s an easy and well-known “fix” for that: raise the MaxTokenSize registry key on all Windows operating systems in your domain. On Windows 8(.1) / 2012 (R2) the MaxTokenSize is already at its maximum (advised) value out of the box. That value is 48.000 bytes. In order to mitigate these users their access problems we raised the MaxTokenSize to 48.000 bytes on all clients and servers that are running Windows 7/ Windows 2008 R2. After this change the typical issues were gone. However new ones came up:

From time to time, when HTTP is involved, issues were encountered:

  • Opening the Direct Access management console (depends on WinRM)
  • Open the FIM Portal
  • Streaming App-V packages over HTTP

Typically the user would receive several authentication prompts and even after specifying valid credentials another prompt would reappear. Example browser based issue:


As you can see the browser gives an HTTP 400 Bad Request error. Using a network trace we can easily see why it’s considered bad:


And the packet details:


The details clearly state that The size of the request headers is too long.

The problem here is that the token is allowed to be up to 48.000 bytes where it used to be 12.000 bytes. The http subsystem of a windows server has several parameters that are supposed to protect the server from oversized requests. However, as the token can now be a lot larger, the maximum request size has to be tuned as well:

From: KB820129

Below: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HTTP\Parameters there are two interesting values:


And from: KB2020943 we can find a formula to calculate the MaxFieldLength to set based on the MaxTokenSIze.

If MaxToken is 48.000 bytes (default in Windows 2012 and configure by GPO for 2008 R2/ Win7):

  • (4/3 * 48000) + 200 = 64200

We’ll use the maximum allowed value of MaxFieldLength 65534 (=~ 64200) to allow tokens up to 48000 bytes. We’ll also use this value for MaxRequestBytes.


  • MaxFieldLength: we can take the maximum allowed value: 65534
  • MaxRequestBytes:  65534



Other useful information:

I specifically wanted to post this information as in many other only articles/posts I always see people just using the maximum allowed value for MaxRequestBytes and I don’t feel 100% comfortable with that. Second,  in my opinion it’s advised to have these values pushed out to all your server systems. Especially now that Windows 2012 and up have a MaxTokenSize of 48.000 by default. If you don’t push these HTTP.sys parameters, you’ll end up troubleshooting the same phenomena multiple times from different angles. Why waste time?


3PAR: Connect to WebAPI using PowerShell

Published on Wednesday, November 5, 2014 in ,

I’m currently involved in a CloudCruiser implementation. CloudCruiser is not one of my usual technologies, but as it’s something new to me it’s refreshing to do. CloudCruiser allows you to collect information from your infrastructure and then generate billing information. You could generate bills for virtual machine instances or storage usage. My customer has 3PAR storage and I had to wrote a script which runs frequently and collects volume information.

As far as I can tell there are two approaches:

  • Use the 3PAR CLI utilities
  • Use the 3PAR Web API

I wanted to avoid the CLI utilities. They need to be installed (or copied) to the server where you want to run the script and integrating these tools and their data with PowerShell is less intuitive. I loved the idea of a Web API. This goes hand in hand with the Invoke-WebRequest cmdlet in PowerShell. This cmdlet does many of the heavy lifting and makes it real easy to talk with a given Web API. Here’s how I connected to the 3PAR device and how I got the volume information.

Calling a method of the 3PAR Web API is a two part job: first you have to call the /credentials method using a HTTP POST and provide a valid username and password. The result of that call will be a session key that you can use in subsequent calls to the Web API.

Getting the session key:

$username = "3PAR user" 
$password = "3PAR user password" 

#IP of the 3PAR device
$IP = "" 
$APIurl = "https://$($IP):8080/api/v1" 

$postParams = @{user=$username;password=$password} | ConvertTo-Json 
$headers = @{} 
$headers["Accept"] = "application/json" 
$credentialdata = Invoke-WebRequest -Uri "$APIurl/credentials" -Body $postParams -ContentType "application/json" -Headers $headers -Method POST -UseBasicParsing 
$key = ($credentialdata.Content | ConvertFrom-Json).key

And that’s it! After this you should get a string in the the $key variable which can be used in calls further down the script. But I have to take a step back. To be honest the above code didn’t work. The problem in my case was that I was accessing the API over HTTPS but the certificate couldn’t be validated. I was using the IP to access the device and it was a self signed certificate. So reasons enough why the Invoke-WebRequest cmdlet was sad… I found the following workaround which you can place somewhere before your first Invoke-WebRequest cmdlet:

#avoid issues with an invalid (self-signed) certificate, try avoid tabs/spaces as this might mess up the string block
add-type @"
    using System.Net;
    using System.Security.Cryptography.X509Certificates;
    public class TrustAllCertsPolicy : ICertificatePolicy {
        public bool CheckValidationResult(
            ServicePoint srvPoint, X509Certificate certificate,
            WebRequest request, int certificateProblem) {
            return true;
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy

Calling the method:

And now on to the actual magic. Here we’ll do a GET to the /volumes method.

$headers = @{}
$headers["Accept"] = "application/json"
$headers["X-HP3PAR-WSAPI-SessionKey"] = $key
$volumedata = Invoke-WebRequest -Uri "$APIurl/volumes" -ContentType "application/json" -Headers $headers -Method GET -UseBasicParsing 
$volumedataPS = ($volumedata.content | ConvertFrom-Json).members
#also works:
#$volumedata = Invoke-RestMethod -Uri "$APIurl/volumes" -ContentType "application/json" -Headers $headers -Method GET

And that’s all there is to it! $volumedataPS now contains an array with objects you can iterate through. No need to work with intermediate CSV files or other tricks.

Some additional information:

The UseBasicParsing parameter. When running the PowerShell script as the user I was logged in I didn’t had any troubles. Once I started running it as SYSTEM (for a scheduled task), it gave the following error: Invoke-WebRequest : The response content cannot be parsed because the Internet Explorer engine is not available, or Internet Explorer's first-launch configuration is not complete. Specify the UseBasicParsing parameter and try again. The UseBasicParsing seems to avoid using the IE engine altogether and thus the script runs fine under SYSTEM.

Invoke-WebRequest versus Invoke-RestMethod: It’s to my understanding  that they both work for calling the Web API, but Invoke-WebRequest seems to return more information regarding the actual call whereas Invoke-RestMethod simply returns the requested data. I figured this might help when adding additional logging.

The Web API might not be enabled by default. You could provide the following instructions to your 3PAR admin: Veeam: Enabling the HP 3PAR Web Services API Server They are from Veeam but I found them to be accurate.


Windows Technical Preview: Cannot Update the System Reserved Partition

Published on Monday, October 27, 2014 in

Last week a new build for Windows Technical Preview (“Windows 10”) was available. You can easily find out by going to PC settings: Windows + C > Settings > Change PC Settings > Update and Recovery > Preview Builds


My current version (build 9841):


Upon clicking install now I got the following error:


In words: Failed to install the new preview build, please try again later. 0x80246007

After rebooting and trying again:


In words: Couldn’t install Windows Technical Preview. We couldn’t update the system reserved partition.


In words: Failed to install the new preview build, please try again later. 0xC1900200

I opened up diskmgmt.msc to find out what was wrong with my system reserved partition:


As you can see the first partition (system reserved) was quite full. I assigned a drive letter and starting looking around. The easiest way to do this is to use PsExec (http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx) and start a command prompt as System (psexec –s cmd). If you use a regular command prompt you’ll get some access denieds here and there as your local administrator user might not have access to some system managed files/folders. Using dir /a you’ll be able to drill down the structure. Eventually I came up with H:\Recovery\WindowsRE\ which contained a file WinRE.wim of 309 MB.


This WinRE.wim contains a Windows Recovery Environment which you can boot when your system is having issues. It’s not vital that this is stored in the system reserved partition so I thought Id move it. Using “reagentc.exe /info” or “bcdedit /enum all” you can also see this configuration:


I then started messing around with takeown and eventually I just used Windows Explorer and moved the Recovery folder to my second internal HDD (D:\) which I use as a data volume. After moving the files I could see that the WinRE configuration was disabled. I googled around a bit to find out how I could update the information to reflect the new location. There seemed to be a reagentc command available, but although it stated success my configuration wasn’t updated to reflect the new path. So I used Visual BCD (http://www.boyans.net/) to just easily change the BCD parameters:

I updated both Windows Recovery Device options (edit SdiDevice and chose D: as my partition)


The same for the Windows Recovery Environment loaders (edit  ApplicationDevice and OSDevice)


Now my configuration showed as enabled again:


After making some free room I could now successfully install the latest build:


Eventually it seemed that the update process also moved (or recreated?) the WinRE environment on my C:\ drive. The Recovery folder I moved was empty (besides the logs folder). Using reagentc /info I could also see that the WinRE.wim was coming from the C:\ partition. So I guess this worked out fine for me.

On a final note: there’s a new option available to set your preference as to how fast you want to receive new builds:


This is also explained on an official blog of Microsoft:blogs.windows.com: We’re rolling out our first new build to the Windows Insider Program



Configure Windows Logon With An Electronic Identity Card (EID)

Published on Wednesday, October 22, 2014 in , , ,

Here in Belgium people have been receiving an Electronic Identity Card (EID) for years now. Every once in a while I have a customer who asks me whether this card can be used to logon to workstations. That would mean a form of strong authentication is applied. The post below will describe the necessary steps in order to make this possible. It has been written using a Belgian EID and the Windows Technical Preview (Threshold) for both client and server.

In my lab I kept the infrastructure to a bare minimum.

  • WS10-DC: domain controller for threshold.local
  • WS10-CA2: certificate authority (enterprise CA)
  • W10-Client: client

The Domain Controller(s) Configuration

Domain Controller Certificate:

You might wonder why I included a certificate authority in this demo. Users will logon using their EID and those cards come with certificates installed that have nothing to do with your internal PKI. However, in order for domain controllers to be able to authenticate users with a smart card, they should have a valid certificate as well. If you fail to complete this requirement, your users will receive an error:


In words: Signing in with a smart card isn’t supported for your account. For more info, contact your administrator.

And your domain controllers will log these errors:


In words: The Key Distribution Center (KDC) cannot find a suitable certificate to use for smart card logons, or the KDC certificate could not be verified. Smart card logon may not function correctly if this problem is not resolved. To correct this problem, either verify the existing KDC certificate using certutil.exe or enroll for a new KDC certificate.



In words: This event indicates an attempt was made to use smartcard logon, but the KDC is unable to use the PKINIT protocol because it is missing a suitable certificate.

In order to give the domain controller a certificate, that can be used to authenticate users using a smart card, we will leverage the Active Directory Certificate Services (AD CS) role on the WS10-CA2 server. This server is installed as an enterprise CA using more or less default values. Once the ADCS role is installed, your domain controller should automatically request a certificate based upon the “Domain Controller” certificate. This is a V1 template. A domain controller is more or less hardcoded to automatically request a certificate based upon this template.


In my lab this certificate was good enough to let my users authenticate using his EID. After restarting the KDC service and performing the first authentication, the following event was logged though:


In words: The Key Distribution Center (KDC) uses a certificate without KDC Extended Key Usage (EKU) which can result in authentication failures for device certificate logon and smart card logon from non-domain-joined devices. Enrollment of a KDC certificate with KDC EKU (Kerberos Authentication template) is required to remove this warning.

Besides the Domain Controller template there’s also the more recent Domain Controller Authentication and Kerberos Authentication templates which depend on auto-enrollment to be configured.

Computer Configuration > Policies > Windows Settings > Security Settings > Public Key Policies


After waiting a bit, gpupdate and/or certutil –pulse might speed things up a bit, we got our new certificates:


You can see that the original domain controller certificate is gone and replaced by its more recent counterparts. After testing we can confirm that the warning is no longer logged in the event log. We have now covered the certificate the domain controller requires, we’ll need to add a few more settings on the domain controllers for EID logons to work.

Domain Controller Settings

Below HKLM\SYSTEM\CurrentControlSet\Services\Kdc we’ll create two registry keys:

  • DWORD SCLogonEKUNotRequired 1
  • DWORD UseCachedCRLOnlyAndIgnoreRevocationUnknownErrors 1

Strictly spoken, the last one shouldn’t be necessary if your domain controller can reach the internet, or at least the URL where the CRL’s used in the EIDs, are hosted. If you use this registry key, make sure to remove a name mapping (more on that later) or disable the user when the EID is stolen or lost. An easy way to push these registry key is using group policy preferences.

Domain Controller Trusted Certificate Authorities

In order for the domain controller to accept the EID of the user, the domain controller has to trust the full path in the issued certificate. Here’s my EID as an example:


We’ll add the Belgium Root CA2 certificate to the Trusted Root Certificate Authorities on the domain controller:

Computer Configuration > Policies > Windows Settings > Security Settings > Public Key Policies > Trusted Root Certification Authorities


And the Citizen CA to the Trusted Intermediate Certificate Authorities on the domain controller:

Computer Configuration > Policies > Windows Settings > Security Settings > Public Key Policies > Intermediate Certification Authorities


Now this is where the first drawback from using EIDs as smartcards comes: there are many Citizen CA’s to add and trust… Each month, sometimes more, sometimes less, a new Citizen CA is issued and used to sign new EID certificates. You can find them all here: http://certs.eid.belgium.be/ So instead of using a GPO to distribute them, scripting a regular download and adding them to the local certificate stores might be a better approach.

The Client Configuration


For starters we’ll configure the following registry keys:

Below HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters we’ll create two registry keys:

  • DWORD CRLTimeoutPeriod 1
  • DWORD UseCachedCRLOnlyAndIgnoreRevocationUnknownErrors 1

Again, if your client is capable of reaching the internet you should not need these. I have to admit that I’m not entirely sure how the client will react when a forward proxy is in use. After all, the SYSTEM doesn’t always know what proxy to use and it might be requiring to authenticate.

Besides the registry keys, there’s also some regular group policy settings to configure. In some articles you’ll probably see these settings also being pushed out as registry keys, but I prefer to use the “proper” settings as they are available anyhow.

Computer Settings > Policies > Administrative Templates > Windows Components > Smart Cards

  • Allow certificates with no extended key usage certificate attribute: Enabled
    • This policy setting lets you allow certificates without an Extended Key Usage (EKU) set to be used for logon.
  • Allow signature keys valid for Logon: Enabled
    • This policy setting lets you allow signature key-based certificates to be enumerated and available for logon.

These two are required so that the EID certificate can be used. As you can see it has a usage attribute of Digital Signature


In some other guides you might also find these Smart Card settings enabled:

  • Force the reading of all certificates on the smart card
  • Turn on certificate propagation from smart card
  • Turn on root certificate propagation from smart card

But my tests worked fine without these.


Out of the box Windows will not be able to use your EID. If you don’t install the required drivers you’ll get an error like this:


You can download the drivers from here: eid.belgium.be On the Windows 10 preview I got an error during the installation. But that probably had to do with the EID viewer software. The drivers seem to function just fine.


Active DIrectory User Configuration

As these certificates are issued by the government, they don’t contain any specific information that allows Active Directory to find out to which user should be authenticated. In order to resolve that we can add a name mapping to a user. And this is the second drawback. If you want to put EID authentication in place you’ll have to have some sort of process or tool that allows users to link their EID to their Active Directory User Account. The helpdesk could do this for them or you could write a custom tool that allows users to do it themselves.

In order to do it manually:

First we need the certificate from the EID. You can use Internet Explorer > Internet Options > Content > Certificates


You should see two certificates. The one you want is the one with Authentication in the Issued To. Use the Export… button to save it to a file.

Open Active Directory Users and Computers > View > Advanced Features


Locate the user the EID belongs too > Right-Click > Name Mappings…


Add an X.509 Certificate


Browse to a copy of the Authentication smart card which can be found on the EID


Click OK


Testing the authentication

You should now be able to logon to a workstation with the given EID. Either by clicking other user and clicking the smart card icon


Or if the client has remembered you from earlier logons you can choose smart card below that entry.


An easy way to see if a user logged on using smart card or username/password is the query for the user his group memberships on the client. When users  log on with a smart card they get the This organization certificate group SID added to their logon token. This is a well-known group (S-1-5-65-1) that was introduced with Windows 7/ Windows 2008 R2.


Forcing smart card authentication

Now all of the above allows a user to authenticate using smart cards, but it doesn’t forces the user to do it. Username password will still be accepted by the workstations. If you want to force smart card logon there are two possibilities. Each with their own drawbacks.

1. On the user level:

There’s a property Smart card is required for interactive logon that you can check on the user object in Active Directory. Once this is checked, the users will only be able to logon using a smart card. There’s one major drawback though. Once you click apply, at the same time this will set the password of that user to a random value and password policies will no longer apply for that user. That means that if you got some applications that are integrated with Active Directory, but do so by asking credentials in a username/password form, your user will not be able to logon as they don’t know the password… If you configure this setting on the user you have to make sure all applications are available through Kerberos/NTLM SSO. If you were to use Exchange Active Sync, you would have to change the authentication scheme from username/password to certificate based for instance. So I’m not really sure enforcing this at the user level is a real option. This option seems more feasible for protection high privilege accounts.


2. On the workstation level:

There’s a group policy setting that can be configured on the computer level that enforces all interactive logons to require a smart card. It can be found under computer settings > Policies > Windows Settings > Security Settings > Local Policies > Security Options > Interactive logon: Require smart card


While you’re there, also look at Interactive logon: Smart card removal behavior. It allows you to configure a workstation to lock when a smart card is removed. If you configure this one, make sure to also configure the Smart Card Removal Policy service to be started on your clients. This service is stopped and set to manual by default.

Now the bad news. Just like with the first one, there’s also a drawback. This one could be less critical for some organisations, might it might require people to operate in a slightly different way. Once this setting is enabled, all interactive logons require a smart card:

  • Ctrl-alt-del logon like a regular user
  • Remote Desktop to this client
  • Right-click run as administrator (in case the user is not an administrator himself) / run as different user

For instance right-click notepad and choosing run as different user will result in the following error if you try to provide a username/password


In words: Account restriction are preventing this user from signing in. For example: blank passwords aren’t allowed, sign-in times are limited, or a policy restriction has been enforced. For us this is an issue as our helpdesk often uses remote assistance (built-in the OS) to help users. From time to time they have to provide their administrative account in order to perform certain actions. As the user his smart card is inserted, the helpdesk admin cannot insert his own EID. That would require an additional smart card reader. And besides that: a lot of the helpdesk tasks are done remotely and that means the EID is in the wrong client… There seem to be third party solutions that tackle this particular issue: redirecting smart cards to the pc you’re offering remote assistance.

Now there’s a possible workaround for this. The policy we configure in fact sets the following registry value to 1:


Using remote registry you could change it to 0 and then perform your run as different again. Changing it to 0 immediately sets the Interactive logon: Require smart card to disabled. Effective immediately. Obviously this isn’t quite elegant, but you could create a small script/utility for it…

Administrative Accounts (or how to link a smart card to two users)

If you would use the same certificate (EID) in the name mapping of two users in Active Directory, your user will fail to login:


In words: Your credentials could not be verified. The reason is quite simple. Your workstation is presenting a certificate to Active Directory, but Active Directory has two principals (users) that map to that certificate. Now which user does the workstation want?

Name hints to the rescue! Let’s add the following GPO setting to our clients:

Computer Settings > Policies > Administrative Templates > Windows Components > Smart Cards

  • Allow user name hint: enabled

After enabling this setting there’s an optional field called Username hint below the prompt for the PIN.


In this username hint field the person trying to logon using a smart card can specify which AccountName to be used. In the following example I’ll be logging on with my thomas_admin account:


NTauth Certificate Store

Whenever you read into the smart card logon subject you’ll see the NTauth certificate store being mentioned from time to time. It seems to be involved in some way, but it’s still not clear to me. All I can say is that in my setup, using an AD integrated CA for the Domain Controller certificates, I did not had to configure/add any certificates to the NTauth store. Not the Belgian Root CA, Not the Citizen CA. My internal CA was in it of course.

I did some tests, and to my experience, the CA that issued your domain controllers certificate has to be in the NTAuth store on both clients and domain controllers. If you would remove that certificate you’ll be greeted with an error like this:


In words: Signin in with a smart card isn’t supported for your account. For more info, contact your administrator. And on the domain controller the same errors are logged like the ones from the beginning of this article.

Some useful commands to manipulate the NTauth store locally on a client/server:

  • Add a certificate manually: certutil -enterprise -addstore ntAuth .\ThresholdCA.cer
  • View the store: certutil -enterprise -viewstore ntAuth
  • Delete a certificate: certutil -enterprise -viewdelstore ntAuth

Keep in mind that the NTauth store exists both locally on the client/servers and in Active Directory. An easy way to view/manipulate the NTauth store in Active Directory is the pkview.msc management console which you typically find on a CA. Right-click the root and choose manage AD containers to view the store.

A second important fact regarding the NTauth store. Whilst you might see the require CA certificate in the store in AD, your clients and servers will only download the content of the AD NTauth store IF they have auto-enrollment configured!


There are definitely some drawbacks to using EID in a corporate environment:

  • No management software to link the certificates to the AD users. Yes there’s active directory users and computers, but you’ll have to ask the users to either come visit your helpdesk or email their certificate. Depending on the number of users in your organisation this might be a hell of a task. A custom tool might be a way to solve this.
  • Regular maintenance: as described, quite regular a new Citizen CA (Subordinate Certificate Authority) is issued. You need to ensure your domain controllers have this CA in their trusted intermediate authorities store. This can be done through GPO, but this particular setting seems hard to automated. You might be better off with a script that performs this task directly on your domain controllers.
  • Helpdesk users will have to face the complexity if the require a smart card setting is enabled.
  • If an EID is stolen/lost you might have to temporary allow normal logons for that user. An alternative is to have a batch of smart cards that you can issue yourself. An example vendor for such smart cards is Gemalto.
  • An other point that I didn’t had to chance to test though. What about the password of the users. If they can’t use it to logon, but the regular password policies still apply, how will they be notified of the expiration? Or even better, how will they change it? Some applications might depend on the username/password to logon.

As always, feedback is welcome!