0 votes

For licensing purposes is it possible to restrict users displayed in Adaxes based on an OU rather than individual accounts?

by (520 points)

1 Answer

0 votes
by (216k points)

Hello,

There is no support for such functionality in the user interface, but you can do this with PowerShell scripts. For example, you can create a PowerShell script that will add users from specific OUs to unmanaged accounts. Then, you can use this script in a Scheduled Task using the Run a program or PowerShell script action to launch it automatically so that if you add/remove users from the OUs that you specify, corresponding changes would be made to the list of unmanaged accounts automatically.

To implement such a solution:

  1. Create a new Scheduled Task.

  2. On the 3rd step of the Create Scheduled Task wizard, select the Show all object types option.

  3. Select the Domain-DNS object type.

  4. On the 4th step of the wizard, add the Run a program or PowerShell script action and paste the following script in the script field.

     $ouDNs = @("OU=MAC Auth Accounts,OU=IT,DC=company,DC=com") # TODO: modify me
    
     function GetUserSids($ouDNs)
     {
         $userSids = New-Object "System.Collections.Generic.List[String]"
    
         foreach ($ouDN in $ouDNs)
         {
             $ou = $Context.BindToObjectByDN($ouDN)
    
             $userSearcher = New-Object "Softerra.Adaxes.Adsi.Search.DirectorySearcher" $NULL, $False
             $userSearcher.SearchParameters.BaseObjectPath = $ou.AdsPath
             $userSearcher.SearchParameters.PageSize = 500
             $userSearcher.SearchParameters.SearchScope = "ADS_SCOPE_SUBTREE"
             $userSearcher.SearchParameters.Filter = "(&(objectCategory=person)(objectClass=user))"
             $userSearcher.SearchParameters.ReferralChasing = "ADS_CHASE_REFERRALS_NEVER"
             $userSearcher.SetPropertiesToLoad(@("objectSid"))
    
             $searcherResult = $userSearcher.ExecuteSearch()
    
             foreach ($user in $searcherResult.FetchAll())
             {
                 $sidBytes = $user.Properties["objectSid"].Value
                 $sid = New-Object "Softerra.Adaxes.Adsi.Sid" @($sidBytes, 0)
    
                 $userSids.Add($sid.ToString()) | Out-Null
             }
          }
    
          return ,$userSids
     }
    
     $userSids = GetUserSids $ouDNs
    
     $configurationSetSettingsPath = $Context.GetWellKnownContainerPath("ConfigurationSetSettings")
     $admConfigurationSetSettings = $Context.BindToObject($configurationSetSettingsPath)
    
     $admConfigurationSetSettings.SetUnmanagedAccounts(@($userSids))
    
  5. In the script, ouDNs specifies a list of Distinguished Names (DNs) of the OUs, users from which should be added to unmanaged accounts. Specify the OUs you don't want to manage.

  6. Add a short description for the script and click OK.

  7. On the 5th step, assign the Scheduled Task over any of your domains.

  8. Click Finish.

Also, you can take a look at the sample scripts in Adaxes SDK: http://adaxes.com/sdk/?SampleScripts.Co ... ounts.html.

0

Exactly what I was looking for and worked perfectly. Thanks very much, I wish every product had support like this one.

0

After setting this up as a task and letting it run a couple of times there seems to be some problem. If I manually run the task it works fine everytime, but if it runs on it's schedule it only seems to add a few of the accounts from the OU supplied. I changed the script a little because I only wanted on OU to be excluded, the script I'm using is below.

Import-Module Adaxes

$ouDN = "OU=MAC Auth Accounts,OU=IT,DC=company,DC=com"

$configurationSetSettingsPath = $Context.GetWellKnownContainerPath("ConfigurationSetSettings")
$admConfigurationSetSettings = $Context.BindToObject($configurationSetSettingsPath)

$allUnmanagedSids = New-Object "System.Collections.Generic.List[String]"

# Find all users under the given OU
$server = $Context.GetObjectDomain($ouDN)
$ouUsers = Get-AdmUser -Filter "*" -SearchBase $ouDN -SearchScope Subtree -Server $server -AdaxesService localhost
if ($ouUsers -ne $NULL)
{
    foreach ($user in $ouUsers)
    {
        $allUnmanagedSids.Add($user.Sid.ToString()) | Out-Null
    }
}

