{"id":4443,"date":"2025-02-14T11:05:14","date_gmt":"2025-02-14T10:05:14","guid":{"rendered":"https:\/\/www.lieben.nu\/liebensraum\/?p=4443"},"modified":"2025-02-14T11:05:14","modified_gmt":"2025-02-14T10:05:14","slug":"scanning-unattended-using-a-service-principal","status":"publish","type":"post","link":"https:\/\/lieben.nu\/liebensraum\/2025\/02\/scanning-unattended-using-a-service-principal\/","title":{"rendered":"Scanning unattended using a Service Principal"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">If you want to use the <a href=\"https:\/\/www.lieben.nu\/liebensraum\/m365permissions\/\" data-type=\"page\" data-id=\"4280\">M365Permissions module<\/a> in unattended (or headless) mode, e.g. from a runbook or on a server as scheduled task, you&#8217;ll need to create an app registration in Entra with sufficient permissions to scan your tenant.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.lieben.nu\/liebensraum\/wp-content\/uploads\/2025\/02\/M365Permissions_v1.1.3.gif\"><img loading=\"lazy\" decoding=\"async\" width=\"1111\" height=\"626\" src=\"https:\/\/www.lieben.nu\/liebensraum\/wp-content\/uploads\/2025\/02\/M365Permissions_v1.1.3.gif\" alt=\"\" class=\"wp-image-4451\"\/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Setup instructions (automated)<\/strong><\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li class=\"has-black-color has-text-color has-link-color wp-elements-ae1475589f98807727cd2b93688b14e6\">Install the module using <em><code>Install-Module<\/code> <code>-Name<\/code> <code>M365Permissions<\/code> <code>-Force<\/code><\/em><\/li>\n\n\n\n<li>Load the module using <em><code>Import-Module<\/code> <code>-Name<\/code> <code>M365Permissions<\/code><\/em><\/li>\n\n\n\n<li>Create a service principal using <code><em>Set-ScanPermissions -switchToSPNAuth<\/em> <em>-appName \"M365Permissions (AppOnly)\"<\/em><\/code><\/li>\n\n\n\n<li>Run <code><em>Connect-M365 -ServicePrincipal<\/em><\/code><\/li>\n\n\n\n<li>Start a scan (e.g. using <code><em>get-allM365Permissions<\/em><\/code>)<\/li>\n\n\n\n<li>Scroll down if you also want to scan PowerBI<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Setup instructions (manual)<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Go to <a href=\"https:\/\/portal.azure.com\/#view\/Microsoft_AAD_RegisteredApps\/CreateApplicationBlade\/quickStartType~\/null\/isMSAApp~\/false\">https:\/\/portal.azure.com\/#view\/Microsoft_AAD_RegisteredApps\/CreateApplicationBlade\/quickStartType~\/null\/isMSAApp~\/false<\/a><\/li>\n\n\n\n<li>Decide on a name and click Register<\/li>\n\n\n\n<li>Go to API permissions and enter as follows:<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.lieben.nu\/liebensraum\/wp-content\/uploads\/2025\/02\/image-1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1302\" height=\"733\" src=\"https:\/\/www.lieben.nu\/liebensraum\/wp-content\/uploads\/2025\/02\/image-1.png\" alt=\"\" class=\"wp-image-4444\" srcset=\"https:\/\/lieben.nu\/liebensraum\/wp-content\/uploads\/2025\/02\/image-1.png 1302w, https:\/\/lieben.nu\/liebensraum\/wp-content\/uploads\/2025\/02\/image-1-300x169.png 300w, https:\/\/lieben.nu\/liebensraum\/wp-content\/uploads\/2025\/02\/image-1-1024x576.png 1024w, https:\/\/lieben.nu\/liebensraum\/wp-content\/uploads\/2025\/02\/image-1-768x432.png 768w\" sizes=\"auto, (max-width: 1302px) 100vw, 1302px\" \/><\/a><\/figure>\n\n\n\n<ol start=\"4\" class=\"wp-block-list\">\n<li>Don&#8217;t forget to click &#8216;Grant admin consent&#8217;<\/li>\n\n\n\n<li>Note down the &#8216;Application (client) id&#8217; and &#8216;Directory (tenant) id&#8217; from the &#8216;Overview&#8217; page<\/li>\n\n\n\n<li>run the new-SpnAuthCert command from the M365Permissions module, it will output a .cer file. Make sure to use the tenant ID from step 5.<\/li>\n\n\n\n<li>The PFX file has to be imported on any machine you wish to run the module on, except for the machine where you ran the new-SpnAuthCert command.<\/li>\n\n\n\n<li>Go to &#8216;Certificates &amp; secrets&#8217; and upload the .cer file<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.lieben.nu\/liebensraum\/wp-content\/uploads\/2025\/02\/image-2.png\"><img loading=\"lazy\" decoding=\"async\" width=\"731\" height=\"417\" src=\"https:\/\/www.lieben.nu\/liebensraum\/wp-content\/uploads\/2025\/02\/image-2.png\" alt=\"\" class=\"wp-image-4445\" srcset=\"https:\/\/lieben.nu\/liebensraum\/wp-content\/uploads\/2025\/02\/image-2.png 731w, https:\/\/lieben.nu\/liebensraum\/wp-content\/uploads\/2025\/02\/image-2-300x171.png 300w\" sizes=\"auto, (max-width: 731px) 100vw, 731px\" \/><\/a><\/figure>\n\n\n\n<ol start=\"8\" class=\"wp-block-list\">\n<li>Go to the <a href=\"https:\/\/portal.azure.com\/#view\/Microsoft_AAD_IAM\/RoleMenuBlade\/~\/RoleMembers\/objectId\/62e90394-69f5-4237-9190-012177145e10\/roleName\/Global%20Administrator\/roleTemplateId\/62e90394-69f5-4237-9190-012177145e10\/adminUnitObjectId\/\/customRole~\/false\/resourceScope\/%2F\/isPrivilegedRole~\/true\">Roles and Administrators<\/a> in Entra and select the Global Administrator role.<\/li>\n\n\n\n<li>Add the new app registration to the global administrator role:<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.lieben.nu\/liebensraum\/wp-content\/uploads\/2025\/02\/image-3.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1519\" height=\"967\" src=\"https:\/\/www.lieben.nu\/liebensraum\/wp-content\/uploads\/2025\/02\/image-3.png\" alt=\"\" class=\"wp-image-4447\" srcset=\"https:\/\/lieben.nu\/liebensraum\/wp-content\/uploads\/2025\/02\/image-3.png 1519w, https:\/\/lieben.nu\/liebensraum\/wp-content\/uploads\/2025\/02\/image-3-300x191.png 300w, https:\/\/lieben.nu\/liebensraum\/wp-content\/uploads\/2025\/02\/image-3-1024x652.png 1024w, https:\/\/lieben.nu\/liebensraum\/wp-content\/uploads\/2025\/02\/image-3-768x489.png 768w\" sizes=\"auto, (max-width: 1519px) 100vw, 1519px\" \/><\/a><\/figure>\n\n\n\n<ol start=\"10\" class=\"wp-block-list\">\n<li>Run set-M365PermissionsConfig -LCTenantId &lt;tenant ID&gt; -LCClientId &lt;client id&gt; with the values from step 5 to configure the module to use your new SPN to log in.<\/li>\n\n\n\n<li>Alternatively, you can configure the LCTENANTID and LCCLIENTID environment variables with above information.<\/li>\n\n\n\n<li>If you also configure the LCAUTHMODE environment variable with a value of &#8220;ServicePrincipal&#8221;, the module will log in to your tenant fully automatically the moment it is imported.<\/li>\n\n\n\n<li>If you&#8217;re running interactively, you can now use connect-M365 -ServicePrincipal before running a scan to use the SPN instead of delegated authentication<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Scanning PowerBI<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If you also want to include PowerBI in your scans, you&#8217;ll have to <a href=\"https:\/\/www.lieben.nu\/liebensraum\/2025\/03\/allowing-a-service-principal-to-scan-powerbi\/\">authorize the service principal.<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">PFX certificate location<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If you want to run from an automation account, Azure function etc, for now you&#8217;ll have to retrieve the .pfx file dynamically and install it before the module loads because the module looks in the local certificate store for a certificate with your tenant ID as subject.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I will consider adding support for Managed Identities in the future to make this simpler, and possibly also add keyvault integration or direct path configuration an option.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Restrictions<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">When scanning as service principal, you cannot scan:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Graph Subscriptions<\/li>\n\n\n\n<li>PowerBI Gateways<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">You&#8217;ll see a warning in the logs about this as they&#8217;ll automatically be excluded.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Setup instructions (automated)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">to be added in a future version<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you want to use the M365Permissions module in unattended (or headless) mode, e.g. from a runbook or on a server as scheduled task, you&#8217;ll need to create an app registration in Entra with sufficient permissions to scan your tenant. Setup instructions (automated) Setup instructions (manual) Scanning PowerBI If you also want to include PowerBI &hellip; <a href=\"https:\/\/lieben.nu\/liebensraum\/2025\/02\/scanning-unattended-using-a-service-principal\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Scanning unattended using a Service Principal<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_crdt_document":"","footnotes":""},"categories":[13,24],"tags":[],"class_list":["post-4443","post","type-post","status-publish","format-standard","hentry","category-entraid","category-m365permissions"],"_links":{"self":[{"href":"https:\/\/lieben.nu\/liebensraum\/wp-json\/wp\/v2\/posts\/4443","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lieben.nu\/liebensraum\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lieben.nu\/liebensraum\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lieben.nu\/liebensraum\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lieben.nu\/liebensraum\/wp-json\/wp\/v2\/comments?post=4443"}],"version-history":[{"count":0,"href":"https:\/\/lieben.nu\/liebensraum\/wp-json\/wp\/v2\/posts\/4443\/revisions"}],"wp:attachment":[{"href":"https:\/\/lieben.nu\/liebensraum\/wp-json\/wp\/v2\/media?parent=4443"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lieben.nu\/liebensraum\/wp-json\/wp\/v2\/categories?post=4443"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lieben.nu\/liebensraum\/wp-json\/wp\/v2\/tags?post=4443"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}