none
Powershell - Windows 2008 - Get-ADUser AccountExpirationDate - Returns wrong result.

    問題

  • Challenge:

    Return all user accounts that has expired. A no brainer, really. I have this working just fine in Windows 2003.

    Since we are moving to Win 2008, I started running my scripts from my first Win 2008 server. This is when I run into this

    Problem:

    This command:

    Get-ADUser -Filter * -SearchBase 'OU=Users,DC=MyDomain,DC=CORP' -properties AccountExpirationDate | `
    Where-Object{$_.AccountExpirationDate -lt (Get-Date) -and $_.AccountExpirationDate -ne $null} | select-object name, samaccountname, `
    AccountExpirationDate

    ...works just fine when running on a Windows 2003 or a Windows 7 with RSAT installed. But running locally on the Win 2008, it return only some of the records.

    Here are some examples:

    Running from Win 7 or Win2003, the command

    Get-ADUser -Filter * -SearchBase 'OU=Users,DC=MyDomain,DC=CORP' -properties AccountExpirationDate | `
    Where-Object{$_.AccountExpirationDate -lt (Get-Date) -and $_.AccountExpirationDate -ne $null} | select-object name, samaccountname, `
    AccountExpirationDate

    ...returns:

    name                                      samaccountname                           AccountExpirationDate                  
    ----                                      --------------                           ---------------------                  
    Ivar Dahl (TEST)                          Test                                 05.11.2010 00:00:00                    
    Buss Buss                                    buss1                                    01.11.2010 00:00:00                    
    Ivar Dahl (Test2)                         Test2                                    02.12.2010 00:00:00  

    This is the correct result.

     

    Still running from Win 7 or Win2003, but specifically addressing the Win2008 server, the command

    Get-ADUser -server <TheWin2008IP> -Filter * -SearchBase 'OU=Users,DC=MyDomain,DC=CORP' -properties AccountExpirationDate | `
    Where-Object{$_.AccountExpirationDate -lt (Get-Date) -and $_.AccountExpirationDate -ne $null} | select-object name, samaccountname, `
    AccountExpirationDate

    ...returns :

    name                                      samaccountname                           AccountExpirationDate                  
    ----                                      --------------                           ---------------------                  
    Ivar Dahl (TEST)                          Test                                 05.11.2010 00:00:00                    
    Buss Buss                                    buss1                                    01.11.2010 00:00:00                    
    Ivar Dahl (Test2)                         Test2                                    02.12.2010 00:00:00  

    Still the correct result.

     

    Running from Win2008, the command

    Get-ADUser -server <TheWin2008IP> -Filter * -SearchBase 'OU=Users,DC=MyDomain,DC=CORP' -properties AccountExpirationDate | `
    Where-Object{$_.AccountExpirationDate -lt (Get-Date) -and $_.AccountExpirationDate -ne $null} | select-object name, samaccountname, `
    AccountExpirationDate

    or

    Get-ADUser -Filter * -SearchBase 'OU=Users,DC=MyDomain,DC=CORP' -properties AccountExpirationDate | `
    Where-Object{$_.AccountExpirationDate -lt (Get-Date) -and $_.AccountExpirationDate -ne $null} | select-object name, samaccountname, `
    AccountExpirationDate

    ...returns:

    name                                      samaccountname                           AccountExpirationDate                  
    ----                                      --------------                           ---------------------                  
    Ivar Dahl (TEST)                          Test                                 05.11.2010 00:00:00                                  
    Ivar Dahl (Test2)                         Test2                                    02.12.2010 00:00:00

    Now we are missing the "buss1" account.

     

    Running from Win2008, but specifically addressing the Win 2003 server, the command

    Get-ADUser -server <TheWin2003IP> -Filter * -SearchBase 'OU=Users,DC=MyDomain,DC=CORP' -properties AccountExpirationDate | `
    Where-Object{$_.AccountExpirationDate -lt (Get-Date) -and $_.AccountExpirationDate -ne $null} | select-object name, samaccountname, `
    AccountExpirationDate

    ...returns :

    name                                      samaccountname                           AccountExpirationDate                  
    ----                                      --------------                           ---------------------                  
    Ivar Dahl (TEST)                          Test                                 05.11.2010 00:00:00                    
    Buss Buss                                    buss1                                    01.11.2010 00:00:00                    
    Ivar Dahl (Test2)                         Test2                                    02.12.2010 00:00:00  

    This is the correct result.

     

    The same thing happens if I search for the accountExpires property.

     

    So, it works just fine from anywhere to anywhere except locally on the win2008. This server is a domain controller. The AD functional level is 2003.

    The problem seems to be consistent.

    This problem is not related to the buss1 account only, as I have seen it numerous times whenever expired accounts were present. I have compared the buss1 account with the test and test1 accounts in ADSIEdit, to check for anything that would explain this behavior, but I just can't see it.

     

    So, has anyone of you gurus out there any suggestions why this happens? This is not the end of the world for me, but as soon as we retire the Win2003 servers, this will be an issue for me. It also makes me wonder if there are other issues in Win 2008 PS scripting, which leaves me in a kind of "can't trust PS"-state...

     

    Best Regards
    Ivar Dahl

    2010年12月2日 下午 01:52

