0 votes

Dear Support, is there a way to check not all attributes listed in the pattern, but only 1? For example user department not matching a list, provided in the pattern, but pattern contains many other attributes except department and creating a separate pattern is really not an option).

Thanks for any advise!

by (920 points)
0

Hello Dmytro,

Do we understand correctly that you need a report that will include users whose values of a specific property do not match the list allowed by a specific Property Pattern? Or the validation should be performed by checking all the Property Patterns effective for a user without predefining? Any additional details regarding the desired report and live examples would be much appreciated.

Could you, please, specify what version of Adaxes you are currently using? For information on how to check it, have a look at the following help article: https://www.adaxes.com/help/HowDoI.ManageService.CheckAdaxesServiceVersion.html.

0

Hello, we are using 3.12.17423.0. We need to have a list of users whose values of specific property does not match the list allowed by a specific pattern (addressed by DN or name?) which contains patters for other properties as well.

E.g. we have a pattern "Organizational properties" which controls 3 attributes - division, department, job title, each of them as list of possible values (A,B,C,etc) We want the report to show users, whos department doesn't match the list provided for this property in that exact "Organizational properties" pattern, not all applied patterns on object, because this pattern might not be applied to all, but we need to check against all.

I really hope I described it correctly :)

Thanks for your help!

0

Hello Dmytro,

Thank you for the provided details. This can be done using a custom report. Before generating the report you will need to select the property whose values will be checked from a drop-down list. Then you will need to select the OU/container where users to be checked are located (if left empty, all users in your environment will be checked). The script used to generate the report will check all the Property Patterns that are effective for the user (not all existing Property Patterns) and add the user to the report if their property value does not match the list. In this case, there will be no need to predefine the Property Pattern name/DN.

Does this solution meet your needs? If not, please, provide us with all the possible details on how exactly you need the report to be generated.

0

Hello, Do I understand correctly, that monitored attributes will be report parameters and OU/container as scope? As in any report generally? If yes - exactly what we are looking for

1 Answer

+1 vote
by (270k points)
selected by
Best answer

Hello Dmytro,

Thank you for the confirmation. To create the report:

  1. Launch Adaxes Administration Console.
  2. In the Console Tree, right-click your service node.
  3. In the context menu, navigate to New and click Report.
  4. Enter a report name and select the Script option. image.png
  5. Click Next.
  6. Click New.
  7. Select Objects in a specific AD location and click Next twice. image.png
  8. Specify scope settings and click Finish.
  9. Click Next.
  10. Click New.
  11. Select Property name picker and click Next. image.png
  12. Specify a parameter name and display name (e.g. propertyToCheck and Property to check). image.png
  13. Click Next.
  14. Select Specific properties and click Select. image.png
  15. Specify the properties that will be available for selection to generate the report.
  16. Click OK and then click Finish.
  17. Click Next.
  18. Specify column settings for the report and click Next.
  19. Paste the below script into the corresponding field. In the script, the $propertyName variable specifies a reference to the parameter used to select the property whose value will be checked. The value of the variable should exactly match the parameter name entered on step 12 (e.g. "%param-propertyToCheck%").
$propertyName = "%param-propertyToCheck%" # TODO: modify 

function IsUserPropertiesValid($propertyPatternDN, $propertyEntry, $user)
{
    # Bind to the Property Pattern
    $propertyPattern = $Context.BindToObjectByDN($propertyPatternDN)
    foreach($item in $propertyPattern.Items)
    {
        if ($item.PropertyName -ine $propertyEntry.Name)
        {
            continue
        }

        # 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
        }

        # Get property entry
        $user.GetInfo()
        try
        {
            $propertyEntry = $user.PropertyList.Item($propertyName)
        }
        catch
        {
            continue
        }
        $propertyEntry.ControlCode = "ADS_PROPERTY_UPDATE"


        foreach($propertyPatternDN in $propertyPatternDNs)
        {
            if (IsUserPropertiesValid $propertyPatternDN $propertyEntry $user)
            {
                continue
            }

            $Context.Items.Add($user)
            break
        }
    }
}
finally
{
    if ($searchIterator) { $searchIterator.Dispose() }
}
  1. Click Next and finish creating the report.
0

Hello, thanks a lot for such detailed description and help! It does the job, but 1 question left, if I may - for some reason it ignores empty values.