$admConfigurationSetSettings.SetUnmanagedAccounts(@($allUnmanagedSids))

Do you see any reason why when this task runs on it's schedule it doesn't add all the accounts it's supposed to? If I look at the Activity History for the task it always shows that it completed successfully. I'm attaching two screenshots below, the first is the scheduled task I have setup and the second is the unmanaged accounts that were added when it last ran. In the second image you can see it only added 11 accounts, but there are a couple hundred in that OU

Scheduled Task

Unmanaged User Accounts

0

Hello,

There is a small issue in the Script. The thing is when using the Get-AdmUser cmdlet and specifying the -AdaxesService parameter, the cmdlet will search for users via Adaxes service, and since some accounts are already unmanaged by Adaxes service, these accounts will not be returned in the search. Thus, the accounts will not be set as unmanaged accounts by the Task.

To remedy the issue, you can search for users using Adaxes ADSI API. Here's a script that meets your requirements:

$ouDNs = @("OU=MAC Auth Accounts,OU=IT,DC=company,DC=com") # TODO: modify me

function GetUserSids($ouDNs)
{
    $userSids = New-Object "System.Collections.Generic.List[String]"

    foreach ($ouDN in $ouDNs)
    {
        $ou = $Context.BindToObjectByDN($ouDN)

        $userSearcher = New-Object "Softerra.Adaxes.Adsi.Search.DirectorySearcher" $NULL, $False
        $userSearcher.SearchParameters.BaseObjectPath = $ou.AdsPath
        $userSearcher.SearchParameters.PageSize = 500
        $userSearcher.SearchParameters.SearchScope = "ADS_SCOPE_SUBTREE"
        $userSearcher.SearchParameters.Filter = "(&(objectCategory=person)(objectClass=user))"
        $userSearcher.SearchParameters.ReferralChasing = "ADS_CHASE_REFERRALS_NEVER"
        $userSearcher.SetPropertiesToLoad(@("objectSid"))

        $searcherResult = $userSearcher.ExecuteSearch()

        foreach ($user in $searcherResult.FetchAll())
        {
            $sidBytes = $user.Properties["objectSid"].Value
            $sid = New-Object "Softerra.Adaxes.Adsi.Sid" @($sidBytes, 0)

            $userSids.Add($sid.ToString()) | Out-Null
        }
    }

    return ,$userSids
}

$userSids = GetUserSids $ouDNs

$configurationSetSettingsPath = $Context.GetWellKnownContainerPath("ConfigurationSetSettings")
$admConfigurationSetSettings = $Context.BindToObject($configurationSetSettingsPath)

$admConfigurationSetSettings.SetUnmanagedAccounts(@($userSids))
0

That actually makes perfect sense and it is working much better now. I've run it multiple times and it always restricts the same amount. Thanks for all the help. I have another issue now however. The count is now below our license threshold, but for some reason I'm still getting an error when I launch the Admin Console that we've exceeded our license count.

0

Hello,

Wait until Adaxes service recalculates the number of users (~20 minutes) or restart your Adaxes service for the settings to take effect immediately.

0

Using code from Adaxes SDK.

Receiving the following error-

"Cannot validate argument on parameter 'SearchBase'. The argument is null. Supply a non-null argument and try the command again."

[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi") 
Import-Module Adaxes

$ouDNs = ("OU=OU's")

$replaceCurnentlyUnmanagedAccounts = $False

$admNS = New-Object "Softerra.Adaxes.Adsi.AdmNamespace"
$admService = $admNS.GetServiceDirectly("localhost")

$configurationSetSettingsPath = $admService.Backend.GetConfigurationContainerPath("ConfigurationSetSettings")
$admConfigurationSetSettings = $admService.OpenObject($configurationSetSettingsPath, $NULL, $NULL, 0)

$allUnmanagedSids = New-Object "System.Collections.Generic.HashSet[String]"

if (!$replaceCurnentlyUnmanagedAccounts)
{
    # Fetch user accounts that are already unmanaged
    $currentUnmanagedAccounts = $admConfigurationSetSettings.GetUnmanagedAccounts(@())
    foreach ($userInfo in $currentUnmanagedAccounts)
    {
        $allUnmanagedSids.Add($userInfo.Key) | Out-Null
    }
}

# Find all users under the given OU
$ouUsers = Get-AdmUser -Filter "*" -SearchBase $ouDN -SearchScope Subtree  -Server "domain.com"
if ($ouUsers -ne $NULL)
{
    foreach ($user in $ouUsers)
    {
        $allUnmanagedSids.Add($user.Sid.ToString()) | Out-Null
    }
}

$admConfigurationSetSettings.SetUnmanagedAccounts(@($allUnmanagedSids))
0

Hello,

It's not the code from the SDK. It's actually a weird mixture of the SDK sample and the script that you can find earlier in this topic :)

