AD Attributes – LastLogon vs. LastLogonTimeStamp…

2017-07-27T00:01:04+00:00 February 27th, 2013|Uncategorized|

A little while back I was working at an enterprise that has many locations across the United States.  I had a list of 30 usernames (from one specific out-of-state location) and a couple brand-new test accounts that I wanted to report on their “last logon times” from the Active Directory domain.  I put together a quick PowerShell script to loop through each user and report on the “lastLogon” time and I had (what I thought were) my results in no-time.  Here is a snippet of the code:

Get-ADUser $UserNameToSearch | Get-ADObject -Properties lastLogon

First, I opened up an RDP session to a domain workstation that I had access to at the out-of-state location that I was working with at the time and I went ahead and logged in with my test user.  I waited a few minutes for the replication to occur back to my location’s domain controller and then I ran the script from my local workstation.  Surprisingly, there were no results reported for that test account, but there were current up-to-date results for 95% of the users who were on my list that are said to work at that same location.

So I logged out, logged back in, waited, and ran the script again.  Still, no “logon time” results for my test user account.

Very interesting….

I did a few minutes of research on the “lastLogon” attribute and then I discovered I was searching the wrong attribute, per Microsoft’s MSDN Attribute Library which states: “This attribute is not replicated and is maintained separately on each domain controller in the domain. To get an accurate value for the user’s last logon in the domain, the Last-Logon attribute for the user must be retrieved from every domain controller in the domain. The largest value that is retrieved is the true last logon time for that user.  But since the enterprise I was working with had more domain controllers than I could count on one hand so I chose to find a simple alternative.

After a few more minutes of research I then found the attribute that is replicated across all domain controllers, the “lastLogonTimeStamp” attribute.  I updated my script to:

Get-ADUser $UserNameToSearch | Get-ADObject -Properties lastLogonTimeStamp

I then had the results that I expected and I carried on with my day.

Hopefully this experience will save you time and effort!

 

 

 

A Wrinkle with a Bundled Wireless Driver and DPInst32…

2017-07-27T00:01:04+00:00 February 20th, 2013|Uncategorized|

Fellow Coreteker Scott DeLand and I were recently working on a “QC” for some bundled wireless drivers, for which the customer used DPInst32.exe to install the drivers.  After the wireless driver folder has been installed to C:ExamplePath, DPInst is launched to install that driver.  Here’s what the launch action originally looked like in ZENworks Configuration Manager (ZCM):

Command:
${WinDisk}ExamplePathCompanyWireless DriverDPInst32.exe

Command Line Parameters:
/s /PATH ${WinDisk}ExamplePathCompanyWireless Driver

Working Directory:
${WinDisk}ExamplePathCompanyWireless Driver

There were a few problems with this, though.  For one, all of the installed driver folders had spaces in them.  When spaces are present in the command line parameters for some executables, they will fail without special care… and DPInst is included in this list. 

The other problem was that the install wasn’t creating an OEM file in C:Windowsinf.  When a new driver is installed, it should create a new OEM file with an incremental counter… so if the last OEM file was OEM94.inf, the next driver install will create an OEM file called OEM95.inf.  Scott pointed out that the drivers weren’t creating a new OEM file… were they really working? 

We tested with the command line and found that if we didn’t use quotes around the /PATH parameter and the parameter contained spaces, DPInst would not work.  Now the Command Line Parameters looked like this:

/s /PATH "${WinDisk}ExamplePathCompanyWireless Driver"

But there was still another problem:  On some machines, this action would fail with an exit code of 768 — and on some bundles, a new OEM file wouldn’t be generated.  Exit code 768 occurs when there is already a wireless driver on the machine, which we discovered previously.  We solved the new issue by adding code 768 as a success return code in the launch action, allowing the process to complete.  The other thing that was discovered was that if the driver was of the same type as another already installed driver, it wouldn’t create a new OEM file.

I thought I’d pass this along to see if it might help others!

 

Windows Activation Error: Code 0x8007232b

2017-07-27T00:01:04+00:00 February 13th, 2013|Uncategorized|

Every once in a while I like to pass along a helpful tip from another website or blog that helped me.  Today, I want to thank György Balássy for his blog posts (post 1, and post 2) last year that helped me with a goofy error, and maybe they can help you too.  I’ll just summarize the problem and results below.

I build a lot of lab servers and VMs for testing various things (including on my laptop or in my home lab, etc.), and I commonly install new Windows servers or workstations from the MSDN media ISO, using what is effectively a volume license.  Usually, I enter the key early in the build, it is accepted without error, and the install continues. 