If attribute which I'm checking is empty and pattern has "Must be one of the following values" (and empty is not one of them for sure) - those users do not get included in the report. Is this something which must be adjusted in the pattern or the script?

Thanks!

0

Maybe if it fails to get property value if it's empty and just skips?

   try
        {
            $propertyEntry = $user.PropertyList.Item($propertyName)
        }
        catch
        {
            continue
        }
0

Hello Dmytro,

Yes, you are right. This behavior is correct in the script because it only checks the list of allowed values while specifying the list does not disallow empty values. This is done by making the property required. Do you want the script to check for property being required and add users with empty required property to the report or all users that have an empty value of a property for which a list of values is specified in a Property Pattern should be added?

0

Hello, Currently I have the pattern of field "office" for example set as "The property is required" and "Must be one of the following values only" with a list of 5 options (blank is not one of them). I cannot set in the pattern explicitly "must not be empty" :( So yes, it would be great if empty value would be considered as "pattern violation" and users with empty attribute should be in the report.

Thanks!

0

Hello Dmytro,

Enabling the The property is required option is exactly the one making empty values not allowed for the property. Are the following examples correct for the report you need?

  1. User has Office property empty, there is a Property Pattern where the The property is required option is enabled and a list of values for the Office property is specified. The user will be added to the report.
  2. User has Office property empty, there is a Property Pattern where the The property is required option is disabled and a list of values for the Office property is specified. The user will not be added to the report.
0

Hello, yes, exactly like you described.

+1

Hello Dmytro,

Thank you for the confirmation. Here is the updated script. You just need to use it in your report instead of the previous script.

$propertyName = "%param-propertyToCheck%" # TODO: modify 

function IsUserPropertiesValid($propertyPatternDN, $propertyEntry, $propertyName, $user)
{
    # Bind to the Property Pattern
    $propertyPattern = $Context.BindToObjectByDN($propertyPatternDN)
    foreach($item in $propertyPattern.Items)
    {
        if ($item.PropertyName -ine $propertyName)
        {
            continue
        }

        if ($item.IsPropertyRequired -and $NULL -eq $propertyEntry)
        {
            return $False
        }
        elseif ($NULL -eq $propertyEntry)
        {
            continue
        }

        # 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
        }

        # Get property entry
        $user.GetInfo()
        try
        {
            $propertyEntry = $user.PropertyList.Item($propertyName)
            $propertyEntry.ControlCode = "ADS_PROPERTY_UPDATE"
        }
        catch
        {
            $propertyEntry = $NULL
        }

        foreach($propertyPatternDN in $propertyPatternDNs)
        {
            if (IsUserPropertiesValid $propertyPatternDN $propertyEntry $propertyName $user)
            {
                continue
            }

            $Context.Items.Add($user)
            break
        }
    }
}
finally
{
    if ($searchIterator) { $searchIterator.Dispose() }
}
0

Hello, thanks a lot for you help! It works perfectly!

Related questions

0 votes
1 answer

Hi, we currenlty have a business rule to send an email everytime the Title, Manager, Department, accountExpires, EmployeeType or FirstName attributes are ... Unit: %BusinessUnit% End Date: %accountExpires% Effective Date of Change: %adm-CustomAttributeDate2%

asked Feb 14 by KevC (60 points)
0 votes
1 answer

Where are the result options located for Reports? I have several admins that do a All Users report search then click on the User Name, from the Menu on the left ... the user does not have the option to select these options. Standard Password Configuration:

asked Sep 2, 2020 by dknapp (100 points)
0 votes
1 answer

I have made a deprovision custom command. I cannot change the attribute directReports, so was thinking - i could take the people in the directReports field of the manager ... (and its subordinates) that im running the deprovision custom command from. Any tips?

asked Mar 21 by EdgarsABG (50 points)
0 votes
1 answer

Dear Support, Is it possible in "generate default value" section of pattern for multivalued attribute to provide more than 1 value from "must be one of" section? E.g. Pattern ... E" and to have default generated values in web interface "A,C" Thanks for advise!

asked Jul 7, 2020 by Dmytro.Rudyi (920 points)
0 votes
1 answer

When a new user account is created by copying an existing one, is it possible to prevent the new account from becoming a member of security groups in a specific OU (when the ... same way as the account being added to the group, which I need for audit purposes.

asked Sep 28, 2020 by markcox (70 points)
3,326 questions
3,026 answers
7,727 comments
544,678 users