Thursday, July 26, 2018

View who has logged into Dynamics 365 - across many environments

A licencing requirement was raised at work this week where we needed to know who out of our Dynamics 365 CRM users were actually using the application.  These licences are really expensive and having many of them unused would cost the company lots of money over the year.

We did think of looking at audit tables in CRM, but unfortunately this wasn't an option due to the fact we have many Dynamics 365 environments.  A single licence will allow you access (if you have permission) to access as many sandbox environments as you wish.  This would mean collating data from many environments into one dataset.

We needed something more overarching.

So I reviewed Azure AD to see if I could view signins for a particular application and low and behold I could see all logins to Dynamics CRM Online.  All we would is visit this page, add the filters and download a CSV file.  The resultant CSV file would then need filtering to remove duplicate users, because we don't care about when and how many times they have logged in, just the fact they have at least once in the time period.



This was a great resource and gave us the information we needed.  Naturally, we wanted to take it further and to provide this programmatically with the least amount of user interaction as possible.

Enter Microsoft Azure AD Graph API

https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-graph-api

This API allows developers to get access to all sorts of data within Azure AD including application signins.

The first step is to setup an application in Azure AD.

https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-graph-api

Once this is complete, you should have an application ID, Access Key and your tenant name.

Next you can write a script to interact with the API.  There are samples around and you can even use the Graph Explorer to play around against a dummy tenant

https://developer.microsoft.com/en-us/graph/graph-explorer


I found the following script which seemed like a good place to start.

https://gallery.technet.microsoft.com/scriptcenter/Pull-Azure-AD-Sign-In-3fead683

I then needed to filter it by application too.  I did this by editing the following line


This then produces a CSV with all the signins to Dynamics CRM Online for the last 30 days, but seeing that we only care if someone as logged on at all, we only want to see one entry per user. 

We added the following line at the bottom of the script which will reimport the CSV selecting only the UPN and then removing any lines which are not unique.  It will then export this to a final csv output.


Here is the full script

Thursday, July 05, 2018

Batch Printing Tool in PowerShell

As part of my company's recent ERP implementation of Dynamics 365, we found that there was no native solution for mass printing.  This is a crucial for our business as we send a lot of letters out to our customers.  We are trying to shift more towards digital, but there are some communications that have to be sent by post and many of our customers are either not online or prefer post.

So, we had to think of how to achieve this.  We had three options


  1. Buy an Commercial off the shelf (COTS) product.  It might be limited, but would be supported and be easier to implement.
  2. Develop an application in house.  Could be costly and difficult to support but could match all requirements.
  3. Have our System Integrator develop an application.  As above, but a lot more expensive.

I had the task of bringing these options to life for our Design Group to make a decision on.

There were some constraints which made it more difficult e.g. our Printing and Enveloper wasn't able to distinguish between different page totals in jobs.  This meant that our post room needed to print all 2 page letters, then 3 page letters and so on.  This seemed bonkers to me, but the cost to replace this beast of a machine was too much to challenge this point.

I looked at various commercial products, some of the really good ones could print automatically, but given the above constraint it wasn't a viable solution.

I decided to try and build an application using PowerShell just to show what is possible if we had in-house developers.

UI
My knowledge of creating UI's in PowerShell is limited to some horrible looking WinForms windows.  I wanted to make something which looked delicious, or at least palatable to the average user and not look like Windows 98.  I found Stephen Owen's website and this blog post series.  Quite simply it is excellent.

https://foxdeploy.com/2015/04/10/part-i-creating-powershell-guis-in-minutes-using-visual-studio-a-new-hope/

With this knowledge in hand, I built the following GUI


The UI top box shows the output folders from our ERP system and provides some detail about each folder.  Clicking expand will then fill the bottom section with all of the documents which are located within.  This is gathered from a CSV file which is output from our ERP system when documents are generated for printing.  If the user clicks on a document and clicks print, it will then add an entry in the CSV saying it has been printed and when.  This will avoid other users printing the same document.

Clicking Archive will move the folder into an archive folder ready to be deleted.  Clicking External will put the documents into a separate folder which will be sent to an external print house.  This is used for massive print jobs, which is cheaper than doing it in-house.

Actual Printing
To actually print from PowerShell is not an easy task to complete reliably.  I found a tool called 2printer which works quite well.  This is a pre-req for this tool to work.

https://www.doc2prn.com/download

I am sure that there is probably some .Net classes that I could use to do this natively, but given the time constraints, this seemed like a good option as a PoC.

GitHub Project
The full code and folders and some sample files can be found at this GitHub repo

https://github.com/shammyowens/TeamasBatchPrint

You just need to edit the folder locations at the bottom of the PowerShell script and you should be good to go.

Conclusion
We actually decided to go with a product called Print Conductor.  It was really close to fulfilling our requirements, it was quick to deploy and it was fairly inexpensive.

https://www.print-conductor.com/

The process of building a dummy application was great though and made our team think strongly about their requirements.  I learnt quite a lot technically which is always a bonus!

Code