<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>EPM Archives - Jens Du Four</title>
	<atom:link href="https://jensdufour.be/tag/epm/feed/" rel="self" type="application/rss+xml" />
	<link>https://jensdufour.be/tag/epm/</link>
	<description>Connecting you to the cloud, one endpoint at a time!</description>
	<lastBuildDate>Fri, 13 Mar 2026 11:50:44 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>
	<item>
		<title>EPM Approval Workflow: Adaptive Cards and Logic Apps</title>
		<link>https://jensdufour.be/2026/01/01/epm-approval-workflow-adaptive-cards-logic-apps/</link>
					<comments>https://jensdufour.be/2026/01/01/epm-approval-workflow-adaptive-cards-logic-apps/#respond</comments>
		
		<dc:creator><![CDATA[Jens Du Four]]></dc:creator>
		<pubDate>Wed, 31 Dec 2025 23:00:00 +0000</pubDate>
				<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Adaptive Cards]]></category>
		<category><![CDATA[EPM]]></category>
		<category><![CDATA[Intune Suite]]></category>
		<category><![CDATA[Logic Apps]]></category>
		<category><![CDATA[Teams]]></category>
		<guid isPermaLink="false">https://jensdufour.be/?p=779</guid>

					<description><![CDATA[<p>Automate EPM approval in Microsoft Teams with Adaptive Cards and Azure Logic Apps. Approve or deny elevation requests without leaving Teams.</p>
<p>The post <a href="https://jensdufour.be/2026/01/01/epm-approval-workflow-adaptive-cards-logic-apps/">EPM Approval Workflow: Adaptive Cards and Logic Apps</a> appeared first on <a href="https://jensdufour.be">Jens Du Four</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Introduction</h2>



<p class="wp-block-paragraph"><strong>EPM automation with Adaptive Cards</strong> transforms how IT teams handle elevation requests in <a href="https://learn.microsoft.com/en-us/intune/intune-service/fundamentals/what-is-intune">Microsoft Intune</a>. By combining <a href="https://learn.microsoft.com/en-us/azure/logic-apps/">Azure Logic Apps</a> with Teams <a href="https://learn.microsoft.com/en-us/adaptive-cards/">Adaptive Cards</a>, you can automate the entire <a href="https://learn.microsoft.com/en-us/intune/intune-service/protect/epm-overview">Endpoint Privilege Management</a> (EPM) approval workflow, allowing approvers to act on requests without leaving Microsoft Teams. This EPM automation solution eliminates the need to constantly monitor the Intune portal.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6a10f7a976c58&quot;}" data-wp-interactive="core/image" data-wp-key="6a10f7a976c58" class="wp-block-image wp-lightbox-container"><img decoding="async" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" alt="EPM automation Adaptive Cards showing an approved elevation request in Microsoft Teams." src="https://raw.githubusercontent.com/jensdufour/blog/main/media/epm-approval-workflow-adaptive-cards-logic-apps/epm-approval-workflow-adaptive-cards-logic-apps-01.webp"/><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<h2 class="wp-block-heading">What Is Endpoint Privilege Management?</h2>



<p class="wp-block-paragraph"><strong>Endpoint Privilege Management (EPM)</strong> is a feature in the <a href="https://learn.microsoft.com/en-us/intune/intune-service/fundamentals/intune-add-ons">Microsoft Intune Suite</a> that allows organizations to manage and control local administrator rights on Windows devices &#8212; without granting permanent admin access. It enables rule-based and Just-In-Time (JIT) elevation, ensuring users can perform privileged tasks only when necessary, and only under defined conditions.</p>



<h3 class="wp-block-heading">Rules-Based Elevation: Three Options</h3>



<p class="wp-block-paragraph">EPM supports three types of elevation rules:</p>



<ol class="wp-block-list">

<li><strong>Automatic Elevation</strong> &#8212; The application is elevated silently without user interaction, based on predefined rules.</li>


<li><strong>User-Confirmed Elevation</strong> &#8212; The user is prompted to confirm the elevation request, typically with a business justification and/or Windows authentication.</li>


<li><strong>Support-Approved Elevation</strong> &#8212; The user submits a request that must be approved by IT or support staff before elevation is granted. This is the model we focus on in this post, as it allows integration with Microsoft Teams for real-time approvals.</li>

</ol>



<h3 class="wp-block-heading">Just-In-Time Elevation with Support Approval</h3>



<p class="wp-block-paragraph">Support-approved elevation is ideal for organizations that want to maintain strict control over admin rights while still enabling flexibility for end users. When a user requests elevation, the request is logged and routed for approval. By integrating this process with Microsoft Teams using Azure Logic Apps, IT teams can receive instant notifications and respond quickly &#8212; without switching tools or missing critical requests.</p>



<p class="wp-block-paragraph">Currently, when approved, these requests remain valid for 24 hours.</p>



<h3 class="wp-block-heading">Benefits of Using EPM</h3>



<p class="wp-block-paragraph">Implementing Endpoint Privilege Management offers several key advantages:</p>



<ul class="wp-block-list">

<li><strong>User Empowerment</strong>: Allows users to perform necessary tasks without waiting for manual intervention &#8212; when policies allow it.</li>


<li><strong>Improved Security</strong>: Reduces the attack surface by eliminating standing admin rights.</li>


<li><strong>Operational Efficiency</strong>: Automates elevation workflows and reduces helpdesk overhead.</li>


<li><strong>Compliance and Auditing</strong>: Provides detailed logs of elevation activity for auditing and compliance reporting.</li>

</ul>



<h2 class="wp-block-heading">The Challenge with Manual EPM Approvals</h2>



<p class="wp-block-paragraph">When EPM is configured in Microsoft Intune, end users can request elevation to run applications requiring administrator privileges. However, the traditional approval workflow requires IT administrators to:</p>



<ol class="wp-block-list">

<li>Navigate to the Intune portal</li>


<li>Find the pending elevation request</li>


<li>Review the request details</li>


<li>Approve or deny the request</li>

</ol>



<p class="wp-block-paragraph">This process, while secure, creates friction, especially when approvers are busy with other tasks or aren&#8217;t actively monitoring the Intune console.</p>



<p class="wp-block-paragraph">The result?</p>



<p class="wp-block-paragraph">Delayed approvals and frustrated users waiting for elevated access.</p>



<h2 class="wp-block-heading">Configuring EPM in Microsoft Intune</h2>



<p class="wp-block-paragraph">Before setting up the automation, you need an EPM elevation rules policy. In this example we enable the &#8220;Mark 8 Project Team&#8221; to request elevation for Wireshark. I am assuming here that EPM was already enabled in your tenant.</p>



<figure data-wp-context="{&quot;galleryId&quot;:&quot;6a10f7a9771d3&quot;}" data-wp-interactive="core/gallery" class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex">

<figure data-wp-context="{&quot;imageId&quot;:&quot;6a10f7a977239&quot;}" data-wp-interactive="core/image" data-wp-key="6a10f7a977239" class="wp-block-image wp-lightbox-container"><img decoding="async" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" alt="" src="https://raw.githubusercontent.com/jensdufour/blog/main/media/epm-approval-workflow-adaptive-cards-logic-apps/epm-approval-workflow-adaptive-cards-logic-apps-03.webp"/><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>


<figure data-wp-context="{&quot;imageId&quot;:&quot;6a10f7a977360&quot;}" data-wp-interactive="core/image" data-wp-key="6a10f7a977360" class="wp-block-image wp-lightbox-container"><img decoding="async" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" alt="" src="https://raw.githubusercontent.com/jensdufour/blog/main/media/epm-approval-workflow-adaptive-cards-logic-apps/epm-approval-workflow-adaptive-cards-logic-apps-04.webp"/><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>


<figure data-wp-context="{&quot;imageId&quot;:&quot;6a10f7a97747c&quot;}" data-wp-interactive="core/image" data-wp-key="6a10f7a97747c" class="wp-block-image wp-lightbox-container"><img decoding="async" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" alt="" src="https://raw.githubusercontent.com/jensdufour/blog/main/media/epm-approval-workflow-adaptive-cards-logic-apps/epm-approval-workflow-adaptive-cards-logic-apps-05.webp"/><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>


<figure data-wp-context="{&quot;imageId&quot;:&quot;6a10f7a9775ce&quot;}" data-wp-interactive="core/image" data-wp-key="6a10f7a9775ce" class="wp-block-image wp-lightbox-container"><img decoding="async" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" alt="" src="https://raw.githubusercontent.com/jensdufour/blog/main/media/epm-approval-workflow-adaptive-cards-logic-apps/epm-approval-workflow-adaptive-cards-logic-apps-06.webp"/><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>


<figure data-wp-context="{&quot;imageId&quot;:&quot;6a10f7a977706&quot;}" data-wp-interactive="core/image" data-wp-key="6a10f7a977706" class="wp-block-image wp-lightbox-container"><img decoding="async" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" alt="" src="https://raw.githubusercontent.com/jensdufour/blog/main/media/epm-approval-workflow-adaptive-cards-logic-apps/epm-approval-workflow-adaptive-cards-logic-apps-07.webp"/><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>

</figure>



<p class="wp-block-paragraph">Start in <a href="https://intune.microsoft.com/">Microsoft Intune</a> and navigate to the <strong>Endpoint security</strong> blade. Under <strong>Endpoint Privilege Management</strong> go to <strong>Policies</strong> and create a new <strong>Elevation rules policy</strong>.</p>



<p class="wp-block-paragraph">After going through the basics, fill in the detailed information about the application you are adding to the rule. This information can be collected using the <code>EpmTools.dll</code>.</p>



<figure data-wp-context="{&quot;galleryId&quot;:&quot;6a10f7a9780fa&quot;}" data-wp-interactive="core/gallery" class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-2 is-layout-flex wp-block-gallery-is-layout-flex">

<figure data-wp-context="{&quot;imageId&quot;:&quot;6a10f7a97816f&quot;}" data-wp-interactive="core/image" data-wp-key="6a10f7a97816f" class="wp-block-image wp-lightbox-container"><img decoding="async" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" alt="" src="https://raw.githubusercontent.com/jensdufour/blog/main/media/epm-approval-workflow-adaptive-cards-logic-apps/epm-approval-workflow-adaptive-cards-logic-apps-08.webp"/><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>


<figure data-wp-context="{&quot;imageId&quot;:&quot;6a10f7a97829b&quot;}" data-wp-interactive="core/image" data-wp-key="6a10f7a97829b" class="wp-block-image wp-lightbox-container"><img decoding="async" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" alt="" src="https://raw.githubusercontent.com/jensdufour/blog/main/media/epm-approval-workflow-adaptive-cards-logic-apps/epm-approval-workflow-adaptive-cards-logic-apps-09.webp"/><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>

</figure>



<p class="wp-block-paragraph">Using this tool you can even extract publisher certificates from the file. These can be added to the reusable library.</p>



<p class="wp-block-paragraph">Finally, fill in all the necessary details about the file.</p>



<figure data-wp-context="{&quot;galleryId&quot;:&quot;6a10f7a9784c7&quot;}" data-wp-interactive="core/gallery" class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-3 is-layout-flex wp-block-gallery-is-layout-flex">

<figure data-wp-context="{&quot;imageId&quot;:&quot;6a10f7a978529&quot;}" data-wp-interactive="core/image" data-wp-key="6a10f7a978529" class="wp-block-image wp-lightbox-container"><img decoding="async" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" alt="" src="https://raw.githubusercontent.com/jensdufour/blog/main/media/epm-approval-workflow-adaptive-cards-logic-apps/epm-approval-workflow-adaptive-cards-logic-apps-10.webp"/><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>


<figure data-wp-context="{&quot;imageId&quot;:&quot;6a10f7a97864f&quot;}" data-wp-interactive="core/image" data-wp-key="6a10f7a97864f" class="wp-block-image wp-lightbox-container"><img decoding="async" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" alt="" src="https://raw.githubusercontent.com/jensdufour/blog/main/media/epm-approval-workflow-adaptive-cards-logic-apps/epm-approval-workflow-adaptive-cards-logic-apps-11.webp"/><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>


<figure data-wp-context="{&quot;imageId&quot;:&quot;6a10f7a97876e&quot;}" data-wp-interactive="core/image" data-wp-key="6a10f7a97876e" class="wp-block-image wp-lightbox-container"><img decoding="async" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" alt="" src="https://raw.githubusercontent.com/jensdufour/blog/main/media/epm-approval-workflow-adaptive-cards-logic-apps/epm-approval-workflow-adaptive-cards-logic-apps-12.webp"/><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>

</figure>



<p class="wp-block-paragraph">Verify the configuration from a demo device. From the end-user perspective the <strong>Run with elevated access</strong> option should be visible, and the elevation request dialog should open.</p>



<figure data-wp-context="{&quot;galleryId&quot;:&quot;6a10f7a978984&quot;}" data-wp-interactive="core/gallery" class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-4 is-layout-flex wp-block-gallery-is-layout-flex">

<figure data-wp-context="{&quot;imageId&quot;:&quot;6a10f7a9789e5&quot;}" data-wp-interactive="core/image" data-wp-key="6a10f7a9789e5" class="wp-block-image wp-lightbox-container"><img decoding="async" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" alt="" src="https://raw.githubusercontent.com/jensdufour/blog/main/media/epm-approval-workflow-adaptive-cards-logic-apps/epm-approval-workflow-adaptive-cards-logic-apps-13.webp"/><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>


<figure data-wp-context="{&quot;imageId&quot;:&quot;6a10f7a978b09&quot;}" data-wp-interactive="core/image" data-wp-key="6a10f7a978b09" class="wp-block-image wp-lightbox-container"><img decoding="async" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" alt="" src="https://raw.githubusercontent.com/jensdufour/blog/main/media/epm-approval-workflow-adaptive-cards-logic-apps/epm-approval-workflow-adaptive-cards-logic-apps-14.webp"/><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>


<figure data-wp-context="{&quot;imageId&quot;:&quot;6a10f7a978c27&quot;}" data-wp-interactive="core/image" data-wp-key="6a10f7a978c27" class="wp-block-image wp-lightbox-container"><img decoding="async" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" alt="" src="https://raw.githubusercontent.com/jensdufour/blog/main/media/epm-approval-workflow-adaptive-cards-logic-apps/epm-approval-workflow-adaptive-cards-logic-apps-15.webp"/><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>


<figure data-wp-context="{&quot;imageId&quot;:&quot;6a10f7a978d49&quot;}" data-wp-interactive="core/image" data-wp-key="6a10f7a978d49" class="wp-block-image wp-lightbox-container"><img decoding="async" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" alt="" src="https://raw.githubusercontent.com/jensdufour/blog/main/media/epm-approval-workflow-adaptive-cards-logic-apps/epm-approval-workflow-adaptive-cards-logic-apps-16.webp"/><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>

</figure>



<p class="wp-block-paragraph">For the Intune administrator, the request should appear in the <strong>Elevation requests</strong> tab almost immediately.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6a10f7a978fc8&quot;}" data-wp-interactive="core/image" data-wp-key="6a10f7a978fc8" class="wp-block-image wp-lightbox-container"><img decoding="async" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" alt="" src="https://raw.githubusercontent.com/jensdufour/blog/main/media/epm-approval-workflow-adaptive-cards-logic-apps/epm-approval-workflow-adaptive-cards-logic-apps-17.webp"/><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<h3 class="wp-block-heading">Verifying the Graph API Data</h3>



