May 19, 2015

Bind Response: InvalidCredentials

Sometimes I get the strangest things that come across my desk. As a manager, I don’t have a lot of time for troubleshooting so when I do get ahold of something, it’s fun to tear apart. I told my team about my findings. One of them asked how I arrived at the answer… so I thought I’d blog it just in case it interests anyone else.

As a favor to a coworker, I looked into an application configuration problem that was described as such:

  • Application is configured for LDAP.
  • All users can successfully log into the application except one person.
  • This one person is also the administrator of the application.

The app owner indicated they were seeing timeout errors in their logs. There was no denying it. The call was timing out:

Servlet.service() for servlet dispatcher threw exception
javax.naming.NamingException: LDAP response read timed out, timeout used:-1ms.; remaining name ''
                at com.sun.jndi.ldap.Connection.readReply(Connection.java:483)
                at com.sun.jndi.ldap.LdapClient.getSearchReply(LdapClient.java:639)
                at com.sun.jndi.ldap.LdapClient.search(LdapClient.java:562)
                at com.sun.jndi.ldap.LdapCtx.doSearch(LdapCtx.java:1985)
                at com.sun.jndi.ldap.LdapCtx.searchAux(LdapCtx.java:1847)
                at com.sun.jndi.ldap.LdapCtx.c_search(LdapCtx.java:1772)

To respond to that, the first thing we did was check the LDAP configuration to make sure it wasn’t misconfigured anywhere. I couldn’t tell if they what it was timing out to. A bind request? A search request? Who knows.

What little there was in the ldap.properties file looked appropriately set so they went back to scour more logs. I asked them to verify there was no application wonkiness by making someone else an admin and having them log on. Negative. All good. Now we’re getting somewhere.

Of course, you never find the log that tells you exactly what’s going on. I’m pretty sure this is why packet tracing became a thing. I asked for a trace. This is what the trace revealed:

image

Now we can confirm that indeed the user’s attempt to bind fails. He had no problem logging into other things though -- his workstation for example. I told the app team that the user was not providing his credentials properly, or it was an application problem. They weren’t sure where to go next. I figured it had to be the logon form, though, so I tried one more thing.404

I asked the user to tell me the character length of his password and verified the character length of the form. The form truncated at least two characters off his password. The password is masked and at such a length that you might not realize little dots weren’t continuing to show up. :o)

PROBLEM SOLVED! The LDAP response InvalidCredentials was indeed correct. Once you get the application logs out of the way and go straight down to the packet, you can see so much more. That’s my lesson of the day.

Mar 29, 2015

Embedding Expressions in Select-Objects

I had my first taste of using Select-Objects in a way more than just modifying values on output or to specifically pick a set of attributes to list.

When someone asks for a list of users and their managers, meh, no big deal. When they ask for the user, their manager, and their manager’s email address -- well, no big deal but not as much of a no big deal as the first one.

I found it a bit annoying that I had to write a script to do this every time I wanted to get this type of information so I did a bit of exploring. Turned out a little while ago, while experimenting in optimizing speed in a script, I had tried a method of using Select-Object to create a custom object.

 

Using Select-Object to Pull Manager Detail on the Fly
$myData | select 
    @{n='UserId';e={$_.samaccountname}}, 
    @{n='Created';e={$_.lastlogon}}, 
    @{n='Name';e={$_.name}}, 
    @{n='Manager';e={$_.manager}},
    @{n='Manager Email';e={ 
        (get-aduser $_.manager -properties mail).mail 
        }
    }

Hopefully this makes sense. I broke it out so it’s clearer to read. For my example, I already had a dataset with specific information in it. I just needed to pipe it out and get the manager email. I piped this to export-csv to create a file to look at.

The meaningful part here is that you can embed things in the expression -- like the Get-AdUser call.

 

Slightly More Challenging
$myData | select 
    @{n='UserId';e={$_.samaccountname}}, 
    @{n='Logon';e={$_.lastlogondate}}, 
    @{n='Name';e={$_.name}}, 
    @{n='Manager';e={ 
        (get-aduser $_.samaccountname -Properties manager).manager 
        }
    }, 
    @{n='Manager Email';e={ 
        (get-aduser $(get-aduser $_.samaccountname -Properties manager).manager -properties mail).mail 
        }
    }`

And again, I broke this out but in reality ran it on a single line. In this case, I didn’t have the manager value already so I had to run a command in both expressions -- manager and manager email.

This process isn’t going to scale well with a lot of data elements. This is just to show you something that might save you a little time if you’re just tooting around. :-)

Mar 27, 2015

DHCP Scope Information

Thought I’d squeeze in this post before Windows Server 2003 drifts off into the sunset. (Don’t pretend like you don’t have these servers floating around.)

Okay, so, I was recently asked to validate that some DHCP scope work was performed correctly. Validation in this case was to pull all the scope options. It would have been immensely helpful to use PowerShell to do this. However, I made do without it using Netsh.

 

Retrieving Scope Options for a Single Scope

netsh dhcp server <servername> scope <scopeaddr> show optionvalue

That’s easy. How about for every scope on my server? That’s easy, too, as it turns out.

 

Retrieving Scope Options for All Scopes
for /f %a in ('netsh dhcp server <servername> show scope ^| find /i "."' ) do @netsh dhcp server <servername> scope %a show optionvalue

Mar 26, 2015

PowerShell: Updating Terminal Services Profile Information

If you’ve done any dabbling in the AD cmdlets and attempted to update terminal services information, you’ll hit a wall with the traditional cmdlets. Why? Well, simply, what you see in AD Users and Computers is not the way the values are actually stored, as Ed explains.

Well, luckily, it turns out it’s not that hard. I was asked to come up with a process to update the profile path. This is a sample of what I ended up with:

$PathValue = <myUserPath>
$myUser = "myUserName" $User = [ADSI]LDAP://$((Get-AdUser $myUser).distinguishedname) $User.psbase.invokeset("TerminalServicesProfilePath",$PathValue) $User.setinfo()

 

Back to the Scripting Guys’ script, here is a function that shows the possible values that can be modified:

function SetTSProperties()
{
 $ou = [adsi]"LDAP://ou=mytestou,dc=nwtraders,dc=com"
 $user = $ou.psbase.get_children().find($userDN)
 $user.psbase.invokeSet("allowLogon",1)
 $user.psbase.invokeSet("TerminalServicesHomeDirectory",$hDirValue)
 $user.psbase.invokeSet("TerminalServicesProfilePath",$ppValue)
 $user.psbase.invokeSet("TerminalServicesHomeDrive",$hdValue)
 $user.setinfo() 
} #end SetTSProperties

Feb 9, 2015

PowerShell: Static Methods

Thanks PowerShell.com for the “Useful Static .NET Methods” PowerTip of the Day. Read the article.

 

Find all static methods.

[net.dns] | gm -MemberType *method -static

 

Find all signatures (overload definitions).

[net.dns]::GetHostByAddress

 

One last thing, if you’re looking for a good reference list of static methods that are useful, pick up a copy of Windows PowerShell Cookbook, 3rd Edition, by Lee Holmes.