Friday, May 26, 2017

How to rename a D365 virtual machine, link it to LCS, and optionally join it to a domain - Dynamics 365 for Finance and Operations, Enterprise edition

Whenever I get a new D365 virtual machine, I need to rename it, link it to LCS, and join it to our domain. I kept forgetting what I did, so I wrote it down here to share.

I rename it because there are multiple copies of the VM on the same network, and joining to a domain should be obvious all of the benefits there.

So here are the steps that I perform to quickly do this, and if anyone has any other steps to add/modify, please let me know and I'll update the post. Follow carefully as each step is important.

  1. Connect to the VM, provision yourself (as usual)
  2. Go to Control Panel>System and Security>Security, click "Change Settings", and rename the machine to something unique.
  3. Restart VM
  4. Open Reporting Services Configuration Manager and connect to "localhost" or whatever you named your machine, and change the Database server so that it connects
  5. Open SQL Management Studio by doing "Run As Administrator", as the Local Admins security group is added but not the local administrator user.  Connect to SQL.
  6. Run these commands to get the name SQL thinks it is and the name you've used
    select @@SERVERNAME
    Select serverproperty('ServerName')
  7. Copy the old machine name and new machine name and replace it in these SQL commands and execute them
    --Run this with the updated names
    sp_dropserver 'MININT-S45GUTR'; --Old Name

    sp_addserver 'D365QDEVMAIN',LOCAL; --New Name
  8. Restart the machine
  9. In SQL (run as admin), run the steps in Step 6 again to verify both return the same new machine name result
  10. (Optional) The following steps are the optional LCS/Domain steps. Create a project in LCS that your D365 for Operations (or whatever it's called at the time of reading this) VM will connect to.
  11. (Optional) Download the LCS diagnostic installer under the "System Diagnostic" tile
  12. (Optional) Extract and run Setup. Choose "Create a new certificate" and enter whatever into the prefix. I usually just do the machine name.
  13. (Optional) This creates a certificate in the same directory as the installer, upload the certificate back into LCS under the same tile, then continue with the installer after it has been uploaded.
  14. (Optional) For the account/password I put in MachineName\Administrator and the administrator password. If you choose to use the local admin, it's important that you type the newly created machine name you chose or it doesn't always work.
  15. (Optional) There should now be a new icon on your desktop to launch the LCS diagnostic utility. Run this.
  16. (Optional) Put in the environment name and server name with your newly chosen name and put "AxDB" for the database name. Then click the buttons at the bottom of the tool in sequence.
  17. (Optional) When you get to step #3, your window may white-out and clear. Just choose the drop-down at the top under "Environment Name" and re-select your environment
  18. (Optional) Click "Generate Command" to get a copy/paste command that you can set up a scheduled task for so that LCS gets regular data. Copy the command and close the window. Mine was:

    "C:\Program Files\Microsoft Dynamics Lifecycle Services System Diagnostic Service\LCSDiagFXCollector.exe" "-Collect" "D365QDEVMAIN" "1"
  19. (Optional) Open "Task Scheduler" and create a new task and choose "Run whether user is logged on or not" and I choose "Run with highest privileges"
  20. (Optional) Choose the Triggers tab and setup a daily trigger (or whatever you want)
  21. (Optional) Choose the "Actions" tab, click New, and paste the entire command in the program/script window and click ok. It will prompt you to automatically fix it so just click yes.
  22. (Optional) Click OK to save the task and enter your user/password so that it can store it to run the task
  23. (Optional) Go back to LCS and under the same "System Diagnostic" tile, click on the "Environments" tab and verify your new environment is there and data is uploaded
  24. (Optional) Finally join it to your domain and restart.

And you are done!

Thursday, May 18, 2017

How to programmatically add menu items to favorites menu via X++ in Dynamics AX

The favorites menu is a bit unusual in AX in the way you need to add to it. Most of the way it works appears to be Kernel level, but through some TreeNode usage you can add items to it.

This will add the "SalesTable" menu item to your favorites.

static void JobAddToFavorites(Args _args)
    TreeNode                treeNode;
    TreeNode                menuToAdd = TreeNode::findNode(@"\Menu Items\Display\SalesTable");
    TreeNodeIterator        iterator;
    UserMenuList            userMenu;
    Menu                    menuNode;

    treeNode = infolog.userNode();
    iterator = treeNode.AOTiterator();
    treeNode =;
    if (treeNode)
        userMenu = treeNode;

        // find 'My Favorites' user menu; 
        treeNode = userMenu.AOTfindChild("@SYS95713");

        // Note menuNode is a different object than userMenu
        menuNode = treeNode;


Another table to take note of is SysPersonalization if you're looking at doing this for multiple users. I haven't dug into this deeply, but this code snippet should get you started with what you may want to do.

Friday, May 5, 2017

How to remove the default filter controls on a ListPane in AX 2012

When you create a ListPage, the kernel automatically adds a FormFilterPaneControl with some filtering options. Many think this can't be removed or hidden, but it can!

It is added during the run method's super() call by the kernel, so using this code on the ListPage you can remove it.  The caveat is if you are using the ListPage FormTemplate, it's not possible because you're not able to override the run method.

The last closing comment I'll add is I don't know if the kernel expects the control to be there later on and if this can cause any issues or not. I just was curious if I could get it to go away.

public void run()
    int                 i;
    FormControl         formControl;

    for (i=1; i<; i++)
        formControl =;

        if (formControl is FormFilterPaneControl)