However, occasionally after the installation completion, the Windows Server 2012 or Windows 8 machine reports an activation error:

Activation Error: Code 0x8007232b
DNS Name does not exist

And back when this first happened to me, it took a little bit of searching before I stumbled on György’s post.  But I’ve referred back to it a handful of times as this frustrating symptom seems to re-appear at random.  In a nutshell, he explains in his two posts that in order to fix this annoying error, you can do it with either the command prompt or GUI, as follows:

Command Prompt:

slmgr.vbs –ipk "XXXXX-XXXXX-XXXXX-XXXXX-XXXXX"

GUI:

slui 3

And it has worked perfectly for me every time.

Now, mind you, I did mention this problem was intermittent.  And the main reason I’m writing this post today after all this time is that it just happened to me again 3 days ago when I was in a hurry.  And today, when I had time to try and reproduce the error for a screen capture for this post, of course the key registration worked just fine and I cannot make it fail.  Argh.  So please take my word for it.

So thanks again György; and to the rest of you, I hope it helps you as well  And if it should pop up again, I’ll try to get a screen shot…

😉

 

 

How To Query Active Directory For Object Group Memberships…

2017-07-27T00:01:04+00:00 February 6th, 2013|Uncategorized|

Not too long ago, I was working with a colleague who was doing a lot of user management and provisioning, and needed to be able to look up the group membership of a user (or a computer) without being too complex or having to memorize anything.  So I installed RSAT on the computer, and made a little batch file that he could run that will take the username (as samAccountName) and dump out the direct or inherited memberships.  Easy as pie.

And as I often do, I thought I’d put up a little blog post detailing the mechanics and concepts of the script.  Of course, we’ve touched on some of these concepts before in this blog, but never in this direct of a way.  So without further ado…

How to Check Group Memberships from the User or Computer Perspective

If you already have the userID/samAccountName, then you can check *user* DIRECT group memberships like this example:

dsquery user -samid "JPavlov" |dsget user -memberof

…and to check *user* INHERITED group memberships, use the expand flag:

dsquery user -samid "JPavlov" |dsget user -memberof -expand

 

Similarly, you can check *computer* DIRECT group memberships like this example:

dsquery computer -name "CTS004895" |dsget computer -memberof

…and to check *computer* INHERITED group memberships:

dsquery computer -name "CTS004895" |dsget computer -memberof -expand

 

How to Check Groups Memberships from the Group Perspective

Of course, I just can’t leave it there.  What if you want to approach it from the other direction?  For instance, if you have a group name (or a prefix if you have a naming convention), and you want to get a membership list of that group?  It’s still doable.  And while I’m at it, I thought I’d sprinkle in a little bit of PowerShell, and still use dsquery to get the job done, as in the following example:

$StartingContext = "OU=Groups,OU=Location,DC=Coretek,DC=local"
$GroupPrefix = "CTS FH "
$GroupList = dsquery * $StartingContext -limit 9000 -filter "(&(objectClass=Group)(name=$GroupPrefix*))" -attr samAccountName,member
$GroupList

…and this works, but… unfortunately, the output is horrible because the dsquery output is ugly.  But, if you happen to already have a list of group names (as in my example groupList.txt below), you could do something like in this example:

$GroupList = Get-Content .groupList.txt
$StartingContext = "OU=Groups,OU=Location,DC=Coretek,DC=local"
foreach ($GroupItem in $GroupList)
{
  write ""
  write "Group is $GroupItem"
  dsquery * $StartingContext -limit 9000 -filter "(&(objectClass=Group)(samAccountName=$GroupItem))" | dsget group -members
}

…and while it’s basically the same dsquery as in the snippet above, the output is much nicer — since we are piping it into dsget, which makes for a much prettier report. 

Now… perhaps my favorite of all, we can do pretty much the same procedure as the previous command, but this time all in PowerShell, and using the Get-AdGroup command (remember to import the ActiveDirectory module!):

$GroupPrefix = "CTS FH "
$MemberList = Get-ADGroup -ldapFilter "(&(objectClass=Group)(name=$GroupPrefix*))" -Properties Members
foreach ($MemberItem in $MemberList)
{
  write ""
  write "Membership for: $MemberItem"
  $MemberItem.Members
}

And that’s it!  You should have a list of group members for the correlating groups. 

So as usual, we have a couple ways to do a few different things.  Have fun with it!