Skip to content

CLI options

Options are specified via command arguments, or within a bdoctor.json file (automatically gets created on initialization bdoctor init). Check the commands section for the commands these options can be passed to.

bdoctor authenticates with the certificate of your own Entra app registration. The --appId, --tenant, and --certificate options are required for every command which talks to SharePoint, and can be defined in the bdoctor.json file so you do not need to repeat them.

-a, --auth <auth> : The authentication type to use. certificate is the only supported value, and it is the default.

--appId <appId> : The ID of the Entra app registration to authenticate with. Required.

--tenant <tenant> : The ID of the tenant to authenticate to. Required.

--certificate <certificate> : The certificate to authenticate with. Required. This can be the path to your certificate file (.pfx, .p12, or .pem), relative to the folder from where you run bdoctor, or the base64 encoded contents of that file.

Terminal window
# Path to the certificate file
bdoctor publish --certificate ./cert.pfx --appId <appId> --tenant <tenant> --url <url>
# Base64 encoded certificate
bdoctor publish --certificate <base64String> --appId <appId> --tenant <tenant> --url <url>

--password <password> : The password of your certificate file, when you protected it with one.

Before v2.0.0, bdoctor could also authenticate with the deviceCode and password authentication types. Both are removed:

  • The password type is no longer supported by the CLI for Microsoft 365.
  • The deviceCode type signs you in as a user, which does not work for all the APIs bdoctor calls during a publishing run.

Certificate authentication uses application permissions, which work for every API bdoctor needs, and it is the only type which works unattended in a CI/CD pipeline. If you used one of the removed types, follow the certificate authentication guide to set up an app registration.

-u, --url <url> : The URL of the site collection to use.

--library <library> : Specified the library which you want to use in SharePoint to store your referenced images.

-f, --folder <folder> : The folder location in where you will create your markdown files.

--webPartTitle <webPartTitle> : The label and compatibility selector for the Better Doctor Markdown control. Default: bdoctor-placeholder. Legacy migration also checks the built-in component ID; a matching title alone does not establish ownership. Ambiguous candidates stop migration.

--overwriteImages : Specifies if you allow bdoctor to overwrite the images in the SharePoint library that are referenced in the markdown files.

--debug : Provides more information of what is happening during command execution. You can also enable this by setting the DEBUG=true environment variable, which is useful in CI/CD pipelines.

--verbose : Provides extended logging output. When enabled, the task list is rendered with the verbose renderer, so every task and its output stays visible instead of being collapsed. For the bdoctor status command, this flag also lists the unchanged files.

--output <default|json> : The way the command reports its result. With json, the human readable output is silenced and a single JSON document is written to stdout, which a CI/CD pipeline can gate on or turn into a pull request comment. Check the JSON output section for the documents the status and publish commands return.

--commandName <commandName> : Override the command used to execute CLI for Microsoft 365. By default, bdoctor executes commands through the bundled @pnp/cli-microsoft365 API directly. The m365 (default) and localm365 values both use this in-process API. Any other value is executed as a binary on your PATH. Use this option only when you explicitly want to run a different command binary.

--commandTimeout <commandTimeout> : The timeout in milliseconds for each CLI for Microsoft 365 command which bdoctor executes. Default value is: 120000 (2 minutes). Increase this value when you run into Command timed out after 120000ms errors, which can happen on large sites or slow connections.

{
"commandTimeout": 300000
}

The --output json argument turns the result of a run into something a script can act on. All human readable output is left out, and bdoctor writes a single JSON document to stdout.

Terminal window
bdoctor status --output json

Which lets your pipeline decide whether it has anything to publish:

Terminal window
if bdoctor status --output json | jq -e '.summary.upToDate' > /dev/null; then
echo "Nothing changed, skipping the publish"
fi
{
"command": "status",
"success": true,
"version": "2.1.0",
"url": "https://<tenant>.sharepoint.com/sites/<documentation>",
"state": {
"enabled": true,
"tracked": 12,
"filesChecked": 14
},
"summary": {
"new": 1,
"modified": 2,
"unchanged": 11,
"deleted": 0,
"orphaned": 0,
"changed": 3,
"upToDate": false
},
"pages": {
"new": [{ "file": "docs/new-page.md", "slug": "new-page.aspx" }],
"modified": [],
"unchanged": [],
"deleted": [],
"orphaned": []
},
"warnings": []
}
Property Description
state.enabled Whether the publish state is used. All pages are reported as new when it is disabled with --disableStatePersistence.
summary.changed The new and modified pages together: what the next publish run processes.
summary.upToDate true when there is nothing left to publish, and nothing to remove.
pages.* The pages of each category, with the file path relative to the folder you ran bdoctor from. A deleted page has no file, an orphaned language file has no slug.

The pages lists are always complete, also for the unchanged pages. The --verbose flag only influences the human readable output.

{
"command": "publish",
"success": true,
"version": "2.1.0",
"url": "https://<tenant>.sharepoint.com/sites/<documentation>",
"summary": {
"pages": { "total": 14, "created": 1, "updated": 2, "skipped": 11, "removed": 0 },
"images": { "total": 3, "uploaded": 3, "skipped": 0 },
"retries": 0,
"errors": 0,
"durationMs": 42123
},
"failedFiles": [],
"warnings": []
}

The timings property is added when you pass the --timingDetails flag.

A failing run writes the same kind of document, and exits with code 1:

{
"command": "publish",
"success": false,
"version": "2.1.0",
"error": {
"message": "The provided folder location doesn't exist."
}
}

Every other command returns a { "command", "success", "version" } document, so --output json never leaves you with output which cannot be parsed.

--continueOnError : Continue when an error occurs during the publishing process.

--outputFolder <outputFolder> : When providing this option, the processed markdown files will be generated in this folder.

--cleanEnd : Removes the pages which have not been touched during the publishing run. This will happen at the end of the whole process.

--cleanStart : Removes all pages before creation. This ensures that you that all changes made to your documentation get removed.

--confirm : Confirms requested cleanup/removal actions and authorizes replacement of an identified legacy Markdown control. Legacy migration requires this explicit flag even without cleanup options. Review the deployment and migration guide first.

--skipExistingPages : Will not overwrite pages if they already existed on the site, leaving their existing controls unmigrated. The shorter --skipExisting alias can be used as well.

--forceAll : Reprocess all pages, ignoring the saved publish state. By default bdoctor only publishes pages whose content or render inputs changed. This flag does not authorize legacy replacement; that still requires --confirm. Check change detection for more information.

--removeDeleted : Recycles the pages which bdoctor published before, but whose markdown file no longer exists. Requires the --confirm flag, or bdoctor asks you to confirm the removal. Check the removing deleted pages section for more information.

--skipPrecheck : Skips local content pre-process validation. It does not bypass mandatory Better Doctor Markdown deployment availability or migration identity checks. Check the pre-process checks section for more information.

--enableMath <true|false> : Enables or disables KaTeX math rendering. This option requires the explicit string value true or false; a missing or other value is invalid. It overrides markdown.enableMath in bdoctor.json, including false overriding a configured true. The default is false, independently of markdown.allowHtml.

Terminal window
bdoctor publish --enableMath true
bdoctor publish --enableMath false
bdoctor status --enableMath false

Use the same effective rendering options for status and publish when comparing changes. See math syntax for delimiters and literal-dollar behavior.

--timingDetails : Shows additional per-page timing statistics (average, fastest and slowest page) after the publishing run. The total publishing time is always shown, also without this flag.

--applyTheme : Applies the theme defined in the siteDesign.theme property of your bdoctor.json file.

--retryWhenFailed : Specifying this flag will retry the command if it failed. In some cases it can be that SharePoint failes to process your request, and this allows you to try again without running the whole flow from scratch.

--skipPages: : This flag allows you to skip the pages provisioning in the publish flow.

--skipNavigation: : This flag allows you to skip setting the navigation in the publish flow.