<p class="wp-block-paragraph">Before building the Logic App, confirm that elevation requests are visible through the <a href="https://learn.microsoft.com/en-us/graph/use-the-api">Microsoft Graph API</a>. Open the <a href="https://developer.microsoft.com/en-us/graph/graph-explorer">Graph Explorer</a> and query <code>deviceManagement/elevationRequests</code>.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6a10f7a979173&quot;}" data-wp-interactive="core/image" data-wp-key="6a10f7a979173" class="wp-block-image wp-lightbox-container"><img decoding="async" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" alt="" src="https://raw.githubusercontent.com/jensdufour/blog/main/media/epm-approval-workflow-adaptive-cards-logic-apps/epm-approval-workflow-adaptive-cards-logic-apps-18.webp"/><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<p class="wp-block-paragraph">Make sure you are using the <strong>beta</strong> version of the API and that the <code>DeviceManagementConfiguration.Read.All</code> permission has been granted. Otherwise, the query returns a permission error.</p>



<h2 class="wp-block-heading">How EPM Automation with Adaptive Cards Works</h2>



<p class="wp-block-paragraph">Our EPM automation solution bridges Microsoft Intune and Microsoft Teams by creating an automated workflow that:</p>



<ul class="wp-block-list">

<li><strong>Polls for pending requests</strong> every 5 minutes using Microsoft Graph API</li>


