Context
When a user opens an Active Directory session with his smartcard, it happens that some applications do not support smartcard logon, but needs classical user/password login.
Dilemma
When you use Active Directory Users and Computers MMC, you only have the option « Smart Card is required for interactive logon »:
This action does the following:
- Disable logon with password
- Change the user password
- User does not password expiration date
Solution
User modification
Do not change user with ADUC MMC
Change users properties with a PowerShell Script
$oUser = [ADSI]("LDAP://" + $Props.distinguishedname) Write-Output "Found user: $($oUser.DistinguishedName)" Write-Output " --> Setting SMARTCARD_REQUIRED (No password change)" [int]$userFlags = $oUser.useraccountcontrol[0] $oUser.useraccountcontrol = $userFlags -bor $ADS_UF_SMARTCARD_REQUIRED $oUser.setinfo() # $oUser.ObjectSecurity $self = [System.Security.Principal.SecurityIdentifier]'S-1-5-10' [guid]$nullGuid = [guid]"00000000-0000-0000-0000-000000000000" Write-Output " --> Changing rights and attributes" $oUser.get_ObjectSecurity().AddAccessRule($(New-Object DirectoryServices.ActiveDirectoryAccessRule ` $self, "ExtendedRight", "Allow", $(GetADRightGuid("Reset Password")) ` )) $oUser.get_ObjectSecurity().AddAccessRule($(New-Object DirectoryServices.ActiveDirectoryAccessRule ` $self, "ExtendedRight", "Allow", $(GetADRightGuid("Change Password")) ` )) $oUser.CommitChanges()
Check password expires
On the OU in which the account is, link a GPO with a PowerShell login script and add the equivalent script:
$oUser = SearchAD -ADSearchBase $RootDSE.defaultNamingContext ` -ADFilter "(&(objectClass=user)(objectcategory=person)(sAMAccountName=$($env:username)))" ` -ADProperties "distinguishedname", "displayname", "samAccountName", "useraccountcontrol", "objectGUID", "PwdLastSet" $PwdLastSet = ([DateTime]::FromFileTime([Int64]::Parse($oUser.Properties["pwdlastset"]))) $UF = [int32]$oUser.Properties["useraccountcontrol"][0] $bSmartCard = ($UF -bor 0x40000) -eq $UF $bExpiresPassword = ($UF -bor 0x10000) -eq $UF $pwdAge = (get-date) - $pwdLastSet $OutBox.AppendText(" --> DistinguishedName : $($oUser.Properties["distinguishedname"])`n") $OutBox.AppendText(" --> DisplayName : $($oUser.Properties["displayname"])`n") $OutBox.AppendText(" --> Password expires : $($bExpiresPassword)`n") $OutBox.AppendText(" --> Requires SmartCard : $($bSmartCard)`n") $OutBox.AppendText(" --> Password date (UTC) : $($pwdLastSet)`n") $OutBox.AppendText(" --> Password age : $($pwdAge.Days) Days $($pwdAge.Hours) Hours $($pwdAge.Minutes) Mn