Skip to main content

Introducing Shadowman - Service Principal Auditing Made Easy!

 Long time no see! The reason for this is because while I was away, I was working on a brand-new tool for administrators to audit their environment for shadow IT apps. This idea came after I wanted to be able to audit my own environment for shadow IT and didn't have a way to do it in a comprehensive manner. Thus, my PowerShell tool was born; I introduce to you, Shadowman!


What is Shadowman?

Shadowman in a nutshell is a tool designed to get you all the information that you need on the service principals in your Azure environment. Administrators have the option to conduct a basic audit that will capture all information and flags that are available through the application, as well as a targeted mode that will give administrators the ability to filter applications based on the following flags:

Service Principal Properties

Property Description
DisplayNameName of the service principal
AppIdApplication ID
ObjectIdObject ID in Azure AD
UserConsentsCountNumber of user consents
ConsentingUsersUsers who have granted consent
DelegatedPermissionsDelegated permissions granted
UnverifiedPublisherIndicates if the publisher is unverified
HasRiskyConsentsFlags if risky consents are present
CountryOfOriginCountry information (if available)
LastSignInUTCTimestamps of last sign-in events
FullAccessAsAppIndicates if app has full access permissions
HasFullAccessAsAppConfirms full access as app
IsOrphanedTrue if app has no owners
HighValueUserTrue if consent was granted by a high-value user
HasBroadMailboxAccessIndicates broad access to mailbox resources
IsRiskyAppFlags app as risky based on permissions or behavior
RiskReasonsReasons why the app is considered risky
RiskyPermissionsFoundSpecific risky permissions detected
IsDisabledAppIndicates if the app is disabled
OldestConsentDateOldest recorded consent date
IsExternalTenantAppTrue if app belongs to an external tenant
RequiresUserAssignmentIndicates if user assignment is required
UsageStatusCurrent usage status (empty by default)

Why Shadowman Matters

Shadow IT is one of the most overlooked risks in cloud environments. When users grant consent to third-party applications without oversight, it opens the door to potential data leaks, privilege escalation, and compliance violations. Shadowman helps you shine a light on these hidden risks by surfacing critical metadata and behavioral flags tied to service principals—giving you the visibility you need to take action.

Whether you're trying to identify orphaned apps, flag risky permissions, or simply understand how external apps are interacting with your tenant, Shadowman is built to give you answers fast and in a format that's easy to work with.

How It Works

Shadowman is written in PowerShell and leverages Microsoft Graph to pull detailed service principal data. You can run it in two modes:

  • Basic Audit Mode: Captures all service principals and their associated flags.

  • Targeted Mode: Allows filtering based on specific risk indicators like HasRiskyConsents, IsExternalTenantApp, or HasBroadMailboxAccess.

The output is structured, exportable, and designed to plug into your existing reporting workflows. You can even integrate it with scheduled tasks or SIEM pipelines for continuous monitoring.

What's Next?

This is just the beginning. I'm actively working on enhancements like:

  • Consent age analysis

  • Integration with Defender for Cloud Apps

  • Automated remediation 

  • Visual dashboards for executive reporting

If you're an admin, security analyst, or just someone who wants to take control of your Azure environment, I invite you to give Shadowman a try. Feedback is welcome—this tool is built by an admin, for admins.

You can access and clone the repository here: https://github.com/pryrotech/entra-app-auditor

Thanks for sticking around, and I’m excited to share more updates soon. Stay secure, stay curious—and let Shadowman help you uncover what’s lurking in the shadows.

test

Using Power Automate to Update Contact Information

 We've all been there- you have a large organization who has out-of-date contact information. What do you do? You could go around to each department and ask them nicely to update their information, or send out an org-wide email prompting people to do so. However, this is tedious and oftentimes a pointless task. By the time you update one department, you're running to fix another. What if you could put the power back in the department's hands to do so? This is a struggle I faced recently as I was trying to find was I could conjure up some updated contact information for each department. As I did my research, I found that I was not alone in this endeavour as it seems that many IT professionals would love to make this process a little bit less painful. With this in mind, I introduce to you my latest flow! This flow will allow you to encourage users to update their contact information, without the overhead that comes with manual effort. In addition to this, this flow utilizes t...

Using Custom Connectors and Microsoft Graph API's to Manage Licenses in Power Automate - Part Two

Hello again! Didn't I promise you that I'd be back to wrap this up? Well, here I am to give you the second tidbit of information that you need to get this started. If you haven't already, take a look at my previous post where I go into depth about creating a custom connector in Power Automate to retrieve the latest sign-in and also gather the user's licenses. Now that we have the custom connector ready, we can now get into the meat n' potatoes of this series. In this post, I will show you the flow that makes this possible and how you can use the custom connector you have created to tie it all together! Hope you enjoy. Understanding the Logic Before we can begin creating the flow, we should first understand how the flow will work. I designed this to flow to be triggered manually, but you may want to schedule it or use another trigger. The trigger will depend on your organization's policies, so please adjust accordingly. Once triggered, the flow will use the Entra...

Using Custom Connectors and Microsoft Graph API's to Manage Licenses in Power Automate - Part One

Happy June folks! I come to you with another post, but this time I wanted to change it up and show you something else I have just finished working on. As a SysAdmin, one of the most common issues we run into is managing licenses. Working at a post-secondary institution makes this an even greater challenge, as you have both students, staff and faculty constantly coming as well as going. Managing to keep up with this constant change can introduce great administrative overhead which takes away time from important upkeep of other systems and initiatives. You may also notice this same issue in large corporations or in other government organizations. To help combat this, I wanted to create a flow that can do the following: Get the user and their licenses Determine their last sign-in and the date Conditional to determine if the user is past the "cutoff" date Remove the user from a group where the license is assigned The only problem with doing this is that Power Automate does not ha...