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.
$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
}
}