We use cookies to improve your experience.
By your continued use of this site you accept such use.
For more details please see our privacy policy and cookies policy.

Script Repository

Add users to Business Units by country

February 22, 2021 Views: 2690

The script creates a set of business units, each containing users from a specific country. All business units created by the script are located in a certain container under the built-in Business Units container.

Descriptions of each business unit contains the number of users in the unit. Thus, when viewing a list of the business units in Adaxes Web interface or Adaxes Administration Console, you can see how many users from each country you have.

To use the script with Adaxes, create a scheduled task that runs it on a periodic basis to update the business units in line with changes in your AD. The task must be cofigured for the Domain-DNS object and assigned over any of your AD domains.

The selected domain is used only to trigger execution of the PowerShell script and does not affect the scope of AD users included in the business units.

Parameters:

  • $businessUnitContainerName - Specifies the name of the container where the business units are created.
  • $descriptionTemplate - Specifies a template for the business unit descriptions. In the template, the {0} placeholder will be replaced with the number of users in the business unit.
  • $usersWithoutCountryUnitName - Specifies a name for the business unit that holds users whose country is not specified in AD.
  • $countryInfo - Specifies a map of 2-letter country codes to the respective country names.
Edit Remove
PowerShell
$businessUnitContainerName = "Users by Country" # TODO: modify me
$descriptionTemplate = "Users: {0}" # TODO: modify me
$usersWithoutCountryUnitName = "Users Without Country" # TODO: modify me
# TODO: Specify country infos @{"two-letter country code" = "Country name";}
$countryInfo = @{
    "US" = "United States";
    "AL" = "Albania";
    "AR" = "Argentina";
    "AU" = "Australia";
    "AT" = "Austria";
    "BY" = "Belarus";
    "BE" = "Belgium";
    "BR" = "Brazil";
    "BG" = "Bulgaria";
    "CA" = "Canada";
    "CL" = "Chile";
    "CN" = "China";
    "CO" = "Colombia";
    "CR" = "Costa Rica";
    "HR" = "Croatia";
    "CZ" = "Czech Republic";
    "DK" = "Denmark";
    "EE" = "Estonia";
    "FI" = "Finland";
    "FR" = "France";
    "DE" = "Germany";
    "GR" = "Greece";
    "HK" = "Hong Kong";
    "HU" = "Hungary";
    "IN" = "India";
    "ID" = "Indonesia";
    "IE" = "Ireland";
    "IT" = "Italy";
    "JP" = "Japan";
    "KZ" = "Kazakhstan";
    "KP" = "Democratic People's Republic of Korea";
    "KR" = "Republic of Korea";
    "LV" = "Latvia";
    "LT" = "Lithuania";
    "MY" = "Malaysia";
    "MX" = "Mexico";
    "ME" = "Montenegro";
    "NL" = "Netherlands";
    "NZ" = "New Zealand";
    "NO" = "Norway";
    "PK" = "Pakistan";
    "PA" = "Panama";
    "PE" = "Peru";
    "PH" = "Philippines";
    "PL" = "Poland";
    "PT" = "Portugal";
    "RO" = "Romania";
    "RU" = "Russian Federation";
    "SA" = "Saudi Arabia";
    "RS" = "Serbia";
    "SG" = "Singapore";
    "SK" = "Slovakia";
    "ZA" = "South Africa";
    "ES" = "Spain";
    "SE" = "Sweden";
    "CH" = "Switzerland";
    "TW" = "Taiwan, Province of China";
    "TH" = "Thailand";
    "TR" = "Turkey";
    "UA" = "Ukraine";
    "AE" = "United Arab Emirates";
    "GB" = "United Kingdom";
    "VN" = "Viet Nam";
    "IL" = "Israel";
} # TODO: modify me

function RemoveBusinessUnit($path)
{
    try
    {
        $unit = $Context.BindToObject($path)
    }
    catch
    {
        return
    }
    
    $unit.DeleteObject("ADM_DELETEOBJECTFLAGS_AUTO")
}

function CreateBusinessUnit($name, $searchFilter, $businessUnitContainer, $description)
{
    # Create new Business Unit
    $unit = $businessUnitContainer.Create("adm-BusinessUnit", "CN=$name")
    $unit.Put("description", $description)
    $rules = $unit.GetMembershipRules()
    $rule = $rules.Create("ADM_BUSINESSUNITMEMBERSHIPTYPE_QUERY")
    $rule.Exclude = $False
    $rule.BaseObjectPath = $NULL
    $rule.Scope = "ADS_SCOPE_SUBTREE"
    $rule.Filter = $searchFilter
    $rules.Add($rule)
    $unit.SetMembershipRules($rules)
    $unit.SetInfo()
    
    # Update description
    UpdateUnitDescription $unit $description
}

