0 votes

Is it possible to create a human readable report for Security Roles, Business Rules, etc?

Scenario: Our audit department wants to save a readable definition of a particular Security Role, then be able to analyze and compare this going forward for any changes made to it from the last review.

If not a report, is it possible to export the role to XML, etc?

Thanks!

by (950 points)

1 Answer

0 votes
by (18.0k points)

Hello,

Unfortunately currently it is impossible. In September we are planning to release SDK for Adaxes. With the help of the SDK it will be possible generate reports you need using PowerShell scripts.

0

Hi,

It's been a while since I've visited this area - ADAxes is still working great for us.

We are on version 2013.1. I'm wondering:

1. Does the latest version have the capability of exporting Security Roles?
2. Would you be able to provide an example Powershell that simply enumerates security roles and the trustees and "assigned over" attributes?

Thanks,

0

Hello,

1. Yes, with the help of PowerShell scripts you can export your Security Roles in a human-readable format, such as CSV sheets, for example. For more details on handling Security Roles using scripts, have a look at the following SDK article: http://www.adaxes.com/sdk/?ManagingSecurityRoles.html.
2. We've assigned our script guys with a task to run a sample for you. We'll update you as soon as they come up with something.

0

Hello,

Here's a script that exports all Security Roles and role assignments to a CSV file specified by $csvFilePath. The CSV file will have the report generation date and time appended to the end of the file name. The date format is specified by $dateFormat.

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

$csvFilePath = "\\Server\share\SecurityRolesReport-{0}.csv" # TODO: modify me
$dateFormat = "MM.dd.yyyy-HH.mm.ss" # TODO: modify me

function GetTrusteeName($trustee)
{
    if ([Softerra.Adaxes.Utils.WellKnownSecurityPrincipalInfo]::IsWellKnown($trustee))
    {
        $wellknownPrincipal = [Softerra.Adaxes.Utils.WellKnownSecurityPrincipalInfo]::GetInfo($trustee)
        return $wellknownPrincipal.DisplayName
    }

    if ([Softerra.Adaxes.Adsi.Sid]::PrimaryOwnerSid -eq $trustee)
    {
        return "Owner (ManagedBy)"
    }
    elseif ([Softerra.Adaxes.Adsi.Sid]::ManagerSid -eq $trustee)
    {
        return "Manager"
    }
    elseif ([Softerra.Adaxes.Adsi.Sid]::SecretarySid -eq $trustee)
    {
        return "Secretary"
    }
    elseif ([Softerra.Adaxes.Adsi.Sid]::AssistantSid -eq $trustee)
    {
        return "Assistant"
    }

    # Get object name
    $objectSid = New-Object "Softerra.Adaxes.Adsi.Sid" $trustee
    $object = $global:admService.OpenObject("Adaxes://<SID=$objectSid>", $NULL, $NULL, 0)
    return $object.Get("name")
}

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

# Find all Security Roles
$securityRolesPath = $global:admService.Backend.GetConfigurationContainerPath("AccessControlRoles")
$searcher = $global:admService.OpenObject($securityRolesPath, $NULL, $NULL, 0)
$searcher.SearchFilter = "(objectCategory=adm-Role)"
$searcher.PageSize = 500
$searcher.SearchScope = "ADS_SCOPE_SUBTREE"

