WPNinjas HeaderWPNinjas Header

Automatic Intune Documentation evolves to Automatic Microsoft 365 Documentation

One of the biggest pain points of many companies is the documentation of their infrastructure. With the fast changing products/features it’s more important to have an accurate documentation. The Automatic Microsoft 365 Documentation is the successor of the Automatic Intune Documentation which provides many advantages. It’s no longer a simple script and you can interact with the collected data. 

General use

The Automatic Microsoft 365 Documentation PowerShell Module is available in the PowerShell Gallery and therefore its simple to install and use. You can just use these commands:
Install-Module MSAL.PS
Install-Module PSWriteWord
Install-Module M365Documentation
This example covers basic functionality for interactive usage. Advanced use cases like creating your own app registration for silent execution or translating API names is covered in the advanced usage section.
# Connect to your tenant
Connect-M365Doc

# Collect information for component Intune as an example 
$doc = Get-M365Doc -Components Intune -ExcludeSections "MobileAppDetailed"

# Output the documentation to a Word file
$doc | Write-M365DocWord -FullDocumentationPath "c:\temp\$($doc.CreationDate.ToString("yyyyMMddHHmm"))-WPNinjas-Doc.docx"

Another example: detect deviations

From the community I got back many feedbacks for new features to allow them to fulfill their requirements. Some of them were also pretty useful for me and therefore I would like to highlight one of them directly in this blog.

From time to time you would like to see if something has changed in your environment. The Azure/Microsoft 365 Audit logs provide not always all information to fully understand the changes. Here the documentation module can help with the option to backup the whole configuration to a json file. These json files can be compared with a webservice like http://www.jsondiff.com/.

You can collect all information like normal, but then use the Write-M365DocJson Cmdlet to save the configuration in a comparable format:

# Connect to your tenant
Connect-M365Doc

# Collect information for component Intune as an example 
$doc = Get-M365Doc -Components Intune -ExcludeSections "MobileAppDetailed"

# Output the documentation to a Word file
$doc | Write-M365DocJson -FullDocumentationPath "c:\temp\$($doc.CreationDate.ToString("yyyyMMddHHmm"))-WPNinjas-Doc.json"

The result looks pretty good:

Support translation process

Tto simplify the translation process I added a UI which is able to show and submit your contribution to the project. A step by step guide is available on the project page.

Follow me

54 Comments

Donovan Sobrero · May 26, 2021 at 17:33

NetNew: after install the 3 required modules msal.ps, pswriteword, m365documenation modules without issue in PS7.1.3 I’m not able to issue the command “connect-m365doc”

Get-MsalToken: C:\Users\sobre\Documents\PowerShell\Modules\MSAL.PS\4.21.0.1\Get-MsalToken.ps1:304
Line |
304 | … ionResult = Get-MsalToken -Interactive -PublicClientApplication $Publ …
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Only loopback redirect uri is supported, but
| msal37f82fa9-674e-4cae-9286-4b21eb9a6389://auth/ was found. Configure
| http://localhost or http://localhost:port both during app registration and when
| you create the PublicClientApplication object. See
| https://aka.ms/msal-net-os-browser for details

    Thomas Kurth · June 13, 2021 at 08:25

    Have you used your own App Registration or my Public Client?

    I have now added http://localhost in my Public client. So you can test it again.

Leon Scott · May 30, 2021 at 09:18

You forgot to mention to enable the application inside your tenant if you have apps set as after approval only.

    Thomas Kurth · June 13, 2021 at 08:21

    Yes this is correct. In this case you can also create your own app registration in your tenant. Then you are under full control.

Brendan · June 2, 2021 at 05:36

error when running following command after approving permissions

PS C:\WINDOWS\system32> $doc = Get-M365Doc -Components Intune -ExcludeSections “MobileAppDetailed”
Used application does not have sufficiant permission to access: https://graph.microsoft.com/v1.0/organization
At C:\Program Files\WindowsPowerShell\Modules\M365Documentation\3.0.3\Internal\Helper\Invoke-DocGraph.ps1:51 char:13
+ throw “Used application does not have sufficiant permissi …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (Used applicatio….0/organization:String) [], RuntimeException
+ FullyQualifiedErrorId : Used application does not have sufficiant permission to access: https://graph.microsoft.
com/v1.0/organization

    Thomas Kurth · June 13, 2021 at 08:28

    Have you used an own app registration? If yes which scopes have you added?