<li><strong>Posts Adaptive Cards</strong> to a designated Teams channel with all request details</li>


<li><strong>Enables one-click approval or denial</strong> directly from Teams</li>


<li><strong>Updates the Adaptive Card</strong> to show the final decision and who made it</li>

</ul>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6a10f7a9793c0&quot;}" data-wp-interactive="core/image" data-wp-key="6a10f7a9793c0" class="wp-block-image wp-lightbox-container"><img decoding="async" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" alt="EPM automation Adaptive Cards displaying a denied elevation request with reviewer details" src="https://raw.githubusercontent.com/jensdufour/blog/main/media/epm-approval-workflow-adaptive-cards-logic-apps/epm-approval-workflow-adaptive-cards-logic-apps-02.webp"/><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<h3 class="wp-block-heading">Architecture for EPM Automation</h3>



<pre class="wp-block-code"><code>1. Logic App (Recurrence Trigger - every 5 minutes)
        │
        ├──&gt; GET Microsoft Graph API
        │    /deviceManagement/elevationRequests
        │
        ├──&gt; Filter requests with status = &quot;pending&quot;
        │
        ├──&gt; For each pending request:
        │    └──&gt; Post Adaptive Card to Teams channel
        │         ├──&gt; Approve button
        │         └──&gt; Deny button
        │
        └──&gt; When button clicked:
             └──&gt; POST approval/denial via Graph API
             └──&gt; Update Adaptive Card with decision
