Showing posts with label ldap. Show all posts
Showing posts with label ldap. Show all posts

Tuesday, September 28, 2021

Capturing unique simple bind or unsigned ldap queries from a domain controller

Using get-winevent in powershell with XML filter, you can grab the 2889 events from the directory services log. These contain the username, and source IP. With some custom defined attributes within select-object along with an array, you can filter this down to unique connections.

$query = @"

<QueryList>

  <Query Id="0" Path="Directory Service">

    <Select Path="Directory Service">*[System[(EventID=2889)]]</Select>

  </Query>

</QueryList>

"@


$somelistofdomaincontrollers | %{

$serv = $_

$hashes = @();

get-winevent -filterxml $query | select @{n="dc";e={$_.machinename}},
@{n="source";e={($_.properties.value[0].split(":"))[0]}},
@{n="user";e={$_.properties.value[1]}},
@{n='connhash';e={$str = ($_.machinename + 
    $_.properties.value[0].split(":"))[0] +
    $_.properties.value[1]; $str.gethashcode()}} | %{

     if ($hashes.contains($_.connhash)) {} else {$hashes += $_.connhash; $_|
        select dc,source,user}

}

Friday, February 14, 2014

AD Account Expiration, search results not giving expected values

I recently ran into a problem when trying to find accounts that were incorrectly set for expiration date, especially searching for accounts that were set to never expire.  The attribute in ActiveDirectory is "accountExpires", however when dealing with AD powershell cmdlets such as Get-ADUser, it is filtered as AccountExpirationDate.  Typically someone may assume that if an account is set to never expire, it should not have a value for this attribute as it is not mandatory.  So a search for Null or Empty on that attribute will give you all of the results.  However, I found in the environment that I was working with, many accounts had the attribute set at some point, but the value was still a value that shows in the GUI tools as "never expires".  In this case, the value is one second above given the maximum calendar date. (Value in attribute: December 30, 9999 12:00:00 AM (GMT)).


[datetime]::maxvalue.ToUniversalTime()
&nbsb &nbsb Friday, December 31, 9999 11:59:59 PM

You can get this value by putting it in with the adjusted current time zone, such as this example of US Central Time:

$forever = [datetime]"12/29/9999 6:00:00 PM"

Using the MaxValue function along with the AddSeconds(1) method will fail.


Alternatively, the AD time format of the value is: 9223372036854775807, so you can do an ldap filter such as:
"(&(objectclass=user)(|(accountexpires=9223372036854775807)(!(accountexpires=*))))"


So when you are trying to find accounts that never expire, you may want to filter in two ways:


1) Attribute is null
2) Attribute is equal to the maximum date value

Thursday, November 22, 2012

LDAP AD: Finding members of a group who have it as their primary group

An interesting problem came up today, where a developer was having problems pulling members of a domain group. The group shows hundreds of users when looking at it in Active Directory Users and Computers, however any LDAP connection to it only results in 50 users. Based on the name, I realized this group was used as a "Primary Group" for a group of special case users. Typically the "Primary Group" for a user is the Domain Users builtin group for the domain. If you look at this forum post, it shows a way to query for this group. On each user account is an attribute called PrimaryGroupID, which is a numeric value. In the article you can see that Domain Users is value 513 which is derived from its well known SID, ending in -513. So if you have another group that you want to look at, you will need to pull its SID, strip off the last number and query for all users that have that PrimaryGroupID number. This may not yield a complete list, so you can also search memberOf for that same group, or go with the member's attribute of the group itself. The first option allows you to build a single query with an | (or) statement in it, the latter would require some combining.

As an example, lets say our group was called SecondaryUsers.

In powershell we can get the object SID
$id = new-object System.Security.Principal.NTAccount(CONTOSO\SecondaryUsers)
$sid = $id.translate([system.security.principal.securityidentifier]).tostring()
$sidval = $sid.substring($sid.lastindexof('-')+1)

Now that we have our group's number, lets do an ldap search