Donovan · June 23, 2021 at 16:56

i’m having the same problem as brendan can you provide the steps to resolve this issue.

    Thomas Kurth · July 21, 2021 at 22:04

    Do you still have this issue? Because I fixed this on the 2021/06/13. If yes, can you delete the Enterprise Application created in your Azure AD. During the next connect this will be created again and hopefully pick up the adjustments.

Jimmy Phelan · June 24, 2021 at 12:38

Thomas, I have been trying to use this as a follow on from the Intune Documentation module, but i keep having the same issue as Brendan, and I have it on multiple tenants. My method was to install the module, run it as a Global Admin, and let it register itself as an App, with the appropriate permissions it requested. Is there any chance that the https://graph.microsoft.com/beta/identity/identityProviders permission is missing?

I have the exact same error as Brendan, i have not used my own app registration, i saw no documentation around that.

One other item, you have not listed what “Components” are potential options. I drilled into the directory of the module and found that your two componets are AzureAD and Intune, but you havent that list of components in the documentation anywhere that i could see

Thank you for this script, it is one of the most complete and excellent i have used, and if i can get this Graph permission sorted, i will be delighted to use it on Conditional Access and AzureAD Documentation too

    Jimmy Phelan · June 24, 2021 at 12:53

    This failure is in my AAD Sign-Ins
    Sign-in error code
    65001
    The user or administrator has not consented to use the application with ID ‘{identifier}'{namePhrase}. Send an interactive authorization request for this user and resource.

    Jimmy Phelan · June 24, 2021 at 13:51

    I was able to work around this by moving the Get-AADIdentityProvider.ps1 script out of the folder “C:\Program Files\WindowsPowerShell\Modules\M365Documentation\3.0.3\Internal\Collector\AzureAD”

    When i installed the module I used the “-scope AllUsers” to place it into that location. I can see that your method uses a Get-ChildItem in Get-M365Doc.ps1 to decide what to get. By moving it i have been able to stop it executing the “identityprovider” portion, and i have successfully retrieved the documentation for AzureAD.

      Thomas Kurth · July 21, 2021 at 22:05

      This is now fixed. I added the correct scope to the app registration.

Michael · July 6, 2021 at 19:27

Thomas, lovely work on this. Question have you worked with or seen with Microsoft365DSC https://microsoft365dsc.com/ ? Wondered if you did what your thoughts were?
Also, is there any documentation around the backed setting names in Azure/Off365 to the setting names that show in the portal all in one document? I know you now have that tool to modify transcription file (Thank you so much for that btw), but was looking for a doc that had everything on it. like a matching 1 to 1 chart.

    Thomas Kurth · July 21, 2021 at 21:59

    Hello Michael,

    Thanks for the input. I was not aware of this tool. The problem I see is that this tool is using the PowerShell modules and not the Graph API directly. But if you want, you can find all translations which I have in the module as json file on Github.

      Nik Charlebois · January 11, 2022 at 20:11

      It actually uses the Microsoft Graph PowerShell SDK under the cover.

Camille Bovy · July 21, 2021 at 14:25

Hi Thomas, First of all great script for documenting, really like it! But I noticed when using the documentation script for AzureAd in Conditional access policies I get duplicates in the Exclude groups. Looking at your script Get-AADConditionalAccess.ps1 I see that on line 78 a empty array is created for Excludeapps and next it fills array Excludegroups. shouldn’t you start at line 78 with a $excludegroups = @()

$ExcludeApps = @()
foreach($group in $CAPolicy.conditions.users.excludeGroups){
$ExcludeGroups += (Invoke-DocGraph -Path “/groups/$($group)”).displayName

    Thomas Kurth · July 21, 2021 at 21:51

    Thanks for this input. Will be fixed in next version.

Imran Awan · October 12, 2021 at 16:47

Hello Sir, Ran the command below and the modules have been installed

Install-Module MSAL.PS
Install-Module PSWriteWord
Install-Module M365Documentation

Then trying to connect to …. Connect-M365Doc … I get this error
Connect-M365Doc : The ‘Connect-M365Doc’ command was found in the module ‘M365Documentation’, but the module could not be loaded. For more information, run ‘Import-Module M365Documentation’.

I have tried to Import-Module M365Documentation as well… Is there anything i am missing

    Thomas Kurth · October 26, 2021 at 08:36

    Hello Imran

    Was no error generated during the Install-Module command? Normally it should just work. Or are you using AppLocker and our code sign certificate is blocked?

Kyle J · November 3, 2021 at 20:47

I’m getting an error when running : $doc = Get-M365Doc -Components Intune -ExcludeSections “MobileAppDetailed”

PS C:\Scripts> $doc = Get-M365Doc -Components Intune -ExcludeSections “MobileAppDetailed”
Get-GroupInfo : Cannot bind argument to parameter ‘Groups’ because it is an empty array.
At C:\Program Files\WindowsPowerShell\Modules\M365Documentation\3.1.2\Internal\Collector\Intune\Get-MobileApp.ps1:53 char:50
+ $DocSec2.Objects = Get-GroupInfo -Groups $AppGroups
+ ~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Get-GroupInfo], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyArrayNotAllowed,Get-GroupInfo