try
{
    # Execute search
    $searchResult = $searcher.ExecuteSearch()
    $roles = $searchResult.FetchAll()

    $report = @()
    foreach ($roleId in $roles)
    {
        # Bind to the Security Role
        $role = $global:admService.OpenObject($roleId.AdsPath, $NULL, $NULL, 0)
        $roleName = $role.Get("name")

        # Add Security Role to the report
        $reportRecordTemplate = New-Object PSObject
        $reportRecordTemplate | Add-Member -Name RoleName -Value $roleName -MemberType NoteProperty
        $reportRecordTemplate | Add-Member -Name Trustee -Value "None" -MemberType NoteProperty
        $reportRecordTemplate | Add-Member -Name AssignedOver -Value "None" -MemberType NoteProperty
        $reportRecordTemplate | Add-Member -Name Exclude -Value "None" -MemberType NoteProperty 
        $reportRecordTemplate | Add-Member -Name Inheritance -Value "None" -MemberType NoteProperty

        if ($role.Assignments.Count -eq 0)
        {
            $reportRecord = $reportRecordTemplate.PSObject.Copy()
            $report += $reportRecord
            continue
        }

        # Get Role Assignments
        foreach ($assignment in $role.Assignments)
        {
            $trusteeName = GetTrusteeName $assignment.Trustee
            foreach ($item in $assignment.ActivityScopeItems)
            {
                switch ($item.Type)
                {
                    "ADM_SCOPEBASEOBJECTTYPE_ALL_DIRECTORY"
                    {
                        $itemName = "All objects"
                    }
                    "ADM_SCOPEBASEOBJECTTYPE_CONFIGURATION"
                    {
                        $itemName = "Configuration objects"
                    }
                    default
                    {

                        $itemName = $item.BaseObject.Get("name")
                    }
                }

                switch ($item.Inheritance)
                {
                    "ADS_SCOPE_BASE"
                    {
                        $inheritance = "This object only"
                    }
                    "ADS_SCOPE_ONELEVEL"
                    {
                        $inheritance = "One level"
                    }
                    "ADS_SCOPE_SUBTREE"
                    {
                        $inheritance = "Subtree"
                    }
                }

                $reportRecord = $reportRecordTemplate.PSObject.Copy()
                $reportRecord.Trustee = $trusteeName
                $reportRecord.AssignedOver = $itemName
                $reportRecord.Exclude = $item.Exclude
                $reportRecord.Inheritance = $inheritance
                $report += $reportRecord
            }
        }
    }
}
finally
{
    $searchResult.Dispose()
}

$report | Export-Csv -NoTypeInformation -Path ($csvFilePath -f (get-date).tostring($dateFormat))
0

I know this is really old but i tried the report anyway. It errors out on this part. image.png

Can you guys update it for 2021.1 ?

0

Hello Mark,

Have a look at the following script from our repository: https://www.adaxes.com/script-repository/report-on-security-roles-s225.htm.

0

We are not on 2023 yet due to some internal applications that need to be updated. We can't use the criteria part of that script.

+1

Hello Mark,

Thank you for specifying. You can use the below script.

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

# Email message settings
$to = "recipient@domain.com" # TODO: modify me
$from = "noreply@domain.com" # TODO: modify me
$smtpServer = "mail.domain.com" # TODO: modify me
$subject = "Security Roles Report" # TODO: modify me
$reportHeader = "<h2><b>Security Roles Report</b></h2>
<table border='1'>
    <tr>
        <th>Name</th>
        <th>Description</th>
        <th>Assignments</th>
        <th>Permissions</th>
    </tr>" # TODO: modify me
$reportFooter = "<hr /><p><i>Please do not reply to this e-mail, it has been sent to you for notification purposes only.</i></p>" # TODO: modify me

# Function to resolve trustee names
function GetTrusteeName($trustee)
{
    if ([Softerra.Adaxes.Utils.WellKnownSecurityPrincipalInfo]::IsWellKnown($trustee))
    {
        $wellknownPrincipal = [Softerra.Adaxes.Utils.WellKnownSecurityPrincipalInfo]::GetInfo($trustee)
        return $wellknownPrincipal.DisplayName
    }

    if ([Softerra.Adaxes.Adsi.Sid]::PrimaryOwnerSid -eq $trustee)
    {
        return "Owner (ManagedBy)"
    }
    elseif ([Softerra.Adaxes.Adsi.Sid]::ManagerSid -eq $trustee)
    {
        return "Manager"
    }
    elseif ([Softerra.Adaxes.Adsi.Sid]::SecretarySid -eq $trustee)
    {
        return "Secretary"
    }
    elseif ([Softerra.Adaxes.Adsi.Sid]::AssistantSid -eq $trustee)
    {
        return "Assistant"
    }

    # Get object name
    $objectSid = New-Object "Softerra.Adaxes.Adsi.Sid" $trustee
    try
    {
        $object = $global:admService.OpenObject("Adaxes://<SID=$objectSid>", $NULL, $NULL, 0)
        $objectName = $object.Get("name")
    }
    catch
    {
        $objectName = $objectSid.ToString()
    }
    return $objectName
}

# Function to resolve Custom Command Names (for permissions to launch Custom Commands)
function FindCustomCommandName($commandID, $customCommandHashTable, $customCommandContainerPath)
{
    $commandName = $customCommandHashTable[$commandID]
    if ($commandName -ne $NULL)
    {
        return $commandName
    }

    $guidByte = (New-Object "System.Guid" $commandID).ToByteArray()
    $guidHexString = [Softerra.Adaxes.Utils.Transform]::ToRfc2254HexString($guidByte)

    $searcher = $global:admService.OpenObject($customCommandContainerPath, $NULL, $NULL, 0)
    $searcher.PageSize = 500
    $searcher.SearchScope = "ADS_SCOPE_SUBTREE"
    $searcher.SearchFilter = "(&(objectClass=adm-CustomCommand)(adm-CustomCommandID=$guidHexString))"
    $searcher.ReferralChasing = "ADS_CHASE_REFERRALS_NEVER"

    try
    {
        $searchResult = $searcher.ExecuteSearch()
        $result = $searchResult.FetchAll()
        if ($result.Count -ne 0)
        {
            $command = $global:admService.OpenObject($result[0].AdsPath, $NULL, $NULL, 0)
            $commandName = $command.Get("name")
            $customCommandHashTable.Add($commandID, $commandName) | Out-Null
            return $commandName
        }
    }
    finally
    {
        $searchResult.Dispose()
    }

    return $NULL
}

# Function to resolve object types (e.g. user, group, OU etc)
function GetObjectType($objectTypeGuid, $customCommandHashTable, $customCommandContainerPath)
{

    $schema = $global:admService.Schema
    $objectType = $schema.TryGetObjectClass($objectTypeGuid)

    if ($objectType -ne $NULL)
    {
        return $objectType.CommonName
    }

    $atributeType = $schema.TryGetAttributeType($objectTypeGuid)
    if ($atributeType -ne $NULL)
    {
        return $atributeType.AdminDisplayName
    }

    $extendedRightsGuid = @{"{014bf69c-7b3b-11d1-85f6-08002be74fab}" = "ChangeDomainMaster";
                            "{cc17b1fb-33d9-11d2-97d4-00c04fd8d5cd}" = "ChangeInfrastructureMaster";
                            "{bae50096-4752-11d1-9052-00c04fc2d4cf}" = "ChangePdc";
                            "{d58d5f36-0a98-11d1-adbb-00c04fd8d5cd}" = "ChangeRidMaster";
                            "{e12b56b6-0a95-11d1-adbb-00c04fd8d5cd}" = "ChangeSchemaMaster";
                            "{fec364e0-0a98-11d1-adbb-00c04fd8d5cd}" = "DoGarbageCollection";
                            "{69ae6200-7f46-11d2-b9ad-00c04f79f805}" = "DSCheckStalePhantoms";
                            "{0bc1554e-0a99-11d1-adbb-00c04fd8d5cd}" = "RecalculateHierarchy";
                            "{62dd28a8-7f46-11d2-b9ad-00c04f79f805}" = "RecalculateSecurityInheritance";
                            "{9432c620-033c-4db7-8b58-14ef6d0bf477}" = "RefreshGroupCache";
                            "{be2bb760-7f46-11d2-b9ad-00c04f79f805}" = "UpdateSchemaCache";
                            "{00299570-246d-11d0-a768-00aa006e0529}" = "UserForceChangePassword";
                            "{ab721a53-1e2f-11d0-9819-00aa0040529b}" = "UserChangePassword";
                            "{ab721a54-1e2f-11d0-9819-00aa0040529b}" = "SendAs";
                            "{B5C7D5F3-F235-43ad-A8D7-9D8374892123}" = "ReadLoggingInformation";
                            "{ED838A5C-56C2-486e-A85E-4D1B23CD2B54}" = "ReadSummaryLog";
                            "{8B3541F7-E278-4AC7-9FF9-D73220847E52}" = "RunScript";
                            "{BD3422E8-7737-4232-A1A6-B78CAB5FEA2D}" = "ExecuteAllCustomCommands";
                            "{D81B5354-169B-4482-981D-090484B7A328}" = "EnrollDisenrollUser";
                            "{649CDC16-A7E3-4D95-AE01-CECD32C79704}" = "GetPasswordSelfServiceReport";
                            "{E783B4EC-83FC-4C51-A0C2-9E3A1FFF9E6A}" = "SendSms";
                            "{299557F6-C974-4696-BC02-17859F1D613B}" = "MoveMailbox";
                            "{D5E7B1E7-C34F-4458-B33B-CEE66C0FBBC6}" = "ExportMailbox";
                            "{F19E8E0A-C601-4234-86A6-4774197A4B99}" = "CreateMailbox";
                            "{DB382E2C-FA7C-499A-85E4-907CFFE3E3E1}" = "DeleteMailbox";
                            "{828D990A-5FA7-4F8D-96D5-2C0F9A833EDF}" = "EstablishEmailAddress";
                            "{6F6D257A-A44E-4EE6-9FF6-1BF5A9144F88}" = "DeleteEmailAddress";
                            "{ADBACEA1-0A7A-407C-9535-D3E51B6AC303}" = "ArchiveHomeDirectory";
                            "{D8F76534-EAFF-4C38-9B4C-D6C0C29365BB}" = "ExchangeProperties";
                            "{87547735-7D75-4D9F-BDA3-EEBD1789397A}" = "ExchangeGeneralProperties";
                            "{EB7861A9-DCE0-434D-A2D9-59B062310BB6}" = "ExchangeEmailAddressesProperties";
                            "{A97C32B0-69D7-47CA-BBC2-0A815C18BCA3}" = "ExchangeSendAsProperties";
                            "{B9BBF393-6BF6-4C82-8957-2DDC25DA169D}" = "ExchangeSendOnBehalfProperties";
                            "{C7C0C556-62F7-45E5-B12D-ABFF8A857A84}" = "ExchangeMailboxRightsProperties";
                            "{274614ED-130F-40BC-BC72-601F0C1D5138}" = "ExchangeMailTipProperties";
                            "{82E50D86-1850-4EEE-9792-82D61A45F53A}" = "ExchangeDeliveryOptionsProperties";
                            "{7A2F504B-F7A7-4D21-B731-8FF9E9BBF48E}" = "ExchangeMessageDeliveryRestrictionsProperties";
                            "{79511D62-2638-4E80-A59B-24D92ABCE291}" = "ExchangeMessageModerationProperties";
                            "{61A0C1FD-9866-46EF-8BD4-60D792DFE554}" = "ExchangeMessageSizeRestrictionsProperties";
                            "{DD6540B6-CA2B-45C6-8D0D-EFBCD51EBD3E}" = "ExchangeMailboxQuotasProperties";
                            "{2C902617-EA87-4AEE-A26A-C3DCA79B38BE}" = "ExchangeMailboxPoliciesProperties";
                            "{CA1A1A17-09D6-4AA7-8369-2B936CCBC674}" = "ExchangeUMFeatureProperties";
                            "{360B7E6B-8042-436E-9117-D9691B10AC0F}" = "ExchangeActiveSyncFeatureProperties";
                            "{3BEF8F48-F5E4-422D-B100-168D4F06ABD9}" = "ExchangeArchiveFeatureProperties";
                            "{3CF80F35-49ED-4BEF-B41F-88C7456BE394}" = "ExchangeMapiFeatureProperties";
                            "{31DE0C27-4D5A-4E23-8F9C-7CB179635D35}" = "ExchangeOwaFeatureProperties";
                            "{795AB3ED-D1B4-49D1-8D16-1C47F2CF2ED7}" = "ExchangeRetentionHoldFeatureProperties";
                            "{3D497EF4-E358-4EB7-91A3-1E16EA054AFF}" = "ExchangeLitigationHoldFeatureProperties";
                            "{AF777E74-5ACB-4848-864C-70707B78C2C3}" = "ExchangePop3FeatureProperties";
                            "{BB3BD947-9C0F-4B38-AACC-2F3BFE301453}" = "ExchangeImapFeatureProperties";
                            "{4F16A030-3C93-4935-8C7F-A9ABEBC60693}" = "ExchangeAutoReplyConfigurationProperties";
                            "{16CAAFF5-74D3-429D-8D66-BCBA270C075C}" = "ExchangeCalendarSettingsProperties";
                            "{683AEA04-F847-4CEB-8D0B-B9534EB0EEEC}" = "Office365AccountProperties";
                            "{609CEF0E-7B62-436D-A621-CFAE0740BDD1}" = "AdaxesCustomAttributes";
                            "{77b5b886-944a-11d1-aebd-0000f80367c1}" = "PersonalInformation";
                            "{e45795b3-9455-11d1-aebd-0000f80367c1}" = "WebInformation";
                            "{e45795b2-9455-11d1-aebd-0000f80367c1}" = "EmailInformation";}

    $extendedRights = $extendedRightsGuid[$objectTypeGuid]
    if ($extendedRights -ne $NULL)
    {
        return $extendedRights
    }

    $commandName = FindCustomCommandName $objectTypeGuid $customCommandHashTable $customCommandContainerPath
    if ($commandName -ne $NULL)
    {
        return "Execute: $commandName"
    }
    return $objectTypeGuid
}

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

# Find all Security Roles
$securityRolesPath = $global:admService.Backend.GetConfigurationContainerPath("AccessControlRoles")
$searcher = $global:admService.OpenObject($securityRolesPath, $NULL, $NULL, 0)
$searcher.SearchFilter = "(objectCategory=adm-Role)"
$searcher.PageSize = 500
$searcher.SearchScope = "ADS_SCOPE_SUBTREE"

try
{
    # Execute search
    $searchResult = $searcher.ExecuteSearch()
    $roles = $searchResult.FetchAll()

    # Build report
    $customCommandHashTable = New-Object "System.Collections.Hashtable"
    $customCommandContainerPath = $global:admService.Backend.GetConfigurationContainerPath("CustomCommands")
    foreach ($roleId in $roles)
    {
        # Bind to the Security Role
        $role = $global:admService.OpenObject($roleId.AdsPath, $NULL, $NULL, 0)

        # Role name
        $roleName = $role.RoleName

        $reportHeader += "<tr valign='top'><td>$roleName</td>"
        Write-Host "Adding role '$roleName'"

        # Description
        $description = $role.Description
        $reportHeader += "<td>$description</td>"

        # Assignments
        $assignments = $role.Assignments
        $reportHeader += "<td>"
        if ($assignments.Count -ne 0)
        {
            $reportHeader += "<table border='1' width = '100%'><tr><th>Trustee</th><th>AssignedOver</th><th>Exclude</th><th>Inheritance</th></tr>"
            foreach ($assignment in $role.Assignments)
            {
                $trusteeName = GetTrusteeName $assignment.Trustee
                foreach ($item in $assignment.ActivityScopeItems)
                {
                    switch ($item.Type)
                    {
                        "ADM_SCOPEBASEOBJECTTYPE_ALL_DIRECTORY"
                        {
                            $itemName = "All objects"
                        }
                        "ADM_SCOPEBASEOBJECTTYPE_CONFIGURATION"
                        {
                            $itemName = "Configuration objects"
                        }
                        default
                        {
                            try
                            {
                                $itemName = $item.BaseObject.Get("name")
                            }
                            catch
                            {
                                $itemName = [Guid]$item.Get("adm-ScopeBaseObjectGuid")
                            }
                        }
                    }

                    switch ($item.Inheritance)
                    {
                        "ADS_SCOPE_BASE"
                        {
                            $inheritance = "This object only"
                        }
                        "ADS_SCOPE_ONELEVEL"
                        {
                            $inheritance = "One level"
                        }
                        "ADS_SCOPE_SUBTREE"
                        {
                            $inheritance = "Subtree"
                        }
                    }
                    $exclude = $item.Exclude

                    $reportHeader += "<tr><td>$trusteeName</td><td>$itemName</td><td>$exclude</td><td>$inheritance</td></tr>"
                }

            }
            $reportHeader += "</table>"
        }
        else
        {
            $reportHeader += "N/A"
        }
        $reportHeader += "</td>"

        # Permissions
        $rolePermissions = $role.Permissions
        $reportHeader += "<td>"
        $reportHeader += "<table border='1' width = '100%'><tr><th>Access Mask</th><th>Object Type</th><th>Access Type</th><th>Applies to</th></tr>"
        for ($i = 0; $i -lt $rolePermissions.Count; $i++)
        {
            $permissionEntry = $rolePermissions.GetObject($i)

            # Access mask
            $accessMask = $permissionEntry.AccessMask.ToString()

            # Object type
            $objectTypeGuid = $permissionEntry.ObjectType
            if ($objectTypeGuid -eq $NULL)
            {
                $objectType = "All"
            }
            else
            {
                $objectType = GetObjectType $objectTypeGuid $customCommandHashTable $customCommandContainerPath
            }

            # Access type
            if ($permissionEntry.AccessType -eq "ADM_PERMISSION_TYPE_ALLOW")
            {
                $accessType = "Allow"
            }
            else
            {
                $accessType = "Deny"
            }

            # Applies to
            $inheritedObjectTypeGuid = $permissionEntry.InheritedObjectType
            if ($inheritedObjectTypeGuid -eq $NULL)
            {
                $inheritedObjectTypeName = "All"
            }
            else
            {
                $inheritedObjectTypeName = GetObjectType $inheritedObjectTypeGuid $customCommandHashTable $customCommandContainerPath
            }

            $reportHeader += "<tr><td>$accessMask</td><td>$objectType</td><td>$accessType</td><td>$inheritedObjectTypeName</td></tr>"
        }
        $reportHeader += "</table></td></tr>"
    }
    $reportHeader += "</table>"
    $htmlReport = $reportHeader + $reportFooter

    # Send message
    Send-MailMessage -To $to -from $from -SmtpServer $smtpServer -Subject $subject -Body $htmlReport -BodyAsHtml -Encoding ([System.Text.Encoding]::UTF8)
}
finally
{
    $searchResult.Dispose()
}
0

Worked great! Thank you!

Related questions

0 votes
0 answers

I have applied a security role to a group at the top of a Business Unit Container and set it to apply to the subtree and it does, all Containers and Business Units do ... Unit. Did I apply the permissions wrong or is there some setting I need to change?

asked Aug 9 by ajmilic (100 points)
0 votes
1 answer

How can I grant read only rights for Configuration items in the Adaxes Admin Console?

asked Jan 26 by mark.it.admin (2.3k points)
0 votes
1 answer

What specific permission is needed in a security role to grant access to enable a user account?

asked Dec 7, 2023 by mightycabal (1.0k points)
0 votes
1 answer

I have 18 domains managed by Adaxes and have noticed that Admin (full access) t all objects acts normally, but for piecemeal scopes like Service Desk that scopes to individual ... role (including 16 denies) and expect it to grow as we add more domains.

asked Sep 20, 2022 by DA-symplr (100 points)
0 votes
1 answer

I only want to allow a security role to write 'user must change password at next logon' and not all options they have under 'Account Options'. The only permission I can see in ... ". I'd rather not assign permissions to all these settings if I don't have to.

asked Apr 6, 2021 by cfrazier (20 points)
3,548 questions
3,239 answers
8,232 comments
547,814 users