</code></pre>



<h2 class="wp-block-heading">Key Components of the EPM Automation Solution</h2>



<h3 class="wp-block-heading">Azure Logic App for EPM Automation</h3>



<p class="wp-block-paragraph">The Logic App serves as the orchestration engine for EPM automation. Using a recurrence trigger, it periodically queries the Microsoft Graph API for pending EPM elevation requests and processes each one by posting an interactive Adaptive Card to Teams.</p>



<h3 class="wp-block-heading">Adaptive Cards for Approval Actions</h3>



<p class="wp-block-paragraph">The Adaptive Cards display comprehensive request information:</p>



<ul class="wp-block-list">

<li><strong>Requester</strong> – Who’s requesting elevation</li>


<li><strong>Device Name</strong> – Which device the request originates from</li>


<li><strong>Application</strong> – The executable requesting elevation</li>


<li><strong>File Path</strong> – Where the application is located</li>


<li><strong>Publisher</strong> – The application’s publisher</li>


<li><strong>Justification</strong> – Why the user needs elevation</li>

</ul>



<p class="wp-block-paragraph">The card includes two action buttons: <strong>Approve</strong> (green) and <strong>Deny</strong> (red). Once clicked, the Adaptive Card updates to reflect the decision.</p>



<h3 class="wp-block-heading">Managed Identity for Secure EPM Automation</h3>