If you describe what you want to achieve in detail, we'll show you how to accomplish that.

0

Sorry about that. Lots of trial and error. No luck with any of the previous examples.

I'm trying to do exactly what the original post was asking. For licensing purposes, I have multiple OU's I would like to restrict from the user count.

0

Hello,

For your task, you need the script from Restrict Users Based On OU. In the script, $ouDNs specifies the Distinguished Names (DNs) of the OUs, users in which must not be managed by Adaxes. To run the script, you'll need to create a Scheduled Task as described in Restrict Users Based On OU.

0

Receiving this error-

0

Hello,

There indeed was a small error in the script. Try this version, it works better:

$ouDNs = @("OU=Unmanaged Accounts 1,DC=domain,DC=com","OU=Unmanaged Accounts 2,DC=domain,DC=com") # TODO: modify me

function GetUserSids($ouDNs)
{
    $userSids = New-Object "System.Collections.Generic.HashSet[String]"

    foreach ($ouDN in $ouDNs)
    {
        $ou = $Context.BindToObjectByDN($ouDN)

        $userSearcher = New-Object "Softerra.Adaxes.Adsi.Search.DirectorySearcher" $NULL, $False
        $userSearcher.SearchParameters.BaseObjectPath = $ou.AdsPath
        $userSearcher.SearchParameters.PageSize = 500
        $userSearcher.SearchParameters.SearchScope = "ADS_SCOPE_SUBTREE"
        $userSearcher.SearchParameters.Filter = "(sAMAccountType=805306368)"
        $userSearcher.SearchParameters.ReferralChasing = "ADS_CHASE_REFERRALS_NEVER"
        $userSearcher.SetPropertiesToLoad(@("objectSid"))

        $searcherResult = $userSearcher.ExecuteSearch()
        $users = $searcherResult.FetchAll()
        $searcherResult.Dispose()

        foreach ($userID in $users)
        {
            $sidBytes = $userID.Properties["objectSid"].Value
            $sid = New-Object "Softerra.Adaxes.Adsi.Sid" @($sidBytes, 0)

            $userSids.Add($sid.ToString()) | Out-Null
        }
    }

    return ,$userSids
}

$userSids = GetUserSids $ouDNs

$configurationSetSettingsPath = $Context.GetWellKnownContainerPath("ConfigurationSetSettings")
$admConfigurationSetSettings = $Context.BindToObject($configurationSetSettingsPath)

$admConfigurationSetSettings.SetUnmanagedAccounts(@($userSids))
0

Works great now. Thanks guys!

0

How do I specify multiple OU's?

I tried creating second task with another OU, and it erased the existing list and it replaced it with the new list.

I also tried running the script from the SDK and it also erased the existing list even if there is a setting "$replaceCurnentlyUnmanagedAccounts = $False"

0

Hello,

To specify multiple OUs, use the script from Restrict Users Based On OU. You need to create a single Scheduled Task and specify Distinguished Names (DNs) of the OUs via $ouDNs. Each DN must be enclosed in double quotes and separated by commas. You can see an example in the script:

$ouDNs = @("OU=Unmanaged Accounts 1,DC=domain,DC=com","OU=Unmanaged Accounts 2,DC=domain,DC=com") # TODO: modify me

where users from the following 2 OUs will be added to Unmanaged Accounts:

  1. OU=Unmanaged Accounts 1,DC=domain,DC=com
  2. OU=Unmanaged Accounts 2,DC=domain,DC=com
0

Thanks! Worked great

0

Hello,
could you show me how I can unrestrict the individual user accounts with powershell command (script).
For example, there is a userlist.txt and all users from the list must be managed in adaxes again.