--skipSiteDesign: : This flag allows you to skip setting the site its look and feel in the publish flow.

--cleanQuickLaunch : Allows you to specify if you want to remove all the navigation elements defined in the QuickLaunch navigation before adding the new navigation structure.

--cleanTopNavigation : Allows you to specify if you want to remove all the navigation elements defined in the TopNavigation navigation before adding the new navigation structure.

--pageTemplate : Name of the default page template to use for all the pages which will be created.

--disableComments : Disable comments for all pages. By default the comments are enabled on the pages.

--disableStatePersistence : Disables loading and saving of the publish state file. When you use this flag, bdoctor cannot detect changes, so all pages are processed on every run.

--stateFile <stateFile> : The path of the state file within the library defined by --library. Default value is: .bdoctor/state.json, which results in Shared Documents/.bdoctor/state.json when the default library is used.

bdoctor keeps track of what it published in a state file stored on your SharePoint site. Each successful page publication records a content/render fingerprint and a publication timestamp.

On the next run, bdoctor compares the hash of each local file with the one in the state file:

  • Pages which are new or modified get published.
  • Pages which are unchanged get skipped.

The fingerprint covers the Markdown file and its resolved partials, effective rendering options (including math), shortcode implementations, and renderer contract version. A rendering change can therefore mark a page as modified without a source-text change. Old state triggers a one-time renderer update rather than losing page ownership. Legacy control replacement still needs --confirm.

Publish state is not a full content backup. Migration recovery data remains in the page’s custom control and native page versions, not the asset-library state file. See migration recovery.

Localized pages are tracked the same way, under the URL SharePoint issued for them. They are published in their own phase which runs after the normal pages, so a changed .lang.md file gets published even when its source page did not change.

The state is saved after each page, so when a publishing run fails halfway, the already published pages do not need to be processed again on the next run.

The following options influence this behavior:

  • --forceAll: reprocess everything, ignoring the state.
  • --disableStatePersistence: do not load or save the state at all.
  • --stateFile: store the state on another location.
  • --library: the library in which the state file is stored.

Use the bdoctor status command to see which pages will be published on the next run.

Deleting a markdown file does not remove the page it created on your site. bdoctor knows which pages it published, as it tracks them in the state file, and bdoctor status lists the ones without a local file as Deleted.

Pass the --removeDeleted flag to act on them:

Terminal window
bdoctor publish --removeDeleted --confirm

Every page which is tracked in the state, but has no markdown file anymore, gets recycled and dropped from the state. The pages end up in the site its recycle bin, so you can still restore them from SharePoint itself.

Good to know:

  • The state file is the source of truth. Pages which were created outside of bdoctor, or before the state file existed, are not touched. Use the --cleanEnd flag when you want to remove everything which was not published during the run.
  • Multilingual pages are removed together with their source page. Translations of a page which still exists are kept.
  • Pages which are already gone from the site are removed from the state as well, so the state keeps matching your site.
  • When a markdown file cannot be resolved to a page (an unreadable file, or one without a title), no pages get removed at all. The pre-process checks catch these before the publishing run, unless you use --skipPrecheck.
  • The flag has no effect in combination with --disableStatePersistence or --skipPages, as bdoctor needs the state to know which pages it created.

bdoctor validates your Markdown files before processing page content and stops the run when it finds issues. The following local checks are performed:

  • Files which cannot be read.
  • Front matter which cannot be parsed.
  • Pages without a title in their front matter.
  • Duplicate slugs, as these pages would overwrite each other on the site.
  • Localization references in the front matter pointing to a file which does not exist on disk.

When one or more issues are found, the run stops and all issues are listed at once (up to a maximum of 20, followed by the number of remaining issues). Language files are handled separately from normal source pages.

Use --skipPrecheck to skip these local checks. It does not skip deployment validation: for a page-publishing run, the custom component must be available before cleanup, uploads, multilingual configuration, or page mutation.

--provider <provider> : The CI/CD platform to generate the definition for. Supported values are github (default) and azdo. Check the workflow command section for more information.