<p class="wp-block-paragraph">Security is paramount. Instead of storing credentials or secrets, the EPM automation solution uses an <strong>Azure Managed Identity</strong> to authenticate to Microsoft Graph API. This eliminates secret management overhead and follows security best practices.</p>



<h3 class="wp-block-heading">Microsoft Graph API Integration</h3>



<p class="wp-block-paragraph">The solution leverages the Graph API beta endpoint for EPM operations:</p>



<ul class="wp-block-list">

<li><code>GET /deviceManagement/elevationRequests</code> – Retrieve pending requests</li>


<li><code>POST /deviceManagement/elevationRequests/{id}/approve</code> – Approve a request</li>


<li><code>POST /deviceManagement/elevationRequests/{id}/deny</code> – Deny a request</li>

</ul>



<h2 class="wp-block-heading">Infrastructure as Code with Bicep</h2>



<p class="wp-block-paragraph">The entire EPM automation solution is defined using <strong>Azure Bicep</strong>, making it reproducible and version-controllable. Here’s a simplified look at the main resources:</p>



<pre class="wp-block-code"><code>// Managed Identity for secure Graph API access
resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
  name: '${logicAppName}-identity'
  location: location
  tags: tags
}

// Teams API Connection
resource teamsConnection 'Microsoft.Web/connections@2016-06-01' = {
  name: 'teams-connection'
  location: location
  properties: {
    displayName: 'Teams Connection for EPM Approval'
    api: {
      id: subscriptionResourceId('Microsoft.Web/locations/managedApis', location, 'teams')
    }
  }
}