Patrick Wilkens · December 17, 2021 at 14:32

How do I change the template? Right now i made my own template/design and need to copy every table over into it. Can i do this a smarter way?

Patrick Wilkens · December 20, 2021 at 22:33

Is it possible to change the template somehow?

    Thomas Kurth · January 28, 2022 at 22:13

    You can just specify an existing Word File as Target. Then this will be used.

      Arnaud Bigot · February 16, 2022 at 11:38

      Hello Thomas,
      thank you for your script.
      for information, I still have to add -scope AllUsers to make it work.

Donovan · May 19, 2022 at 00:42

PS C:\temp> Connect-M365Doc
PS C:\temp> $doc | Write-M365DocWord -FullDocumentationPath “c:\temp\$($doc.CreationDate.ToString(“yyyyMMddHHmm”))-WPNinjas-Doc.docx”
You cannot call a method on a null-valued expression.
At line:1 char:60
+ … ionPath “c:\temp\$($doc.CreationDate.ToString(“yyyyMMddHHmm”))-WPNinj …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull

Write-M365DocWord : Cannot bind argument to parameter ‘Data’ because it is null.
At line:1 char:8
+ $doc | Write-M365DocWord -FullDocumentationPath “c:\temp\$($doc.Creat …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Write-M365DocWord], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Write-M365DocWord

Jan · October 23, 2022 at 18:47

Is it possible to write the docx to an Azure storage share?

Ken Bergeron · December 5, 2022 at 20:02

Hi Thomas, thank you for this invaluable tool. I am unable to export to csv. Error is –
Write-M365DocCsv : Cannot validate argument on parameter ‘ExportFolder’. Folder does not exist.

    Ken Bergeron · December 5, 2022 at 21:11

    Please disregard. I was able to find under the advanced usage section.

Thomas · February 15, 2023 at 12:53

What kind of roles are required to run this script? Should Global Reader suffice?

    Thomas Kurth · July 24, 2023 at 22:46

    I have never tried but in general it should be enough after the first run where the Consent needs to be granted.

Richard · June 8, 2023 at 13:23

what are the graph permissions needed. please a screen shot?

LvilleSystemsJockey · July 24, 2023 at 20:50

When will this pull the “Endpoint Security” portion of Intune?

    Thomas Kurth · July 24, 2023 at 22:42

    As they are based on Configuration Policies they should already be documented. Can you please verify and if one is not documented provide Feedback including which one of the Endpoint Security Policy Types.

      DevRin · November 14, 2023 at 16:01

      I have ran it twice and am not seeing any of the endpoint security policy types (ASR, AV, even the EDR onboarding) within the document. I used the example command –

      # Connect to your tenant
      Connect-M365Doc

      # Collect information for component Intune as an example
      $doc = Get-M365Doc -Components Intune -ExcludeSections “MobileAppDetailed”

      # Output the documentation to a Word file
      $doc | Write-M365DocWord -FullDocumentationPath “c:\temp\$($doc.CreationDate.ToString(“yyyyMMddHHmm”))-WPNinjas-Doc.docx”

        Thomas Kurth · February 20, 2024 at 11:49

        This functionality is now added in the newest version

thegood1 · November 22, 2023 at 08:48

i could not find any information in regards to Windows Applications & script getting out from intune into the Doc what i am missing i used the normal commands

# Connect to your tenant
Connect-M365Doc

# Collect information for component Intune as an example
$doc = Get-M365Doc -Components Intune -ExcludeSections “MobileAppDetailed”