function UpdateUnitDescription($unit, $description)
{
    $unit.Put("description", $description)
    $unit.SetInfoEx(@("description"))
}

# Search container for Business Units
$businessUnitsPath = $Context.GetWellKnownContainerPath("BusinessUnits")
$businessUnitsContainer = $Context.BindToObject($businessUnitsPath)
$businessUnitsContainer.SearchFilter = "(&(objectCategory=container)(name=$businessUnitContainerName))"
$businessUnitsContainer.SearchScope = "ADS_SCOPE_SUBTREE"
$businessUnitsContainer.PageSize = 500
$businessUnitsContainer.ReferralChasing = "ADS_CHASE_REFERRALS_NEVER"

try
{
    $searchResultIterator = $businessUnitsContainer.ExecuteSearch()
    $containers = $searchResultIterator.FetchAll()
    if ($containers.Count -eq 0)
    {
        # The container does not exist, create it
        $container = $businessUnitsContainer.Create("container","CN=$businessUnitContainerName")
        $container.SetInfo()
        $businessUnitContainerPathObj = New-Object "Softerra.Adaxes.Adsi.AdsPath" $container.AdsPath
    }
    elseif ($containers.Count -gt 1)
    {
        $Context.LogMessage("Found more than one Business Unit container with name '$businessUnitContainerName'.", "Error")
        return
    }
    else
    {
        # Open the container
        $businessUnitContainerPathObj = New-Object "Softerra.Adaxes.Adsi.AdsPath" $containers[0].AdsPath
    }
    
}
finally
{
    # Release resources
    $searchResultIterator.Dispose()
}

# Find all users and their countries
$searcher = $Context.BindToObject("Adaxes://rootDSE")
$searcher.SearchFilter = "(sAMAccountType=805306368)"
$searcher.PageSize = 500
$searcher.SearchScope = "ADS_SCOPE_SUBTREE"
$searcher.ReferralChasing = "ADS_CHASE_REFERRALS_NEVER"
$searcher.SetPropertiesToLoad(@("c"))
$searcher.VirtualRoot = $True

try
{
    $searchResultIterator = $searcher.ExecuteSearch()
    $users = $searchResultIterator.FetchAll()
    
    $usersWithoutCountryCount = 0
    $countries = @{}
    foreach ($userId in $users)
    {
        $country = $userId.Properties["c"].Value
        if ([System.String]::IsNullOrEmpty($country))
        {
            $usersWithoutCountryCount++
        }
        elseif ($countries.ContainsKey($country))
        {
            $countries[$country]++
        }
        else
        {
            $countries.Add($country, 1)
        }
    }
}
finally
{
    # Release resources
    $searchResultIterator.Dispose()
}

# Check Business Unit for users without country
$businessUnitDescription = [System.String]::Format($descriptionTemplate, $usersWithoutCountryCount)
$businessUnitContainer = $Context.BindToObject($businessUnitContainerPathObj)
try
{
    # Bind to Business Unit
    $businessUnitPath = $businessUnitContainerPathObj.CreateChildPath("CN=$usersWithoutCountryUnitName")
    $businessUnit = $Context.BindToObject($businessUnitPath)
    
    # Update unit description
    UpdateUnitDescription $businessUnit $businessUnitDescription
}
catch
{
    # Business Unit does not exist, create a new one
    CreateBusinessUnit $usersWithoutCountryUnitName "(&(sAMAccountType=805306368)(!(c=*)))" $businessUnitContainer $businessUnitDescription
}

# Check Business Units for each country
foreach ($country in $countries.Keys)
{
    if ($countryInfo.Contains($country))
    {
        # Get country name
        $countryName = $countryInfo[$country]
        
        # Check if Business unit with the same name as the two-letter country code exists
        $unitPathToRemove = $businessUnitContainerPathObj.CreateChildPath("CN=$country")
        RemoveBusinessUnit $unitPathToRemove
    }
    else
    {
        $countryName = $country
    }
    
    # Bind to the Business Unit
    $unitPath = $businessUnitContainerPathObj.CreateChildPath("CN=$countryName")
    $description = [System.String]::Format($descriptionTemplate, $countries[$country])
    try
    {
        $unit = $Context.BindToObject($unitPath)
        
        # Update description
        UpdateUnitDescription $unit $description
        continue
    }
    catch
    {
        # Business Unit for this country does not exist, create a new one
        CreateBusinessUnit $countryName "(&(sAMAccountType=805306368)(c=$country))" $businessUnitContainer $description
    }
}
Comments 0
Leave a comment
Loading...

Got questions?

Support Questions & Answers