The script generates a report that will include users whose property values do not match the ones allowed by effective property patterns. Also, the report will include users with empty properties that are mandatory according to effective property patterns. To execute the script, create a report with a scope that will include users that should be checked by the script.
PowerShell
function IsUserPropertiesValid($propertyPatternDN, $user)
{
# Bind to the Property Pattern
$propertyPattern = $Context.BindToObjectByDN($propertyPatternDN)
# Get all properties from the Property Pattern to load
$propertiesToLoad = @()
foreach($item in $propertyPattern.Items)
{
$propertiesToLoad += $item.PropertyName
}
$user.GetInfoEx($propertiesToLoad, 0)
$userPropertyList = $user.PropertyList
foreach($item in $propertyPattern.Items)
{
# Get property entry
try
{
$propertyEntry = $userPropertyList.Item($item.PropertyName)
}
catch
{
if ($item.IsPropertyRequired)
{
return $False
}
else
{
continue
}
}
if ($item.IsPropertyRequired -and ($propertyEntry.Values.Length -le 0))
{
return $False
}
$propertyEntry.ControlCode = "ADS_PROPERTY_UPDATE"
# Get constraints
$constraints = $item.GetConstraints()
foreach($constraint in $constraints)
{
$errorMsg = $NULL
if ($constraint.Check($propertyEntry, $user, [ref]$errorMsg))
{
continue
}
return $False
}
}
return $True
}
try
{
$Context.DirectorySearcher.AppendFilter("(sAMAccountType=805306368)")
$searchIterator = $Context.DirectorySearcher.ExecuteSearch()
while ($Context.MoveNext($searchIterator))
{
$user = $Context.BindToObjectBySearchResult($searchIterator.Current)
# Get Property Patterns effective for the user
try
{
$propertyPatternDNs = $user.GetEx("adm-EffectivePropertyPatterns")
}
catch
{
continue
}
$user.GetInfo()
foreach($propertyPatternDN in $propertyPatternDNs)
{
if (IsUserPropertiesValid $propertyPatternDN $user)
{
continue
}
$Context.Items.Add($user)
break
}
}
}
finally
{
if ($searchIterator) { $searchIterator.Dispose() }
}