Thank you!

0

Is there a way to modify this script to handle the list of OUs when imported from a CSV?

0

Hello,

Could you specify, whether user accounts from the OUs in CSV file should be added to the already existing list of Unmanaged Accounts or completely replace the list?

0

Probably replace the entire list, right? We'll want to automate this to repopulate the list once a month (or whatever), and as users are provisioned / deprovisioned the simplest fix is probably to just redo the list each time, I assume.

Thank you!

0

Hello,

We've added the script to our Script Repository. See the following page, the script entitled Import Organizational Units from CSV: http://www.adaxes.com/script-repository ... htm#import.

0

Great, I'll test it out. Thanks!

0

I've tested and am unable to get the script to run via the Adaxes powershell on Windows Server 2016. I get the following error:

%% : The term '%%' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the
spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:\Users\user\Desktop\UnlicensingCSV.ps1:43 char:21
+ $ouDNs = $records | %%{$_.$ouDNColumnName}
+ ~~
+ CategoryInfo : ObjectNotFound: (%%:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException

I'm unsure what the double % is (I'm not very knowledgeable about scripting), but I assume it's just a typo and it's supposed to be a single %, meaning 'foreach'?

Under that assumption I dropped one of the %s and reran the script, which generated a (different) host of errors, some as shown below:

You cannot call a method on a null-valued expression.
At C:\Users\user\Desktop\UnlicensingCSV.ps1:9 char:9
+ $searcher = $Context.BindToObjectByDN($ouDN)
+ ~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull

The property 'PageSize' cannot be found on this object. Verify that the property exists and can be set.
At C:\Users\user\Desktop\UnlicensingCSV.ps1:10 char:9
+ $searcher.PageSize = 500
+ ~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyNotFound

The property 'SearchScope' cannot be found on this object. Verify that the property exists and can be set.
At C:\Users\user\Desktop\UnlicensingCSV.ps1:11 char:9
+ $searcher.SearchScope = "ADS_SCOPE_SUBTREE"
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyNotFound

Have you been able to run this successfully? Am I missing a module or something? The values in my CSV look normal (I got them by running an export of our AD structure with this commandlet)

Get-ADOrganizationalUnit -filter * | select Name,DistinguishedName | Export-csv OUs.csv -NoTypeInformation

Thanks for the assistance.

0

Hello,

The script is using the Context variable and can be executed only in Business Rules, Scheduled Tasks and Custom Commands. You can create a Custom Command configured for Domain-DNS Object type to update the Unmanaged Accounts list on demand. For information on how to create a Custom Command, have a look at the following tutorial: http://www.adaxes.com/tutorials_ActiveD ... ommand.htm.

To schedule updating the Unmanaged Accounts list use a Scheduled Task configured for Domain-DNS Object type. To create the task, have a look at the following tutorial: http://www.adaxes.com/tutorials_Automat ... gement.htm.

Related questions

0 votes
1 answer

This is for license purposes and we do not want them visible in the Adaxes portal.

asked Oct 22, 2021 by jfrederickwl (20 points)
0 votes
1 answer

Is it possible to have Adaxes dynamically provide a list for the Offices AD property to choose based on a OU structure?

asked Aug 27, 2017 by audiblehum (50 points)
0 votes
1 answer

Hi, I would like to be able to provision my user accounts "Department" fields based on the Organizational Unit name in which the user is in. Basically I'd like to copy the ... Adaxes? ex: OU = IT Corp Name = Paul Fakename Department = IT Corp Thanks in advance

asked Nov 26, 2012 by cedricb (50 points)
0 votes
1 answer

Hi, would it be possible to achieve the following idea: Creating and updating rule based groups, based on user attributes like company? For each company value in AD, ... get all unique company values, then create a group with this company value as filter.

asked Mar 7 by wintec01 (1.1k points)
0 votes
1 answer

Hi we are trying to add users to a group based on the values of their "Office" and "Description" attributes within Active Directory. We have populated the below ... $Context.LogMessage("No matching criteria found for User $($Context.TargetObject.Name).") }

asked Sep 18, 2023 by Loopy8822 (20 points)
3,326 questions
3,026 answers
7,727 comments
544,678 users