// Logic App with workflow definition
resource logicApp 'Microsoft.Logic/workflows@2019-05-01' = {
  name: logicAppName
  location: location
  identity: {
    type: 'UserAssigned'
    userAssignedIdentities: {
      '${managedIdentity.id}': {}
    }
  }
  properties: {
    definition: loadJsonContent('workflow.json').definition
    // ... parameters
  }
}
</code></pre>



<h2 class="wp-block-heading">Deploying Your EPM Automation with Adaptive Cards</h2>



<p class="wp-block-paragraph">A PowerShell deployment script automates the entire setup process:</p>



<pre class="wp-block-code"><code># Deploy with default settings
.\deploy.ps1

# Or customize the deployment
.\deploy.ps1 -ResourceGroupName &quot;rg-epm-approval&quot; -Location &quot;westeurope&quot;

# Preview changes first
.\deploy.ps1 -WhatIf
</code></pre>



<p class="wp-block-paragraph">The script handles:</p>



<ul class="wp-block-list">

<li>Prerequisites validation (Azure CLI, Bicep, login status)</li>


<li>Resource group creation</li>


<li>Bicep template deployment</li>


<li>Graph API permission assignment via Microsoft Graph PowerShell</li>


<li>Teams connection authorization prompt</li>

</ul>



<h3 class="wp-block-heading">Required Graph API Permissions</h3>



<p class="wp-block-paragraph">The Managed Identity needs the following application permissions:</p>



<figure class="wp-block-table"><table>
<thead>
<tr>
<th>Permission</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>DeviceManagementConfiguration.ReadWrite.All</code></td>
<td>Read and update EPM elevation requests</td>
</tr>
<tr>
<td><code>DeviceManagementManagedDevices.Read.All</code></td>
<td>Read device information</td>
</tr>
</tbody>
</table></figure>



<h2 class="wp-block-heading">Cost of EPM Automation</h2>



<p class="wp-block-paragraph">One of the best aspects of this EPM automation solution is its cost-effectiveness:</p>



