Second Life of a Hungarian SharePoint Geek

July 7, 2018

Checking user properties in Active Directory using PowerShell to identify logon issues

Filed under: Active Directory, PowerShell, Tips & Tricks — Tags: , , — Peter Holpar @ 17:45

While supporting a SharePoint environment having several thousands of users from multiple Active Directory domains, we have quite often complains, that one can not access the site. Beyond trivial network related problems, like incorrect proxy settings, it is probably the second most common reason for such complains having issues with the Active Directory account of the user.

To support such cases, I wrote a short PowerShell script that checks for the most common problems, like User must change password at next logon flag is activated, account is disabled or locked out, and password expired. Prerequisite: you should have PowerShell Active Directory module installed.

$userLogin = ‘Domain\UserName’
$userLoginSplitted = $userLogin.Split(‘\’)
$domainName = $userLoginSplitted[0]
$dcServer = Get-ADDomainController -Discover -DomainName $domainName

$user = Get-ADUser -Identity $userLoginSplitted[1] -Server $dcServer.HostName[0] -Properties Enabled, LockedOut, PwdLastSet, PasswordNeverExpires, msDS-UserPasswordExpiryTimeComputed
$pwdNeverExp = $user.PasswordNeverExpires
$pwdExpiresOn = If ($pwdNeverExp) { $null } Else { [DateTime]::FromFileTime($user."msDS-UserPasswordExpiryTimeComputed") }

Write-Host Checking user: $userLogin
Write-Host User must change password at next logon: $($user.PwdLastSet -eq 0)
Write-Host Account disabled: $(!$user.Enabled)
Write-Host Account locked out: $($user.LockedOut)
Write-Host Password expired: $((!$pwdNeverExp) -and ($pwdExpiresOn -lt [DateTime]::Now))

First thing to highlight in the script is how we get and use the domain controller. Getting the domain controller is the easy part, after splitting the user login name to a domain name and a user name, you simply invoke the Get-ADDomainController cmdlet with the Discover switch and passing the domain name you are looking for in the DomainName parameter.

Using the value returned is a bit more complicated, at least until you learn how to do it the right way. Although Active Directory cmdlets support the Server parameter, there is a lot of confusion how to use it correctly. If you simply pass the domain controller as you received it in the previous step from the Get-ADDomainController cmdlet, like:

$user = Get-ADUser -Identity $userLoginSplitted[1] -Server $dcServer

you receive this error message:

Unable to contact the server. This may be because this server does not exist, it is currently down, or it does not have the Active Directory Web Services running.

After researching the samples on the web (like Get-ADUser -Server ‘servername’) and the official documentation of the Get-ADUser cmdlet we realized that the Server parameter requires a string value, so passing the $dcServer (of type Microsoft.ActiveDirectory.Management.ADDirectoryServer) was really not a good idea. But wait, scrolling through the properties of $dcServer by PowerShell autocomplete shows it has a property called HostName. That sounds really promising! Try it out!

$user = Get-ADUser -Identity $userLoginSplitted[1] -Server $dcServer.HostName

Now you have another error message:

Cannot convert ‘Microsoft.ActiveDirectory.Management.ADPropertyValueCollection’ to the type ‘System.String’ required by parameter ‘Server’. Specified method is not supported.

Well, that means that the HostName property is of type Microsoft.ActiveDirectory.Management.ADPropertyValueCollection and not a string either, even though PowerShell displays it as string if you output it like $dcServer.HostName. To get the name of the domain controller as string you should address it in the collection using an array indexer, like $dcServer.HostName[0].

So the right usage is:

$user = Get-ADUser -Identity $userLoginSplitted[1] -Server $dcServer.HostName[0]

although you might check first if there was any domain controller found ($dcServer and its HostName property not null, and HostName has at leas a single entry) if you want to be sure.

Note furthermore, that the largest possible 64-bit value (2^63-1 = 9223372036854775807) in property msDS-UserPasswordExpiryTimeComputed means PasswordNeverExpires is true. Invoking the FromFileTime method using this value would cause an error:

Exception calling "FromFileTime" with "1" argument(s): "Not a valid Win32 FileTime. Parameter name: fileTime"

Advertisements

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: