web
You’re offline. This is a read only version of the page.
close
Skip to main content

Announcements

No record found.

News and Announcements icon
Community site session details

Community site session details

Session Id :
Finance | Project Operations, Human Resources, ...
Answered

Find Security Privileges linked to menu item

(4) ShareShare
ReportReport
Posted on by 2,334
Hi,
 
I can get all the menu items under System Administration module using below code.
 
Now I want to get the Security Privileges linked to these menu items. I'm unable to figure out how to do it.
 
using Microsoft.Dynamics.AX.Metadata.MetaModel;

class AOTFind
{
    public static void main(Args _args)
    {
        str rootName = "SystemAdministration";   
        AxMenu sysAdminMenu = Microsoft.Dynamics.Ax.Xpp.MetadataSupport::GetMenu(rootName);
        
        if (sysAdminMenu)
        {
            AOTFind explorer = new AOTFind();
            info(strFmt("Starting traversal of: %1", rootName));
            explorer.traverseElements(sysAdminMenu.Elements.getEnumerator());
        }
        else
        {
            error(strFmt("Menu '%1' not found in AOT.", rootName));
        }
    }

    private void traverseElements(System.Collections.IEnumerator _enumerator)
    {
        while (_enumerator.MoveNext())
        {
            AxMenuElement element = _enumerator.Current;

            if (element is AxMenuElementSubMenu)
            {
                AxMenuElementSubMenu subMenu = element as AxMenuElementSubMenu;
                info(strFmt("Folder: %1", subMenu.Name));
                
                this.traverseElements(subMenu.Elements.getEnumerator());
            }
            else if (element is AxMenuElementMenuItem)
            {
                AxMenuElementMenuItem menuItemRef = element as AxMenuElementMenuItem;
                this.processMenuItem(menuItemRef);
            }
        }
    }

    private void processMenuItem(AxMenuElementMenuItem _ref)
    {
        info(strFmt("  - Item: %1 (%2)", _ref.MenuItemName, _ref.MenuItemType));
    }

}
 
 
Appreciate any tips.
Categories:
I have the same question (0)
  • Suggested answer
    Mohamed Amine Mahmoudi Profile Picture
    26,801 Super User 2026 Season 1 on at
    Hi @MYGz,
     
    You can use a simples queries to find the list of privileges for each menu item.
     
    Best regards,
    Mohamed Amine
  • MYGz Profile Picture
    2,334 on at
     
    Already went through that blog and many others. But most of the blogs are written for AX 2012. The code doesn't works in D365 F&O.
  • MYGz Profile Picture
    2,334 on at
    So, I have just drilled down to a single menu item (SysUserInfoPage) to arrive at the working code.
     
    Although I'm able to find the MenuItem and the Security Privilege, I can't figure out how to get the SecurityPrivilege linked to the MenuItem.
     
    Below is the update:
    using Microsoft.Dynamics.AX.Metadata.MetaModel;
    using Microsoft.Dynamics.ApplicationPlatform.Environment;
    using Microsoft.Dynamics.AX.Metadata.Storage;
    using Microsoft.Dynamics.AX.Metadata.Storage.Runtime;
    using Microsoft.Dynamics.AX.Security;
    using Microsoft.Dynamics.AX.Security.Management.Domain;
    
    class AOTFind
    {
        public static void main(Args _args)
        {
            // Set root to the System Administration module menu
            str rootName = "SystemAdministration";
            
            AxMenu sysAdminMenu = Microsoft.Dynamics.Ax.Xpp.MetadataSupport::GetMenu(rootName);
            
            if (sysAdminMenu)
            {
                AOTFind explorer = new AOTFind();
                info(strFmt("Starting traversal of: %1", rootName));
                
                // Begin recursion
                explorer.traverseElements(sysAdminMenu.Elements.getEnumerator());
            }
            else
            {
                error(strFmt("Menu '%1' not found in AOT.", rootName));
            }
        }
    
        private void traverseElements(System.Collections.IEnumerator _enumerator)
        {
            while (_enumerator.MoveNext())
            {
                AxMenuElement element = _enumerator.Current;
    
                if (element is AxMenuElementSubMenu)
                {
                    AxMenuElementSubMenu subMenu = element as AxMenuElementSubMenu;
                    //info(strFmt("Folder: %1", subMenu.Name));
                    
                    // Recurse into the sub-menu's elements
                    this.traverseElements(subMenu.Elements.getEnumerator());
                }
                else if (element is AxMenuElementMenuItem)
                {
                    AxMenuElementMenuItem menuItemRef = element as AxMenuElementMenuItem;
                    if(menuItemRef.MenuItemName=='SysUserInfoPage')
                    {
                        this.processMenuItem(menuItemRef);
                    }
                }
            }
        }
    
        private void processMenuItem(AxMenuElementMenuItem _ref)
        {
            str targetMenuItem = _ref.ToString(); // Your menu item name here
            
            var securityRepository = SysSecurity::GetSecurityRepository();
            var privilegesRepo = securityRepository.Privileges;
            var privEnumerator = privilegesRepo.LoadAll().GetEnumerator();
    
            info(strFmt("Searching for privileges linked to: %1", targetMenuItem));
    
            while (privEnumerator.MoveNext())
            {
                Privilege privilege = privEnumerator.Current;
    
                if(privilege.ToString() == 'SysUserInfoMaintain')
                {
                    if (AOTFind::hasMenuItemAccess(privilege, targetMenuItem))
                    {
                        info(strFmt("Match Found: %1", privilege.Name));
                    }
                }
            }
            
            // Safe access to MenuItemName and Type
            info(strFmt("  - Item: %1 (%2)", _ref.MenuItemName, _ref.MenuItemType));
        }
    
        private static boolean hasMenuItemAccess(Privilege _privilege, str _menuItemName)
        {
            // Check Display Menu Items
            var displayGrants = _privilege.DisplayMenuItemGrants.GetEnumerator();
            while (displayGrants.MoveNext())
            {
                if (displayGrants.Current.Name == _menuItemName)
                    return true;
            }
    
            // Check Action Menu Items
            var actionGrants = _privilege.ActionMenuItemGrants.GetEnumerator();
            while (actionGrants.MoveNext())
            {
                if (actionGrants.Current.Name == _menuItemName) 
                    return true;
            }
    
            // Check Output Menu Items
            var outputGrants = _privilege.OutputMenuItemGrants.GetEnumerator();
            while (outputGrants.MoveNext())
            {
                if (outputGrants.Current.Name == _menuItemName) 
                    return true;
            }
    
            return false;
        }
    
    }
     
  • Verified answer
    André Arnaud de Calavon Profile Picture
    303,706 Super User 2026 Season 1 on at
    Hi MYGz,
     
    On each form, you can use the Security diagnostics which is showing you all related roles, duties and privileges. You can reverse engineer that logic to find out how to find the privileges per menu item. 
     
    You can find the example code on form SysSecDiagnostics > datasource SysSecSecurityObjects > method executeQuery.
  • MYGz Profile Picture
    2,334 on at
    Found the issue, but now it's taking soo long for the Job to run..... like forever....
     
    _ref.ToString()
    
    // change to
    
    _ref.MenuItemName;
  • MYGz Profile Picture
    2,334 on at
     
    Thank you, trying that now.
  • Suggested answer
    Mohamed Amine Mahmoudi Profile Picture
    26,801 Super User 2026 Season 1 on at
    Hi @MYGz,
     
    Sorry, I thought it was for FO. I found this table ‘SECURITYRESOURCEPRIVILEGEPERMISSIONS’ which contains all the privileges but does not exist in the AOT. You can look at this method. 
    public static void GetPrivilegesByMenuItem(str menuItem)
    {
        Connection      connection;
        Statement       statement;
        str             query;
        Resultset       resultSet;
        ;
      
        // create connection object
        connection = new Connection();
      
        // create statement
        statement = connection.createStatement();
      
        // Set the SQL statement
        query = strFmt(@"select PP.PRIVILEGEIDENTIFIER,P.Name
                    from SECURITYRESOURCEPRIVILEGEPERMISSIONS PP
                    join dbo.SECURITYPRIVILEGE P on P.IDENTIFIER = PP.PRIVILEGEIDENTIFIER
                    where PP.AOTName = '%1'
                    and PP.SECURABLETYPE in (1,2,3)", menuItem);
      
        // assert SQL statement execute permission
        new SqlStatementExecutePermission(query).assert();
      
        // when the query returns result,
        // loop all results for processing
        //BP Deviation documented
        resultSet = statement.executeQuery(query);
      
        while(resultSet.next())
        {
            // do something with the result
            info(strFmt("%1 - %2",resultSet.getString(1),resultSet.getString(2)));
        }
      
        // limit the scope of the assert call
        CodeAccessPermission::revertAssert();
    }
    Best regards
     

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Introducing the 2026 Season 1 community Super Users

Congratulations to our 2026 Super Stars!

Congratulations to our 2025 Community Spotlights

Thanks to all of our 2025 Community Spotlight stars!

Leaderboard > Finance | Project Operations, Human Resources, AX, GP, SL

#1
Giorgio Bonacorsi Profile Picture

Giorgio Bonacorsi 659

#2
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 465 Super User 2026 Season 1

#3
Syed Haris Shah Profile Picture

Syed Haris Shah 304 Super User 2026 Season 1

Last 30 days Overall leaderboard

Product updates

Dynamics 365 release plans