解答

  • When you query for disabled users it involves a different attribute (userAccountControl). Do you get the same results in all cases with the query:

    dsquery user domainroot

    It would be interesting if the sum of the two following queries results in all users. This first query should return all disabled users:

    dsquery * -filter "(&(objectCategory=person)(objectClass=user)" _
      & "(userAccountControl:1.2.840.113556.1.4.803:=2))" 

    while this query should return all users that are not disabled:

    dsquery * -filter "(&(objectCategory=person)(objectClass=user)" _
      & "(!userAccountControl:1.2.840.113556.1.4.803:=2))" 

    You might need to post your question in the Directory Services forum:

    http://social.technet.microsoft.com/Forums/en-US/winserverDS/threads

    Richard Mueller


    MVP ADSI
    2010年12月10日 下午 01:36
    版主

所有回覆

  • One thing I would point out is that the AccountExpirationDate isn't an attribute in AD, but the PS cmdlet converting the interval value into the datetime format.  So it could be something on the 2008 machine that isn't the same as a 2003 machine which is converting the value incorrectly.

    Maybe do something like:

    get-aduser buss1 -properties AccountExpirationDate,AccountExpires -server . | select AccountExpirationDate,accountExpires

    . . on each of the servers and see if there are differences?

    2010年12月2日 下午 05:57
  • I cannot duplicate the problem. I have several expired accounts in my domain and they all show up, even if I run your PS script on a W2k8 R2 Domain Controller. As noted, AccountExpirationDate is a method that converts the value of the accountExpires attribute into a date in the current time zone. I cannot think of anything to account for your experience.

    Richard Mueller


    MVP ADSI
    2010年12月3日 上午 02:02
    版主
  • Thank you guys for taking the time to test and answer.

    Thanks for pointing out the fact about AccountExpirationDate, but as I stated in the original posting, "The same thing happens if I search for the accountExpires property". Ok, I know it is an attribute in AD, but since the syntax used in PS is "-properties", that's why I called it that :)


    Anyway, I'm puzzled. I just can't see the light here.

    Of course I have made sure that I run as administrator while working on this. One theory was that the two "Ivar Dahl"-accounts were created by me, and the buss1-account was created by somebody else. But even if something like that had any influence, it still wouldn't make sense that it works from other systems.

    Could this have anything to do with the installed version of .NET framework? When running form a remote system, is it using the servers .NET framework, or the local systems .NET framework?

     

    Trying Dereks approach:

    From Win 7 :

    get-aduser buss1 -properties AccountExpirationDate,AccountExpires -server <MyWin2008> | select AccountExpirationDate,accountExpires | ft -auto

    or

    get-aduser buss1 -properties AccountExpirationDate,AccountExpires  | select AccountExpirationDate,accountExpires | ft -auto

    Results (both syntaxes):

    AccountExpirationDate     accountExpires
    ---------------------     --------------
    01.11.2010 00:00:00   129330396000000000

     

    Locally on the Win 2008 server:

    get-aduser buss1 -properties AccountExpirationDate,AccountExpires  | select AccountExpirationDate,accountExpires | ft -auto

    Results:

    AccountExpirationDate accountExpires
    --------------------- --------------

     

    Still running from the 2008 system, but addressing the win 2003 domain controller :

    get-aduser buss1 -properties AccountExpirationDate,AccountExpires -Server <MyWin2003>  | select AccountExpirationDate,accountExpires | ft -auto

    Results:

    AccountExpirationDate     accountExpires
    ---------------------     --------------
    01.11.2010 00:00:00   129330396000000000

     

    Different approach, but same result all the way. Very consistent.

    The fact that AccountExpirationDate is a calculated result of accountExpires, just enforces the fact that accountExpires isn't returned correctly.

     

    Ivar Dahl

    2010年12月3日 上午 08:23
  • It would use the local system's framework to do the calculation.  I also cannot reproduce the issue, but something strikes me funny just because its not returning the value, almost like that DC believes that attribute to be blank.  Try specifying the server in the command when running locally from 2008. Like:

    Locally on the Win 2008 server:
    get-aduser buss1 -properties AccountExpirationDate,AccountExpires  -server <2008server> | select AccountExpirationDate,accountExpires | ft -auto

    Are both 2003 and 2008 GCs?

     

    2010年12月3日 下午 02:41
  • Your results indicate to me that the accountExpires attribute has not replicated to the W2k8 computer. I would troubleshoot replication. Perhaps you can use ADSI Edit to verify. The value might be 0 or 2^63-1 (9223372036854775807). 0 means the expiration date has been removed, the other value means the account never had an expiration date.

    Richard Mueller


    MVP ADSI
    2010年12月3日 下午 03:50
    版主
  • While I really appreciate all your suggestions, I humbly point out that they have all been tested, as outlined in the original posting.

    I have tried to address the Win2008 server form the 2008 server itself. It fails.
    While addressing the 2008 server from the Win 2003 server, or from the Win 7 workstation, it respond with the correct result, which means that replication is working.
    Just to make sure, I initiated a replication from the AD Sites and Services snap-in. It replicated successfully. Then tried immediately to run my PS query, but the results are still the same.

    I have also compared these accounts in ADSI edit, and everything looks just right. The expiry date is there, and it is correct.

    Are both 2003 and 2008 GCs?
    Assuming GC means Global Catalog, the answer is yes.

    I'm wondering if there is some kind of bug in either .NET or PS or both, or maybe somewhere else. But since it is working all other ways than locally on the Win 2008 server, it would be some weird combination of something like "If if is snowing in London, AND the Euros exchange rate is going down, AND Hillary Clinton is drinking tea at the same time, then it fails, but only of the drivers name is Ivar".
    Of course, the system is up to date regarding versions and hot fixes.

    I have opened a support case with Microsoft, but so far it is still awaiting tech assignment.

     

    Ivar Dahl

     

    2010年12月6日 上午 09:07
  • Ivar,

    I'm sorry the suggestions we offered didn't pan out.  I'd be interested to hear what you find out in either case.  Feel free to post up your findings in this thread or message me directly if I can help.

    2010年12月6日 下午 04:35
  • It occurred to me after I last responded that replication problems wouldn't account for your experience, unless when you specifically query the W2k8 machine from the W2k3 machine the query is somehow redirected. Viewing the value with ADSI Edit confirms replication is not the problem. The value you see (129330396000000000) is correct, if your time zone is 1 hour east of GMT.

    I guess a problem with the .NET version or PS is the only explanation, but there still must be something different about the user that we cannot duplicate. It doesn't matter who created the object, nothing about the creator is saved in AD.

    Richard Mueller


    MVP ADSI
    2010年12月6日 下午 05:05
    版主
  • Now it gets really interesting :)
    While playing around with DSQuery, I experience pretty much the exact same behavior.

    Take a look at this:

    I have about a couple of hundred disabled accounts in my system. The reason for this is that we don’t reuse login initials, so instead, we disable accounts for users that are no longer working with us.

    Server2003 = Windows 2003 Domain Controller
    Server2008 = Windows 2008 Domain Controller

    --

    From the 2008, this command:
    dsquery user domainroot -disabled -gc  -limit 0
    Returns 9 records, which is not even close to the correct result.

    --

    From the 2008, this command:
    dsquery user domainroot -disabled -gc -s server2003 -limit 0
    returns a couple of hundred records, which is the correct result.

    --

    From the 2003, the command:
    dsquery user domainroot -disabled -gc  -limit 0
    returns a couple of hundred records, which is the correct result.

    --

    From the 2003, the command:
    dsquery user domainroot -disabled -gc  -s server2008 -limit
    returns a couple of hundred records, which is the correct result.

     

    So, as you can see, this is exactly the same problem, and now the issue isn’t script related anymore. There is something fishy in the 2008 server. It obviously has the correct information, but when queried from its local self, it fails, while when queried from any other host, it returns the correct results.

     In other words, Powershell is not the cause of this behavior.

    So I guess this issue no longer belongs in this forum, or at least not in the Powershell category.
    But if you have any suggestions based on the new facts, I's appreciate your feedback.

    Cheers
    Ivar Dahl

    2010年12月10日 上午 10:05
  • When you query for disabled users it involves a different attribute (userAccountControl). Do you get the same results in all cases with the query:

    dsquery user domainroot

    It would be interesting if the sum of the two following queries results in all users. This first query should return all disabled users:

    dsquery * -filter "(&(objectCategory=person)(objectClass=user)" _
      & "(userAccountControl:1.2.840.113556.1.4.803:=2))" 

    while this query should return all users that are not disabled:

    dsquery * -filter "(&(objectCategory=person)(objectClass=user)" _
      & "(!userAccountControl:1.2.840.113556.1.4.803:=2))" 

    You might need to post your question in the Directory Services forum:

    http://social.technet.microsoft.com/Forums/en-US/winserverDS/threads

    Richard Mueller


    MVP ADSI
    2010年12月10日 下午 01:36
    版主
  • Greetings Ivar,

    Were you able to find the resolution to this issue of the disabled users / AccountExpirationDate with Windows 2008?  I am interested in the results.

    Thanks,

    Brett

    2012年3月16日 下午 03:23
  • Greetings Ivar,

    Were you able to find the resolution to this issue of the disabled users / AccountExpirationDate with Windows 2008?  I am interested in the results.

    Thanks,

    Brett

    The topic is closed.

    Thger is also an issue with teh question.  RSAT or AD CmdLets cannopt and do not run on WS2008.  They only run on Vista and later and are built into WS2008R2.  Yu can install teh tools on an R2 member server but not on WS2008.  You can,however, install the server component of RSAT on WS2008 and WS2003.

    If you need to pursue this further then please open a new topic with your specific question.


    ¯\_(ツ)_/¯

    2012年3月16日 下午 04:43