Thank you very much, this was very helpful! You did this really quick as well!
For my code I needed to check every attribute but a few exceptions (samAccount & upn are generated dynamically, the support has no rights on it); here is the final code implementing that (I changed the first lines only):
$exclusion=@("objectClass","samAccountName","userPrincipalName","pwdLastSet","adm-CanNotChangePassword")
$propertiesToCheck=@()
for($i=0;$i -lt $Context.Action.PropertyList.PropertyCount;$i++){
$propertyName=$Context.Action.PropertyList.Item($i).Name
if($exclusion -notcontains $propertyName) {
$propertiesToCheck+=$propertyName
}
}
# Get the properties that the user can modify
$pipelinedTargetObject = $Context.TargetObject.AsPipelined()
$comparer = [System.StringComparer]::OrdinalIgnoreCase
$allowedToModifyProperties = New-Object "System.Collections.Generic.HashSet[System.String]" $comparer
foreach ($propertyName in $pipelinedTargetObject.PropertiesAllowedToModify)
{
$allowedToModifyProperties.Add($propertyName) | Out-Null
}
# Remove the properties that the user cannot modify
$removedProperties = New-Object "System.Collections.Generic.List[System.String]"
foreach ($propertyName in $propertiesToCheck)
{
if ($allowedToModifyProperties.Contains($propertyName))
{
continue
}
# Check whether the property is set for the target object
try
{
$Context.TargetObject.Get($propertyName)
}
catch
{
# Property is not set
continue
}
$removedProperties.Add($propertyName)
$Context.TargetObject.Put($propertyName, $NULL)
}
if ($removedProperties.Count -ne 0)
{
$Context.TargetObject.SetInfo()
$messageBuilder = New-Object "System.Text.StringBuilder"
$messageBuilder.Append("The following properties were cleared because you are not allowed to modify them: ")
$friendlyNamesCache = [Softerra.Adaxes.Directory.AttributeFriendlyNamesCache]::GetInstance([System.Globalization.CultureInfo]::CurrentUICulture)
for ($i = 0; $i -lt $removedProperties.Count; $i++)
{
$propertyFriendlyName = $removedProperties[$i]
if ($friendlyNamesCache.HasFriendlyName($propertyFriendlyName))
{
$propertyFriendlyName = $friendlyNamesCache.GetFriendlyName($propertyFriendlyName, $Context.TargetObject.Class)
}
$messageBuilder.Append($propertyFriendlyName)
if ($i -lt ($removedProperties.Count - 1))
{
$messageBuilder.Append(", ")
}
}
$Context.LogMessage($messageBuilder.ToString(), "Warning")
}
One last tiny question remains; is it possible to remove the checkbox password never expires and so on from the create mask? Thanks to the granular authorization I was able deny rights on those features (those are grayed in password reset mask) but it is still possible to set it when the user is created.
If not, this is not an issue at all; I will implement a condition that cancel the user creation if "password never expires" is checked.