# Output the documentation to a Word file
$doc | Write-M365DocWord -FullDocumentationPath “c:\temp\$($doc.CreationDate.ToString(“yyyyMMddHHmm”))-WPNinjas-Doc.docx”

    Thomas Kurth · February 20, 2024 at 11:48

    Do you have any error messages you can share? Perhaps the user you leverage has no access to this objects. In my test I have them documented.

Jörg Köppen · February 20, 2024 at 10:52

It has already been asked above. Which components can be documented so far? Is there a list (except AzureAD,Intune)?

Gerardo Hernandez · February 20, 2024 at 15:58

Can I run this without an app registration? With my admin user for example? How?

    Thomas Kurth · February 20, 2024 at 16:48

    Yes, just use the Connect-M365Doc command without any parameter.

David · March 20, 2024 at 10:41

Thanks for your great job.
I´m trying to use the module with Connect-M365DDoc command but it request an administrator to grant permissions to the app, but there is no refference about which permissions are needed or which is the app name.
Which is the behaviour of these command? will an enterprise app be registered automatically on the tenant? which are the needed permissions?
Thanks again

Ben · August 9, 2024 at 15:05

This looks like a great addition for us. We created our own App registration etc. However some reason I keep running into the error “Used application does not have sufficiant permission to access: https://graph.microsoft.com/v1.0/deviceManagement/applePushNotificationCertificate“.
But I cannot find any permissions related to applePushNotificationCertificate, any ideas?

JohnK · September 25, 2024 at 16:29

I’m getting the below Error, when running connect-M365Doc

New-MsalClientApplication : Cannot convert argument “builder”, with value: “Microsoft.Identity.Client.PublicClientApplicationBuilder”, for “WithDesktopFeatures” to type
“Microsoft.Identity.Client.PublicClientApplicationBuilder”: “Cannot convert the “Microsoft.Identity.Client.PublicClientApplicationBuilder” value of type
“Microsoft.Identity.Client.PublicClientApplicationBuilder” to type “Microsoft.Identity.Client.PublicClientApplicationBuilder”.”
At C:\Program Files\WindowsPowerShell\Modules\MSAL.PS\4.37.0.0\Select-MsalClientApplication.ps1:56 char:29
+ … plication = New-MsalClientApplication -ErrorAction Stop @paramNewMsal …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [New-MsalClientApplication], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument,New-MsalClientApplication

The property ‘AppConfig’ cannot be found on this object. Verify that the property exists.
At C:\Program Files\WindowsPowerShell\Modules\MSAL.PS\4.37.0.0\Select-MsalClientApplication.ps1:88 char:9
+ Write-Debug (‘Adding Application with ClientId [{0}] and Redi …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], PropertyNotFoundException
+ FullyQualifiedErrorId : PropertyNotFoundStrict

Add-MsalClientApplication : Cannot bind argument to parameter ‘PublicClientApplication’ because it is null.
At C:\Program Files\WindowsPowerShell\Modules\MSAL.PS\4.37.0.0\Select-MsalClientApplication.ps1:89 char:35
+ Add-MsalClientApplication $ClientApplication
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Add-MsalClientApplication], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Add-MsalClientApplication

The property ‘ClientId’ cannot be found on this object. Verify that the property exists.
At C:\Program Files\WindowsPowerShell\Modules\MSAL.PS\4.37.0.0\Get-MsalToken.ps1:291 char:21
+ … Write-Verbose (‘Attempting Silent Authentication to Appli …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], PropertyNotFoundException
+ FullyQualifiedErrorId : PropertyNotFoundStrict

Get-MsalToken : Cannot bind argument to parameter ‘PublicClientApplication’ because it is null.
At C:\Program Files\WindowsPowerShell\Modules\MSAL.PS\4.37.0.0\Get-MsalToken.ps1:293 char:96
+ … ken -Silent -PublicClientApplication $PublicClientApplication @paramG …
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Get-MsalToken], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Get-MsalToken

    Thomas Kurth · October 31, 2024 at 07:52

    This error is thrown by one of the used modules. Please check if your MSAL.PS installation is correct.

Seth Cutler · October 30, 2024 at 16:42

Does this support app registrations with certificate based authentication vs a client secret?

How to Configure App Protection Policies (MAM) for Unmanaged Android, iOS, and Windows 11 Devices | CheckYourLogs.Net · April 30, 2024 at 14:19

[…] If you want to automatically document your entire Intune implementation, a great script has been developed by MVP Thomas Kurth, and is available here. […]

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *

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