C/AL Source Code Analysis with PowerShell

Last Directions US and EMEA, I had the opportunity to talk about – uhm – myself. Well, not really – about my tools. It was a weird experience – but it got more attention than I ever expected.

Now, during that session, I showed a tool that I wanted to put out there for sooooo long: a way to analyze your C/AL Source Code with PowerShell.

This was actually an “let’s see what we can do and how far we can go”-challenge during our free time ;-), where the .Net part (which is the majority of the work) wasn’t done by me, although I was quite (let’s say “overly”) involved with the entire evolution of it ;-). The tool might not be completely new to you. I have been using it for quite some time to talk about some things within the product, like:

So as you can see – it’s basically about analyzing C/AL code.

Also at NAVTechDays, I spent a topic on it during my session with Vjeko. You can see it here:

The Tool

When we talk about the tool, we call it the “ModelToolsAPI“. It’s a PowerShell-module-dll that my partner in crime wrote, “on top of” the existing “Microsoft.Dynamics.Nav.Model.Tools.dll”, which is a library that serves the PowerShell Merge-CmdLets provided by Microsoft. It basically builds you an Object Model from your text files, which it needs to be able to merge in a smart way. For example, the tool knows all objects, or properties, what fields, relationships, … and a hell-of-a-lot more. And simply said: when you have an object model, you can work with it. When you only have a text-file, all you can do is search in text.

And I was wondering – what if we could do this in PowerShell? Because simply, I don’t know what I want to analyze today, and how I want the output to look like. Or better yet – what if I want to make the analysis part of my build, or commit, or pull request, or .. you know what I mean: part of my integration scenario! For analyzing code, PowerShell all of a sudden made all the sense in the world! At least for us ;-).

But we saw two problems with the out-of-the-box “Microsoft.Dynamics.Nav.Model.Tools”:

  • It sees code as just text – so it doesn’t really “understand” code. And with understand, I mean:
    • being able to trace fields, variables, procedures, keys, .. back to where they are used in code
    • Understand an “if” statement and any other statement for that matter
    • Being able to track complexity of a certain procedure
  • Its default object structure was quite complex.

So, my fellow nerd started to crunch a better, more understandable object model out of it, and started to write a code tokenizer (if I can call it like that) for C/AL code, basically mapping all words in code to something it understands.

As a result, we have a complete object model, understanding code, which we can query any way we like. Even more, because we’re using the default “Microsoft.Dynamics.Nav.Model.Tools”, we also have its modification- and export-functionality at our disposal (you hear me coming? ControlIDs? .. (but that’s for a later blogpost) :-)). And still even more, because (again) we are using default Microsoft libraries, with an update, we simply tap into the new version, and off we go :-).

Where can I find it?

I understand it’s not going to be easy to get started with a tool like this. But if you pick up the challenge, you won’t regret it! I tried to make it as approachable as at all possible:

  • You can just clone/fork/download from my github repository here: https://github.com/waldo1001/Waldo.Model.Tools
    • The repo contains readme-files and scripts to get you started. Just export a txt-file from your database, and you’re good to go. Almost.
  • Before you can use the tool, you need to get a license. Don’t worry, it’s free and only takes a few minutes. I even put it in a script and explained it in the readme. Don’t worry, we have no intention to ever monetize this tool.
    • Just fill in your details in the browser when it pops up, and you’ll get a license mailed to you, which you need to put in the same folder as the dlls.
  • Now, you’re good to go load your object model into a variable by calling the “Get-NAVObjectModel” (which points to a text-file), and you are about to analyze it.
  • To get you started on anything useful, I have foreseen some scripts here, like:

Once you get used to it, it’s super-readable!

Now it’s up to you!

There are quite a number of scenarios where we apply this tool.

Just now, we are about to rewrite our product in AL. With this tool, we did a complete, in depth dependency analysis for figuring what apps we would end up with. It gave us an overview of problems with “circular dependencies”, and an easy way to document all changes we did for certain modules/apps. I’m definitely coming back to that exercise!

We also used this for figuring out and fixing controlid-errors – if you ever encountered them, you sure know what I’m talking about! ;-).

And much much more – basically, it’s a bit up to you to get familiar with it (if you at least want it to be), and apply it on whatever you want to apply it.

Expect more scripts and blogs about this in the future, but please do know you can contribute as well (just fork and make a pullrequest), … .


5.00 avg. rating (98% score) - 2 votes

Permanent link to this article: https://www.waldo.be/2019/02/15/c-al-source-code-analysis-with-powershell/