<figure class="wp-block-table"><table>
<thead>
<tr>
<th>Resource</th>
<th>Estimated Monthly Cost</th>
</tr>
</thead>
<tbody>
<tr>
<td>Logic App (Consumption)</td>
<td>~$0.50</td>
</tr>
<tr>
<td>Managed Identity</td>
<td>Free</td>
</tr>
<tr>
<td>Teams API Connection</td>
<td>Free</td>
</tr>
<tr>
<td>Log Analytics (optional)</td>
<td>~$2-5</td>
</tr>
</tbody>
</table></figure>



<p class="wp-block-paragraph"><strong>Total: ~$2-6/month</strong> depending on the number of requests processed.</p>



<h2 class="wp-block-heading">Security Best Practices</h2>



<p class="wp-block-paragraph">The EPM automation solution follows security best practices:</p>



<ul class="wp-block-list">

<li><strong>No secrets stored</strong> – Managed Identity handles authentication</li>


<li><strong>Least privilege</strong> – Only required Graph permissions are assigned</li>


<li><strong>Audit trail</strong> – All decisions are logged in both Intune and Logic App run history</li>


<li><strong>Secure outputs</strong> – Sensitive data is protected in Logic App runs</li>

</ul>



<h2 class="wp-block-heading">Extending the EPM Automation Solution</h2>



<p class="wp-block-paragraph">The modular design allows for easy extensions:</p>



<ul class="wp-block-list">

<li><strong>Email notifications</strong> – Add email alerts for high-priority requests</li>


<li><strong>ServiceNow integration</strong> – Create tickets for tracking purposes</li>


<li><strong>Conditional logic</strong> – Auto-approve requests from specific applications</li>


<li><strong>Escalation workflows</strong> – Escalate unanswered requests after a timeout</li>

</ul>



<h2 class="wp-block-heading">Conclusion</h2>



<p class="wp-block-paragraph"><strong>EPM automation with Adaptive Cards</strong> transforms the approval experience from a portal-centric task into a seamless Teams-based workflow. Approvers can now handle elevation requests without context-switching, leading to faster response times and improved user satisfaction.</p>



<p class="wp-block-paragraph">The solution is cost-effective (under $10/month), secure (no secrets, managed identity), and easy to deploy (Infrastructure as Code with automated deployment scripts).</p>



<p class="wp-block-paragraph">Ready to implement EPM automation with Adaptive Cards in your environment? Check out the full source code and detailed deployment instructions on <a href="https://github.com/jensdufour/PUB-EPM-Teams-Integration">GitHub</a>!</p>



<h2 class="wp-block-heading">Sources</h2>



<ul class="wp-block-list">

<li><a href="https://learn.microsoft.com/en-us/intune/intune-service/protect/epm-overview">Endpoint Privilege Management overview | Microsoft Learn</a></li>


<li><a href="https://learn.microsoft.com/en-us/azure/logic-apps/">Azure Logic Apps documentation | Microsoft Learn</a></li>


<li><a href="https://learn.microsoft.com/en-us/adaptive-cards/">Adaptive Cards documentation | Microsoft Learn</a></li>


<li><a href="https://learn.microsoft.com/en-us/connectors/teams/?tabs=text1%2Cdotnet">Microsoft Teams Connectors | Microsoft Learn</a></li>


<li><a href="https://learn.microsoft.com/en-us/graph/use-the-api">Microsoft Graph API | Microsoft Learn</a></li>


<li><a href="https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/overview">Azure Managed Identities | Microsoft Learn</a></li>


<li><a href="https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/">Azure Bicep documentation | Microsoft Learn</a></li>

</ul>
<p>The post <a href="https://jensdufour.be/2026/01/01/epm-approval-workflow-adaptive-cards-logic-apps/">EPM Approval Workflow: Adaptive Cards and Logic Apps</a> appeared first on <a href="https://jensdufour.be">Jens Du Four</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://jensdufour.be/2026/01/01/epm-approval-workflow-adaptive-cards-logic-apps/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Page Caching using Disk: Enhanced 
Minified using Disk

Served from: jensdufour.be @ 2026-05-23 01:41:13 by W3 Total Cache
-->