$de = new-object directoryservices.directoryentry("LDAP://dc=contoso,dc=com")
$ds = new-object directoryservices.directorysearcher($de)
$ds.filter = "(&(objectclass=user)(|(primarygroupid=$($sidval))(memberof:=cn=SecondaryUsers,ou=MyGroups,dc=Contoso,Dc=com)))"
$ds.propertiestoload.add("samaccountname") |out-null
$users = $ds.findall()

Now we have all of the users under that group, whether they are memberof or member by PrimaryGroup.

Wednesday, June 27, 2012

Getting AD object metadata via powershell

Occasionally I receive requests in my organization to see when was a user changed, when was someone added removed from a group, etc etc.  I thought it would be nice to get away from repadmin with this and come up with something that can provide enough information, be somewhat easy to use, and not require any special rights or tools.  So I put together this script to pull metadata (either attribute changes, or multivalue changes) on computers, users, or group objects.  In the script, you provide the common name of the object and the type of object.  From here it searches the global catalog for it, pulls the metadata, cuts down the attributes and outputs it in pre-sorted columns.  From there it can be searched or further formated using typical powershell commandlets to manipulate objects.  For those that want to take this further, you can follow the example of how to pull the metadata via ldap and manipulate the XML to include the attributes you want.  Some caveats with this which you won't find in repadmin /showobjmeta is that the times are in Z time, and recording domain controller data is using the domain controller GUID.  So there are some opportunities for expansion and improvement of this script for a more tech oriented audience.




#requires -version 2

param(
 [parameter(mandatory=$true)][alias('samaccountname','cn','username','groupname')]$name,
 [parameter(mandatory=$true)][ValidateSet("Group","Computer","User")]
  [alias('object','objecttype')]$type,
 [switch][alias("members","member")]$valuemeta
)

#Set up connection to forest
$de = New-Object directoryservices.DirectoryEntry("GC://dc=contoso,dc=com")
$ds = new-object directoryservices.directorysearcher($de)

#set an appropriate search filter for each type of object
switch ($type) {
  "group" {$ds.filter = "(&(objectclass=group)(|(samaccountname=$name)(cn=$name)))" }
  "computer" { $ds.filter = "(&(objectclass=computer)(cn=$name))" }
  "user" { $ds.filter = "(&(objectclass=user)(samaccountname=$name))" }
} 

#load up metadata attribs and search
$ds.propertiestoload.add("distinguishedname") > $null
$fu = $ds.findone()
if ($fu -ne $null) {
 $de = New-Object directoryservices.DirectoryEntry("LDAP://" + $fu.properties.distinguishedname[0])
} else {
 Write-Error "Object not found in AD"
 exit 1
}
$ds.searchroot = $de
$ds.propertiestoload.add("msDS-ReplAttributeMetaData") > $null
$ds.propertiestoload.add("msDS-ReplValueMetaData") > $Null
$fu = $ds.findone()

#display the requested type of data
if ($valuemeta) {
 $xml = "<root>" + $fu.properties."msds-replvaluemetadata" + "</root>"
 $xml = [xml]$xml
 $xml.root.DS_REPL_VALUE_META_DATA | 
  Select-Object @{name="Attribute"; expression={$_.pszAttributeName}},@{name="objectDN";expression={$_.pszObjectDN}},ftimeDeleted,ftimeCreated |
  Sort-Object attribute
} else {
 $xml = "" + $fu.properties."msds-replattributemetadata" + ""
 $xml = [xml]$xml
 $xml.root.DS_REPL_ATTR_META_DATA |
  select-object @{name="Attribute";expression={$_.pszAttributeName}},@{name="ChangeTime";expression={$_.ftimeLastOriginatingChange}}|
  Sort-Object attribute
}

<#
.DESCRIPTION
 Show-ADObjMeta will show the attributes and last time written on the object.
 
.PARAMETER Name
 The name of the user/computer/group that you want to pull the metadata for.  This should be the logon
 id if it is a user, the computer name for computers, and the groupname (cn or samaccountname) for groups.

.PARAMETER ValueMeta
 Use this parameter if you want to view multivalue item metadata, like Group Member add/remove details
 
.PARAMETER Type
 Specify the type of object: User, Group, Computer
 
.EXAMPLE
 Show-ADObjMeta -type user -name myuser

 Get the metadata for attributes of myuser
 
#>