Skip to comment form

  1. Wow, this sounds like a really great tool! I think I could need it myself. Good yob and thumbs up!

      • waldo on February 15, 2019 at 8:40 am

      I’m looking forward to see what you will do with it 😉

    • Ron Koppelaar on February 15, 2019 at 12:20 pm
    • Reply

    Nice tool Waldo. Already ran some checks on this through our code base. Question, isn’t true that the Cyclomatic Complexity is at least 1? Currently with only 1 path it calculates to 0.
    Another question, would be helpful to also include the Halstead volume. Together with the cyclomatic complexity, number of lines of code, it’s possible to calculate the maintainability index, like we have this in Visual Studio projects.

      • waldo on February 15, 2019 at 12:43 pm

      All nice suggestions :-). You’re welcome to put them on GitHub!

    • Ricardo Paiva on February 21, 2019 at 1:06 pm
    • Reply

    Hi Waldo,
    It seems to be a great tool but I’m having some issues with it.
    I’ve tried to load objects from a BC W1 database and from a NAV 2017 database. The objects are loaded with some warnings that I believe to be normal but when I try the $Model.NAVObjects.Count command it returns me 0.

    Thanks for your time!

      • waldo on February 21, 2019 at 3:04 pm

      Did you request a license?

    • Ricardo Paiva on February 21, 2019 at 7:42 pm
    • Reply

    Yes, I’ve requested the license and when I run the RequestLicense script everything seems to be ok.

    • Ramesh on May 12, 2019 at 3:57 pm
    • Reply

    Hi Waldo,

    Great Tool, is it work for AL project files.

    Thank you!

      • waldo on May 13, 2019 at 12:13 pm

      Nope, it only works for C/AL.

      We need something completely different for AL – at some point, Microsoft will document their code analysis framework (as I was told…).

    • Nareshwar Raju Vaneshwar on February 7, 2020 at 6:27 pm
    • Reply

    Hi Waldo,

    We tried to use the powershell to build the model but we are getting license “EXPIRED” error. We tried requesting new licenses and still the error continues.

    Exact Error Message: Get-NAVObjectModel : EXPIRED

    Your help is appreciated.


      • waldo on February 7, 2020 at 6:28 pm

      I recently refreshed the dlls in my repo. Did you download the latest version?

      • Nareshwar Raju Vaneshwar on February 7, 2020 at 6:36 pm

      Hi Waldo,

      Yes, we did cloned it from your repo early this week.
      Did you update very recently though?


      • waldo on February 7, 2020 at 6:38 pm

      Last week. Sorry, but I can’t do anything about it now :-/. I’ll test it when I have time..

      • Nareshwar Raju Vaneshwar on February 13, 2020 at 4:17 pm

      HI Waldo,

      Sorry to bother you again on this.

      By any chance did you have a look at this issue? You help is much appreciated at this point.


      • waldo on March 12, 2020 at 11:56 pm

      This should have been fixed quite a while ago – did you try again?

    • Kash T on June 21, 2020 at 6:09 pm
    • Reply

    Hi Waldo,
    Which versions of NAV objects this tool will be able to analyze?

      • waldo on June 21, 2020 at 8:03 pm

      It should work for anything C/AL since NAV2013….

      • Kash T on June 21, 2020 at 8:29 pm

      Thank you. So it won’t work for the versions older than NAV 2013. (i.e. NAV 5.0)

      • waldo on June 22, 2020 at 8:24 am

      Probably not. It’s highly dependent from the “microsoft.dynamics.nav.model.tools.dll”, and that only exists from NAV2013 (along with the powershell tools to merge). I don’t think it “understands” forms, for example..

      • Kash T on June 22, 2020 at 1:32 pm

      That’s true. When you run application merge commands with forms and dataports in the text file comparison – they error out. As these are based off of microsoft.dynamics.nav.model.tools.dll. Thank you Waldo.

    • Marcel on September 6, 2023 at 12:23 pm
    • Reply

    Hello Waldo, the license check no longer works. Is it still possible to get a license?

    Website: “404
    We can’t find this page.”

      • waldo on September 6, 2023 at 12:36 pm

      Hi – can you please try without a license? I think we removed the licensing from the dll .. but I’m not sure anymore (quite some time ago)

      • Marcel on September 6, 2023 at 12:52 pm

      It works thank you!

      • Marcel on September 6, 2023 at 2:52 pm

      ok, excited too soon. The data model is loaded but the analysis CSV is empty:

      $csvFilePath = ‘C:\Temp\ObjectsAnalysis.csv’
      CreateCALFieldsCSV $csvFilePath `
      -fieldFilter ‘50000..99999’

      • waldo on September 6, 2023 at 3:02 pm

      If the model is loaded, it works.
      I don’t know about that function, I’m afraid – that was a community contribution 3 years ago ..

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.