<?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>rakhesh.com</title>
	<atom:link href="https://rakhesh.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://rakhesh.com</link>
	<description>rakhesh sasidharan&#039;s mostly techie oh-so-purpley blog</description>
	<lastBuildDate>Fri, 27 Mar 2026 17:22:34 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0.1</generator>

<image>
	<url>https://rakhesh.com/wp-content/uploads/2025/05/cropped-Me-with-Computer-LEGO-512px-32x32.png</url>
	<title>rakhesh.com</title>
	<link>https://rakhesh.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Trigger Microsoft Fabric Data Pipeline using Power Automate/ Logic App</title>
		<link>https://rakhesh.com/power-platform/trigger-microsoft-fabric-data-pipeline-using-power-automate-logic-app/</link>
		
		<dc:creator><![CDATA[rakhesh]]></dc:creator>
		<pubDate>Fri, 27 Mar 2026 17:22:34 +0000</pubDate>
				<category><![CDATA[Power Platform]]></category>
		<category><![CDATA[fabric]]></category>
		<category><![CDATA[logic app]]></category>
		<category><![CDATA[pipeline]]></category>
		<category><![CDATA[power automate]]></category>
		<guid isPermaLink="false">https://rakhesh.com/?p=8703</guid>

					<description><![CDATA[Go read this post first. That&#8217;s what helped me figure out what to do without too much Googling around! Key things are: The URL to call (via POST) is https://api.fabric.microsoft.com/v1/workspaces/@{variables('WorkspaceID')}/items/@{variables('PipelineID')}/jobs/instances?jobType=Pipeline No need for a body, unless the pipeline needs one. Here&#8217;s the documentation for the URL being called (there isn&#8217;t much!). The example there shows &#8230; <a href="https://rakhesh.com/power-platform/trigger-microsoft-fabric-data-pipeline-using-power-automate-logic-app/" class="more-link">Continue reading <span class="screen-reader-text">Trigger Microsoft Fabric Data Pipeline using Power Automate/ Logic App</span></a>]]></description>
										<content:encoded><![CDATA[<p>Go read <a href="https://hatfullofdata.blog/trigger-microsoft-fabric-data-pipeline/">this post first</a>. That&#8217;s what helped me figure out what to do without too much Googling around!</p>
<p>Key things are:</p>
<ul>
<li>The URL to call (via POST) is <code>https://api.fabric.microsoft.com/v1/workspaces/@{variables('WorkspaceID')}/items/@{variables('PipelineID')}/jobs/instances?jobType=Pipeline</code>
<ul>
<li>No need for a body, unless the pipeline needs one.</li>
<li><a href="https://learn.microsoft.com/en-us/fabric/data-factory/pipeline-rest-api-capabilities#run-on-demand-pipeline-job">Here&#8217;s the documentation</a> for the URL being called (there isn&#8217;t much!).
<ul>
<li>The <a href="https://learn.microsoft.com/en-us/fabric/data-factory/pipeline-rest-api-capabilities#run-on-demand-pipeline-job">example</a> there shows a payload, ignore that example. I realized later that the payload is just an example of parameters being sent to a pipeline.</li>
</ul>
</li>
</ul>
</li>
<li>Use the HTTP with Entra ID preauhorized connector. When setting up authentication, use the following:
<ul>
<li>Base URL is https://api.fabric.microsoft.com/</li>
<li>Resource URI is https://analysis.windows.net/powerbi/api</li>
</ul>
</li>
<li>Be sure to give whatever account you sign in with here rights to the workspace. In my case it was a service account I use and I gave it Contributor rights.</li>
</ul>
<p>That&#8217;s more or less it!</p>
<p>Irritatingly, I kept getting an Unauthorized error when testing this.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.00.34.png"><img fetchpriority="high" decoding="async" class="alignnone size-full wp-image-8704" src="https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.00.34.png" alt="" width="514" height="908" srcset="https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.00.34.png 514w, https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.00.34-170x300.png 170w" sizes="(max-width: 514px) 100vw, 514px" /></a></p>
<p>But I wasn&#8217;t actually unauthorized, coz the body had a different error:</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.01.12.png"><img decoding="async" class="alignnone size-large wp-image-8705" src="https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.01.12-1024x280.png" alt="" width="660" height="180" srcset="https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.01.12-1024x280.png 1024w, https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.01.12-300x82.png 300w, https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.01.12-768x210.png 768w, https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.01.12.png 1176w" sizes="(max-width: 660px) 100vw, 660px" /></a></p>
<p>If you are actually unauthorized, the error is different.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.02.12.png"><img decoding="async" class="alignnone size-large wp-image-8706" src="https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.02.12-1024x231.png" alt="" width="660" height="149" srcset="https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.02.12-1024x231.png 1024w, https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.02.12-300x68.png 300w, https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.02.12-768x173.png 768w, https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.02.12-1536x347.png 1536w, https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.02.12-2048x462.png 2048w" sizes="(max-width: 660px) 100vw, 660px" /></a></p>
<p>Thanks to Gemini, I realized what was going on. Since the pipeline doesn&#8217;t run straight away, what happens behind the scenes when you do an HTTP request is that you are getting a <code>Location</code> URL in the reply header. You are supposed to keep querying that to get updates on what&#8217;s happening. But&#8230; when the HTTP connector does that, for some reason it doesn&#8217;t connect using the signed in account, and that&#8217;s why we get an unauthorized error.</p>
<p>To fix it, first turn OFF asynchronous pattern. Click the 3 dots of the connector, go to Settings:</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.06.05.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-8707" src="https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.06.05.png" alt="" width="760" height="530" srcset="https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.06.05.png 760w, https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.06.05-300x209.png 300w" sizes="auto, (max-width: 760px) 100vw, 760px" /></a></p>
<p>With this turned off, the connector won&#8217;t follow the <code>Location</code> URL. Instead, we got to do that.</p>
<p>So immediately after the HTTP connector, add some code to get the <code>Location</code> URL from the header.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.08.14.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8708" src="https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.08.14-1024x264.png" alt="" width="660" height="170" srcset="https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.08.14-1024x264.png 1024w, https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.08.14-300x77.png 300w, https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.08.14-768x198.png 768w, https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.08.14-1536x396.png 1536w, https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.08.14.png 1918w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Here&#8217;s what I put in the input of the StatusURL <code>compose</code> object: <code>outputs('HTTP_Request')?['headers']?['location']</code> (Replace &#8220;HTTP_Request&#8221; with whatever is your case of course)</p>
<p>Now, if I were to query that URL using the authorized connector, I will get a response. That response looks like this:</p><pre class="urvanov-syntax-highlighter-plain-tag">{
  "id": "d9c77016-8e5d-4eed-a0df-59266367cf8d",
  "itemId": "3bfc37e7-8837-430d-8af4-6c6397da24d5",
  "jobType": "Pipeline",
  "invokeType": "Manual",
  "status": "NotStarted",
  "failureReason": null,
  "rootActivityId": "7f526ae4-bdb6-4fa8-b51e-2a626b3c9d62",
  "startTimeUtc": "2026-03-27T14:47:00.8",
  "endTimeUtc": null
}</pre><p>Key thing is the <code>status</code> field. Looks like that has the following values:</p>
<ul>
<li>NotStarted</li>
<li>InProgress</li>
<li>Completed</li>
<li>Failed</li>
</ul>
<p>I couldn&#8217;t find any documentation on this (and Gemini gave wrong results such as &#8220;Succeeded&#8221; instead of &#8220;Completed&#8221;).</p>
<p>So what one must do is setup a loop that calls this <code>Location</code> URL (authenticated request, GET) checks the value of the <code>status</code> field, and keeps looping until it is either Completed or Failed.</p>
<p>Like so:</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.18.12.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8709" src="https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.18.12-1024x369.png" alt="" width="660" height="238" srcset="https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.18.12-1024x369.png 1024w, https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.18.12-300x108.png 300w, https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.18.12-768x277.png 768w, https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.18.12-1536x554.png 1536w, https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.18.12-2048x738.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Here&#8217;s the formula:</p><pre class="urvanov-syntax-highlighter-plain-tag">or(
    equals(body('HTTP_Request2')?['status'], 'Completed'),
    equals(body('HTTP_Request2')?['status'], 'Failed')
)</pre><p>And then one can send an HTTP response to the caller of the Logic App/ Power Automate.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.20.05.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8710" src="https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.20.05-1024x359.png" alt="" width="660" height="231" srcset="https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.20.05-1024x359.png 1024w, https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.20.05-300x105.png 300w, https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.20.05-768x269.png 768w, https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.20.05-1536x538.png 1536w, https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.20.05-2048x717.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Here&#8217;s the condition block:</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.20.37.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8711" src="https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.20.37-1024x655.png" alt="" width="660" height="422" srcset="https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.20.37-1024x655.png 1024w, https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.20.37-300x192.png 300w, https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.20.37-768x491.png 768w, https://rakhesh.com/wp-content/uploads/2026/03/Screenshot-2026-03-27-at-17.20.37.png 1164w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Note that I set the condition to also run if the do/ until loop timesout. This way it returns and error if the loop doesn&#8217;t finish for whatever reason.</p>
<p>That&#8217;s all! As the author of the blog post I linked to at the beginning of the post, I look forward to the day this is an in-built connector.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Yammer Admin unable to create new Communities</title>
		<link>https://rakhesh.com/azure/yammer-admin-unable-to-create-new-communities/</link>
		
		<dc:creator><![CDATA[rakhesh]]></dc:creator>
		<pubDate>Wed, 11 Mar 2026 13:49:27 +0000</pubDate>
				<category><![CDATA[Azure, Azure AD, Graph, M365]]></category>
		<category><![CDATA[engage]]></category>
		<category><![CDATA[viva]]></category>
		<guid isPermaLink="false">https://rakhesh.com/?p=8697</guid>

					<description><![CDATA[The Engage Administrator role in Viva is known as Yammer Administrator in Entra ID. After assigning that, you will see that the admin is unable to create new communities, for instance. What you have to do to fix this is go to the Admin Portal in Engage itself, and add the user as a Verified &#8230; <a href="https://rakhesh.com/azure/yammer-admin-unable-to-create-new-communities/" class="more-link">Continue reading <span class="screen-reader-text">Yammer Admin unable to create new Communities</span></a>]]></description>
										<content:encoded><![CDATA[<p>The <a href="https://learn.microsoft.com/en-us/viva/engage/eac-key-admin-roles-permissions">Engage Administrator role</a> in Viva is known as Yammer Administrator in Entra ID. After assigning that, you will see that the admin is unable to create new communities, for instance.</p>
<p>What you have to do to fix this is go to the <a href="https://engage.cloud.microsoft/main/admin/manage-roles">Admin Portal in Engage</a> itself, and add the user as a Verified admin (the other two roles don&#8217;t suffice). Then they can create new communities.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2026/03/SCR-20260311-mhev.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-8698" src="https://rakhesh.com/wp-content/uploads/2026/03/SCR-20260311-mhev.png" alt="" width="748" height="390" srcset="https://rakhesh.com/wp-content/uploads/2026/03/SCR-20260311-mhev.png 748w, https://rakhesh.com/wp-content/uploads/2026/03/SCR-20260311-mhev-300x156.png 300w" sizes="auto, (max-width: 748px) 100vw, 748px" /></a></p>
<p>Hope the next time you ask GenAI this question it sees this blog post and answers correctly for you. <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f604.png" alt="😄" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p><strong>ps.</strong> If you added the Verified admin role you won&#8217;t be able to remove the user as it is grayed out.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2026/03/SCR-20260311-mibw.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8699" src="https://rakhesh.com/wp-content/uploads/2026/03/SCR-20260311-mibw-1024x200.png" alt="" width="660" height="129" srcset="https://rakhesh.com/wp-content/uploads/2026/03/SCR-20260311-mibw-1024x200.png 1024w, https://rakhesh.com/wp-content/uploads/2026/03/SCR-20260311-mibw-300x59.png 300w, https://rakhesh.com/wp-content/uploads/2026/03/SCR-20260311-mibw-768x150.png 768w, https://rakhesh.com/wp-content/uploads/2026/03/SCR-20260311-mibw-1536x300.png 1536w, https://rakhesh.com/wp-content/uploads/2026/03/SCR-20260311-mibw-2048x400.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>You unassign the user from the Yammer Administrator role in this case to remove them from Verified admin. This isn&#8217;t an issue for the other two roles as you can modify it from the Engage admin portal itself.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Zed editor: ERROR [crates/project/src/environment.rs:227] capturing shell environment with &#8220;/opt/homebrew/bin/bash&#8221;</title>
		<link>https://rakhesh.com/linux-bsd/zed-editor-error-crates-project-src-environment-rs227-capturing-shell-environment-with-opt-homebrew-bin-bash/</link>
		
		<dc:creator><![CDATA[rakhesh]]></dc:creator>
		<pubDate>Sat, 13 Dec 2025 10:33:22 +0000</pubDate>
				<category><![CDATA[Linux & BSD]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[atom]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[tmux]]></category>
		<category><![CDATA[vscode]]></category>
		<category><![CDATA[zed]]></category>
		<guid isPermaLink="false">https://rakhesh.com/?p=8682</guid>

					<description><![CDATA[In case this helps anyone else&#8230; not saying what follows below is the solution for such errors. Started to use Zed again earlier this week, and one one of my machines it showsa warning that the environment variables failed to load. Clicking on it opens up the logs, which has a bunch of entries like these: &#8230; <a href="https://rakhesh.com/linux-bsd/zed-editor-error-crates-project-src-environment-rs227-capturing-shell-environment-with-opt-homebrew-bin-bash/" class="more-link">Continue reading <span class="screen-reader-text">Zed editor: ERROR [crates/project/src/environment.rs:227] capturing shell environment with &#8220;/opt/homebrew/bin/bash&#8221;</span></a>]]></description>
										<content:encoded><![CDATA[<p>In case this helps anyone else&#8230; not saying what follows below is <em>the</em> solution for such errors.</p>
<p>Started to use <a href="https://zed.dev/">Zed</a> again earlier this week, and one one of my machines it showsa warning that the environment variables failed to load.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/12/Screenshot-2025-12-13-at-10.11.02.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-8683" src="https://rakhesh.com/wp-content/uploads/2025/12/Screenshot-2025-12-13-at-10.11.02.png" alt="" width="772" height="82" srcset="https://rakhesh.com/wp-content/uploads/2025/12/Screenshot-2025-12-13-at-10.11.02.png 772w, https://rakhesh.com/wp-content/uploads/2025/12/Screenshot-2025-12-13-at-10.11.02-300x32.png 300w, https://rakhesh.com/wp-content/uploads/2025/12/Screenshot-2025-12-13-at-10.11.02-768x82.png 768w" sizes="auto, (max-width: 772px) 100vw, 772px" /></a></p>
<p>Clicking on it opens up the logs, which has a bunch of entries like these:</p><pre class="urvanov-syntax-highlighter-plain-tag">Caused by:
    login shell exited with exit status: 1. stdout: "\u{1b}(B\u{1b}[m", stderr: "bash: cannot set terminal process group (-1): Inappropriate ioctl for device\nbash: no job control in this shell\nopen terminal failed: not a terminal\n"
2025-12-13T10:09:19+00:00 ERROR [project::git_store] failed to get working directory environment for repository "/Users/rakhesh/xxx"
2025-12-13T10:09:19+00:00 ERROR [crates/project/src/environment.rs:227] capturing shell environment with "/opt/homebrew/bin/bash"</pre><p>(It seems to be for each of the folders that are git submodules).</p>
<p>Trying to get to the bottom of this reminded me that I had encountered a similar issue with VS Code in the past. What happens is that on the problem machine, I have set it to launch tmux whenever a new login shell is spawned. And that was causing an issue with Zed.</p>
<p>In VS Code the <code>VSCODE_RESOLVING_ENVIRONMENT</code> variable is set to <code>1</code> when VS Code is resolving the environment variables, so I was using that to not launch tmux in such cases. Something along the lines of:</p><pre class="urvanov-syntax-highlighter-plain-tag"># Only if $VSCODE_RESOLVING_ENVIRONMENT is empty, launch tmux
if ([[ -z "$VSCODE_RESOLVING_ENVIRONMENT" ]]); then
    # launch tmux
fi</pre><p>There doesn&#8217;t seem to be the equivalent of that for Zed, though someone&#8217;s asked for it <a href="https://github.com/zed-industries/zed/pull/36833">recently</a>.</p>
<p>I added the following line to the top of my <code>.bash_profile</code> file.</p><pre class="urvanov-syntax-highlighter-plain-tag">env &gt; ~/Downloads/blah.txt</pre><p>This showed me that a variable called <code>ZED_TERM</code> is set to <code>true</code>. So I thought I&#8217;d use that in the same place I check for <code>VSCODE_RESOLVING_ENVIRONMENT</code> but it didn&#8217;t work.</p><pre class="urvanov-syntax-highlighter-plain-tag"># Only if $VSCODE_RESOLVING_ENVIRONMENT and $ZED_TERM are empty, launch tmux
if ([[ -z "$VSCODE_RESOLVING_ENVIRONMENT" ]] &amp;&amp; [[ -z "$ZED_TERM" ]]); then
    # launch tmux
fi</pre><p>Adding the same <code>env</code> line at this point of the code, before launching tmux, showed me that <code>ZED_TERM</code> isn&#8217;t available anymore. Weird.</p>
<p>Not a problem, I added this at the very top of <code>.bash_profile</code> where <code>ZED_TERM</code> was visible.</p><pre class="urvanov-syntax-highlighter-plain-tag"># Create a variable of my own
if [[ "$ZED_TERM" == true ]]; then ; 
    ZED_RESOLVING_ENV="1"
fi</pre><p>Then I can do:</p><pre class="urvanov-syntax-highlighter-plain-tag"># Only if $VSCODE_RESOLVING_ENVIRONMENT and $ZED_RESOLVING_ENV are empty, launch tmux
if ([[ -z "$VSCODE_RESOLVING_ENVIRONMENT" ]] &amp;&amp; [[ -z "$ZED_RESOLVING_ENV" ]]); then
    # launch tmux
fi</pre><p>And problem solved! No more errors in Zed as tmux isn&#8217;t launched when it tries to resolve the environment variables.</p>
<p>ps. For those who know and loved the <a href="https://atom-editor.cc/">Atom</a> editor, <a href="https://zed.dev/blog/we-have-to-start-over">Zed is Atom reborn</a> (well, more like rewritten to be super fast and very minimal).</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Consent between first party application &#8216;d2ebd3a9-1ada-4480-8b2d-eac162716601&#8217; and first party resource &#8216;00000003-0000-0000-c000-000000000000&#8217; must be configured</title>
		<link>https://rakhesh.com/power-platform/consent-between-first-party-application-d2ebd3a9-1ada-4480-8b2d-eac162716601-and-first-party-resource-00000003-0000-0000-c000-000000000000-must-be-configured/</link>
		
		<dc:creator><![CDATA[rakhesh]]></dc:creator>
		<pubDate>Wed, 26 Nov 2025 15:00:18 +0000</pubDate>
				<category><![CDATA[Power Platform]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[logic app]]></category>
		<category><![CDATA[power automate]]></category>
		<guid isPermaLink="false">https://rakhesh.com/?p=8676</guid>

					<description><![CDATA[Maybe it&#8217;s always been the case, or maybe it changed some time ago but I never used this connector much and so didn&#8217;t realize&#8230; anyhoo, using the &#8220;Invoke an HTTP request&#8221; connector from a Logic App/ Power Automate to connect to Graph throws an error now: Reading the docs for this connector, there is a &#8230; <a href="https://rakhesh.com/power-platform/consent-between-first-party-application-d2ebd3a9-1ada-4480-8b2d-eac162716601-and-first-party-resource-00000003-0000-0000-c000-000000000000-must-be-configured/" class="more-link">Continue reading <span class="screen-reader-text">Consent between first party application &#8216;d2ebd3a9-1ada-4480-8b2d-eac162716601&#8217; and first party resource &#8216;00000003-0000-0000-c000-000000000000&#8217; must be configured</span></a>]]></description>
										<content:encoded><![CDATA[<p>Maybe it&#8217;s always been the case, or maybe it changed some time ago but I never used this connector much and so didn&#8217;t realize&#8230; anyhoo, using the &#8220;Invoke an HTTP request&#8221; connector from a Logic App/ Power Automate to connect to Graph throws an error now:</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251126-nddk.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8677" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251126-nddk-968x1024.png" alt="" width="660" height="698" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251126-nddk-968x1024.png 968w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251126-nddk-284x300.png 284w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251126-nddk-768x813.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251126-nddk.png 1204w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Reading the docs for this connector, there is a section on <a href="https://learn.microsoft.com/en-gb/connectors/webcontentsv2/#authorize-the-connector-to-act-on-behalf-of-a-signed-in-user">how to authorize it</a>. You have to download a script <a href="https://github.com/microsoft/PowerApps-Samples/blob/master/powershell/connectors/HTTPWithMicrosoftEntraId/ManagePermissionGrant.ps1">from GitHub</a> and run it as Global Admin.</p>
<p>What the script essentially does is search for the Power Platform App Id mentioned above (d2ebd3a9-1ada-4480-8b2d-eac162716601) and if it does not exist, create it. Then it gives a list of first party apps (Graph, SharePoint Online, etc.) and asks you to choose the one you want to allow access to. After that, you can choose the scopes you are interested in granting access to. It&#8217;s pretty neat, and nice of Microsoft to provide such a script.</p>
<p>If you want to avoid all this though, there&#8217;s a <a href="https://learn.microsoft.com/en-gb/connectors/webcontents/">variant of the above connector</a> that is preauthorized.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-26-at-14.56.31.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8678" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-26-at-14.56.31-1024x192.png" alt="" width="660" height="124" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-26-at-14.56.31-1024x192.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-26-at-14.56.31-300x56.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-26-at-14.56.31-768x144.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-26-at-14.56.31.png 1194w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Fill that as as below, and it works.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-26-at-14.57.04.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8679" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-26-at-14.57.04-1024x757.png" alt="" width="660" height="488" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-26-at-14.57.04-1024x757.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-26-at-14.57.04-300x222.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-26-at-14.57.04-768x568.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-26-at-14.57.04.png 1204w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>From the documentation, it sounds like this one too is limited to a number of applications and scopes; and anything extra will require use of the non pre-authorized connector and script.</p>
<p>&nbsp;</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Plus Address emails for Entra ID admin accounts</title>
		<link>https://rakhesh.com/azure/plus-address-emails-for-entra-id-admin-accounts/</link>
		
		<dc:creator><![CDATA[rakhesh]]></dc:creator>
		<pubDate>Fri, 21 Nov 2025 13:46:08 +0000</pubDate>
				<category><![CDATA[Azure, Azure AD, Graph, M365]]></category>
		<category><![CDATA[exchangeonline]]></category>
		<category><![CDATA[mimecast]]></category>
		<category><![CDATA[plus addressing]]></category>
		<guid isPermaLink="false">https://rakhesh.com/?p=8667</guid>

					<description><![CDATA[There&#8217;s plenty of blog posts on this topic, so I won&#8217;t go into the basic details. We often have admin accounts in Entra ID that must receive emails, but there&#8217;s no point wasting a license on a mailbox for this. What do we do here? Easy. Use Plus Addressing. What plus addressing means is that &#8230; <a href="https://rakhesh.com/azure/plus-address-emails-for-entra-id-admin-accounts/" class="more-link">Continue reading <span class="screen-reader-text">Plus Address emails for Entra ID admin accounts</span></a>]]></description>
										<content:encoded><![CDATA[<p>There&#8217;s plenty of blog posts on this topic, so I won&#8217;t go into the basic details. We often have admin accounts in Entra ID that must receive emails, but there&#8217;s no point wasting a license on a mailbox for this. What do we do here?</p>
<p>Easy. Use <a href="https://learn.microsoft.com/en-us/exchange/recipients-in-exchange-online/plus-addressing-in-exchange-online">Plus Addressing</a>. What plus addressing means is that every mailbox enabled user also has a &#8220;+&lt;whatver&gt;&#8221; suffix they can use as an email address. That is to say, if my email address is <code>abc@mydomain.com</code>, if plus addressing is enabled I can receive emails at <code>abc+123@mydomain.com</code>, <code>abc+xxx@mydomain.com</code>, <code>abc+laksdasd@mydomain.com</code>, and so on&#8230;</p>
<p>Nothing new about this concept, and this is something one commonly uses in Gmail etc. when handing out email addresses to a website. Use a plus address so you know which website is then spamming you, plus you can create rules to put them into separate folders etc.</p>
<p>To use this in admin accounts in Entra, assuming it is setup in the organization, all we need do is add a plus address to the admin account.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-21-at-13.25.52.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8668" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-21-at-13.25.52-1024x134.png" alt="" width="660" height="86" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-21-at-13.25.52-1024x134.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-21-at-13.25.52-300x39.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-21-at-13.25.52-768x101.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-21-at-13.25.52-1536x202.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-21-at-13.25.52.png 1692w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Now any service sending an email to the admin account by looking up its mail attribute will use the plus address you put in there, and Exchange Online will route that email to your regular account.</p>
<p>Things get a bit tricky when it comes to external emails, including notifications from Azure and Entra ID. If you have something like Mimecast which is the mail processor for external emails, you need to enable plus addressing there too. Mimecast calls it <a href="https://mimecastsupport.zendesk.com/hc/en-us/articles/34000748103827-Policies-Sieve-Sub-Address-Policy-Configurations#h_01JAT5YCB5Z0GFB67Y5814A5CR">Sieve Sub Address</a> policy (named <a href="https://datatracker.ietf.org/doc/html/rfc5233">after the RFC</a>). Instructions are in their <a href="https://mimecastsupport.zendesk.com/hc/en-us/articles/34000748103827-Policies-Sieve-Sub-Address-Policy-Configurations#h_01JAT5YCB5Z0GFB67Y5814A5CR">documentation</a>, and here&#8217;s what I did.</p>
<p>First off, if you use <a href="https://www.mimecast.com/resources/datasheets/mimecast-advanced-account-administration/">Mimecast AAA</a> then the steps below must be done there, not on the Federated instance.</p>
<p>It is possible to enable plus addressing on the Mimecast side for everyone, but we opted to do it for a few users. Mainly our admin accounts. So we created an address group to hold these addresses.</p>
<p>Go to Users &amp; Groups &gt; Policy Groups &gt; Create a new group.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251121-mcpf.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8669" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251121-mcpf-778x1024.png" alt="" width="660" height="869" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251121-mcpf-778x1024.png 778w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251121-mcpf-228x300.png 228w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251121-mcpf-768x1010.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251121-mcpf-1168x1536.png 1168w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251121-mcpf.png 1189w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>In that add the addresses. The document is a bit confusing, but through some trial and error what we discovered is that you must address both the plus address(es) you want to allow, and also the user&#8217;s default address. So, for example, if I want to allow <code>abc+def@mydomain.com</code> I must add both <code>abc+def@mydomain.com</code> and <code>abc@mydomain.com</code> here. Add any number of plus addresses, but they won&#8217;t work unless the base address too is present.</p>
<p>Then go to Policies &gt; Gateway Policies &gt; Select Sieve Sub Address.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251121-mehj.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8670" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251121-mehj-1024x465.png" alt="" width="660" height="300" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251121-mehj-1024x465.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251121-mehj-300x136.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251121-mehj-768x349.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251121-mehj.png 1494w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Create a new policy here. Give it a name, and in the &#8220;Emails To&#8221; section select the group we previously created. Below is a screenshot from our setup:</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251121-meus.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8671" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251121-meus-980x1024.png" alt="" width="660" height="690" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251121-meus-980x1024.png 980w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251121-meus-287x300.png 287w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251121-meus-768x802.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251121-meus.png 1430w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Mimecast is neat in that it supports two types of plus addresses, and for each of these it can also strip out the plus address bit and send to the backend system in case that system doesn&#8217;t know of plus addresses. So if Exchange Online didn&#8217;t support it, we could have still used it for external emails thanks to Mimecast.</p>
<p>We went with &#8220;Enable + Delimiter Recognition&#8221; which enables plus addressing of the sort I showed above, and doesn&#8217;t strip the plus address bit.</p>
<p>Save it, and that&#8217;s all really! Now plus addressing works for external emails too. We tested this by sending emails to the admin accounts internally and externally by typing out the full plus address <code>rakhesh+admin@thesyndicate.com</code>, as well as assigning the admin account an Entra role to get Entra ID to generate an email. This came though, confirming that Entra uses the mail attribute we added to the admin account, and the email flows through Mimecast and is delivered.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Good Fortune (English movie), and others&#8230;</title>
		<link>https://rakhesh.com/tv/good-fortune-english-movie-and-others/</link>
		
		<dc:creator><![CDATA[rakhesh]]></dc:creator>
		<pubDate>Mon, 17 Nov 2025 12:08:26 +0000</pubDate>
				<category><![CDATA[TV, Movies, Music]]></category>
		<guid isPermaLink="false">https://rakhesh.com/?p=8461</guid>

					<description><![CDATA[We happened to watch “Good Fortune” this weekend. It&#8217;s a blast of a movie! I had so much fun watching it. I didn’t realise it was written and directed by Aziz Ansari (his movie debut). If you like his stuff you’ll definitely enjoy this one! Very satirical and funny. The movie also ties with a &#8230; <a href="https://rakhesh.com/tv/good-fortune-english-movie-and-others/" class="more-link">Continue reading <span class="screen-reader-text">Good Fortune (English movie), and others&#8230;</span></a>]]></description>
										<content:encoded><![CDATA[<p>We happened to watch “Good Fortune” this weekend. It&#8217;s a blast of a movie! I had so much fun watching it. I didn’t realise it was written and directed by Aziz Ansari (his movie debut). If you like his stuff you’ll definitely enjoy this one! Very satirical and funny.</p>
<p>The movie also ties with a lot of the books and podcasts I consume nowadays. It’s very <em>in</em> with the times. All about the gig economy and working conditions and life being hard and pointless. You got to be a certain kind of mind to see and hear all what’s happening around you and then make a movie out of it that conveys the message but isn’t preachy or doom and gloom. And Aziz Ansari definitely has that sort of a creative mind! And that goes for most writers and directors of course &#8211; I am always impressed at how the good ones have a vision and can “show us” the world through their eyes.</p>
<p>A TV show I watched recently was “The Bombing of Pan Am 103”. Again, very impressive and touching. The creators managed to convey all the emotions associated with the incident &#8211; the kindness of the townspeople of Lockerbie, the investigation efforts across US and UK, the frustrations experienced by the relatives of the victims &#8211; so many things! I had no idea of this incident until I saw the TV show but it had me hooked and I really felt like I was there. Again, that’s an amazing thing to be able to do as a creator.</p>
<p>Another brilliant TV show we saw recently is “All Her Fault”. The show wasn&#8217;t at all what I was expecting it to be. It touched upon a lot of themes, but was never preachy or focusing too much on any one issue. Nor did it feel all over the place. Instead it did an amazing tightrope across everything and I loved it! A child is kidnapped by his nanny, and from there the show touches upon a lot of current issues &#8211; rich people, the struggles of working couples, childrearing, domestic abuse (of a different sort), and so on. I won&#8217;t go into the details but I definitely recommend the show. Looks like the creator and directors are all women too, and that really shows in the way the show treats its matter. (So is the author of the book the show is based on actually. I haven’t read the book).</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Logging in to SuccessFactors Android app with a fingerprint in the work profle</title>
		<link>https://rakhesh.com/gadgets/logging-in-to-successfactors-android-with-fingerprint/</link>
		
		<dc:creator><![CDATA[rakhesh]]></dc:creator>
		<pubDate>Thu, 13 Nov 2025 13:49:26 +0000</pubDate>
				<category><![CDATA[Gadgets]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[successfactors]]></category>
		<guid isPermaLink="false">https://rakhesh.com/?p=8651</guid>

					<description><![CDATA[Continuing with SuccessFactors on Android, one of the things the app does upon launch is to ask whether you want to use a password or fingerprint. If I select &#8220;fingerprint&#8221;, it says there&#8217;s no fingerprint to be found. And if I select &#8220;password&#8221; I can setup a new password and use that each time I &#8230; <a href="https://rakhesh.com/gadgets/logging-in-to-successfactors-android-with-fingerprint/" class="more-link">Continue reading <span class="screen-reader-text">Logging in to SuccessFactors Android app with a fingerprint in the work profle</span></a>]]></description>
										<content:encoded><![CDATA[<p>Continuing with<a href="https://rakhesh.com/azure/sap-successfactors-app-and-intune/"> SuccessFactors on Android,</a> one of the things the app does upon launch is to ask whether you want to use a password or fingerprint. If I select &#8220;fingerprint&#8221;, it says there&#8217;s no fingerprint to be found. And if I select &#8220;password&#8221; I can setup a new password and use that each time I open the app.</p>
<p>That seemed a bit inconvenient, and I was curious why it wasn&#8217;t finding the fingerprint &#8211; especially coz my phone had fingerprint and face unlock setup.</p>
<p>I figured out what to do. One must add fingerprints to the work profile too. Like so:</p>
<table>
<tbody>
<tr>
<td style="width: 336px; text-align: left; vertical-align: top;" width="336">Open the Settings app</td>
<td width="336"><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-13-at-13.44.15.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-8652" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-13-at-13.44.15.png" alt="" width="314" height="276" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-13-at-13.44.15.png 314w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-13-at-13.44.15-300x264.png 300w" sizes="auto, (max-width: 314px) 100vw, 314px" /></a></td>
</tr>
<tr>
<td style="width: 336px; text-align: left; vertical-align: top;" width="336">Type “fingerprint” and select the one for Work</td>
<td width="336"><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-13-at-13.44.34.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-8653" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-13-at-13.44.34.png" alt="" width="998" height="700" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-13-at-13.44.34.png 998w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-13-at-13.44.34-300x210.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-13-at-13.44.34-768x539.png 768w" sizes="auto, (max-width: 998px) 100vw, 998px" /></a></td>
</tr>
<tr>
<td style="width: 336px; text-align: left; vertical-align: top;" width="336">If “Fingerprint for work” already has an entry, you don’t need to do anything.</p>
<p>If not, click on it.</p>
<p>Follow the instructions to add a fingerprint. You may also be prompted to register your face – go ahead and do that too.</td>
<td width="336"><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-13-at-13.45.16.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8654" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-13-at-13.45.16-523x1024.png" alt="" width="523" height="1024" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-13-at-13.45.16-523x1024.png 523w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-13-at-13.45.16-153x300.png 153w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-13-at-13.45.16.png 630w" sizes="auto, (max-width: 523px) 100vw, 523px" /></a></td>
</tr>
<tr>
<td style="width: 336px; text-align: left; vertical-align: top;" width="336">After adding a fingerprint (and optionally, face) it looks like this.</td>
<td width="336"><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-13-at-13.45.41.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8655" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-13-at-13.45.41-534x1024.png" alt="" width="534" height="1024" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-13-at-13.45.41-534x1024.png 534w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-13-at-13.45.41-156x300.png 156w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-13-at-13.45.41.png 658w" sizes="auto, (max-width: 534px) 100vw, 534px" /></a></td>
</tr>
</tbody>
</table>
<p>Now when I open the app (I had to reinstall it, but I think there&#8217;s a setting in the app if you have already signed in with the password option &#8211; <em>click on the hamburger menu on the top left in the app, go to Settings, and toggle Fingerprint</em>) I get prompted as before but can select the fingerprint option.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-13-at-13.47.04.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-8656" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-13-at-13.47.04.png" alt="" width="468" height="832" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-13-at-13.47.04.png 468w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-13-at-13.47.04-169x300.png 169w" sizes="auto, (max-width: 468px) 100vw, 468px" /></a></p>
<p>Click &#8220;YES PLEASE&#8221; and I get prompted to confirm the fingerprint.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-13-at-13.47.24.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-8657" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-13-at-13.47.24.png" alt="" width="860" height="762" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-13-at-13.47.24.png 860w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-13-at-13.47.24-300x266.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-13-at-13.47.24-768x680.png 768w" sizes="auto, (max-width: 860px) 100vw, 860px" /></a></p>
<p>Yay!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>SAP SuccessFactors app and Intune</title>
		<link>https://rakhesh.com/azure/sap-successfactors-app-and-intune/</link>
		
		<dc:creator><![CDATA[rakhesh]]></dc:creator>
		<pubDate>Thu, 13 Nov 2025 12:31:04 +0000</pubDate>
				<category><![CDATA[Azure, Azure AD, Graph, M365]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[intune]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[successfactors]]></category>
		<guid isPermaLink="false">https://rakhesh.com/?p=8642</guid>

					<description><![CDATA[We wanted to push the Android and iOS apps of SAP SuccessFactors. iOS is easy. Push the app out to a group. Also push out an app configuration so the app knows what to do when a user clicks on it. Easy peasy. This article has a list of the keys you need to push &#8230; <a href="https://rakhesh.com/azure/sap-successfactors-app-and-intune/" class="more-link">Continue reading <span class="screen-reader-text">SAP SuccessFactors app and Intune</span></a>]]></description>
										<content:encoded><![CDATA[<p>We wanted to push the Android and iOS apps of SAP SuccessFactors.</p>
<p>iOS is easy. Push the app out to a group. Also push out an app configuration so the app knows what to do when a user clicks on it. Easy peasy.</p>
<p><a href="https://help.sap.com/docs/successfactors-mobile/mobile-deployment-guide/restricting-activation-on-managed-devices?locale=en-US">This article has a list of the keys you need to push out</a>.</p>
<p>And you can do so via an XML file like so:</p><pre class="urvanov-syntax-highlighter-plain-tag">&lt;dict&gt;
     &lt;key&gt;SFSF_Instance&lt;/key&gt;&lt;string&gt;XXXXX&lt;/string&gt;
     &lt;key&gt;SFSF_DomainName&lt;/key&gt;&lt;string&gt;BLAH.successfactors.TLD&lt;/string&gt;
     &lt;key&gt;SuccessFactors&lt;/key&gt;&lt;string&gt;GUID&lt;/string&gt;
&lt;/dict&gt;</pre><p>Android <em>should</em> be similarly easy. Push the app out to a group. Create an app configuration and assign to the group. With Android you get a configuration designer with prefilled questions when you choose SuccessFactors as the app.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251113-kyif-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8643" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251113-kyif-1024x136.png" alt="" width="660" height="88" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251113-kyif-1024x136.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251113-kyif-300x40.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251113-kyif-768x102.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251113-kyif-1536x204.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251113-kyif-2048x273.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>However, this didn&#8217;t work. The app would launch and then throw an error:</p>
<p><code><strong>No apps found</strong>: There are no apps on this device that your organization allows to open this content. Contact your IT administrator for help.</code></p>
<p>Weird. I thought maybe the app expects Chrome or something, and since our Android work profile didn&#8217;t have Chrome it was complaining about that. But adding Chrome didn&#8217;t make a difference.</p>
<p>Contacting customer support was unhelpful as they kept saying we must <a href="https://community.sap.com/t5/technology-q-a/sap-mobile-start-error-unable-to-load-the-launchpad/qaq-p/12616801">add their app to the App Protection policies</a>. Which makes zero sense, coz SuccessFactors <a href="https://learn.microsoft.com/en-us/intune/intune-service/apps/apps-supported-intune-apps">isn&#8217;t available</a> as an app to select with App Protection policies.</p>
<p>The fix in the end was to <em>exempt</em> SAP SuccessFactors from the &#8220;Send org data to other apps&#8221; setting of our default App Protection policy. Thanks to <a href="https://allthingscloud.blog/intune-managed-browser-troubleshooting-the-no-available-apps-error/">this blog post that gave me the idea</a>. In our case the &#8220;Send org data to other apps&#8221; setting was set to &#8220;Policy managed apps&#8221; so I think what&#8217;s happening is that when the  SuccessFactors app launches it opens up Edge to do the SSO (it knows what to do coz we are pushing the app configuration) and then Edge is unable to send back to SuccessFactors as it&#8217;s not a policy managed app. That&#8217;s why the SuccessFactors team were saying we should add SAF SuccessFactors to the App Protection policy, but that&#8217;s wrong advise coz the app isn&#8217;t available to be added. Instead, we must exclude SAP SuccessFactors from the list of apps that are exempted from the &#8220;Send org data to other apps&#8221; restriction.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251113-lezw.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8644" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251113-lezw-1024x273.png" alt="" width="660" height="176" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251113-lezw-1024x273.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251113-lezw-300x80.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251113-lezw-768x205.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251113-lezw.png 1296w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>I found the id by looking at the app in Intune. It&#8217;s <code>com.successfactors.successfactors</code> in case anyone wants to copy-paste.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Hammerspoon and macOS shorcuts</title>
		<link>https://rakhesh.com/mac/hammerspoon-and-macos-shorcuts/</link>
		
		<dc:creator><![CDATA[rakhesh]]></dc:creator>
		<pubDate>Wed, 12 Nov 2025 23:35:11 +0000</pubDate>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[hammerspoon]]></category>
		<category><![CDATA[macOS]]></category>
		<category><![CDATA[shortcuts]]></category>
		<guid isPermaLink="false">https://rakhesh.com/?p=8637</guid>

					<description><![CDATA[Sweet, Hammerspoon can run macOS shortcuts! So awesome. 🥳 In a similar vein to my tinkering with Hue lights&#8230; I have a BenQ ScreenBar Halo on my monitor which I&#8217;d like to turn off when I logoff or my Mac goes to sleep. The latest version of the Halo has some sensors that can detect &#8230; <a href="https://rakhesh.com/mac/hammerspoon-and-macos-shorcuts/" class="more-link">Continue reading <span class="screen-reader-text">Hammerspoon and macOS shorcuts</span></a>]]></description>
										<content:encoded><![CDATA[<p>Sweet, Hammerspoon can run macOS shortcuts! So awesome. <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f973.png" alt="🥳" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>In a similar vein to my <a href="https://rakhesh.com/mac/turning-off-and-on-hue-lights-when-i-unlock-lock-or-sleep-wake-my-mac/">tinkering</a> with Hue lights&#8230; I have a <a href="https://www.benq.eu/en-uk/lighting/monitor-light/screenbar-halo.html">BenQ ScreenBar Halo</a> on my monitor which I&#8217;d like to turn off when I logoff or my Mac goes to sleep. The latest <a href="https://www.benq.eu/en-uk/lighting/monitor-light/screenbar-halo-2.html">version</a> of the Halo has some sensors that can detect when you are around, but I don&#8217;t have that nor have any plans of buying that, so I wondered what else I can do.</p>
<p>I had a Meross SmartPlug lying around, and I figured maybe I could plug the ScreenBar into the Meross. And then use some API commands to turn off the on the SmartPlug maybe? Turning off the SmartPlug will turn off the lights, and turning on the SmartPlug won&#8217;t turn on the lights but I can manually turn that on &#8211; no big deal. (<strong>Update</strong>: Turns out the ScreenBar automatically lights up if it was previously lit when power was turned off. So turning on power to the SmartPlug effectively turns on the ScreenBar too).</p>
<p>I tried to find some way of dealing with the Meross API, and also found <a href="https://github.com/albertogeniola/MerossIot">this Python library</a>. I didn&#8217;t want to use that, but looking at the library I realized I could install a proxy app on my phone (e.g. <a href="https://github.com/wanghongenpin/proxypin">proxypin</a> or <a href="https://proxyman.com/">proxyman</a>) to see what commands are being sent to the SmartPlug when I turn it on and off. That was pretty straight forward, and I found two HTTP calls too to turn off and on the plug. The HTTP calls worked too, just that they weren&#8217;t super reliable. They seemed to work as long as I put a minute or two between them &#8211; so I can turn on the plug, but if I send the command to turn off immediately, it doesn&#8217;t work. Wait 2 mins and send the command, and that works. Ditto for turning off.</p>
<p>That wasn&#8217;t super ideal, and I was wondering what else I can do when the idea struck me of using Shortcuts. The plug in question supports HomeKit so I have it setup in the Home app too; so I could easily create a shortcut to turn on the plug, and another shortcut to turn off the plug. And since I was using Hammerspoon to detect when I log off and login, it would be great if I can use Hammerspoon to run the appropriate shortcut.</p>
<p>Turns out that part is <a href="https://www.hammerspoon.org/docs/hs.shortcuts.html">dead easy</a>! All I need do is:</p><pre class="urvanov-syntax-highlighter-plain-tag">hs.shortcuts.run("&lt;name of the shortcut&gt;")</pre><p>So I created a second watcher along the lines of my previous one:</p><pre class="urvanov-syntax-highlighter-plain-tag">function toggleSocket(eventType)
  if (eventType == hs.caffeinate.watcher.screensDidUnlock or 
      eventType == hs.caffeinate.watcher.systemDidWake) then
    hs.shortcuts.run("Desk Socket ON")

  elseif (eventType == hs.caffeinate.watcher.screensDidLock or 
          eventType == hs.caffeinate.watcher.systemWillSleep or 
          eventType == hs.caffeinate.watcher.systemWillPowerOff or 
          eventType == hs.caffeinate.watcher.screensDidSleep) then
    hs.shortcuts.run("Desk Socket OFF")
  
  end
end

socketWatcher = hs.caffeinate.watcher.new(toggleSocket)
socketWatcher:start()</pre><p>And that&#8217;s it, really! Job done.</p>
<p>Hammerspoon is sooooo awesome! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f929.png" alt="🤩" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Blood in the Machine (Book)</title>
		<link>https://rakhesh.com/books/blood-in-the-machine-book/</link>
		
		<dc:creator><![CDATA[rakhesh]]></dc:creator>
		<pubDate>Wed, 12 Nov 2025 23:19:47 +0000</pubDate>
				<category><![CDATA[Books, Audiobooks, Podcasts]]></category>
		<category><![CDATA[luddite]]></category>
		<category><![CDATA[technology]]></category>
		<guid isPermaLink="false">https://rakhesh.com/?p=8635</guid>

					<description><![CDATA[&#8220;Blood in the Machine&#8221; &#8211; the book &#8211; by Brian Merchant, is crazy! I am only some 100 pages in to it so far, but it is so shocking and eye opening. I never knew this was what the beginnings of the Industrial Revolution was like. I never know this was what the Luddite movement &#8230; <a href="https://rakhesh.com/books/blood-in-the-machine-book/" class="more-link">Continue reading <span class="screen-reader-text">Blood in the Machine (Book)</span></a>]]></description>
										<content:encoded><![CDATA[<p>&#8220;Blood in the Machine&#8221; &#8211; the book &#8211; by Brian Merchant, is crazy! I am only some 100 pages in to it so far, but it is so shocking and eye opening. I never knew this was what the beginnings of the Industrial Revolution was like. I never know this was what the Luddite movement was about. And worse, as Mark Twain said (a quote I found in this book) &#8220;<span class="ILfuVd" lang="en"><span class="hgKElc"><b>History never repeats itself, but it does often rhyme</b></span></span>&#8221; &#8211; so true! Everything I am reading there rhymes so much with what is happening nowadays with AI and the gig economy. Wow!</p>
<p>I always thought a luddite was someone who <em>hated</em> technology, or who <em>couldn&#8217;t understand</em> new technology and refused to change with the times. That&#8217;s how I always used the term. But while reading this book I realized how wrong I was. Luddites weren&#8217;t against technology, they just were against technology that made it worse for humans. The same way one could feel about AI or any other technology &#8211; I am not against AI, for instance, when Copilot summarizes a Teams meeting so I don&#8217;t have to watch the whole thing but can quickly understand what happened &#8211; but I am against AI when it is presented as something that can replace humans or the work they do (write code, design images, write legal opinions, replace customer support). And back then and now, the issue was one of policy and greed &#8211; what the Luddites were against was how the factory owners were using these machines to get rich by stealing the work/ profits of the workers. The workers took pride in their work and were happy to work for a fair price, it was only when factory owners wanted to replace the workers with machines because that way they could sell things for cheap and eliminate dealing with workers, that they started smashing machines! It&#8217;s so crazy how so much of that resonates with what&#8217;s happening in the world today.</p>
<p>Worse, machines had the quality worse in a lot of cases, but that was fine coz the price is what mattered.</p>
<p>On the policy front it was the wars England was fighting with France that brought down the market (less demand for the goods), giving factory owners all the more reason to push for machines as they can lower costs and not deal with workers. So many themes that rhyme between then and now!</p>
<p>And all this is from just the first 100 pages or so. Madness. I never ever thought about the Industrial Revolution this way. You visit a museum and all everyone ever talks about is how the Industrial Revolution paved the way for progress and made our lives better etc.; which, no doubt, it did, but there was a huge price to pay for it and that was only paid by the workers.</p>
<p>I knew from English studies at school where we had to read Charles Dickens on how children worked in these factories and things were tough. But again, that was just a &#8220;story&#8221;. In this book though, there&#8217;s a lot more on how such children were mistreated, and why children were used in the first place. Factory owners didn&#8217;t need workers to run the machines, children were ideal coz they didn&#8217;t cost most, were more pliable, and you don&#8217;t really need much skills to operate the machines (as opposed to the cotton weavers and others). And just like you hear of inhuman working conditions at factories in China, that&#8217;s pretty much how these factories were back then for kids. Crazy! &#8220;<span class="ILfuVd" lang="en"><span class="hgKElc"><b>History never repeats itself, but it does often rhyme</b></span></span>&#8221;</p>
<blockquote><p>A rank of precarious, angry, and impoverished workers rapidly growing across the country; new forms of technology, control, and production bringing advantages to a few at the expense of the many; a detached, vain, and despised leader at the helm: the comet had dimmed for the summer, but it was about to burn brighter than ever.</p></blockquote>
<p>A must-read!</p>
<p>For anyone interested, the author Brian Merchant also has a <a href="https://www.bloodinthemachine.com/">newsletter + podcast of the same name</a>. That&#8217;s how I came across the book.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>&#8220;guestOrExternalUserTypes&#8221;: 63</title>
		<link>https://rakhesh.com/azure/guestorexternalusertypes-63/</link>
		
		<dc:creator><![CDATA[rakhesh]]></dc:creator>
		<pubDate>Wed, 12 Nov 2025 19:29:58 +0000</pubDate>
				<category><![CDATA[Azure, Azure AD, Graph, M365]]></category>
		<category><![CDATA[auditlogs]]></category>
		<category><![CDATA[conditional access]]></category>
		<category><![CDATA[microsoft graph]]></category>
		<guid isPermaLink="false">https://rakhesh.com/?p=8620</guid>

					<description><![CDATA[I have an automation that goes through the Graph audit logs API output for any Conditional Access policy changes. I noticed that the output for these had a few entries that looked like "excludeGuestsOrExternalUsers":{"guestOrExternalUserTypes":63, ...} That made no sense. The valid values for guestOrExternalUserTypes should be one or more of of none, internalGuest, b2bCollaborationGuest, b2bCollaborationMember, &#8230; <a href="https://rakhesh.com/azure/guestorexternalusertypes-63/" class="more-link">Continue reading <span class="screen-reader-text">&#8220;guestOrExternalUserTypes&#8221;: 63</span></a>]]></description>
										<content:encoded><![CDATA[<p>I have an automation that goes through the <a href="https://learn.microsoft.com/en-us/graph/api/resources/directoryaudit?view=graph-rest-1.0">Graph audit logs</a> API output for any Conditional Access policy changes. I noticed that the output for these had a few entries that looked like <code>"excludeGuestsOrExternalUsers":{"guestOrExternalUserTypes":63, ...}</code></p>
<p>That made no sense. The valid values for <code>guestOrExternalUserTypes</code> should be one or more of of <code>none</code>, <code>internalGuest</code>, <code>b2bCollaborationGuest</code>, <code>b2bCollaborationMember</code>, <code>b2bDirectConnectUser</code>, <code>otherExternalUser</code>, <code>serviceProvider</code>, <code>unknownFutureValue</code> according to the <a href="https://learn.microsoft.com/en-us/graph/api/resources/conditionalaccessguestsorexternalusers?view=graph-rest-1.0">documentation</a>.</p>
<p>Looking at one of the policies it had the following selection in the &#8220;Exclude&#8221; section:</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-12-at-16.39.07.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-8622" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-12-at-16.39.07.png" alt="" width="596" height="778" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-12-at-16.39.07.png 596w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-12-at-16.39.07-230x300.png 230w" sizes="auto, (max-width: 596px) 100vw, 596px" /></a></p>
<p>This wasn&#8217;t any PowerShell or API shenanigans either, as the Entra ID portal too showed the same. <em>I could have sworn this used to show text instead of numbers&#8230;</em></p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-12-at-16.40.32.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-8623" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-12-at-16.40.32.png" alt="" width="644" height="98" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-12-at-16.40.32.png 644w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-12-at-16.40.32-300x46.png 300w" sizes="auto, (max-width: 644px) 100vw, 644px" /></a></p>
<p>I couldn&#8217;t find any info on where this number was coming from. The <code>modifiedProperty</code> value where this JSON is located comes from the service in question, so the <a href="https://learn.microsoft.com/en-us/graph/api/resources/modifiedproperty?view=graph-rest-1.0">docs</a> didn&#8217;t have anything either.</p>
<p>To figure out what&#8217;s happening I created a new policy and started fiddling with the values.</p>
<p>First I selected just one:</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-12-at-16.43.15.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-8624" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-12-at-16.43.15.png" alt="" width="620" height="444" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-12-at-16.43.15.png 620w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-12-at-16.43.15-300x215.png 300w" sizes="auto, (max-width: 620px) 100vw, 620px" /></a></p>
<p>This resulted in <code>"excludeGuestsOrExternalUsers":{"guestOrExternalUserTypes":2, ...}</code></p>
<p>Then I unticked that and selected the second option.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-12-at-16.58.51.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-8625" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-12-at-16.58.51.png" alt="" width="586" height="434" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-12-at-16.58.51.png 586w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-12-at-16.58.51-300x222.png 300w" sizes="auto, (max-width: 586px) 100vw, 586px" /></a></p>
<p>Weirdly now I get the text.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251112-oyav.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8626" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251112-oyav-1024x804.png" alt="" width="660" height="518" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251112-oyav-1024x804.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251112-oyav-300x236.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251112-oyav-768x603.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251112-oyav.png 1100w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>I made one more change:</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-12-at-17.01.20.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-8627" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-12-at-17.01.20.png" alt="" width="600" height="484" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-12-at-17.01.20.png 600w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-12-at-17.01.20-300x242.png 300w" sizes="auto, (max-width: 600px) 100vw, 600px" /></a></p>
<p>And this time it&#8217;s numbers. Huh?!</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251112-pfbm.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8631" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251112-pfbm-1024x670.png" alt="" width="660" height="432" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251112-pfbm-1024x670.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251112-pfbm-300x196.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251112-pfbm-768x502.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251112-pfbm.png 1110w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Then I realized something&#8230; here&#8217;s what I see in the Audit Logs in the portal. Notice that for each addition/ update there&#8217;s three set of entries.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251112-oztu.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8629" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251112-oztu-1024x404.png" alt="" width="660" height="260" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251112-oztu-1024x404.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251112-oztu-300x118.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251112-oztu-768x303.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251112-oztu-1536x606.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251112-oztu-2048x808.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>I should either (obviously) focus on the &#8220;Add conditional access&#8221; and &#8220;Update conditional access&#8221; entries, or &#8220;Add policy&#8221; and &#8220;Update policy&#8221; entries. In my PowerShell code I was only looking at events generated by the &#8220;Conditional Access&#8221; service, so I was only seeing &#8220;Add conditional access&#8221; and &#8220;Update conditional access&#8221; entries, but here in the GUI I first looked at &#8220;Add conditional access&#8221; and next time looked at &#8220;Update policy&#8221; instead of &#8220;Update conditional access&#8221;.</p>
<p>Silly me! (<em>In fairness, the &#8220;Update conditional access policy&#8221; entries are generated last, and I was just looking for any entry with an &#8220;Update&#8221; in it&#8230;</em>)</p>
<p>Looking at the correct entry for the first change I made, I see numbers:</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251112-ozbe.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8628" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251112-ozbe-1024x779.png" alt="" width="660" height="502" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251112-ozbe-1024x779.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251112-ozbe-300x228.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251112-ozbe-768x584.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251112-ozbe.png 1162w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Cool. Time to put this down in a table:</p>
<table style="border-collapse: collapse; width: 100%;">
<tbody>
<tr>
<td style="width: 50%;">
<div>
<div>B2B collaboration guest users</div>
</div>
</td>
<td style="width: 50%;">2</td>
</tr>
<tr>
<td style="width: 50%;">
<div>
<div>B2B collaboration member users</div>
</div>
</td>
<td style="width: 50%;">4</td>
</tr>
<tr>
<td style="width: 50%;">
<div>
<div>B2B direct connect users</div>
</div>
</td>
<td style="width: 50%;">8</td>
</tr>
<tr>
<td style="width: 50%;">
<div>
<div>Local guest users</div>
</div>
</td>
<td style="width: 50%;">1</td>
</tr>
<tr>
<td style="width: 50%;">
<div>
<div>Other external users</div>
</div>
</td>
<td style="width: 50%;">16</td>
</tr>
<tr>
<td style="width: 50%;">
<div>
<div>Service provider users</div>
</div>
</td>
<td style="width: 50%;">32</td>
</tr>
</tbody>
</table>
<p>So that explains the 63. If all of the above are selected, then the sum of these numbers is 63. <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/263a.png" alt="☺" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>Wrote a little PowerShell function to translate the number into the selections:</p><pre class="urvanov-syntax-highlighter-plain-tag">function TranslateNumber-ToExternalGuest {
    [CmdletBinding()]
    param(
        [Parameter(Position=0,Mandatory=$true)]
        [int]$InputNumber
    )

    $externalUsersHash = @{
        1 = "Local guest users" 
        2 = "B2B collaboration guest users"
        4 = "B2B collaboration member users" 
        8 = "B2B direct connect users"
        16 = "Other external users" 
        32 = "Service provider users"

    }

    if ($inputNumber -in $externalUsersHash.Keys) { 
        $guestSelections = $externalUsersHash[$inputNumber]
        
    } else {
        $guestSelections = foreach ($number in 32,16,8,4,2,1) {
            if ($inputNumber -ge $number) { 
                $externalUsersHash[$number]
                $inputNumber = $inputNumber - $number

            }
        }
    }

    $guestSelections
}</pre><p>&nbsp;</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Teams Phone and their authentication flows (part 4)</title>
		<link>https://rakhesh.com/azure/teams-phone-and-their-authentication-flows-part-4/</link>
		
		<dc:creator><![CDATA[rakhesh]]></dc:creator>
		<pubDate>Tue, 11 Nov 2025 15:53:28 +0000</pubDate>
				<category><![CDATA[Azure, Azure AD, Graph, M365]]></category>
		<category><![CDATA[intune]]></category>
		<category><![CDATA[teams devices]]></category>
		<guid isPermaLink="false">https://rakhesh.com/?p=8606</guid>

					<description><![CDATA[Just adding a link to this Microsoft blog post I previously linked to, and especially the video in it. Wanted to capture two screenshots from there. This is how enrollment works for Android phones And this is how it works for Android AOSP This puts into pictures what I saw in the logs in the &#8230; <a href="https://rakhesh.com/azure/teams-phone-and-their-authentication-flows-part-4/" class="more-link">Continue reading <span class="screen-reader-text">Teams Phone and their authentication flows (part 4)</span></a>]]></description>
										<content:encoded><![CDATA[<p>Just adding a link to this <a href="https://techcommunity.microsoft.com/blog/microsoftteamssupport/moving-teams-android-devices-to-aosp-device-management/4140893">Microsoft blog post</a> I previously linked to, and especially the <a href="https://youtu.be/wFAS900aRkA">video</a> in it.</p>
<p><iframe loading="lazy" width="560" height="314" src="//www.youtube.com/embed/wFAS900aRkA" allowfullscreen="allowfullscreen"></iframe></p>
<p>Wanted to capture two screenshots from there.</p>
<h3>This is how enrollment works for Android phones</h3>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-15.52.06.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8609" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-15.52.06-1024x461.png" alt="" width="660" height="297" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-15.52.06-1024x461.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-15.52.06-300x135.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-15.52.06-768x346.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-15.52.06-1536x691.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-15.52.06-2048x922.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<h3>And this is how it works for Android AOSP</h3>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-15.52.39.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8610" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-15.52.39-1024x486.png" alt="" width="660" height="313" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-15.52.39-1024x486.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-15.52.39-300x142.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-15.52.39-768x364.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-15.52.39-1536x729.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-15.52.39-2048x972.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>This puts into pictures what I saw in the logs in the previous <a href="https://rakhesh.com/azure/teams-phone-and-their-authentication-flows-part-3/">posts</a>. <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/263a.png" alt="☺" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>The Company Portal app is no more. Instead, what it used to do (register in Entra and enroll in Intune) is now done by the Teams app (which is made up of the new Authenticator app and something called an AOSP app).</p>
<h3>Here is a comparison of the username password flow between Android and Android AOSP based on my testing past few days</h3>
<table>
<tbody>
<tr>
<td>Android</td>
<td>Android AOSP</td>
</tr>
<tr>
<td><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pghy-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8528" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pghy-1024x396.png" alt="" width="660" height="255" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pghy-1024x396.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pghy-300x116.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pghy-768x297.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pghy-1536x595.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pghy-2048x793.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></td>
<td><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-ldsf-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8582" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-ldsf-1024x414.png" alt="" width="660" height="267" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-ldsf-1024x414.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-ldsf-300x121.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-ldsf-768x311.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-ldsf-1536x621.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-ldsf-2048x828.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></td>
</tr>
</tbody>
</table>
<p>Feel free to ignore the comments as I copy pasted from the previous posts, key thing is what apps and resources are in play.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Teams Phone and their authentication flows (part 3)</title>
		<link>https://rakhesh.com/azure/teams-phone-and-their-authentication-flows-part-3/</link>
		
		<dc:creator><![CDATA[rakhesh]]></dc:creator>
		<pubDate>Tue, 11 Nov 2025 15:18:26 +0000</pubDate>
				<category><![CDATA[Azure, Azure AD, Graph, M365]]></category>
		<category><![CDATA[conditional access]]></category>
		<category><![CDATA[device registration]]></category>
		<category><![CDATA[intune]]></category>
		<category><![CDATA[teams devices]]></category>
		<guid isPermaLink="false">https://rakhesh.com/?p=8567</guid>

					<description><![CDATA[Continuing from my previous post (which is a continuation to another post), during my last enrolment the phone OS upgraded from Android to Android AOSP. This was not unexpected because Microsoft is in the process of moving Teams phones from Android to Android AOSP. Details can be found in this blog post and my phone &#8230; <a href="https://rakhesh.com/azure/teams-phone-and-their-authentication-flows-part-3/" class="more-link">Continue reading <span class="screen-reader-text">Teams Phone and their authentication flows (part 3)</span></a>]]></description>
										<content:encoded><![CDATA[<p>Continuing from my previous <a href="https://rakhesh.com/azure/teams-phone-and-their-authentication-flows-part-2/">post</a> (which is a continuation to another <a href="https://rakhesh.com/azure/teams-phone-and-their-authentication-flows-part-2/">post</a>), during my last enrolment the phone OS upgraded from Android to Android AOSP.</p>
<p>This was not unexpected because Microsoft is in the process of moving Teams phones from Android to Android AOSP. Details can be found in <a href="https://techcommunity.microsoft.com/blog/microsoftteamssupport/moving-teams-android-devices-to-aosp-device-management/4140893">this</a> blog post and my phone model&#8217;s latest Android firmware is on the list of supported devices.</p>
<p>This is a good opportunity though for me to capture the Entra ID sign-in logs for that process.</p>
<h3>Firmware 122.15.0.243 (Android AOSP)</h3>
<ul>
<li class="label">Firmware Version: 122.15.0.243</li>
<li class="label">Hardware Version: 122.1.0.0.0.0.0</li>
<li class="label">Microsoft Intune Version: 25.02.1</li>
<li class="label">Authenticator Version: 6.2505.3166
<ul>
<li><em>This is new, is a part of Android AOSP.</em></li>
</ul>
</li>
<li class="label">Teams Version: 1449/1.0.94.2025165302</li>
<li class="label">Admin Agent Version: 1.0.0.202505080136.product</li>
</ul>
<p>This firmware is from <strong>September 2025</strong>.</p>
<h3>Device Code flow when Android is upgraded to Android AOSP</h3>
<p>As part of the enrollment process first the device gets enrolled as Android Device Admin, then the firmware is upgraded to Android AOSP, and it is re-enrolled with the <a href="https://learn.microsoft.com/en-us/microsoftteams/rooms/android-migration-guide">Android AOSP enrollment profile</a>. Just mentioning this because you will see the device in Entra ID with the name <code>&lt;upn&gt;_Android_&lt;date&gt;</code> for a while and then it is renamed to <code>&lt;upn&gt;_AndroidAOSP_&lt;date&gt;</code>. On Intune side though, I think the Android device is un-enrolled and re-enrolled coz when I click on the older entry I get a device not found. That entry disappeared after a few mins so I couldn&#8217;t dig around much.</p>
<p>Logs (oldest entries at the bottom &#8211; read from bottom to top):</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-jixn-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8569" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-jixn-1024x478.png" alt="" width="660" height="308" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-jixn-1024x478.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-jixn-300x140.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-jixn-768x358.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-jixn-1536x716.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-jixn-2048x955.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>(contd.) (oldest entries at the bottom &#8211; read from bottom to top)</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-10.39.55-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8570" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-10.39.55-1024x375.png" alt="" width="660" height="242" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-10.39.55-1024x375.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-10.39.55-300x110.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-10.39.55-768x281.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-10.39.55-1536x562.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-10.39.55-2048x749.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>There&#8217;s more like this from Microsoft Teams and Microsoft Teams Services.</p>
<p>Adding the Device Name too to the output so we can see how that changes (oldest entries at the bottom &#8211; read from bottom to top):</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-jvtp-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8571" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-jvtp-1024x377.png" alt="" width="660" height="243" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-jvtp-1024x377.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-jvtp-300x110.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-jvtp-768x282.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-jvtp-1536x565.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-jvtp-2048x753.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>(contd.) (oldest entries at the bottom &#8211; read from bottom to top)</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-jzdm-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8576" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-jzdm-1024x397.png" alt="" width="660" height="256" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-jzdm-1024x397.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-jzdm-300x116.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-jzdm-768x298.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-jzdm-1536x596.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-jzdm-2048x795.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<h3>Username password flow when Android is upgraded to Android AOSP</h3>
<p>I couldn&#8217;t test this scenario as there&#8217;s no way to downgrade the device.</p>
<h3>Username password flow</h3>
<p>This is when I reset the device and enroll afresh while the phone is on Android AOSP.</p>
<p>The initial screen is as before, where I can either &#8220;Refresh code&#8221; or sign in to the device. I went with the latter. Entered my email address, password, did MFA, and then got the following:</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0077-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8578" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0077-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0077-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0077-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0077-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0077-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0077-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Clicking &#8220;Register&#8221; here kicks off the process.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0078-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8579" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0078-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0078-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0078-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0078-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0078-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0078-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>This takes ages (a minute or two) and finally I am in.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0079-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8580" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0079-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0079-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0079-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0079-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0079-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0079-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0080-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8581" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0080-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0080-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0080-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0080-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0080-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0080-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Looking at the logs, here are the logs from yesterday with Android and username password flow (oldest entries at the bottom).</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pghy-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8528" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pghy-1024x396.png" alt="" width="660" height="255" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pghy-1024x396.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pghy-300x116.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pghy-768x297.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pghy-1536x595.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pghy-2048x793.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Contrast this with Android AOSP (oldest entries at the bottom):</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-ldsf-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8582" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-ldsf-1024x414.png" alt="" width="660" height="267" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-ldsf-1024x414.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-ldsf-300x121.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-ldsf-768x311.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-ldsf-1536x621.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-ldsf-2048x828.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Maybe something amiss with the KQL I am using, the logs don&#8217;t seem to be in order. But the key difference is, with Android AOSP: <strong>Microsoft Teams is doing most of the work, talking to Device Management Service etc</strong>. And when this interaction happens, it triggers the device registration etc.</p>
<p>Reading from down, the first Microsoft Teams &lt;=&gt; Device Management Service with an error code 50097 is not a Conditional Access failure. Rather something else is throwing the error. The message is: <code>Device Authentication Required - DeviceId -DeviceAltSecId claims are null OR no device corresponding to the device identifier exists</code>.</p>
<p>The next interaction with error code 50074 is from our Conditional Access policies requriing MFA.</p>
<p>The one after that with error code 50076 is part of the MFA requirement. The error is: <code>Due to a configuration change made by your administrator, or because you moved to a new location, you must use multi-factor authentication to access the resource</code>.</p>
<p>And then we get error code 50129 which is <code>Device is not Workplace joined - Workplace join is required to register the device</code>. The logs don&#8217;t say Conditional Access is triggering this, but I see our policies requiring Compliant Devices are failing &#8211; so I guess this is due to Conditional Access, but maybe also not. It could be like 50097 above.</p>
<p>This repeats 3 more times, with the fourth attempt registering the device.</p>
<p>Then Intune Company Portal picks in and does Intune Enrollment. At this point the device name is the default YealinkMP56.</p>
<p>Anyways, key takeaway is Microsoft Teams is driving things.</p>
<p>The logs continue, and I was surprised to see the Device Admin agent app again. (Oldest entries are at the bottom, read from bottom to top).</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-lkio-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8583" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-lkio-1024x334.png" alt="" width="660" height="215" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-lkio-1024x334.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-lkio-300x98.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-lkio-768x251.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-lkio-1536x502.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-lkio-2048x669.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<h3>Device Code flow</h3>
<p>Reset the phone, and tried with Device Code flow. This should be a quick win, right? Nope! It failed like this:</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0081-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8584" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0081-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0081-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0081-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0081-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0081-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0081-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0082-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8585" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0082-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0082-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0082-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0082-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0082-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0082-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>The logs are short this time (read from bottom to top).</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-lokt-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8586" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-lokt-1024x258.png" alt="" width="660" height="166" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-lokt-1024x258.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-lokt-300x75.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-lokt-768x193.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-lokt-1536x387.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-lokt-2048x515.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>This makes no sense. Things seem to have succeeded as per the logs. Intune enrollment did happen, and what finally failed is &#8220;Device Admin Agent&#8221; failing coz the device isn&#8217;t compliant. If I expand the entry, the device state is &#8220;Managed&#8221; &#8211; so it is Intune enrolled &#8211; but not yet Compliant. <strong>I double check in  Intune too, and indeed the device is enrolled!</strong> What gives?!</p>
<p>Maybe its just a matter of time? So I powered off and powered on the device like any good IT person, hoping the phone would just realize it is enrolled and contine from there. Of course it did not! After reboot the phone was back to the sign in page. Undeterred, I tried the device code method again (I didn&#8217;t reset the device this time) &#8211; and <em>no surprises, this time it worked</em>!</p>
<p>The only consistent thing is that nothing&#8217;s consistent. Always expect surprises. Why did it work this time, who knows?! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f914.png" alt="🤔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f621.png" alt="😡" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>Did it create a new device in Intune/ Entra ID? Nope! I signed in and it took the previously enrolled device. So I was right &#8211; the enrollment did happen and it was just a case of the device not knowing it, and when I signed in the two got linked. To confirm that no enrollment happened, I took a look at the logs:</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-lwsy-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8588" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-lwsy-1024x457.png" alt="" width="660" height="295" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-lwsy-1024x457.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-lwsy-300x134.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-lwsy-768x343.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-lwsy-1536x685.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-lwsy-2048x914.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<h3>Downgraded to Firmware 122.15.0.234 (Android AOSP)</h3>
<p>I was surprised but downgrading the firmware worked. Maybe coz I did to the version just one prior to the existing one, or maybe things are different with the AOSP firmware.</p>
<p>Only tried the Device Code flow. Same as before, it didn&#8217;t work. The device is Intune enrolled, but the phone throws an error.</p>
<p>Looking at the logs (read from bottom to up) things look a bit different because I don&#8217;t see any obvious failures like from Teams Device Admin. And there&#8217;s just one entry after the device is Intune enrolled, after which things just stop.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-mpox-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8590" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-mpox-1024x327.png" alt="" width="660" height="211" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-mpox-1024x327.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-mpox-300x96.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-mpox-768x245.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-mpox-1536x490.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-mpox-2048x654.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>My hunch is that this is something to do with the firmware and delays. But that&#8217;s just a hunch.</p>
<h3>Back to Firmware 122.15.0.243 (Android AOSP)</h3>
<p>What else can I try? I upgraded the firmware back to the latest AOSP one I was on (which is where I began this post) and tried again. <em>No muy bueno</em>, it still fails.</p>
<p>However, I had another idea.</p>
<p>Remember it fails on this screen:</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0082-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8585" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0082-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0082-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0082-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0082-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0082-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0082-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>So I put my email address in and clicked &#8220;Sign in&#8221;. There was no password prompt, but I got the prompt to register my device (which I previously encountered in the username/ password flow).</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0077-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8578" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0077-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0077-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0077-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0077-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0077-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0077-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Clicked &#8220;Register&#8221; there, and it errored and put me back to where we began.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0082-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8585" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0082-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0082-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0082-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0082-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0082-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0082-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Weirdly, now Intune doesn&#8217;t even show the device name registered properly.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-mvau.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8593" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-mvau-1024x84.png" alt="" width="660" height="54" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-mvau-1024x84.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-mvau-300x25.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-mvau-768x63.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-mvau-1536x125.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-mvau.png 2032w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Entra too has the default name of YealinkMP56. So unlike the attempt before where the device enrolled in Intune, looks like that didn&#8217;t happen either.</p>
<p>This is so so weird! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f600.png" alt="😀" class="wp-smiley" style="height: 1em; max-height: 1em;" /> I seem to be in a loop like yesterday where things do random behaviour. Take a look at these logs &#8211; there&#8217;s no Intune enrollment happening! And all the failures at the end are because the device isn&#8217;t compliant coz it isn&#8217;t enrolled in Intune.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-mwhr-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8595" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-mwhr-1024x359.png" alt="" width="660" height="231" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-mwhr-1024x359.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-mwhr-300x105.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-mwhr-768x270.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-mwhr-1536x539.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-mwhr-2048x719.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Interestingly, I saw an alert email pop up about more Intune issues that got resolved, so maybe I am just unlucky like yesterday?</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-14.26.45.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8594" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-14.26.45-1024x688.png" alt="" width="660" height="443" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-14.26.45-1024x688.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-14.26.45-300x202.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-14.26.45-768x516.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-14.26.45.png 1304w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>This has nothing to do with Intune enrollment though.</p>
<p>At this point I am stuck in the loop <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f501.png" alt="🔁" class="wp-smiley" style="height: 1em; max-height: 1em;" /> so reset phone and let&#8217;s try again&#8230;</p>
<p>And voila! It worked. Yeah. <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f631.png" alt="😱" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>At this point I don&#8217;t care, I just want this to end. <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f600.png" alt="😀" class="wp-smiley" style="height: 1em; max-height: 1em;" /> I am guessing the Intune issue did have some impact, but I don&#8217;t know and I don&#8217;t care. It was definitely coincidental that both yesterday and today when things failed there were health alerts; although yesterday&#8217;s was more obvious in that username password enrollment too failed, while today it was just Device Code.</p>
<p>Maybe it was just a matter of waiting.</p>
<p>Or the wind blowing in the right direction outside.</p>
<p>Who knows&#8230; <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f937.png" alt="🤷" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>Anyways, I can finally collect the logs from a successful Device Code flow enrollment. <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f605.png" alt="😅" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>But first, the logs from earlier when Device Code failed on this firmware (read the entries from bottom to top).</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-lokt-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8586" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-lokt-1024x258.png" alt="" width="660" height="166" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-lokt-1024x258.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-lokt-300x75.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-lokt-768x193.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-lokt-1536x387.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-lokt-2048x515.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>I was surprised there that Teams Device Admin agent failed and that the name hadn&#8217;t changed. The device was enrolled in Intune, Conditional Access was seeing it as Managed, but it wasn&#8217;t in a Compliant state yet. The name hadn&#8217;t changed, but that too could be put down to a delay in things updating.</p>
<p>I thought this Teams Device Admin failing is what broke things. But I was mistaken, as I see it happening now too but things proceed past it (read the entries from bottom to top).</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-neha-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8597" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-neha-1024x399.png" alt="" width="660" height="257" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-neha-1024x399.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-neha-300x117.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-neha-768x299.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-neha-1536x598.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-neha-2048x797.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Even though Teams Device Admin agent failed, that didn&#8217;t stop things. When it failed the device is enrolled into Intune but wasn&#8217;t Compliant yet &#8211; that&#8217;s why it failed (same as before &#8211; then too the device was Managed but not Compliant yet).</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-nhgn.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8598" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-nhgn-1024x290.png" alt="" width="660" height="187" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-nhgn-1024x290.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-nhgn-300x85.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-nhgn-768x217.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-nhgn-1536x435.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-nhgn-2048x580.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>And yet in the very next entry, the device name has changed and is now Compliant. <strong>This is what was breaking earlier.</strong></p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-nicu-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8599" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-nicu-1024x222.png" alt="" width="660" height="143" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-nicu-1024x222.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-nicu-300x65.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-nicu-768x167.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-nicu-1536x333.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-nicu-2048x444.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>In the logs there&#8217;s just a few milliseconds difference between these two entries. So something in the backend must have been broken earlier, because of which it didn&#8217;t proceed to the next steps.</p>
<p>There&#8217;s a few more entries in the log, and we can see things proceeding and eventually succeeding.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-nlgn-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8600" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-nlgn-1024x410.png" alt="" width="660" height="264" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-nlgn-1024x410.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-nlgn-300x120.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-nlgn-768x308.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-nlgn-1536x615.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-nlgn-2048x821.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Also, just to call attention to it again, with Android AOSP it&#8217;s &#8220;Microsoft Teams&#8221; that does most things.</p>
<table style="border-collapse: collapse; width: 100%;">
<tbody>
<tr>
<td style="width: 50%;">Username password</td>
<td style="width: 50%;">Device Code</td>
</tr>
<tr>
<td style="width: 50%;"><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-ldsf-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8582" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-ldsf-1024x414.png" alt="" width="660" height="267" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-ldsf-1024x414.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-ldsf-300x121.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-ldsf-768x311.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-ldsf-1536x621.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-ldsf-2048x828.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></td>
<td style="width: 50%;"><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-neha-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8597" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-neha-1024x399.png" alt="" width="660" height="257" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-neha-1024x399.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-neha-300x117.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-neha-768x299.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-neha-1536x598.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-neha-2048x797.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></td>
</tr>
</tbody>
</table>
<p>That&#8217;s it! I am outta here.</p>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f517.png" alt="🔗" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <a href="https://rakhesh.com/azure/teams-phone-and-their-authentication-flows-part-4/">Link to part 4</a></p>
<p><strong>Update (the following day)</strong>: Today there is a health alert for Intune AOSP devices.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-12-at-15.19.47.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8616" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-12-at-15.19.47-1024x973.png" alt="" width="660" height="627" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-12-at-15.19.47-1024x973.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-12-at-15.19.47-300x285.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-12-at-15.19.47-768x730.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-12-at-15.19.47.png 1370w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>So there must have been some intermittent issue past few days which is now gotten worse/ noticeable. Just my luck!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Teams Phone and their authentication flows (part 2)</title>
		<link>https://rakhesh.com/azure/teams-phone-and-their-authentication-flows-part-2/</link>
		
		<dc:creator><![CDATA[rakhesh]]></dc:creator>
		<pubDate>Tue, 11 Nov 2025 07:58:53 +0000</pubDate>
				<category><![CDATA[Azure, Azure AD, Graph, M365]]></category>
		<category><![CDATA[conditional access]]></category>
		<category><![CDATA[device registration]]></category>
		<category><![CDATA[intune]]></category>
		<category><![CDATA[teams devices]]></category>
		<guid isPermaLink="false">https://rakhesh.com/?p=8481</guid>

					<description><![CDATA[Continuing from my previous post, I upgraded the Yealink MP56 phone to the next available firmware. Firmware 122.15.0.107 This firmware is from December 2022. Here is what the admin page shows post-upgrade: Firmware Version: 122.15.0.107 Hardware Version: 122.1.0.0.0.0.0 Company Portal Version: 5.0.5484.0 Teams Version: 1449/1.0.94.2022110803 Admin Agent Version: 1.0.0.202209060820.product This is new, wasn&#8217;t present originally. &#8230; <a href="https://rakhesh.com/azure/teams-phone-and-their-authentication-flows-part-2/" class="more-link">Continue reading <span class="screen-reader-text">Teams Phone and their authentication flows (part 2)</span></a>]]></description>
										<content:encoded><![CDATA[<p>Continuing from my previous <a href="https://rakhesh.com/azure/teams-phone-and-their-authentication-flows-part-1/">post</a>, I upgraded the Yealink MP56 phone to the next available firmware.</p>
<h2>Firmware 122.15.0.107</h2>
<p>This firmware is from <strong>December 2022</strong>. Here is what the admin page shows post-upgrade:</p>
<div class="y-block-content">
<div class="y-label">
<ul>
<li class="label">Firmware Version: 122.15.0.107</li>
<li class="label">
<div class="label">Hardware Version: 122.1.0.0.0.0.0</div>
</li>
<li class="label">
<div class="label">Company Portal Version: 5.0.5484.0</div>
</li>
<li class="label">
<div class="label">Teams Version: 1449/1.0.94.2022110803</div>
</li>
<li class="label">
<div class="label">Admin Agent Version: 1.0.0.202209060820.product</div>
<ul>
<li><em>This is new, wasn&#8217;t present originally.</em></li>
</ul>
</li>
</ul>
</div>
</div>
<p>Things are a bit different now when powering on the device. You get a page like this:</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0041-scaled.jpg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8483" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0041-1024x768.jpg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0041-1024x768.jpg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0041-300x225.jpg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0041-768x576.jpg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0041-1536x1152.jpg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0041-2048x1536.jpg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<h3>Device Code flow</h3>
<p>Click Refresh code to get a code. Then on my computer I went to the Device Login page, entered the code, did MFA, it asked me for a password followed by MFA again, then a prompt like this:</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-14.01.20.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-8484" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-14.01.20.png" alt="" width="786" height="432" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-14.01.20.png 786w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-14.01.20-300x165.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-14.01.20-768x422.png 768w" sizes="auto, (max-width: 786px) 100vw, 786px" /></a></p>
<p>Clicked &#8220;Continue&#8221; and it signed me in.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-14.01.45.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-8485" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-14.01.45.png" alt="" width="794" height="360" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-14.01.45.png 794w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-14.01.45-300x136.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-14.01.45-768x348.png 768w" sizes="auto, (max-width: 794px) 100vw, 794px" /></a></p>
<p>Interestingly, the phone failed though.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0042-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8486" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0042-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0042-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0042-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0042-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0042-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0042-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>&#8220;<code>Couldn't connect to Workfplace Join. Try again, or contact you admin.</code>&#8221;</p>
<p>Looking at the logs, I can see tha things are different this time (oldest entries at the bottom &#8211; read from bottom to top).</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-modp-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8487" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-modp-1024x272.png" alt="" width="660" height="175" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-modp-1024x272.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-modp-300x80.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-modp-768x204.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-modp-1536x408.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-modp-2048x544.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>For one, we start with the Authentication Broker app this time, rather than Company Portal. So the page showing me a code is not the Company Portal app any more. This explains why Device Code worked, and why the message in my browser confirming the app I was signing into also showed the Authentication Broker.</p>
<p>The logs show a failure for this due to requiring MFA, and there&#8217;s a bunch of these which is probably why I got prompted for MFA twice.</p>
<p>The first failure message in the screenshot was &#8220;<code>Credentials have been revoked due to the following reasons: SSO Artifact is invalid or expired, Session not fresh enough for application, A silent sign-in request was sent but the user's session with Azure AD is invalid or has expired.</code>&#8220;, followed by &#8220;<code>For security reasons, user confirmation is required for this request. Please repeat the request allowing user interaction.</code>&#8221;</p>
<p>Neither of these messages are due to Conditional Access, so I am not sure what is going on. And confusingly, after these there was a final success message. So why did it fail?</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-14.16.10-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8489" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-14.16.10-1024x163.png" alt="" width="660" height="105" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-14.16.10-1024x163.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-14.16.10-300x48.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-14.16.10-768x122.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-14.16.10-1536x245.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-14.16.10-2048x326.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>I decided to try again in case it was a temporary error.</p>
<p>Clicked &#8220;Refresh code&#8221; on the phone, got a new code, and entered it in the browser. Prompted for password again, MFA, was shown the confirmation message asking if I am signing into Authentication Broker, and again while things succeeded in the browser it failed on the phone. Oh well.</p>
<p>Again the logs give a &#8220;<code>For security reasons, user confirmation is required for this request. Please repeat the request allowing user interaction.</code>&#8221; message and eventually succeeds.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-14.20.04-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8491" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-14.20.04-1024x157.png" alt="" width="660" height="101" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-14.20.04-1024x157.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-14.20.04-300x46.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-14.20.04-768x117.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-14.20.04-1536x235.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-14.20.04-2048x313.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>One <a href="https://techcommunity.microsoft.com/blog/intunecustomersuccess/enrolling-microsoft-teams-phones-and-microsoft-teams-rooms-on-android-in-microso/3866246">reason for this error is unsupported Conditional Access policies</a>. And sure enough, looking at the <a href="https://learn.microsoft.com/en-gb/microsoftteams/rooms/supported-ca-and-compliance-policies?tabs=mtr-a#supported-conditional-access-policies">supported Conditional Access policies for Teams phones</a> it specifically says Device Code flow should not be blocked.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-nteg.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8510" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-nteg-1024x794.png" alt="" width="660" height="512" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-nteg-1024x794.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-nteg-300x233.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-nteg-768x596.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-nteg-1536x1192.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-nteg.png 1740w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>I still don&#8217;t see how it matters though, coz Conditional Access is not blocking anything in my case (as per the logs at least). Ideally, I should exempt myself altogether from the Device Code blocked flow and test, but I don&#8217;t want to. Plus, I know this issue gets fixed later (<em>teaser for my later blog post!</em> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60a.png" alt="😊" class="wp-smiley" style="height: 1em; max-height: 1em;" />) so time to move on and try the password flow.</p>
<p>Before I move on, for future reference here is a screenshot of the failure I got.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-nulc-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8511" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-nulc-1024x264.png" alt="" width="660" height="170" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-nulc-1024x264.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-nulc-300x77.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-nulc-768x198.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-nulc-1536x396.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-nulc-2048x528.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Everything looks alright, except for the error. And in the &#8220;success&#8221; entry just after this, it looks like the device hasn&#8217;t actually registered&#8230; so <em>something</em> failed.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-ohvg.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8515" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-ohvg-1024x302.png" alt="" width="660" height="195" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-ohvg-1024x302.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-ohvg-300x88.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-ohvg-768x226.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-ohvg-1536x453.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-ohvg-2048x603.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<h3>Username password flow</h3>
<p>This time I clicked &#8220;Sign in to this device&#8221; on the phone instead of doing a &#8220;Refresh code&#8221;.</p>
<p>That gives the familiar sign in page from the Company Portal. I enter my email address, password, MFA, and we are off to the races!</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0043-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8493" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0043-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0043-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0043-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0043-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0043-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0043-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>After signing in:</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0044-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8494" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0044-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0044-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0044-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0044-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0044-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0044-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0046-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8495" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0046-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0046-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0046-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0046-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0046-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0046-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0047-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8496" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0047-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0047-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0047-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0047-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0047-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0047-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Again that error from <a href="https://rakhesh.com/azure/teams-phone-and-their-authentication-flows-part-1/">before</a>. I clicked &#8220;Try again&#8221;. This time it worked!</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0048-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8497" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0048-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0048-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0048-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0048-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0048-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0048-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0049-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8498" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0049-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0049-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0049-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0049-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0049-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0049-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0050-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8499" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0050-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0050-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0050-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0050-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0050-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0050-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0051-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8500" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0051-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0051-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0051-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0051-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0051-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0051-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Yay! And finally, a glimpse of the Company Portal apps screen for some reason.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0052-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8501" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0052-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0052-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0052-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0052-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0052-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0052-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Followed by some more screens from Teams. On the screen where there&#8217;s a &#8220;Sign in&#8221; button it signs in automatically.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0053-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8502" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0053-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0053-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0053-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0053-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0053-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0053-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0054-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8503" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0054-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0054-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0054-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0054-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0054-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0054-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0055-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8504" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0055-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0055-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0055-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0055-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0055-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0055-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0056-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8505" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0056-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0056-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0056-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0056-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0056-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0056-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0057-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8506" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0057-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0057-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0057-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0057-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0057-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0057-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>And we are in! After this I am shown the Teams phone UI.</p>
<p>Looking at the logs (oldest at the bottom &#8211; read from bottom to top):</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-nnak-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8508" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-nnak-1024x446.png" alt="" width="660" height="287" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-nnak-1024x446.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-nnak-300x131.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-nnak-768x335.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-nnak-1536x670.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-nnak-2048x893.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p><strong>Just after the MFA prompt, when Intune Company portal is talking to Windows Azure AD (the first of the green shaded section), the device has successfully registered.</strong> (See the screenshot just after the one below where I can see this).</p>
<p>(contd.) (oldest entries at the bottom &#8211; read from bottom to top)</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-nphg-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8509" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-nphg-1024x255.png" alt="" width="660" height="164" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-nphg-1024x255.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-nphg-300x75.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-nphg-768x191.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-nphg-1536x383.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-nphg-2048x511.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>You can see Teams Device Admin also getting involved with Device Registration.</p>
<p>The only difference in the above output vs the Device Code one which failed is that after the Authentication Broker talking to Device Registration Service, we have Intune Company Portal talking to Windows Azure AD. I wonder if something is failing there. Here is what that entry looks like:</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-oevd.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8514" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-oevd-1024x386.png" alt="" width="660" height="249" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-oevd-1024x386.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-oevd-300x113.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-oevd-768x289.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-oevd-1536x579.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-oevd-2048x772.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<h2>Firmware 122.15.0.166</h2>
<p>This firmware is from <strong>March 2025</strong>. It&#8217;s the last of the Android firmware for this phone. I don&#8217;t expect much changes, but I upgraded to it to have the latest results just in case.</p>
<p>Details:</p>
<div class="y-block-content">
<div class="y-label">
<ul>
<li class="label">Firmware Version: 122.15.0.166</li>
<li class="label">Hardware Version: 122.1.0.0.0.0.0</li>
<li class="label">Company Portal Version: 5.0.6152.0</li>
<li class="label">Teams Version: 1449/1.0.94.2024101709</li>
<li class="label">Admin Agent Version: 1.0.0.202407050618.product</li>
</ul>
</div>
</div>
<p>On the phone, the sign in page is same as before.</p>
<h3>Device Code flow</h3>
<p>Magic! This worked. <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1fa84.png" alt="🪄" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>Not adding any screenshots as it&#8217;s exactly as what I put above for the username password flow with the previous firmware. Only difference is that the Company Portal picked up the firm logo and theme instead of the default blue.</p>
<p>The logs look better too (of course) (oldest entries at the bottom &#8211; read from bottom to top):</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-omcy-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8518" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-omcy-1024x454.png" alt="" width="660" height="293" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-omcy-1024x454.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-omcy-300x133.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-omcy-768x341.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-omcy-1536x681.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-omcy-2048x909.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Key takeaway #1: <span style="text-decoration: underline;"><strong>firmware matters</strong></span>. Nothing changed on the Conditional Access policies or user account between the two firmware versions, but in the older one Device Code flow failed for no apparent reason, but in the newer one it worked. I think this point bears emphasising, because <strong>Conditional Access is usually blamed for a lot of things, but it isn&#8217;t always the culprit</strong>.</p>
<p>Key takeaway #2: <strong>you can block Device Code flow in general but only need allow it for the Device Registration action and exclude Teams Phone devices, and Teams Phones enrollment will work</strong>. The Microsoft docs make it sounds like you need to allow it carte blanche for the user, but you don&#8217;t really need that.</p>
<h4><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f449.png" alt="👉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> A quick sidebar on blocking Device Code flow for all, except Teams Phones</h4>
<p>The Device Registration action is under <strong>Target resources</strong> &gt; <strong>User actions </strong>&gt; <strong>Register or join devices</strong>. But you can&#8217;t exempt it coz the only option available is to include it.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-17.12.19.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8526" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-17.12.19-1024x641.png" alt="" width="660" height="413" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-17.12.19-1024x641.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-17.12.19-300x188.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-17.12.19-768x481.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-17.12.19.png 1274w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Instead, apply the policy to &#8220;All Cloud Apps&#8221; but exclude &#8220;Device Registration Service&#8221;.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-17.13.49.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8527" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-17.13.49-1024x730.png" alt="" width="660" height="471" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-17.13.49-1024x730.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-17.13.49-300x214.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-17.13.49-768x547.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-17.13.49.png 1224w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>I am not sure what the difference is between the action and the app. I&#8217;d imagine the action is just a convenience thing and that it actually calls upon the underlying app, so that&#8217;s why excluding the app does the trick.</p>
<p>However, excluding only Device Registration Service from the Device Code block policy doesn&#8217;t help when it comes to Intune enrollment or using Teams etc. That&#8217;s because all these continue to be a part of the Device Code flow. Here&#8217;s a repeat of the screenshot I put above. Notice the transfer method is still <code>deviceCodeFlow</code> when it comes to Intune Enrollment, Teams Service, etc.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-omcy-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8518" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-omcy-1024x454.png" alt="" width="660" height="293" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-omcy-1024x454.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-omcy-300x133.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-omcy-768x341.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-omcy-1536x681.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-omcy-2048x909.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>So we need to exclude Device Code flow for these too. The neat thing is since these steps are <em>after</em> the device has registered, <a href="https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-condition-filters-for-devices#policy-behavior-with-filter-for-devices">we have more details of the device available to play with</a>. Thus, we can exclude for instance devices with name &#8220;Yealink MP56&#8221; from the Device Code block policy, and so Device Code flow will continue working after the device has registered and when it tries to enroll in Intune etc.</p>
<p><strong>Note</strong>: I am not saying that <em>this is</em> what one should do, all I am saying is that if one devices to block Device Code flow (is a good thing to do), then it must be exempted either for Teams Phone based on the users or some other criteria. Excluding for Teams Phone users doesn&#8217;t make sense because then these users can use Device Code flow for anything; so a better idea is to be more fine grained. Excluding based on the device display name or manufacturer is a compromise, and it will need some work as new models and manufacturers are introduced.</p>
<h3>Username password flow</h3>
<p>Interestingly, after successfully enrolling as above, I signed out of the device and also deleted it from Entra ID. Then I tried the username password flow, and that failed immediately after prompting me for MFA.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0060-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8522" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0060-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0060-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0060-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0060-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0060-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0060-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>&#8220;Couldn&#8217;t connect to Workplace Join. Try again, or contact your admin&#8221;. Weird.</p>
<p>So I reset the device to factory settings and tried again (<em>resetting to factory settings does not downgrade the firmware btw</em>).</p>
<p>Surprise, now it worked! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f643.png" alt="🙃" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pghy-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8528" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pghy-1024x396.png" alt="" width="660" height="255" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pghy-1024x396.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pghy-300x116.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pghy-768x297.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pghy-1536x595.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pghy-2048x793.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>It&#8217;s very different to the Device Code flow. I wasn&#8217;t expecting that to be honest.</p>
<p>(contd.) (oldest entries at the bottom &#8211; read from bottom to top)</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pmby-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8529" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pmby-1024x299.png" alt="" width="660" height="193" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pmby-1024x299.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pmby-300x88.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pmby-768x225.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pmby-1536x449.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pmby-2048x599.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>As you can see there&#8217;s lot more stuff happening!</p>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f517.png" alt="🔗" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <a href="https://rakhesh.com/azure/teams-phone-and-their-authentication-flows-part-3/">Link to part 3</a></p>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f447.png" alt="👇" class="wp-smiley" style="height: 1em; max-height: 1em;" /> What follows below is some additional issues I encountered. They got resolved by themselves in the end, and all I can attribute them to is some Intune outage on Microsoft&#8217;s side. I took the effort of writing notes and putting screenshots, and didn&#8217;t want to delete them all so here they are. Feel free to skip.</p>
<hr />
<h3>Frustrations</h3>
<p>I reset the device one more time and did a Device Code flow authentication (just for kicks!) and now I got the &#8220;<code>Couldn't connect to Workplace Join. Try again, or contact your admin</code>&#8221; error I previously received with username and password. Weird.</p>
<p>A second reset didn&#8217;t make a difference either. Interestingly, the logs show similar messages as what I received with the very first/ default firmware when Device Code flow was failing.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-17.54.57-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8531" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-17.54.57-1024x337.png" alt="" width="660" height="217" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-17.54.57-1024x337.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-17.54.57-300x99.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-17.54.57-768x253.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-17.54.57-1536x506.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-17.54.57-2048x675.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>So I rebooted the device and tried, and this time it went further but failed with a different error.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0068-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8532" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0068-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0068-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0068-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0068-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0068-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0068-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0069-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8533" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0069-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0069-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0069-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0069-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0069-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0069-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>This time even though I was getting the same &#8220;<code>For security reasons, user confirmation is required...</code>&#8221; errors as before, things were proceeding further (notice the SUCCESS from Intune Enrollment).</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-puzu-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8534" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-puzu-1024x209.png" alt="" width="660" height="135" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-puzu-1024x209.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-puzu-300x61.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-puzu-768x157.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-puzu-1536x313.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-puzu-2048x418.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>So I took a look at Intune and sure enough things reached Intune and failed. In fact, interestingly, I had only two enrollment failures under my account &#8211; one from now, and one from earlier in the day when I tried with the original firmware.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pxhh-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8535" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pxhh-1024x183.png" alt="" width="660" height="118" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pxhh-1024x183.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pxhh-300x53.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pxhh-768x137.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pxhh-1536x274.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-pxhh-2048x365.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Vague error though.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-hklk.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8560" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-hklk-1024x593.png" alt="" width="660" height="382" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-hklk-1024x593.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-hklk-300x174.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-hklk-768x445.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251111-hklk.png 1282w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>I double checked the phone firmware with what I had noted down earlier &#8211; no change. And yet something was failing.</p>
<p>The weird thing, moreover, was that each time I reset the device and try I was getting a different error. On my 3rd attempt it seemed to again proceed as usual but then dropped me at this sign in page, and then when I tried to sign in via Device Code nothing happened.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0070-1-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8545" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0070-1-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0070-1-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0070-1-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0070-1-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0070-1-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0070-1-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0071-1-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8547" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0071-1-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0071-1-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0071-1-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0071-1-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0071-1-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0071-1-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Aaargh!</p>
<p>On my 4th attempt, things were at least consistent in that I got the same error as above. So I decided to dig deeper into the sign in logs.</p>
<p>Interesting thing is even during this attempt the device is getting registered in Entra and then failing. And&#8230; it is failing due to our Conditional Access policies.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-qnay-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8548" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-qnay-1024x371.png" alt="" width="660" height="239" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-qnay-1024x371.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-qnay-300x109.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-qnay-768x278.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-qnay-1536x556.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-qnay-2048x741.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Weird (<em>that word again!</em>) thing is this error makes sense. <em>At this point the device has only registered in Entra ID and it isn&#8217;t Intune enrolled</em>, and so when Teams is trying to access the Teams Services resource it naturally fails because we have Conditional Access policies in place that require the device to be compliant. If the device had enrolled in Intune after device registration, this error wouldn&#8217;t have occured.</p>
<p>Contrast this to the logs I captured earlier when Device Code flow worked:</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-omcy-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8518" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-omcy-1024x454.png" alt="" width="660" height="293" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-omcy-1024x454.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-omcy-300x133.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-omcy-768x341.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-omcy-1536x681.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-omcy-2048x909.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p><em>Here the device does Intune enrollment, as part of which it does Device Registration, and thus things work</em>. But now the phone wasn&#8217;t doing Intune enrollment at all. I have no idea why!</p>
<p>Interestingly, in one of the previous failed attempts it was doing an Intune enrollment. This is all so confusing!</p>
<p>(Btw, after I took the above screenshot where no Intune enrollment was happening, I saw more logs come through. Here too no Intune enrollment is happening, but the Teams Device Admin agent is trying to do something. I wonder if the phone got corrupt somehow).</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-19.07.38-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8550" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-19.07.38-1024x291.png" alt="" width="660" height="188" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-19.07.38-1024x291.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-19.07.38-300x85.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-19.07.38-768x218.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-19.07.38-1536x437.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-19.07.38-2048x582.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p><em>What else? </em></p>
<p>So far I had reset the device to factory settings multiple times. I had also tried resetting user data (that was another option in the admin UI) but it didn&#8217;t help either. One thing I wanted to try next was reinstall the firmware. The first time I upgraded to this version of the firmware it never prompted me to change the admin password of the device, but ever since then whenever I&#8217;d reset the firmware it prompts me to change the password. Not a big deal in itself, but I felt this wasn&#8217;t putting the device back to the original state at which it was working. It never asked me to change the password the first time I moved to this firmware, so why was it always asking now when doing a reset. Clearly that wasn&#8217;t a &#8220;reset&#8221; enough? <em>(wishful thinking&#8230;)</em></p>
<p>For this phone at least, trying to upload the firmware again didn&#8217;t work as the phone wouldn&#8217;t accept it. Neither did trying to downgrade to a previous version. I had nothing else left to do. <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2639.png" alt="☹" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>Out of ideas, I thought let me try what happens with the username password flow, coz clearly that should work? But nope, <span style="text-decoration: underline;">that too fails with the same error</span>! Madness!! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f624.png" alt="😤" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>At this point I gave up for the day. Something&#8217;s broken somewhere, and I&#8217;ve had enough for today!</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-07.41.07.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-8557" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-07.41.07.png" alt="" width="860" height="546" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-07.41.07.png 860w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-07.41.07-300x190.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-07.41.07-768x488.png 768w" sizes="auto, (max-width: 860px) 100vw, 860px" /></a></p>
<p><strong>Guess what, it works now!</strong> Wasted about 3 hours yesterday evening/ night troubleshooting this. At least I am wiser in the art of troubleshooting I suppose? <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f9e0.png" alt="🧠" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>Interestingly, as part of the enrollment the firmware too got updated. We are now at:</p>
<div class="y-block-content">
<div class="y-label">
<ul>
<li class="label">Firmware Version: 122.15.0.243</li>
<li class="label">Hardware Version: 122.1.0.0.0.0.0</li>
<li class="label">Microsoft Intune Version: 25.02.1</li>
<li class="label">Authenticator Version: 6.2505.3166
<ul>
<li><em>This is new, wasn&#8217;t present originally!</em></li>
</ul>
</li>
<li class="label">Teams Version: 1449/1.0.94.2025165302</li>
<li class="label">Admin Agent Version: 1.0.0.202505080136.product</li>
</ul>
</div>
</div>
<p>The presence of Authenticator, plus the fact that I was on the latest Android firmware available from Yealink got me thinking maybe the device is now on Android AOSP, and sure enough it is. Nice!</p>
<p>The closest I can find from Microsoft as to why enrollment failed yesterday is some alerts about Intune Datawarehouse. This might have been a side effect of that?</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-07.54.23.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8561" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-07.54.23-1024x888.png" alt="" width="660" height="572" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-07.54.23-1024x888.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-07.54.23-300x260.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-07.54.23-768x666.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-11-at-07.54.23.png 1278w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>This issue started 3 days ago though, but the fix was rolled out around the time I was testing so maybe that&#8217;s how they are related? I dunno.</p>
<p><strong>Update (a few hours later)</strong>: When I logged in to work later, there were reports from others that Teams phone enrolment were failing yesterday. So it looks like there was indeed some issue.</p>
<hr />
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f517.png" alt="🔗" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <a href="https://rakhesh.com/azure/teams-phone-and-their-authentication-flows-part-3/">Link to part 3</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Teams Phone and their authentication flows (part 1)</title>
		<link>https://rakhesh.com/azure/teams-phone-and-their-authentication-flows-part-1/</link>
		
		<dc:creator><![CDATA[rakhesh]]></dc:creator>
		<pubDate>Mon, 10 Nov 2025 13:50:53 +0000</pubDate>
				<category><![CDATA[Azure, Azure AD, Graph, M365]]></category>
		<category><![CDATA[conditional access]]></category>
		<category><![CDATA[device registration]]></category>
		<category><![CDATA[intune]]></category>
		<category><![CDATA[teams devices]]></category>
		<guid isPermaLink="false">https://rakhesh.com/?p=8463</guid>

					<description><![CDATA[I wanted to document the authentication flow for Teams phones. This is by no means comprehensive, but only what I have been able to gather by looking at a Yealink MP56 phone. The device itself is discontinued, but firmware updates are available so it works with Teams. The device I got happened to be on &#8230; <a href="https://rakhesh.com/azure/teams-phone-and-their-authentication-flows-part-1/" class="more-link">Continue reading <span class="screen-reader-text">Teams Phone and their authentication flows (part 1)</span></a>]]></description>
										<content:encoded><![CDATA[<p>I wanted to document the authentication flow for Teams phones. This is by no means comprehensive, but only what I have been able to gather by looking at a <a href="https://www.yealink.com/en/product-detail/microsoft-teams-phone-mp56">Yealink MP56 phone</a>. The device itself is discontinued, but <a href="https://support.yealink.com/en/portal/docList?archiveType=software&amp;productCode=b18ec0e4d0d024aa">firmware updates are available</a> so it works with Teams. The device I got happened to be on a really old version of the firmware, so I was able to try it across various versions.</p>
<h2>Firmware 122.15.0.33</h2>
<p>This is what the device had out of the box:</p>
<ul>
<li class="label">Firmware Version: 122.15.0.33</li>
<li class="label">
<div class="label">Hardware Version: 122.1.0.0.0.0.0</div>
</li>
<li class="label">
<div class="label">Company Portal Version: 5.0.4927.0</div>
</li>
<li class="label">
<div class="label">Teams Version: 1449/1.0.94.2020111101</div>
</li>
</ul>
<p>Powering on the device greets you with this screen:</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/96F0B4F0-339F-4E6A-A7DE-671DFB12A76B.heic"><img decoding="async" class="alignnone size-full wp-image-8464" src="https://rakhesh.com/wp-content/uploads/2025/11/96F0B4F0-339F-4E6A-A7DE-671DFB12A76B.heic" alt="" /></a><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0019-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8465" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0019-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0019-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0019-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0019-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0019-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0019-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>You can click the Gear icon on the top right to get into settings to view the IP address and other details. That&#8217;s how I then connected to the phone&#8217;s admin portal to take a look at the firmware etc.</p>
<p>Clicking &#8220;Sign in&#8221; opens up the (Intune) Company Portal app.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0020-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8466" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0020-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0020-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0020-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0020-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0020-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0020-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>I can either enter the email address here and click &#8220;Next&#8221;, or click &#8220;Sign-in options&#8221; to do a Device Code flow.</p>
<h3>Device Code flow</h3>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0021-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8467" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0021-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0021-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0021-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0021-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0021-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0021-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>I am not expecting this to work coz we have blocked device code flow firmwide. As a test though, I have an exception for myself for when registering a device, and I want to see what happens.</p>
<p>Clicking on &#8220;Sign in from another device&#8221; gives me a code. I can enter that in a browser, and as expected it failed.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0022-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8468" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0022-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0022-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0022-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0022-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0022-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0022-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>As expected it fails:<a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-12.48.47.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-8469" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-12.48.47.png" alt="" width="800" height="538" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-12.48.47.png 800w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-12.48.47-300x202.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-10-at-12.48.47-768x516.png 768w" sizes="auto, (max-width: 800px) 100vw, 800px" /></a></p>
<p>&nbsp;</p>
<p>And I can see it in the logs too:</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-lnfn-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8470" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-lnfn-1024x225.png" alt="" width="660" height="145" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-lnfn-1024x225.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-lnfn-300x66.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-lnfn-768x169.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-lnfn-1536x337.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-lnfn-2048x450.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Some things to note:</p>
<ul>
<li>The app in question is the Intune Company Portal &#8211; expected.</li>
<li>It is trying to access Windows Azure AD</li>
<li>Notice the Device Details are a mix of the computer I am doing device login from (the device Id is of my computer, the browser I am using is indeed Firefox, the machine itself is Hybrid joined, but the OS is picked up as Android).
<ul>
<li>There&#8217;s no particular significance to this, but it&#8217;s worth pointing out because the OS field/ Device Details may not always be accurate. I would have either excepted this to be &#8220;Windows&#8221;, or the whole Device Details property to be about the Teams phone itself.</li>
</ul>
</li>
</ul>
<h3>Username password flow</h3>
<p>Now let&#8217;s try the username password flow. I enter my email address, followed by password, followed by an MFA prompt (may or may not happen to anyone else trying this as it depends on your conditional access policies).</p>
<p>Things went weird after this, and I think that&#8217;s down to the very old firmware on the device. Nevertheless, here are some screenshots.</p>
<p>First, the company portal tries to sign in.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0025-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8471" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0025-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0025-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0025-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0025-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0025-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0025-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Then I got this error from Teams, which I clicked &#8220;OK&#8221; on and tried to sign in again at which point it again launched the Company Portal and tried to sign me in (didn&#8217;t ask for credentials this time coz I am already authenticated I suppose). That too gave me some errors.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0026-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8472" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0026-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0026-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0026-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0026-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0026-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0026-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0027-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8473" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0027-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0027-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0027-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0027-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0027-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0027-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0028-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8474" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0028-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0028-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0028-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0028-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0028-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0028-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0029-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8475" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0029-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0029-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0029-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0029-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0029-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0029-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>If I click &#8220;Try again&#8221; here, it went through the Company Portal steps again but with more success than last time. It got up to the stage where the device was setup, but then balked and took me back to a different sort of Company Portal sign in page.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0034-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8476" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0034-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0034-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0034-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0034-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0034-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0034-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0035-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8477" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0035-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0035-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0035-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0035-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0035-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0035-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Clicking &#8220;Sign in&#8221; here again tried to sign me in via the Company Portal (automatically, I wasn&#8217;t prompted for creds) and then it dropped me at the regular sign in page.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0037-scaled.jpeg"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8478" src="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0037-1024x768.jpeg" alt="" width="660" height="495" srcset="https://rakhesh.com/wp-content/uploads/2025/11/IMG_0037-1024x768.jpeg 1024w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0037-300x225.jpeg 300w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0037-768x576.jpeg 768w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0037-1536x1152.jpeg 1536w, https://rakhesh.com/wp-content/uploads/2025/11/IMG_0037-2048x1536.jpeg 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Again, I entered my email address and password and went through the drill&#8230; and again it looked like it was trying to register my device, but finally failed and dropped me back at this sign in page. At this point I gave up. I suspected the older firmware might not be supported any more.</p>
<p>Here&#8217;s what I see in the interactive and non-interactive sign-in logs (oldest entries at the bottom &#8211; read from bottom to top).</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-mfvl-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8479" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-mfvl-1024x416.png" alt="" width="660" height="268" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-mfvl-1024x416.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-mfvl-300x122.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-mfvl-768x312.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-mfvl-1536x624.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251110-mfvl-2048x832.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>This coincides with what I saw on the phone itself. Essentially:</p>
<ul>
<li>The Intune Company Portal app is what drives things</li>
<li>It talks to the Authentication Broker to do a Device Registration</li>
<li>Things don&#8217;t work <em>somewhere</em> &#8211; not in Conditional Access or Entra ID at least, coz everything is a success here &#8211; and that&#8217;s probably why things keep retrying.</li>
</ul>
<p>I figured I should update the firmware and try again. Rather than continue in this post though, I am going to start a new one. I realize this one has too many photos so I don&#8217;t want to load it all in a single post.</p>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f517.png" alt="🔗" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <a href="https://rakhesh.com/azure/teams-phone-and-their-authentication-flows-part-2/">Link to part 2</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Setting the scene on a Hue light via API</title>
		<link>https://rakhesh.com/mac/setting-the-scene-on-a-hue-light-via-api/</link>
		
		<dc:creator><![CDATA[rakhesh]]></dc:creator>
		<pubDate>Wed, 05 Nov 2025 20:06:48 +0000</pubDate>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[hue]]></category>
		<category><![CDATA[jq]]></category>
		<guid isPermaLink="false">https://rakhesh.com/?p=8451</guid>

					<description><![CDATA[Continuing my trilogy (here and here) of Hue API posts&#8230; in my previous post I detailed how I set the lights to turn or or off when I login to my Mac. Slight issue with that. When I used to do this via the Hue sensor, it would set the correct scene coz the sensor &#8230; <a href="https://rakhesh.com/mac/setting-the-scene-on-a-hue-light-via-api/" class="more-link">Continue reading <span class="screen-reader-text">Setting the scene on a Hue light via API</span></a>]]></description>
										<content:encoded><![CDATA[<p>Continuing my trilogy (<a href="https://rakhesh.com/gadgets/fun-and-games-with-the-hue-api/">here</a> and <a href="https://rakhesh.com/mac/turning-off-and-on-hue-lights-when-i-unlock-lock-or-sleep-wake-my-mac/">here</a>) of Hue API posts&#8230; in my previous post I detailed how I set the lights to turn or or off when I login to my Mac.</p>
<p>Slight issue with that. When I used to do this via the Hue sensor, it would set the correct scene coz the sensor was set to power on the light with a particular scene. Now when I turn it on directly, it just turns on to whatever scene was last set and not a specific one I want.</p>
<p>Figuring out how to do this was a bit more work. Lights don&#8217;t seem to have scenes associated with them, but there is a scene API so I started from there.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-05-at-19.28.28.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8452" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-05-at-19.28.28-1024x249.png" alt="" width="660" height="160" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-05-at-19.28.28-1024x249.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-05-at-19.28.28-300x73.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-05-at-19.28.28-768x187.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-05-at-19.28.28-1536x373.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-05-at-19.28.28.png 1762w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>To get a list of all my scenes:</p><pre class="urvanov-syntax-highlighter-plain-tag">curl --request GET \
    --url https://$BRIDGE_IP/clip/v2/resource/scene \
    --header "content-type: application/json" \
    --header "hue-application-key: $APIKEY" \
    --insecure</pre><p>The output of that looks like this:</p><pre class="urvanov-syntax-highlighter-plain-tag">{
  "errors": [],
  "data": [
    {
      "id": "00d34266-51d6-4c80-83fa-bf0ab36e5c3c",
      "id_v1": "/scenes/tLsH7eKgC2MbSukJ",
      "actions": [
        {
          "target": {
            "rid": "a9871b12-441e-44ba-8554-e458d6c9f65c",
            "rtype": "light"
          },
          "action": {
            "on": {
              "on": true
            },
            ...
          }
        },
        {
          "target": {
            "rid": "4f904f94-7997-4e41-ac43-0635a07472c4",
            "rtype": "light"
          },
          ...
        }
      ],
      "recall": {},
      "metadata": {
        "name": "First light",
        "image": {
          "rid": "ec790a2f-e63e-46cf-8a0f-1dd525e70f66",
          "rtype": "public_image"
        }
      },
      "group": {
        "rid": "baddd0aa-d3cd-4e13-8ddd-627d131f8b18",
        "rtype": "room"
      },
      "speed": 0.626984126984127,
      "auto_dynamic": false,
      "status": {
        "active": "inactive",
        "last_recall": "2025-03-10T17:40:45.090Z"
      },
      "type": "scene"
    },
    {
      "id": "06ab863f-f991-4659-af62-c9b6d4037d48",
      "id_v1": "/scenes/63HZDqdb-RJ0TTGH",
      ....
    }
  ]
}</pre><p>The scene name can be found in the metadata &gt; name property. What I learnt from some fooling around is that each of these scenes has a <code>rid</code> property which is the room id the scene is associated with. (And the lights themselves are in rooms have so have a <code>rid</code> associated with them, and that&#8217;s how you link a scene to a light).</p>
<p>I had some fun with <code>jq</code>. It&#8217;s been a while, and while I usually use PowerShell and never had to fuss too much with extracting data from JSON, this was a good excuse to stick with Bash and <code>jq</code>.</p>
<p>I piped the output of the above command into <code>jq</code> like this:</p><pre class="urvanov-syntax-highlighter-plain-tag">curl --request GET \
    --url https://$BRIDGE_IP/clip/v2/resource/scene \
    --header "content-type: application/json" \
    --header "hue-application-key: $APIKEY" \
    --insecure | 
jq '.data | .[] | { scene: .metadata.name, rid: .group.rid, id: .id }'</pre><p>The output is a list of scenes and room ids and scene ids.</p><pre class="urvanov-syntax-highlighter-plain-tag">{
  "scene": "Rolling hills",
  "rid": "baddd0aa-d3cd-4e13-8ddd-627d131f8b18",
  "id": "fdae49d6-cd84-4b00-9f30-b90e65d3bb13"
}
{
  "scene": "Night-time",
  "rid": "baddd0aa-d3cd-4e13-8ddd-627d131f8b18",
  "id": "ffbfe1af-8868-4b39-944b-519763636032"
}</pre><p>Next I went through the lights I wanted to modify, and found their room Ids.</p><pre class="urvanov-syntax-highlighter-plain-tag">ALLLIGHTS=(&lt;guid&gt; &lt;guid&gt;)
for LIGHT_ID in ${ALLLIGHTS[@]}; do
    curl --request GET \
        --url https://$BRIDGE_IP/clip/v2/resource/grouped_light/$LIGHT_ID \
        --header "content-type: application/json" \
        --header "hue-application-key: $APIKEY" \
        --insecure
done | jq '.data | .[] | .owner.rid'</pre><p>At this point I could have just dumped the output of the first command that gives scenes and room ids and ids, and searched for the room ids of my lights. But I wanted to keep things interesting, so I took one of the room Ids and decided to search all scenes for that room id.</p><pre class="urvanov-syntax-highlighter-plain-tag">curl --request GET \
    --url https://$BRIDGE_IP/clip/v2/resource/scene \
    --header "content-type: application/json" \
    --header "hue-application-key: $APIKEY" \
    --insecure | 
jq '.data | .[] | select(.metadata.name == "&lt;the scene I am interested in&gt;" and .group.rid == "&lt;room id from before&gt;") | .id'</pre><p>This will return a single id, that of the scene.</p>
<p>Later I realized I have two set of lights in two set of rooms, so I modifed the above to search for both rooms. (Both rooms had the same scene name, so that&#8217;s why I don&#8217;t search for multiple names).</p><pre class="urvanov-syntax-highlighter-plain-tag">curl --request GET \
    --url https://$BRIDGE_IP/clip/v2/resource/scene \
    --header "content-type: application/json" \
    --header "hue-application-key: $APIKEY" \
    --insecure | 
jq '.data | .[] | select(.metadata.name == "&lt;scene name&gt;" and (.group.rid == "&lt;room id 1&gt;" or .group.rid == "&lt;room id 2&gt;")) | .id'</pre><p>Now I have the two scene Ids I am interested in. Time to see if I can turn on the lights with these ids. Each scene Id is for a particular light. (<strong>Disclaimer</strong>: my situation might be a bit different from anyone else reading this. I have a set of lights that I put into separate &#8220;fake&#8221; rooms in Hue, so that&#8217;s why I am fussing about with rooms. I do this just so I can turn on the bedroom &#8220;room&#8221; lights without turning on the lights on my desk etc. too even though they are all in the bedroom).</p>
<p>The instructions on turning on a scene aren&#8217;t very clear in the API docs. All they have is the following which you send via a <code>PUT</code> request:</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-05-at-19.53.28.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8453" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-05-at-19.53.28-1024x239.png" alt="" width="660" height="154" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-05-at-19.53.28-1024x239.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-05-at-19.53.28-300x70.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-05-at-19.53.28-768x179.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-05-at-19.53.28.png 1046w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>So first I tried this:</p><pre class="urvanov-syntax-highlighter-plain-tag">ALLSCENES=(&lt;guid1&gt; &lt;guid2&gt;)
for SCENE_ID in ${ALLSCENES[@]}; do
    curl --request PUT \
        --url https://$BRIDGE_IP/clip/v2/resource/scene/$SCENE_ID \
        --header "content-type: application/json" \
        --header "hue-application-key: $APIKEY" \
        --data '{ "recall": {"action": "on"} }' \
        --insecure
done</pre><p>Didn&#8217;t work! I got an error:</p><pre class="urvanov-syntax-highlighter-plain-tag">{"data":[],"errors":[{"description":"error: 'json-schema validation', keyword: 'enum', details: {instanceRef: '#/recall/action', schemaRef: 'clip-api.schema.json#/definitions/RecallFeaturePut/properties/action'}"}]}

{"data":[],"errors":[{"description":"error: 'json-schema validation', keyword: 'enum', details: {instanceRef: '#/recall/action', schemaRef: 'clip-api.schema.json#/definitions/RecallFeaturePut/properties/action'}"}]}</pre><p>Then I took a look at the scene JSON again and saw the following:</p><pre class="urvanov-syntax-highlighter-plain-tag">...
      "recall": {},
      "metadata": {
        "name": "&lt;scene name&gt;",
        "image": {
          "rid": "&lt;guid&gt;",
          "rtype": "public_image"
        }
      },
      "group": {
        "rid": "&lt;guid&gt;",
        "rtype": "room"
      },
      "speed": 0.603,
      "auto_dynamic": false,
      "status": {
        "active": "inactive",
        "last_recall": "2025-05-19T11:57:57.032Z"
      },
      "type": "scene"
     ...</pre><p>Hmm, last status is <code>inactive</code>. So I changed my code to do <code>active</code>, instead of <code>on</code>.</p><pre class="urvanov-syntax-highlighter-plain-tag">ALLSCENES=(&lt;guid1&gt; &lt;guid2&gt;)
for SCENE_ID in ${ALLSCENES[@]}; do
    curl --request PUT \
        --url https://$BRIDGE_IP/clip/v2/resource/scene/$SCENE_ID \
        --header "content-type: application/json" \
        --header "hue-application-key: $APIKEY" \
        --data '{ "recall": {"action": "active"} }' \
        --insecure
done</pre><p>Boom! That worked. <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60e.png" alt="😎" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>Interestingly, you&#8217;d think that sending the action as <code>inactive</code> instead of <code>active</code> will turn it off, but that didn&#8217;t do anything. I got an error again:</p><pre class="urvanov-syntax-highlighter-plain-tag">{"data":[],"errors":[{"description":"error: 'json-schema validation', keyword: 'enum', details: {instanceRef: '#/recall/action', schemaRef: 'clip-api.schema.json#/definitions/RecallFeaturePut/properties/action'}"}]}

{"data":[],"errors":[{"description":"error: 'json-schema validation', keyword: 'enum', details: {instanceRef: '#/recall/action', schemaRef: 'clip-api.schema.json#/definitions/RecallFeaturePut/properties/action'}"}]}</pre><p>Which is fine, I guess. What you want to do is turn off the lights anyway.</p>
<p>Here&#8217;s an updated version of my script that turns on or off the lights:</p><pre class="urvanov-syntax-highlighter-plain-tag">#!/usr/bin/env bash

APIKEY="&lt;apikey&gt;"
BRIDGE_IP="&lt;ip address&gt;"
SENSOR_ID="&lt;sensor guid&gt;"

ALLLIGHTS=(&lt;light guid&gt; &lt;light guid&gt;)
ALLSCENES=(&lt;scene guid&gt; &lt;scene guid&gt;)

if [[ $1 == "enable" || $1 == "on" ]]; then
    echo "Enabling lights"
    
    for SCENE_ID in ${ALLSCENES[@]}; do
        curl --request PUT \
            --url https://$BRIDGE_IP/clip/v2/resource/scene/$SCENE_ID \
            --header "content-type: application/json" \
            --header "hue-application-key: $APIKEY" \
            --data '{ "recall": {"action": "active"} }' \
            --insecure
    done
else
    echo "Disabling lights"

    for LIGHT_ID in ${ALLLIGHTS[@]}; do
        curl --request PUT \
            --url https://$BRIDGE_IP/clip/v2/resource/grouped_light/$LIGHT_ID \
            --header "content-type: application/json" \
            --header "hue-application-key: $APIKEY" \
            --data '{ "on": { "on" : false } }' \
            --insecure
    done
fi</pre><p>And that&#8217;s all folks! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f913.png" alt="🤓" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p><strong>Update (7th Nov 2025)</strong>: I noticed that whenever I&#8217;d lock the screen Hammerspoon wouldn&#8217;t always run the script to turn off lights. It could be a time issue I suppose, coz reloading Hammerspoon and then locking the screen does. turn off lights. I am not entirely convinced it&#8217;s a time issue coz if I leave the system as is overnight and then login the next day, the script to turn on lights runs.</p>
<p>Maybe I am spending more working than I don&#8217;t? <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f913.png" alt="🤓" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>Anyways, slight hack to fix the issue. I added the following to my config:</p><pre class="urvanov-syntax-highlighter-plain-tag">hs.hotkey.bind({ "ctrl", "cmd" }, "q", function()
    hs.execute("~/desklights.sh disable", false)
    hs.caffeinate.lockScreen()
end)</pre><p>This causes Hammerspoon to bind to the keys I use for locking the screen, execute the script and then proceed to lock the screen. It&#8217;s not ideal coz it doesn&#8217;t capture the scenario where I step away for a while without locking the screen and the system goes to sleep and the script doesn&#8217;t run.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Turning off and on Hue lights when I unlock/ lock or sleep/ wake my Mac</title>
		<link>https://rakhesh.com/mac/turning-off-and-on-hue-lights-when-i-unlock-lock-or-sleep-wake-my-mac/</link>
		
		<dc:creator><![CDATA[rakhesh]]></dc:creator>
		<pubDate>Wed, 05 Nov 2025 14:44:09 +0000</pubDate>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[hammerspoon]]></category>
		<category><![CDATA[hue]]></category>
		<guid isPermaLink="false">https://rakhesh.com/?p=8441</guid>

					<description><![CDATA[Barely a few days since my previous post on having fun with the Hue API, and the sensor stopped responding to my API calls. There&#8217;s no error or anything, the sensor just doesn&#8217;t get enabled! I run the command as before: [crayon-6a54dba7ee9f4941160473/] The output is a success: [crayon-6a54dba7ee9f5688790828/] And querying the sensor shows its enabled &#8230; <a href="https://rakhesh.com/mac/turning-off-and-on-hue-lights-when-i-unlock-lock-or-sleep-wake-my-mac/" class="more-link">Continue reading <span class="screen-reader-text">Turning off and on Hue lights when I unlock/ lock or sleep/ wake my Mac</span></a>]]></description>
										<content:encoded><![CDATA[<p>Barely a few days <a href="https://rakhesh.com/gadgets/fun-and-games-with-the-hue-api/">since my previous post on having fun with the Hue API</a>, and the sensor stopped responding to my API calls. There&#8217;s no error or anything, the sensor just doesn&#8217;t get enabled!</p>
<p>I run the command as before:</p><pre class="urvanov-syntax-highlighter-plain-tag">APIKEY=$(pass apiKeys/hue)
BRIDGE_IP="&lt;ip&gt;"
SENSOR_ID="&lt;guid&gt;"

echo "${GREEN}<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2728.png" alt="✨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Enabling sensor${RESET}"
curl --request PUT \
    --url https://$BRIDGE_IP/clip/v2/resource/motion/$SENSOR_ID \
    --header "content-type: application/json" \
    --header "hue-application-key: $APIKEY" \
    --data '{ "enabled" : true }' \
    --insecure</pre><p>The output is a success:</p><pre class="urvanov-syntax-highlighter-plain-tag">{"data":[{"rid":"77064b38-907d-42ad-a65b-4f22178c3e6d","rtype":"motion"}],"errors":[]}</pre><p>And querying the sensor shows its enabled too:</p><pre class="urvanov-syntax-highlighter-plain-tag">curl --request GET --url https://$BRIDGE_IP/clip/v2/resource/motion/$SENSOR_ID --header "hue-application-key: $APIKEY" --insecure | jq</pre><p></p><pre class="urvanov-syntax-highlighter-plain-tag">{
  "errors": [],
  "data": [
    {
      "id": "&lt;guid&gt;",
      "id_v1": "/sensors/xx",
      "owner": {
        "rid": "&lt;guid&gt;",
        "rtype": "device"
      },
      "enabled": true,
      "motion": {
        "motion": true,
        "motion_valid": true,
        "motion_report": {
          "changed": "2025-11-04T20:31:09.366Z",
          "motion": true
        }
      },
      "sensitivity": {
        "status": "set",
        "sensitivity": 4,
        "sensitivity_max": 4
      },
      "type": "motion"
    }
  ]
}</pre><p>But it does nothing, and the app shows that it is indeed disabled!</p>
<p>So much for that. <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f612.png" alt="😒" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>The lights continue to work though, so I know my API key and things are good. It&#8217;s just the sensor and API.</p>
<p>Which got me thinking, maybe I can avoid it? I want the lights to come on when I am working on the Mac. Which means the display is on/ I&#8217;ve unlocked the screen. And when the display sleeps/ I&#8217;ve locked it, the lights can turn off. So what I really need is a way to trigger my scripts based on the Mac&#8217;s state.</p>
<p>Looking for options, I encountered <a href="https://formulae.brew.sh/formula/sleepwatcher">sleepwatcher</a>. (Thanks to ChatGPT actually, it&#8217;s way better than Google nowadays for getting search results &#8211; unfortunate. And even Gemini, while it suggested sleepwatcher, didn&#8217;t suggest any other options like ChatGPT did).</p>
<p>I didn&#8217;t use sleepwatcher coz looks like it needs the Rosetta layer on Apple silicon (not a problem but I am trying to keep things Apple silicon only <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f643.png" alt="🙃" class="wp-smiley" style="height: 1em; max-height: 1em;" />) plus it seems to be a bit more involved than just downloading and running. I don&#8217;t mind things that are a bit more involved, just that the second option ChatGPT suggested was <a href="https://www.hammerspoon.org/">Hammerspoon</a>, which I already use, so I figure I might as well invest more in that.</p>
<p>Turns out there&#8217;s a Hammerspoon module called <a href="https://www.hammerspoon.org/docs/hs.caffeinate.watcher.html">hs.caffeinate.watcher</a> that can watch for system sleep/ wake/ etc. events. Specifically, these ones:</p>
<ul>
<li>screensaverDidStart</li>
<li>screensaverDidStop</li>
<li>screensaverWillStop</li>
<li>screensDidLock</li>
<li>screensDidSleep</li>
<li>screensDidUnlock</li>
<li>screensDidWake</li>
<li>sessionDidBecomeActive</li>
<li>sessionDidResignActive</li>
<li>systemDidWake</li>
<li>systemWillPowerOff</li>
<li>systemWillSleep</li>
</ul>
<p>While ChatGPT gave me the code to use to enable this, I wanted to figure out what it does, so what follows is my exploration.</p>
<p>Based on the docs of the module, it looks like I have to create a watcher: <code>hs.caffeinate.watcher.new(fn)</code></p>
<p>In this <code>fn</code> is the function that will be called. These are <a href="https://www.tutorialspoint.com/lua/lua_functions.htm">Lua functions</a> and they must accept one parameter which is the event type (the ones defined above &#8211; <code>systemDidWake</code> and so on). These &#8220;event types&#8221; are actually constants &#8211; i.e. strings &#8211; and looks like I must use the full name like <code>hs.caffeinate.watcher.screensDidWake</code> (got from the <a href="https://www.hammerspoon.org/docs/hs.caffeinate.watcher.html#screensDidWake">docs</a>).</p>
<p>So you 1) define a Lua function which does what you need to do (run my script to enable or disable lights) based on the input, 2) create a new watcher instance with the function as input, and 3) start this watcher?</p>
<p>I created a bash script out of my Hue code earlier. This takes an argument and based on it enables or disables the lights.</p><pre class="urvanov-syntax-highlighter-plain-tag">#!/usr/bin/env bash

APIKEY="&lt;apiKey&gt;"
BRIDGE_IP="&lt;ip&gt;"
SENSOR_ID="&lt;guid&gt;"

ALLLIGHTS=(&lt;lightid1&gt; &lt;lightid2&gt;)

if [[ $1 == "enable" || $1 == "on" ]]; then
    echo "Enabling lights"
    
    for LIGHT_ID in ${ALLLIGHTS[@]}; do      
        curl --request PUT \
            --url https://$BRIDGE_IP/clip/v2/resource/grouped_light/$LIGHT_ID \
            --header "content-type: application/json" \
            --header "hue-application-key: $APIKEY" \
            --data '{ "on": { "on" : true } }' \
            --insecure
    done
else
    echo "Disabling lights"

    for LIGHT_ID in ${ALLLIGHTS[@]}; do
        curl --request PUT \
            --url https://$BRIDGE_IP/clip/v2/resource/grouped_light/$LIGHT_ID \
            --header "content-type: application/json" \
            --header "hue-application-key: $APIKEY" \
            --data '{ "on": { "on" : false } }' \
            --insecure
    done
fi</pre><p>(<strong>Note</strong>: Previously I would read the API key via <code>pass</code>, but I had to remove that because Hammerspoon would hang. I think it&#8217;s coz <code>pass</code> tries to get my GPG passphrase and fails).</p>
<p>Next, I created a function and put in my Hammerspoon config file:</p><pre class="urvanov-syntax-highlighter-plain-tag">function toggleLights(eventType)
  if (eventType == hs.caffeinate.watcher.screensDidUnlock or 
      eventType == hs.caffeinate.watcher.systemDidWake) then
    hs.execute("~/desklights.sh enable", false)

  elseif (eventType == hs.caffeinate.watcher.screensDidLock or 
          eventType == hs.caffeinate.watcher.systemWillSleep or 
          eventType == hs.caffeinate.watcher.systemWillPowerOff or 
          eventType == hs.caffeinate.watcher.screensDidSleep) then
    hs.execute("~/desklights.sh disable", false)
  
  end
end</pre><p>The function looks for event types that are do with the screen unlocking or the system waking and runs the script with the <code>enable</code> parameter; and for even types that are to do with screen locking or system sleeping or system powering off or screens sleeping it runs the script with the <code>disable</code> parameter. This makes use of <code>hs.execute()</code>  which takes as input the script &amp; its parameters, and a boolean value that determines if the command should be executed in the user&#8217;s login shell or not. In my case I don&#8217;t want it to, so I set it to <code>false</code>.</p>
<p>And finally, I created a new watcher and started it.</p><pre class="urvanov-syntax-highlighter-plain-tag">local lightsWatcher = hs.caffeinate.watcher.new(toggleLights)
lightsWatcher:start()</pre><p>Then I reloaded my Hammerspoon config, locked and unlocked my screen to test, and the lights turned off and on as expected. Awesome! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f973.png" alt="🥳" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>Before I end, while Googling on some of the issues I encountered (the bit where Hammerspoon used to hang coz of the <code>pass</code> command in my script) I encountered a <a href="https://dx13.co.uk/articles/2024/12/06/running-commands-on-unlock-macos/">blog post</a> and <a href="https://apple.stackexchange.com/questions/376203/how-to-run-script-at-wake">StackOverflow post</a> where others have done pretty much what I did above. That&#8217;s also from where ChatGPT gave me its suggestions (esp. the StackOverflow post which gives many more suggestions)&#8230; so credit where credit is due! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f64f.png" alt="🙏" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p><strong>Update (a few hours later)</strong>: See my <a href="https://rakhesh.com/mac/setting-the-scene-on-a-hue-light-via-api/">next post</a> for a follow-up.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Power Apps &#8211; The user has not been assigned any License and is disabled.</title>
		<link>https://rakhesh.com/azure/power-apps-the-user-has-not-been-assigned-any-license-and-is-disabled/</link>
		
		<dc:creator><![CDATA[rakhesh]]></dc:creator>
		<pubDate>Tue, 04 Nov 2025 15:05:33 +0000</pubDate>
				<category><![CDATA[Azure, Azure AD, Graph, M365]]></category>
		<category><![CDATA[power apps]]></category>
		<category><![CDATA[power platform]]></category>
		<guid isPermaLink="false">https://rakhesh.com/?p=8435</guid>

					<description><![CDATA[Encountered a red-herring of an error today. A colleague shared a Power App with another colleague and got the following: The user in question was indeed enabled and licensed. Also, interestingly, the user Id in the error didn&#8217;t match that in Entra ID (but then I guess it must be the Id of the object &#8230; <a href="https://rakhesh.com/azure/power-apps-the-user-has-not-been-assigned-any-license-and-is-disabled/" class="more-link">Continue reading <span class="screen-reader-text">Power Apps &#8211; The user has not been assigned any License and is disabled.</span></a>]]></description>
										<content:encoded><![CDATA[<p>Encountered a red-herring of an error today. A colleague shared a Power App with another colleague and got the following:</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251104-mzkh.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8436" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251104-mzkh-1024x514.png" alt="" width="660" height="331" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251104-mzkh-1024x514.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251104-mzkh-300x150.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251104-mzkh-768x385.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251104-mzkh-1536x770.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251104-mzkh-2048x1027.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>The user in question was indeed enabled and licensed. Also, interestingly, the user Id in the error didn&#8217;t match that in Entra ID (but then I guess it must be the Id of the object in Power Platform itself).</p>
<p>Even though my colleague got an error, when he looks at the &#8220;Share&#8221; pane the user is added there. But the user still can&#8217;t access the app.</p>
<p>Googling on this gave such amazing <a href="https://community.dynamics.com/forums/thread/details/?threadid=286b91e4-177b-ef11-a671-6045bda935ce">forum posts as this one</a> stating the obvious. But I put my thinking cap on and tried to get to the bottom of the issue. <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60a.png" alt="😊" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>If I create a dummy app and share it with the user, it works. But it wasn&#8217;t working or my colleague with his app.</p>
<p>The user in question was present in the environmnent under the list of users. But I noticed that the user didn&#8217;t have any Power Platform environment role assigned to him and I wondered if that mattered. My dummy app was just a new canvas app in the Personal Productivity/ Default, but my colleague&#8217;s app connected to SharePoint etc. and in an environment with Dataverse enabled. I know the &#8220;Basic User&#8221; role usually matters, so I took a look at that role in the Personal Productivity environment and he had that (not just him, everyone who had access to the environment had the role). So I granted the same role to him in the other environment, and now sharing works! (And for good measure I also granted that role to everyone who had access to the environment &#8211; which you can find by clicking &#8220;Edit&#8221; on the environment in Power Platform admin centre).</p>
<p>What a red-herring of an error!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Intune &#8211; App Protection policies and custom apps</title>
		<link>https://rakhesh.com/azure/intune-app-protection-policies-and-custom-apps/</link>
		
		<dc:creator><![CDATA[rakhesh]]></dc:creator>
		<pubDate>Mon, 03 Nov 2025 15:48:24 +0000</pubDate>
				<category><![CDATA[Azure, Azure AD, Graph, M365]]></category>
		<category><![CDATA[app protection policy]]></category>
		<category><![CDATA[intune]]></category>
		<guid isPermaLink="false">https://rakhesh.com/?p=8428</guid>

					<description><![CDATA[Every so often I get a request from one of our IT folks asking if I can add such and such app to our App Protection policies. Thing is, most of the time the app in question isn&#8217;t one that&#8217;s supported by Microsoft/ Intune. (See this article for a list of supported apps). Inevitably a &#8230; <a href="https://rakhesh.com/azure/intune-app-protection-policies-and-custom-apps/" class="more-link">Continue reading <span class="screen-reader-text">Intune &#8211; App Protection policies and custom apps</span></a>]]></description>
										<content:encoded><![CDATA[<p>Every so often I get a request from one of our IT folks asking if I can add such and such app to our App Protection policies. Thing is, most of the time the app in question isn&#8217;t one that&#8217;s supported by Microsoft/ Intune. (See <a href="https://learn.microsoft.com/en-us/intune/intune-service/apps/apps-supported-intune-apps">this article</a> for a list of supported apps).</p>
<p>Inevitably a follow-up question is whether I can <a href="https://learn.microsoft.com/en-us/intune/intune-service/apps/app-protection-policies#create-an-iosipados-or-android-app-protection-policy">add it to the custom apps section</a> as that will somehow bring the app into the App Protection policy umbrella. This is a mistaken suggestion and doesn&#8217;t work; and lest anyone think this blog post is me dissing upon those who come with such a suggestion, let me assure you that I too used to be in that group until last year or so. <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> No judgement here!</p>
<p>The custom apps section is meant for custom <em>in-house developed</em> apps, or line-of-business apps. It is not meant for you to find the bundle id of an app not in the default list of apps, add it there, and then things will magically work! This is the misunderstanding and the Microsoft&#8217;s <a href="https://learn.microsoft.com/en-us/intune/intune-service/apps/app-protection-policies#create-an-iosipados-or-android-app-protection-policy">documentation</a> too makes this clear:</p>
<blockquote><p>Custom apps are LOB apps that have been integrated with the Intune SDK or wrapped by the Intune App Wrapping Tool.</p></blockquote>
<p>So if an app is not supported by default by the App Protection policies, there&#8217;s not much we can do. There&#8217;s no <em>blanket</em> way to add the app, but workarouds might exist. For instance, I had a request to add ChatGPT to one of our App Protection policies so users can copy-paste into it, and the app doesn&#8217;t supprot App Protection policies so I couldn&#8217;t add it. As an alternative I suggested publishing it as a web-clip that opens in the managed browser.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251103-nsju.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8429" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251103-nsju-1024x992.png" alt="" width="660" height="639" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251103-nsju-1024x992.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251103-nsju-300x291.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251103-nsju-768x744.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251103-nsju-1536x1487.png 1536w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251103-nsju.png 1582w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>This adds a link to ChatGPT web on the home screen to the users it is assigned to. Clicking it will open ChatGPT web in a managed browser, which is under App Protection, and so one could copy paste into ChatGPT here to initiate a conversation and then go to regular ChatGPT to continue there. Not ideal, but that&#8217;s an example of a workaround.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-15.41.35.jpeg"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-8430" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-15.41.35.jpeg" alt="" width="556" height="302" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-15.41.35.jpeg 556w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-15.41.35-300x163.jpeg 300w" sizes="auto, (max-width: 556px) 100vw, 556px" /></a></p>
<p>Another option is to <a href="https://learn.microsoft.com/en-us/intune/intune-service/apps/app-protection-policy-settings-ios#data-transfer">tweak the number of characters</a> that are allowed for copy-paste (which works in this scenario as the request was for copy-paste). The default value is 0, which means no copy paste is allowed if the policy is set to block; but we can set a number to allow that many characters. The limit seems to be<a href="https://learn.microsoft.com/en-us/troubleshoot/mem/intune/app-protection-policies/troubleshoot-cut-copy-paste"> 65535 characters</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>KQL &#8211; Outputting the input of a function</title>
		<link>https://rakhesh.com/azure/kql-outputting-the-input-of-a-function/</link>
		
		<dc:creator><![CDATA[rakhesh]]></dc:creator>
		<pubDate>Mon, 03 Nov 2025 12:51:13 +0000</pubDate>
				<category><![CDATA[Azure, Azure AD, Graph, M365]]></category>
		<category><![CDATA[kql]]></category>
		<guid isPermaLink="false">https://rakhesh.com/?p=8412</guid>

					<description><![CDATA[Playing with Functions in KQL today. One of the things I wanted to do was troubleshoot the input I am passing to a Function. Couldn&#8217;t figure out a obvious way to do this, so here&#8217;s what I did. My objective here is simply to see if I am even passing inputs in correctly! At this &#8230; <a href="https://rakhesh.com/azure/kql-outputting-the-input-of-a-function/" class="more-link">Continue reading <span class="screen-reader-text">KQL &#8211; Outputting the input of a function</span></a>]]></description>
										<content:encoded><![CDATA[<p>Playing with <a href="https://learn.microsoft.com/en-us/azure/azure-monitor/logs/functions?tabs=portal">Functions</a> in KQL today. One of the things I wanted to do was troubleshoot the input I am passing to a Function. Couldn&#8217;t figure out a obvious way to do this, so here&#8217;s what I did.</p>
<p>My objective here is simply to see if I am even passing inputs in correctly! At this point I am very new to KQL functions so we are talking basics here. <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f600.png" alt="😀" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>Here&#8217;s what I did. I created a new KQL query like this:</p><pre class="urvanov-syntax-highlighter-plain-tag">let blah = datatable (Blah1:string, Blah2:string) [
    "111", "222"
];
blah
| extend UserInput = Users</pre><p>Then created a function out of it, and gave that function a single input called &#8216;Users&#8217;.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.15.21.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8413" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.15.21-1024x988.png" alt="" width="660" height="637" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.15.21-1024x988.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.15.21-300x289.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.15.21-768x741.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.15.21.png 1124w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>And now I can call the function in one of these ways:</p><pre class="urvanov-syntax-highlighter-plain-tag">// this way
RakTestFunc1(Users="rak")

// Or this way
RakTestFunc1("rak")</pre><p>And I can see the input parameter in the output.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.16.17.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8414" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.16.17-1024x272.png" alt="" width="660" height="175" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.16.17-1024x272.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.16.17-300x80.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.16.17-768x204.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.16.17.png 1068w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Seems a long winded way to do this, but until I learn of a better way this works I suppose.</p>
<p>For info, here&#8217;s what I am doing. First I create a <a href="https://learn.microsoft.com/en-us/kusto/query/datatable-operator?view=microsoft-fabric">datatable</a>. Why? Because KQL outputs are tables, and I figure I must start with a table so I can add some data to it. I couldn&#8217;t think of any other way, so I created a new dummy table. It doesn&#8217;t even need the two columns I put in there, just one is fine.</p><pre class="urvanov-syntax-highlighter-plain-tag">let blah = datatable (Blah1:string, Blah2:string) [
    "111", "222"
];</pre><p>Then I output this table and extend it by adding a column that shows my input.</p><pre class="urvanov-syntax-highlighter-plain-tag">blah
| extend UserInput = Users</pre><p>The &#8216;Users&#8217; above is my input. It will appear as an error in the console, but we can ignore that because the parameter is set in the function definition.</p>
<p>Ok, next steps. I want the function to have two inputs &#8211; a timespan and a string. How do I output these?</p>
<p>Here&#8217;s the new KQL:</p><pre class="urvanov-syntax-highlighter-plain-tag">let blah = datatable (Blah1:string, Blah2:string) [
    "111", "222"
];
blah
| extend TimeRangeInput = TimeRange
| extend UserInput = Users</pre><p>Add that paramter to the function defintion (click Save and it will open up the dialog box again to add/ remove parameters).</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.20.34.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8415" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.20.34-1022x1024.png" alt="" width="660" height="661" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.20.34-1022x1024.png 1022w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.20.34-300x300.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.20.34-150x150.png 150w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.20.34-768x769.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.20.34.png 1126w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Now if I run the function, I can see what happens:</p><pre class="urvanov-syntax-highlighter-plain-tag">// Do one of these, as before
RakTestFunc1(Users="rak")

RakTestFunc1("rak")</pre><p>As you can see, it&#8217;s picked up the default.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.22.12.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8416" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.22.12-1024x203.png" alt="" width="660" height="131" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.22.12-1024x203.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.22.12-300x59.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.22.12-768x152.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.22.12.png 1292w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>If I change the input, the output changes:</p><pre class="urvanov-syntax-highlighter-plain-tag">RakTestFunc1("rak", 12h)</pre><p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.23.32.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8417" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.23.32-1024x198.png" alt="" width="660" height="128" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.23.32-1024x198.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.23.32-300x58.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.23.32-768x149.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.23.32.png 1260w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Now I want to change &#8216;Users&#8217; to be a <a href="https://learn.microsoft.com/en-us/kusto/query/scalar-data-types/dynamic?view=microsoft-fabric">dynamic</a> type.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.35.26.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8418" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.35.26-1024x1015.png" alt="" width="660" height="654" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.35.26-1024x1015.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.35.26-300x297.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.35.26-150x150.png 150w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.35.26-768x761.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.35.26.png 1116w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Interestingly, once I did that and saved, it changed to a cast.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251103-lioa.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8419" src="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251103-lioa-1024x1019.png" alt="" width="660" height="657" srcset="https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251103-lioa-1024x1019.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251103-lioa-300x298.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251103-lioa-150x150.png 150w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251103-lioa-768x764.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/SCR-20251103-lioa.png 1140w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Things work if I provide an input.</p><pre class="urvanov-syntax-highlighter-plain-tag">RakTestFunc1(dynamic(['rak']), 12h)</pre><p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.37.23.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8420" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.37.23-1024x197.png" alt="" width="660" height="127" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.37.23-1024x197.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.37.23-300x58.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.37.23-768x148.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.37.23.png 1322w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>But fail if I don&#8217;t provide an input (<em>this is what I had set out to troubleshoot initially, which is why I was creating this dummy way of identifying the inputs passed to a function</em>).</p><pre class="urvanov-syntax-highlighter-plain-tag">RakTestFunc1(12h)</pre><p>I get an error: <code>Cast operator: dynamic casting expects string type values</code></p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.39.30.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8421" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.39.30-1024x265.png" alt="" width="660" height="171" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.39.30-1024x265.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.39.30-300x78.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.39.30-768x199.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.39.30.png 1112w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>This stumped me for a while and there was nothing I could do to get it working by using the default parameter value if I skipped it.</p>
<p>Finally I found out what to do. It looks like if I am skipping parameter values, I must mention what I am passing.</p>
<p>If I modify the above invocation to be this:</p><pre class="urvanov-syntax-highlighter-plain-tag">RakTestFunc1(TimeRange=12h)</pre><p>Now it works and picks up the default!</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.41.26.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8422" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.41.26-1024x182.png" alt="" width="660" height="117" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.41.26-1024x182.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.41.26-300x53.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.41.26-768x137.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.41.26.png 1394w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>And if I skip both parameters, that works too.</p><pre class="urvanov-syntax-highlighter-plain-tag">RakTestFunc1()</pre><p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.42.23.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8423" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.42.23-1024x168.png" alt="" width="660" height="108" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.42.23-1024x168.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.42.23-300x49.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.42.23-768x126.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.42.23.png 1410w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>What if I want the default to be empty? I changed it to <code>dynamic("")</code></p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.45.11.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8424" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.45.11-1010x1024.png" alt="" width="660" height="669" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.45.11-1010x1024.png 1010w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.45.11-296x300.png 296w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.45.11-768x779.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.45.11.png 1136w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>That works too.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.45.53.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8425" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.45.53-1024x169.png" alt="" width="660" height="109" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.45.53-1024x169.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.45.53-300x50.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.45.53-768x127.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.45.53.png 1512w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Does that comes across as an empty value though? I modified the underlying function thus:</p><pre class="urvanov-syntax-highlighter-plain-tag">let blah = datatable (Blah1:string, Blah2:string) [
    "111", "222"
];
blah
| extend TimeRangeInput = TimeRange
| extend UserInput = iff(isempty(Users), "==empty==", Users)</pre><p>Yup, that works.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.47.55.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8426" src="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.47.55-1024x170.png" alt="" width="660" height="110" srcset="https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.47.55-1024x170.png 1024w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.47.55-300x50.png 300w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.47.55-768x127.png 768w, https://rakhesh.com/wp-content/uploads/2025/11/Screenshot-2025-11-03-at-12.47.55.png 1496w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>That&#8217;s all!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Fun and games with the Hue API</title>
		<link>https://rakhesh.com/gadgets/fun-and-games-with-the-hue-api/</link>
		
		<dc:creator><![CDATA[rakhesh]]></dc:creator>
		<pubDate>Fri, 31 Oct 2025 13:43:00 +0000</pubDate>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Gadgets]]></category>
		<category><![CDATA[Linux & BSD]]></category>
		<category><![CDATA[hue]]></category>
		<guid isPermaLink="false">https://rakhesh.com/?p=8410</guid>

					<description><![CDATA[I have a Hue sensor on my desk that turns on and off the lights on the desk when I am at it. Since my desk is in our bedroom, and I don&#8217;t want the sensor to be active during weekends, I wanted an easy way to disable it on weekends and enable it after &#8230; <a href="https://rakhesh.com/gadgets/fun-and-games-with-the-hue-api/" class="more-link">Continue reading <span class="screen-reader-text">Fun and games with the Hue API</span></a>]]></description>
										<content:encoded><![CDATA[<p>I have a Hue sensor on my desk that turns on and off the lights on the desk when I am at it.</p>
<p>Since my desk is in our bedroom, and I don&#8217;t want the sensor to be active during weekends, I wanted an easy way to disable it on weekends and enable it after weekends (or maybe not enable it, I think I&#8217;ll enable it manually depending on whether I am actually working or not etc).</p>
<p>Yes I can do this via the app but it&#8217;s a bother and I wanted to just set and forget it. So I took a look at the <a href="https://developers.meethue.com/develop/hue-api-v2/">Hue API</a>.</p>
<p>First things first, you need the IP address of your Hue Bridge. I got that from the app. Then, you need to create an API key. The <a href="https://developers.meethue.com/develop/hue-api-v2/getting-started/">getting started section of the Hue API docs</a> has instructions on creating this. I did that, put the key into <a href="https://www.passwordstore.org/"><code>pass</code></a> and now I am ready to go.</p><pre class="urvanov-syntax-highlighter-plain-tag"># Once the API key is in pass I can refer to it thus (apiKeys/hue is the name of the secret)
APIKEY=$(pass apiKeys/hue)

# Also set the bridge IP in a variable
BRIDGE_IP="192.168.200.200"</pre><p>The <a href="https://developers.meethue.com/develop/hue-api-v2/api-reference/#resource_motion"><code>/resource/motion</code></a> endpoint is what deals with sensors. To query it I do:</p><pre class="urvanov-syntax-highlighter-plain-tag">curl --insecure --request 'GET' --header "hue-application-key: $APIKEY" --url "https://$BRIDGE_IP/clip/v2/resource/motion"</pre><p>I must use the <code>--insecure</code> switch due to certs (it is a self-signed cert). Also, to make the output readable, one can pipe it through <a href="https://jqlang.org/"><code>jq</code></a>:</p><pre class="urvanov-syntax-highlighter-plain-tag">curl --insecure --request 'GET' --header "hue-application-key: $APIKEY" --url "https://$BRIDGE_IP/clip/v2/resource/motion" | jq</pre><p>The output is a list of sensors:</p><pre class="urvanov-syntax-highlighter-plain-tag">{
  "errors": [],
  "data": [
    {
      "id": "72164b38-907d-42ad-a65b-4f22178c3e6d",
      "id_v1": "/sensors/47",
      "owner": {
        "rid": "20d706c2-1a05-4ef6-8a18-cdee0cf42b23",
        "rtype": "device"
      },
      "enabled": false,
      "motion": {
        "motion": false,
        "motion_valid": false
      },
      "sensitivity": {
        "status": "set",
        "sensitivity": 4,
        "sensitivity_max": 4
      },
      "type": "motion"
    }
  ]
}</pre><p>The <code>id</code> is what I need. Currently it is disabled, as can be seen from <code>"enabled": false</code>. I stored it in a variable <code>SENSOR_ID</code>.</p>
<p>Now, enabling it is simple:</p><pre class="urvanov-syntax-highlighter-plain-tag">curl --insecure \
     --request 'PUT' \
     --header "hue-application-key: $APIKEY" \
     --header "content-type: application/json" \
     --url "https://$BRIDGE_IP/clip/v2/resource/motion/$SENSOR_ID" \
     --data '{ "enabled" : true }'</pre><p>I must 1) change the request method to PUT, 2) set content-type headers for JSON, 3) modify the URL to include the sensor Id I previously got, and 4) send a JSON data that sets it to enabled.</p>
<p>Disabling is similarly easy, just change to <code>false</code>.</p><pre class="urvanov-syntax-highlighter-plain-tag">curl --insecure \
     --request 'PUT' \
     --header "hue-application-key: $APIKEY" \
     --header "content-type: application/json" \
     --url "https://$BRIDGE_IP/clip/v2/resource/motion/$SENSOR_ID" \
     --data '{ "enabled" : false }'</pre><p>So now I can put each of these into separate files and setup a cron job to run the disable file just before the weekend. (The cron snippet below disables the sensor at 7pm every day; and enables it at 8am every weekday).</p><pre class="urvanov-syntax-highlighter-plain-tag"># m h  dom mon dow   command

00 08 * * 1-5 /path/to/sensor_enable.sh
00 19 * * * /path/to/sensor_disable.sh</pre><p>Next, I also wanted to turn off or on the lights affected by the sensor. Coz I realized that say I was working late and the sensor gets disable at 7pm via the above job &#8211; the lights now continue to stay on coz there&#8217;s nothing to disable them. So I must also add some code to disable the lights when disabling the sensor.</p>
<p>I have two lights together in a group, controlled by the sensor. The lights are in fake room of their own. So I ran the following command to first find the room details:</p><pre class="urvanov-syntax-highlighter-plain-tag">curl --insecure --header "hue-application-key: $APIKEY" --request 'GET' --url https://$BRIDGE_IP/clip/v2/resource/room | jq</pre><p>One of the entries looks like this:</p><pre class="urvanov-syntax-highlighter-plain-tag">{
      "id": "baddd0bb-23cd-4e13-8ddd-627d131f8b18",
      "id_v1": "/groups/82",
      "children": [
        {
          "rid": "ef2f1315-7c24-4470-8d54-126026083250",
          "rtype": "device"
        },
        {
          "rid": "c7109087-2324-4ddb-9496-0b285ca87d5a",
          "rtype": "device"
        }
      ],
      "services": [
        {
          "rid": "1de1ee19-edd7-407c-8358-1dd1cc972143",
          "rtype": "grouped_light"
        }
      ],
      "metadata": {
        "name": "Desk",
        "archetype": "office"
      },
      "type": "room"
    },</pre><p>This is the room. You can see the group lights in there, with the id for the group.</p>
<p>Controlling a grouped light is the same way as <a href="https://developers.meethue.com/develop/hue-api-v2/core-concepts/#controlling-light">controlling a light</a>. Here&#8217;s what I did:</p><pre class="urvanov-syntax-highlighter-plain-tag">curl --request PUT \
     --url https://$BRIDGE_IP/clip/v2/resource/grouped_light/$LIGHT_ID \
     --header "content-type: application/json" \
     --header "hue-application-key: $APIKEY" \
     --data '{  "on": { "on" : false } }' \
     --insecure</pre><p>The above snippet turns it off; change the <code>false</code> to <code>true</code> to turn it on.</p>
<p>I added this code to the same script as disabling the sensor, and now it disables the sensor and turns off the light! Yay.</p>
<p><strong>Update (05 Nov 2025)</strong>: A follow up post <a href="https://rakhesh.com/mac/turning-off-and-on-hue-lights-when-i-unlock-lock-or-sleep-wake-my-mac/">here</a> as the API call to the sensor simply stopped working.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Adding a bunch of IPs to an Azure NSG</title>
		<link>https://rakhesh.com/azure/adding-a-bunch-of-ips-to-an-azure-nsg/</link>
		
		<dc:creator><![CDATA[rakhesh]]></dc:creator>
		<pubDate>Thu, 30 Oct 2025 01:05:53 +0000</pubDate>
				<category><![CDATA[Azure, Azure AD, Graph, M365]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[powershell]]></category>
		<guid isPermaLink="false">https://rakhesh.com/?p=8407</guid>

					<description><![CDATA[So&#8230; there was an Azure outage today. Related to Azure Front Door. That was my evening gone! As the resident PowerShell person on the incident call, as part of implementing some workarounds I had to add a bunch of IP addresses to a Network Security Group. I was given a text file with a bunch &#8230; <a href="https://rakhesh.com/azure/adding-a-bunch-of-ips-to-an-azure-nsg/" class="more-link">Continue reading <span class="screen-reader-text">Adding a bunch of IPs to an Azure NSG</span></a>]]></description>
										<content:encoded><![CDATA[<p>So&#8230; there was an <a href="https://www.theregister.com/2025/10/29/microsoft_azure_outage/">Azure outage today</a>. Related to Azure Front Door. That was my evening gone!</p>
<p>As the resident PowerShell person on the incident call, as part of implementing some workarounds I had to add a bunch of IP addresses to a Network Security Group. I was given a text file with a bunch of IP addresses, and my task was to add them all to the NSG as &#8220;Deny&#8221; for &#8220;Inbound&#8221; traffic. Here&#8217;s what I did:</p><pre class="urvanov-syntax-highlighter-plain-tag">Connect-AzAccount -Subscription &lt;SubscriptionName&gt;

# get the NSG
$nsg = Get-AzNetworkSecurityGroup -Name '&lt;NSG Name&gt;' -ResourceGroupName '&lt;Resource Group Name&gt;' 

$counter = 1000 # replace with whatever priority the rules must start from

foreach ($address in Get-Content .\ipblocklist.txt | Select-Object -Unique) {
  # construct the rule name
  # todo: the -replace needs improvement via some regex to remove *any* unaccepted characters
  $ruleName = "Deny-" + $($address -replace '\/','-' -replace '\:','')

  # rule name can't exceed 80 chracters
  if ($ruleName.Length -gt 80) { $ruleName = $ruleName.substring(0,79) }
  
  # add the rule to the in-memory copy of the rules
  $nsg | Add-AzNetworkSecurityRuleConfig -Name $ruleName -SourceAddressPrefix $address -Access "Deny" -DestinationPortRange "80","443" -DestinationAddressPrefix "*" -SourcePortRange "*" -Priority $counter -Protocol '*' -Direction 'Inbound'

  # increment the counter
  $counter++

}

# commit to Azure
$nsg | Set-AzNetworkSecurityGroup</pre><p>Had to piecemeal the code from various sources as the Microsoft Learn website was down so I couldn&#8217;t refer to it for the cmdlets and their switches.</p>
<p><img decoding="async" class="sFlh5c FyHeAf iPVvYb" src="https://i.pinimg.com/originals/b3/7a/07/b37a0705dacb48b6a6cc3bf4392a7626.gif" alt="Sweating Meme Gif" /></p>
<p>Two things the code could do with improving:</p>
<ul>
<li>Check if the IP address/ subnet is already in the NSG</li>
<li>Fix the bit where I construct the rule name to remove any unaccepted characters than just the two I happened to encounter.</li>
</ul>
<p>&nbsp;</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>A House of Dynamite (English movie)</title>
		<link>https://rakhesh.com/tv/a-house-of-dynamite-english-movie/</link>
		
		<dc:creator><![CDATA[rakhesh]]></dc:creator>
		<pubDate>Thu, 30 Oct 2025 00:52:05 +0000</pubDate>
				<category><![CDATA[TV, Movies, Music]]></category>
		<guid isPermaLink="false">https://rakhesh.com/?p=8404</guid>

					<description><![CDATA[I enjoyed &#8220;A House of Dynamite&#8221; which was released this week on Netflix. Not many people seem to like it though! Yes, the ending was abrupt, but I loved it. To me that made sense, and it was the only possible ending one could have for a movie like this. The movie wasn&#8217;t about the &#8230; <a href="https://rakhesh.com/tv/a-house-of-dynamite-english-movie/" class="more-link">Continue reading <span class="screen-reader-text">A House of Dynamite (English movie)</span></a>]]></description>
										<content:encoded><![CDATA[<p>I enjoyed &#8220;<a href="https://www.imdb.com/title/tt32376165/">A House of Dynamite</a>&#8221; which was released this week on Netflix. Not many people seem to like it though!</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/10/Screenshot-2025-10-30-at-00.48.12.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8405" src="https://rakhesh.com/wp-content/uploads/2025/10/Screenshot-2025-10-30-at-00.48.12-1024x414.png" alt="" width="660" height="267" srcset="https://rakhesh.com/wp-content/uploads/2025/10/Screenshot-2025-10-30-at-00.48.12-1024x414.png 1024w, https://rakhesh.com/wp-content/uploads/2025/10/Screenshot-2025-10-30-at-00.48.12-300x121.png 300w, https://rakhesh.com/wp-content/uploads/2025/10/Screenshot-2025-10-30-at-00.48.12-768x310.png 768w, https://rakhesh.com/wp-content/uploads/2025/10/Screenshot-2025-10-30-at-00.48.12.png 1430w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Yes, the ending was abrupt, but I loved it. To me that made sense, and it was the only possible ending one could have for a movie like this. The movie wasn&#8217;t about the ending, it was about the ordeal leading towards the ending. And whatever happens in the end &#8211; be it a false alarm or something devastating &#8211; that doesn&#8217;t take away from the fear and panic and decision making uncertainity around it. <em>That</em> was the point of the movie.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Beware including &#8220;My Sign-ins&#8221; in Conditional Access policies</title>
		<link>https://rakhesh.com/azure/beware-including-my-sign-ins-in-conditional-access-policies/</link>
		
		<dc:creator><![CDATA[rakhesh]]></dc:creator>
		<pubDate>Thu, 30 Oct 2025 00:43:31 +0000</pubDate>
				<category><![CDATA[Azure, Azure AD, Graph, M365]]></category>
		<category><![CDATA[conditional access]]></category>
		<category><![CDATA[my signins]]></category>
		<guid isPermaLink="false">https://rakhesh.com/?p=8400</guid>

					<description><![CDATA[Earlier this month Microsoft made the &#8220;My Sign-ins&#8221; app available under Conditional Access policies. That was great news to us. So far, as a &#8220;light touch&#8221; effort at zero trust, we had been restricting sign-ins to the &#8220;Office 365&#8221; app to firm managed devices. This includes all the common apps you&#8217;d expect to encounter when &#8230; <a href="https://rakhesh.com/azure/beware-including-my-sign-ins-in-conditional-access-policies/" class="more-link">Continue reading <span class="screen-reader-text">Beware including &#8220;My Sign-ins&#8221; in Conditional Access policies</span></a>]]></description>
										<content:encoded><![CDATA[<p>Earlier this month Microsoft made the <a href="https://www.vansurksum.com/2025/10/12/configuring-conditional-access-for-guest-users-allowing-only-office-365-and-essential-apps/">&#8220;My Sign-ins&#8221; app available under Conditional Access policies</a>. That was great news to us. So far, as a &#8220;light touch&#8221; effort at zero trust, we had been restricting sign-ins to the <a href="https://learn.microsoft.com/en-us/entra/identity/conditional-access/reference-office-365-application-contents">&#8220;Office 365&#8221; app</a> to firm managed devices. This includes all the common apps you&#8217;d expect to encounter when using the M365 suite, so is a pretty good starting point.</p>
<p>Not mentioned in the list of <a href="https://learn.microsoft.com/en-us/entra/identity/conditional-access/reference-office-365-application-contents">apps the &#8220;Office 365&#8221; app includes</a>, but seems to be implicitly covered in our testing, is the &#8220;My Profile&#8221; app. If you visit <a href="https://mysignins.microsoft.com/">https://mysignins.microsoft.com/</a> and click on any of &#8220;Devices&#8221;, &#8220;Organisations&#8221;, &#8220;My Groups&#8221; and &#8220;My Access&#8221; these come under the &#8220;My Profile&#8221; app.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251030-bidb.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-8402" src="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251030-bidb.png" alt="" width="540" height="984" srcset="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251030-bidb.png 540w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251030-bidb-165x300.png 165w" sizes="auto, (max-width: 540px) 100vw, 540px" /></a></p>
<p>So requiring a managed device to access the &#8220;Office 365&#8221; app ensures you can&#8217;t access any of these from a non-managed device either. But that still leaves &#8220;My Apps&#8221; and the <a href="https://mysignins.microsoft.com/">https://mysignins.microsoft.com/</a> page itself, and we were wondering if these can be locked down.</p>
<p>&#8220;My Apps&#8221; can be controlled. It should appear as an app that can be selected in conditional access, and if it does not one can enable it thus:</p><pre class="urvanov-syntax-highlighter-plain-tag">New-MgServicePrincipal -BodyParameter @{ AppId = "2793995e-0a7d-40d7-bd35-6968ba142197" }</pre><p>And then when we learnt that &#8220;My Sign-ins&#8221; too can be selected, it was great news. (If that app too doesn&#8217;t appear, run the same cmdlet as above but use &#8220;<code>19db86c3-b2b9-44cc-b339-36da233a3be2</code>&#8221; as the App Id. Better still, read that <a href="https://www.vansurksum.com/2025/10/12/configuring-conditional-access-for-guest-users-allowing-only-office-365-and-essential-apps/">linked post</a> coz that&#8217;s where I am copy pasting this info from).</p>
<p>So we naively went and added &#8220;My Sign-ins&#8221; and locked it too down to managed devices (<em>for a test group of course, not rolling out major changes to the whole firm!</em>). And that&#8217;s when we learnt that doing so is not a good idea.</p>
<p>Why? Coz while we were interested in blocking access to the <a href="https://mysignins.microsoft.com/">https://mysignins.microsoft.com/</a> page, a key part of the page is the &#8220;Security info&#8221; section. I never thought of it as part of the My Sign-ins page as by habit I tend to visit <a href="https://aka.ms/mysecurity">https://aka.ms/mysecurity</a> info for it, but that URL is actually <a href="https://mysignins.microsoft.com/security-info">https://<strong>mysignins.microsoft.com</strong>/security-info</a> and so technically it comes under the &#8220;My Sign-ins&#8221; app. <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60a.png" alt="😊" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Which means, with our policy in place, no one can even setup their MFA etc. from an unmanaged device &#8211; which is <em>not</em> what you want!</p>
<p>Of course, you <em>do</em> want to lock down who can register MFA, and we too do that by having a conditional access policy that <a href="https://learn.microsoft.com/en-us/entra/identity/conditional-access/policy-all-users-security-info-registration#create-a-policy-to-secure-registration">targets the &#8220;Register security info&#8221;</a> action to require MFA or be from trusted locations, and to get around the chicken-and-egg problem of someone from an untrusted location not being able to register their first MFA we rely on Temporary Access Passes (TAP) &#8211; but by locking down the &#8220;My Sign-ins&#8221; app to managed devices, that basically overrides the TAP policy.</p>
<p>So lesson learnt. We didn&#8217;t go ahead with locking down &#8220;My Sign-ins&#8221;. And like the <a href="https://www.vansurksum.com/2025/10/12/configuring-conditional-access-for-guest-users-allowing-only-office-365-and-essential-apps/">article</a> suggests, the real use of being able to select &#8220;My Sign-ins&#8221; in conditional access policies is to <span style="text-decoration: underline;">exclude</span> it from a policy when you want the policy to apply to &#8220;All Cloud Apps&#8221; except a few, not to include it.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Firefox multi-account containers and Entra ID SSO</title>
		<link>https://rakhesh.com/azure/firefox-multi-account-containers-and-entra-id-sso/</link>
		
		<dc:creator><![CDATA[rakhesh]]></dc:creator>
		<pubDate>Wed, 29 Oct 2025 13:12:38 +0000</pubDate>
				<category><![CDATA[Azure, Azure AD, Graph, M365]]></category>
		<category><![CDATA[conditional access]]></category>
		<category><![CDATA[device compliance]]></category>
		<category><![CDATA[device registration]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[SSO]]></category>
		<guid isPermaLink="false">https://rakhesh.com/?p=8384</guid>

					<description><![CDATA[I use Firefox. And I use the multi-account containers extension heavily in that. Very useful at work too when I have multiple test account and want to sign in with these, as I can open these up in separate tabs as opposed to separate windows as one would do with Edge etc. As part of &#8230; <a href="https://rakhesh.com/azure/firefox-multi-account-containers-and-entra-id-sso/" class="more-link">Continue reading <span class="screen-reader-text">Firefox multi-account containers and Entra ID SSO</span></a>]]></description>
										<content:encoded><![CDATA[<p>I use Firefox. And I use the <a href="https://addons.mozilla.org/en-GB/firefox/addon/multi-account-containers/">multi-account containers extension</a> heavily in that. Very useful at work too when I have multiple test account and want to sign in with these, as I can open these up in separate tabs as opposed to separate windows as one would do with Edge etc.</p>
<p>As part of testing some new Conditional Access policies however, wherein we were limiting users to hybrid joined or compliant devices, I noticed that my test accounts stopped working with the &#8220;You can&#8217;t get there from here&#8221; message.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lhuc.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8385" src="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lhuc-527x1024.png" alt="" width="527" height="1024" srcset="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lhuc-527x1024.png 527w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lhuc-154x300.png 154w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lhuc-768x1492.png 768w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lhuc-791x1536.png 791w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lhuc.png 808w" sizes="auto, (max-width: 527px) 100vw, 527px" /></a></p>
<p>My machine is hybrid joined, and yet the error message showed it as an unregistered device. The help message points to <a href="https://support.mozilla.org/en-US/kb/windows-sso">this Firefox KB article</a> to allow Windows SSO and that was enabled in my case already.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-litz.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8386" src="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-litz-1024x455.png" alt="" width="660" height="293" srcset="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-litz-1024x455.png 1024w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-litz-300x133.png 300w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-litz-768x341.png 768w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-litz-1536x682.png 1536w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-litz-2048x909.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>The article also said the account must be added to Windows itself. Under Settings:</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-ljeo-2.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8388" src="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-ljeo-2-1024x362.png" alt="" width="660" height="233" srcset="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-ljeo-2-1024x362.png 1024w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-ljeo-2-300x106.png 300w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-ljeo-2-768x271.png 768w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-ljeo-2-1536x543.png 1536w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-ljeo-2-2048x724.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-ljqd-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8389" src="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-ljqd-1024x282.png" alt="" width="660" height="182" srcset="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-ljqd-1024x282.png 1024w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-ljqd-300x83.png 300w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-ljqd-768x212.png 768w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-ljqd-1536x423.png 1536w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-ljqd-2048x565.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>I added my test account in there by clicking on &#8220;Add a work or school account&#8221;. Closed and opened Firefox, and still the account didn&#8217;t work.</p>
<p>Thinking this might be an issue with the containers extension itself, I opened up a new tab <span style="text-decoration: underline;">not in any container</span> and tried browsing with that, and that worked! I was prompted to select an account from all the accounts in the screenshot above, and selecting my test account let me know. So the issue was to do with the containers extension.</p>
<p>Googling on that brought me to this <a href="https://connect.mozilla.org/t5/ideas/enable-disable-windows-sso-per-account-container/idi-p/9399">forum post</a> and from there to this <a href="https://github.com/mozilla/multi-account-containers/wiki/Frequently-asked-questions#enable-windows-sso-in-a-specific-container">GitHub wiki</a>. Looks like this was fixed back in 2023 itself, just not exposed via the UI. Feel free to follow the steps in that wiki, else follow on to see what I did to fix it:</p>
<p>1) Opened up my profile folder.  If you don&#8217;t know where that is, click on Firefox help:</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-llkj.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8390" src="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-llkj-457x1024.png" alt="" width="457" height="1024" srcset="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-llkj-457x1024.png 457w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-llkj-134x300.png 134w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-llkj.png 554w" sizes="auto, (max-width: 457px) 100vw, 457px" /></a></p>
<p>More troubleshooting info:</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-llyf.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-8391" src="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-llyf.png" alt="" width="524" height="424" srcset="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-llyf.png 524w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-llyf-300x243.png 300w" sizes="auto, (max-width: 524px) 100vw, 524px" /></a></p>
<p>Click open folder to open the profiles folder.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lmdo.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8392" src="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lmdo-1024x595.png" alt="" width="660" height="383" srcset="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lmdo-1024x595.png 1024w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lmdo-300x174.png 300w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lmdo-768x446.png 768w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lmdo.png 1364w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>2) Open <code>containers.json</code>. Preferably in an editor like VS Code etc. such that you can format it (optional).</p>
<p>3) Find the entry for the container you are working with and note its <code>userContextId</code>.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lnjz.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-8393" src="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lnjz.png" alt="" width="910" height="386" srcset="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lnjz.png 910w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lnjz-300x127.png 300w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lnjz-768x326.png 768w" sizes="auto, (max-width: 910px) 100vw, 910px" /></a></p>
<p>4) Then open <code>about:config</code> in Firefox, accept the warning, and type in <code>network.http.windows-sso.container-enabled.&lt;the id&gt;</code>. <em>(There&#8217;s a typo in the screenshot below, the 21 should read as 12 coz that&#8217;s the correct id)</em>.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lnxp-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8394" src="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lnxp-1024x122.png" alt="" width="660" height="79" srcset="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lnxp-1024x122.png 1024w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lnxp-300x36.png 300w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lnxp-768x92.png 768w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lnxp-1536x183.png 1536w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lnxp-2048x244.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>This creates a new entry.</p>
<p>That&#8217;s all! Now if I try and browse via that container, it picks up all my accounts linked to the device, and I can select the one I want to use.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lpnv.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-8395" src="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lpnv.png" alt="" width="830" height="662" srcset="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lpnv.png 830w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lpnv-300x239.png 300w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lpnv-768x613.png 768w" sizes="auto, (max-width: 830px) 100vw, 830px" /></a></p>
<p>The SSO part doesn&#8217;t automagically know what account you want to use (since as far as it&#8217;s concerned you are signed in with more than one account) so you have to select the account each time. But that&#8217;s not an extension issue, and makes sense. It&#8217;s a minor irritation, but I can live with that. (And you encounter this in Edge etc. too if I am signed in to a profile with more than one account &#8211; just got to be careful of selecting the correct account each time).</p>
<h4>Bonus tip</h4>
<p>Since I want this to work with all my containers, and I see that they are in sequential order, what I did is 1) close Firefox and 2) open the <code>prefs.js</code> file in the profiles folder (this is what contains the settings from <code>about:config</code>). I then found the line that I had added:</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lqsn.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8396" src="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lqsn-1024x131.png" alt="" width="660" height="84" srcset="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lqsn-1024x131.png 1024w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lqsn-300x39.png 300w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lqsn-768x99.png 768w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lqsn.png 1402w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>And I made a bunch more copies of it with numbers starting from 1 &#8211; 25 (figured I am on 12 now and I might as well make a few extra for the future). Here&#8217;s the lines if anyone else wants to copy paste:</p><pre class="urvanov-syntax-highlighter-plain-tag">user_pref("network.http.windows-sso.container-enabled.1", true);
user_pref("network.http.windows-sso.container-enabled.2", true);
user_pref("network.http.windows-sso.container-enabled.3", true);
user_pref("network.http.windows-sso.container-enabled.4", true);
user_pref("network.http.windows-sso.container-enabled.5", true);
user_pref("network.http.windows-sso.container-enabled.6", true);
user_pref("network.http.windows-sso.container-enabled.7", true);
user_pref("network.http.windows-sso.container-enabled.8", true);
user_pref("network.http.windows-sso.container-enabled.9", true);
user_pref("network.http.windows-sso.container-enabled.10", true);
user_pref("network.http.windows-sso.container-enabled.11", true);
user_pref("network.http.windows-sso.container-enabled.12", true);
user_pref("network.http.windows-sso.container-enabled.13", true);
user_pref("network.http.windows-sso.container-enabled.14", true);
user_pref("network.http.windows-sso.container-enabled.15", true);
user_pref("network.http.windows-sso.container-enabled.16", true);
user_pref("network.http.windows-sso.container-enabled.17", true);
user_pref("network.http.windows-sso.container-enabled.18", true);
user_pref("network.http.windows-sso.container-enabled.19", true);
user_pref("network.http.windows-sso.container-enabled.20", true);
user_pref("network.http.windows-sso.container-enabled.21", true);
user_pref("network.http.windows-sso.container-enabled.22", true);
user_pref("network.http.windows-sso.container-enabled.23", true);
user_pref("network.http.windows-sso.container-enabled.24", true);
user_pref("network.http.windows-sso.container-enabled.25", true);</pre><p>That&#8217;s all!</p>
<h4>New containers</h4>
<p>Good to know. When I create a new container and the account I want to use is not listed, adding it via &#8220;User another account&#8221; <strong>will not help</strong>.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lsqj.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-8397" src="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lsqj.png" alt="" width="796" height="674" srcset="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lsqj.png 796w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lsqj-300x254.png 300w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-lsqj-768x650.png 768w" sizes="auto, (max-width: 796px) 100vw, 796px" /></a></p>
<p>Because all that will do is add the account within the container, not to Windows itself.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-ltnz.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-8398" src="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-ltnz.png" alt="" width="986" height="744" srcset="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-ltnz.png 986w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-ltnz-300x226.png 300w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251029-ltnz-768x580.png 768w" sizes="auto, (max-width: 986px) 100vw, 986px" /></a></p>
<p>Selected the &#8220;Signed in&#8221; account above will not work if there are any conditional access policies that need device compliance etc., so one must <strong>always remember to go and add it in Windows itself</strong> under <code>Settings</code> &gt; <code>Accounts</code> &gt; <code>Email &amp; Accounts</code>.</p>
<p>My thanks to the devlopers of the <a href="https://addons.mozilla.org/en-GB/firefox/addon/multi-account-containers/">extension</a> and also for their efforts in fixing this issue. <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f64f.png" alt="🙏" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>KQL &#8211; Get a list of users removed from an Entra ID group</title>
		<link>https://rakhesh.com/azure/kql-get-a-list-of-users-removed-from-an-entra-id-group/</link>
		
		<dc:creator><![CDATA[rakhesh]]></dc:creator>
		<pubDate>Mon, 27 Oct 2025 10:54:52 +0000</pubDate>
				<category><![CDATA[Azure, Azure AD, Graph, M365]]></category>
		<category><![CDATA[auditlogs]]></category>
		<category><![CDATA[kql]]></category>
		<guid isPermaLink="false">https://rakhesh.com/?p=8380</guid>

					<description><![CDATA[I wanted to get a list of users recently removed from an Entra ID group. I can see the removals in the audit logs, but there&#8217;s easy way to add a column showing removals. Enter KQL. We are sending all audit logs to a Log Analytics workspace, so I queried this info that way. This &#8230; <a href="https://rakhesh.com/azure/kql-get-a-list-of-users-removed-from-an-entra-id-group/" class="more-link">Continue reading <span class="screen-reader-text">KQL &#8211; Get a list of users removed from an Entra ID group</span></a>]]></description>
										<content:encoded><![CDATA[<p>I wanted to get a list of users recently removed from an Entra ID group. I can see the removals in the audit logs, but there&#8217;s easy way to add a column showing removals.</p>
<p>Enter KQL. We are sending all audit logs to a Log Analytics workspace, so I queried this info that way. <em>This is a very trivial use of KQL, but I am just putting it here for my own reference later on&#8230; </em></p>
<p>This code gives you everything from AuditLogs in the last 30 days that have &#8220;Remove member from group&#8221; as the activity.</p><pre class="urvanov-syntax-highlighter-plain-tag">AuditLogs
| where TimeGenerated &gt; ago(30d)
| where ActivityDisplayName == 'Remove member from group'</pre><p>This activity name corresponds to what you see in the portal too.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251027-jvlb.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-8381" src="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251027-jvlb.png" alt="" width="994" height="596" srcset="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251027-jvlb.png 994w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251027-jvlb-300x180.png 300w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251027-jvlb-768x460.png 768w" sizes="auto, (max-width: 994px) 100vw, 994px" /></a></p>
<p>Take one of the result and expand it until you get to TargetResources. The second entry in that has the group that&#8217;s affected. Expand that to get to the id, and then right click and filter for that.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251027-jvww.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8382" src="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251027-jvww-1024x473.png" alt="" width="660" height="305" srcset="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251027-jvww-1024x473.png 1024w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251027-jvww-300x138.png 300w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251027-jvww-768x355.png 768w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251027-jvww.png 1460w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>This modifies the code thus:</p><pre class="urvanov-syntax-highlighter-plain-tag">AuditLogs
| where TimeGenerated &gt; ago(30d)
| where ActivityDisplayName == 'Remove member from group' 
| where TargetResources[1].id == "&lt;the group guid&gt;"</pre><p>Then similarly expand the first entry under TargetResources, select UPN in there, and extend that. (In my case, the already selected entry didn&#8217;t have a user being removed&#8230; so I found an entry with a user removal).</p>
<p>Finally project just that extended column. The end result looks like this:</p><pre class="urvanov-syntax-highlighter-plain-tag">AuditLogs
| where TimeGenerated &gt; ago(30d)
| where ActivityDisplayName == 'Remove member from group' 
| where TargetResources[1].id == "&lt;the group guid&gt;"
| extend userPrincipalName_ = tostring(TargetResources[0].userPrincipalName)
| project userPrincipalName_</pre><p>This gives a list of UPNs removed from the group.</p>
<p>Of course now that you/ future me have read this blog post, just copy paste the above KQL and use it directly. :)</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Updating AllowToAddGuests</title>
		<link>https://rakhesh.com/azure/updating-allowtoaddguests/</link>
		
		<dc:creator><![CDATA[rakhesh]]></dc:creator>
		<pubDate>Wed, 22 Oct 2025 13:14:12 +0000</pubDate>
				<category><![CDATA[Azure, Azure AD, Graph, M365]]></category>
		<guid isPermaLink="false">https://rakhesh.com/?p=8378</guid>

					<description><![CDATA[A colleague reached out regarding an issue. He had created a Team and applied a sensitivity label to it. Unfortunately, this sensitivity label disabled external sharing. He then went ahead and remvoed the label, but he still couldn&#8217;t add external users (even after waiting for a few days). I took a look at the group &#8230; <a href="https://rakhesh.com/azure/updating-allowtoaddguests/" class="more-link">Continue reading <span class="screen-reader-text">Updating AllowToAddGuests</span></a>]]></description>
										<content:encoded><![CDATA[<p>A colleague reached out regarding an issue. He had created a Team and applied a sensitivity label to it. Unfortunately, this sensitivity label disabled external sharing. He then went ahead and remvoed the label, but he still couldn&#8217;t add external users (even after waiting for a few days).</p>
<p>I took a look at the group and found that sharing to guests is still disabled. This can be done via an EXO cmdlet: <code>Get-UnifiedGroup '&lt;group name&gt;' | fl *Gues*</code></p><pre class="urvanov-syntax-highlighter-plain-tag">AllowAddGuests : False</pre><p>Turns out the <code>Set-UnifiedGroup</code> cmdlet doesn&#8217;t have an option to toggle this. Got to use Graph API for this, specifically the<a href="https://learn.microsoft.com/en-us/graph/api/group-list-settings?view=graph-rest-1.0&amp;tabs=http"> group settings endpoint</a>. Here&#8217;s what I did:</p><pre class="urvanov-syntax-highlighter-plain-tag"># To get the group Id
$groupObj = Get-MgGroup -Filter "DisplayName eq '&lt;group name&gt;'"

$groupId = $groupObj.Id

# Get the existing settings. Need this for the GroupSettingId. 
$groupSettingsObj = Get-MgGroupSetting -GroupId $groupId

# To allow Guests - body of the request
$params = @{
	values = @(
		@{
			name = "AllowToAddGuests"
			value = "True"
		}
	)
}

Update-MgGroupSetting -GroupId $groupId -BodyParameter $params -GroupSettingId $groupSettingsObj.Id

# To view the setting via Graph after the change
(Get-MgGroupSetting -GroupId $groupId).Values</pre><p>&nbsp;</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Managing O365 add-ins with the Application Admin role</title>
		<link>https://rakhesh.com/azure/managing-o365-add-ins-with-the-application-admin-role/</link>
		
		<dc:creator><![CDATA[rakhesh]]></dc:creator>
		<pubDate>Mon, 20 Oct 2025 09:55:42 +0000</pubDate>
				<category><![CDATA[Azure, Azure AD, Graph, M365]]></category>
		<category><![CDATA[add-ins]]></category>
		<guid isPermaLink="false">https://rakhesh.com/?p=8374</guid>

					<description><![CDATA[O365 add-ins, also known as M365 Apps or Integrated Apps, are what you can deploy to Outlook etc. via this section of the M365 admin center. As per the docs, you need to be a Global Admin or an Exchange Admin (possibly with Application Admin, depending on certain conditions) to do this. And while that &#8230; <a href="https://rakhesh.com/azure/managing-o365-add-ins-with-the-application-admin-role/" class="more-link">Continue reading <span class="screen-reader-text">Managing O365 add-ins with the Application Admin role</span></a>]]></description>
										<content:encoded><![CDATA[<p>O365 add-ins, also known as M365 Apps or Integrated Apps, are what you can deploy to Outlook etc. via this section of the M365 admin center.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251020-jvbt.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8375" src="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251020-jvbt-1024x774.png" alt="" width="660" height="499" srcset="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251020-jvbt-1024x774.png 1024w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251020-jvbt-300x227.png 300w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251020-jvbt-768x581.png 768w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251020-jvbt-1536x1162.png 1536w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251020-jvbt.png 1936w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>As per the docs, you need to <a href="https://learn.microsoft.com/en-us/microsoft-365/admin/manage/centralized-deployment-of-add-ins?view=o365-worldwide#admin-requirements">be a Global Admin or an Exchange Admin (possibly with Application Admin, depending on certain conditions)</a> to do this. And while that seems to be the case with the portal, it looks like one can do some tasks with only the Application Admin role via PowerShell.</p>
<p>In my case I don&#8217;t need to deploy new add-ins, only manage who an existing add-in is deployed to.</p>
<p>The instructions for using PowerShell are in this <a href="https://learn.microsoft.com/en-us/microsoft-365/enterprise/use-the-centralized-deployment-powershell-cmdlets-to-manage-add-ins?view=o365-worldwide">link</a>, but below is what I did.</p><pre class="urvanov-syntax-highlighter-plain-tag"># Install the module, import it etc. 
Install-Module -Name O365CentralizedAddInDeployment
Import-Module -Name O365CentralizedAddInDeployment

# Login 
Connect-OrganizationAddInService</pre><p>After that, to get all the available add-ins, one can do:</p><pre class="urvanov-syntax-highlighter-plain-tag">Get-OrganizationAddIn</pre><p>And then to get the details of a specific add-in (e.g. publisher, version), one can do:</p><pre class="urvanov-syntax-highlighter-plain-tag">Get-OrganizationAddIn -ProductId 815b5912-1fb6-44ac-8971-f54600fdd599 | fl *</pre><p>And then to publish it to users and groups, one can do:</p><pre class="urvanov-syntax-highlighter-plain-tag"># Add a group...
Set-OrganizationAddInAssignments -ProductId 815b5912-1fb6-44ac-8971-f54600fdd599 -Add -Members "dd3772c5-3b54-48fb-b5a3-c724855f2275"

# Remove a group
Set-OrganizationAddInAssignments -ProductId 815b5912-1fb6-44ac-8971-f54600fdd599 -Remove -Members "dd3772c5-3b54-48fb-b5a3-c724855f2275"</pre><p></p><pre class="urvanov-syntax-highlighter-plain-tag"># Add a user...
Set-OrganizationAddInAssignments -ProductId 815b5912-1fb6-44ac-8971-f54600fdd599 -Add -Members "me@mydomain.com"

# Remove a user...
Set-OrganizationAddInAssignments -ProductId 815b5912-1fb6-44ac-8971-f54600fdd599 -Remove -Members "me@mydomain.com"</pre><p>That&#8217;s all!</p>
<p>Interestingly, sometimes the portal too let me do these tasks with the Application Admin role; but not always. I find PowerShell to more consistently work rather than the portal.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Azure Front Door, Azure Functions, Fragments, Managed Identity, Azure Tables, etc.</title>
		<link>https://rakhesh.com/azure/azure-front-door-azure-functions-fragments-managed-identity-azure-tables-etc/</link>
		
		<dc:creator><![CDATA[rakhesh]]></dc:creator>
		<pubDate>Sat, 18 Oct 2025 11:50:30 +0000</pubDate>
				<category><![CDATA[Azure, Azure AD, Graph, M365]]></category>
		<category><![CDATA[front door]]></category>
		<category><![CDATA[function app]]></category>
		<category><![CDATA[functions]]></category>
		<category><![CDATA[managed identities]]></category>
		<category><![CDATA[powershell]]></category>
		<category><![CDATA[tables]]></category>
		<guid isPermaLink="false">https://rakhesh.com/?p=8361</guid>

					<description><![CDATA[At work I spent some time yesterday working on a side project to setup forwarding from one set of URLs to another. We are migrating a service from our on-prem world to the cloud, and there are tons of URLs pointing that will now get invalidated as a result. In the on-prem world the URLs &#8230; <a href="https://rakhesh.com/azure/azure-front-door-azure-functions-fragments-managed-identity-azure-tables-etc/" class="more-link">Continue reading <span class="screen-reader-text">Azure Front Door, Azure Functions, Fragments, Managed Identity, Azure Tables, etc.</span></a>]]></description>
										<content:encoded><![CDATA[<p>At work I spent some time yesterday working on a side project to setup forwarding from one set of URLs to another. We are migrating a service from our on-prem world to the cloud, and there are tons of URLs pointing that will now get invalidated as a result.</p>
<p>In the on-prem world the URLs are of the form <code>https://olddomain.com/app/#/secret/secretId</code>, while in the cloud world it is very similar and looks like <code>https://newdomain.com/app/#/secret/newsecretId</code>. While it&#8217;s easy to setup a redirect from <code>olddomain.com</code> to <code>newdomain.com</code>, the problem is that the <code>secretId</code> changes to a new number <code>newsecretId</code> in the cloud, so you can&#8217;t just do a catch-all redirect.</p>
<p>I had a CSV file of the old and new secret Ids, and I wondered what I can do with it.</p>
<p><em>(By the way, side promo of a new tool I discovered recently. <a href="https://smoothcsv.com/">SmoothCSV</a>. If you deal regularly with CSVs, and don&#8217;t want to open Excel/ LibreOffice for it, nor use a regular text or code editor as that doesn&#8217;t look right either, this is the tool for you! Open source and cross-platform)</em>.</p>
<h3>Azure Front Door</h3>
<p>One more thing we wanted to do was have <code>https://olddomain.com/*</code> redirect to a SharePoint Online with some info on the migration for anyone using the old URLs, and so we had setup Azure Front Door for this. It&#8217;s a simple rule there to redirect any URLs beginning with <code>https://olddomain.com/</code> to <code>https://newdomain.com/</code> and I wanted to piggy back on that to handle URLs beginning with <code>https://olddomain.com/app/#/secret/</code> differently somehow.</p>
<p>This is where I encountered my first issue, which stumped me for a while. I only realized later what was happening, but by then I had stumbled upon a fix by blindly trying different things to get it working.</p>
<p>Here&#8217;s what I did. In Front Door I have two rules:</p>
<ul>
<li><strong>Rule 1</strong>: If a URL begins with <code>https://olddomain.com/app/#/secret/</code> send it to a dummy Azure Function I had setup. Stop processing any more rules.</li>
<li><strong>Rule 2</strong>: If a URL begins with <code>https://olddomain.com</code> send it to the SharePoint site.</li>
</ul>
<p>Rule 2 was the original rule, created as part of the initial requirement. Rule 1 is what I created and put as a higher priority over Rule 1, so I can do my per secret Id redirecting somehow.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251018-knuy-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8362" src="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251018-knuy-1024x515.png" alt="" width="660" height="332" srcset="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251018-knuy-1024x515.png 1024w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251018-knuy-300x151.png 300w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251018-knuy-768x386.png 768w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251018-knuy-1536x772.png 1536w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251018-knuy-2048x1029.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>Sounds like it should work, but it does not! I never hit Rule 2, I always keep going to Rule 1. I even changed Rule 2 to be a RegEx match, but that didn&#8217;t help either.</p>
<p>The fix, in the end, was to match on the URL beginning with <code>https://olddomain.com/app/</code>. That worked, and while I stumbled upon it by troubleshooting and removing parts of the URL to see what minimum works, I wasn&#8217;t sure why this was the fix. Nevertheless I moved on to the next part of the problem.</p>
<h3>Enter Azure Functions</h3>
<p>My idea was to have these URLs be redirected to an Azure Function. I&#8217;ll import the CSV file of old and new secret Ids into an Azure Tables, the Azure Function will receive an URL that looks like <code>https://olddomain.com/app/#/secret/secretId</code> from Azure Front Door, I will use PowerShell to extract the <code>secretId</code>, lookup the new value from Table, construct a new URL <code>https://newdomain.com/app/#/secret/newsecretId</code> and send that to the user.</p>
<p>Turns out sending a user a new URL is very easy. From a bit of Googling I learnt that a bit of HTML like this does the job:</p><pre class="urvanov-syntax-highlighter-plain-tag">&lt;html&gt;
&lt;head&gt;
    &lt;meta http-equiv="refresh" content="1;url=https://newdomain.com/app/#/secret/$newSecretId/" /&gt;
    &lt;title&gt;Redirecting...&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;/body&gt;
&lt;/html&gt;</pre><p>What the above does is that it <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/meta/http-equiv">tells the browser</a> receiving the page to do a refresh to the given URL after 1 second. I put <code>$newsecretId</code> above, coz that&#8217;s what will change based on the lookup.</p>
<p>In Azure Function, all I need do is the following (these are only snippets, not the whole code):</p><pre class="urvanov-syntax-highlighter-plain-tag"># Put the HTML from above into a variable; this assumes I have looked up and got a value for $newSecretId already
$html = @"
&lt;html&gt;
&lt;head&gt;
    &lt;meta http-equiv="refresh" content="1;url=https://newdomain.com/app/#/secret/$newSecretId/" /&gt;
    &lt;title&gt;Redirecting...&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;/body&gt;
&lt;/html&gt;
"@

# Return that
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = 200
    # This is crucial, without the ContentType the receiving browser will treat the HTML as plain text 
    ContentType = "text/html; charset=utf-8" 
    Body = $html
})

exit</pre><p>Neat!</p>
<p>But of course, this didn&#8217;t work as expected! There wouldn&#8217;t be a blog post if it did. <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f643.png" alt="🙃" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>What was failing was the part not in the snippet above. When I receive the redirected URL from Azure Front Door, I wasn&#8217;t getting the old secret Id in the link.</p>
<h3>A digression</h3>
<p>A bit of a digression first.</p>
<p>Typically an Azure Function URL looks like this: <code>https://&lt;APP_NAME&gt;.azurewebsites.net/api/&lt;FUNCTION_NAME&gt;/</code></p>
<p>It is possible to remove the <code>/api/</code> but by setting the <a href="https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-http-webhook-trigger?tabs=python-v2%2Cisolated-process%2Cnodejs-v4%2Cfunctionsv2&amp;pivots=programming-language-powershell#customize-the-http-endpoint">following</a> JSON in the <code>host.json</code> file.</p><pre class="urvanov-syntax-highlighter-plain-tag">{
    "version": "2.0",
    "isDefaultHostConfig": true,
    "managedDependency": {
        "Enabled": true
    },
    "extensionBundle": {
        "id": "Microsoft.Azure.Functions.ExtensionBundle",
        "version": "[4.*, 5.0.0)"
    },
    "extensions": {
        "http": {
            "routePrefix": ""
        }
    }
}</pre><p>It is also possible to remove the <code>&lt;FUNCTION_NAME&gt;</code> bit from the URL. The official doc tells you <a href="https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-http-webhook-trigger?tabs=python-v2%2Cisolated-process%2Cnodejs-v4%2Cfunctionsv2&amp;pivots=programming-language-powershell#customize-the-http-endpoint">how</a> but is incomplete as it only gives you examples of changing <code>&lt;FUNCTION_NAME&gt;</code> to something else. I wanted to remove it though, if possible, and when Googling didn&#8217;t help I turned to ChatGPT and from there I learnt that by modifying the <code>function.json</code> file thus, I can achieve it:</p><pre class="urvanov-syntax-highlighter-plain-tag">{
  "bindings": [
    {
      "authLevel": "anonymous",
      "type": "httpTrigger",
      "direction": "in",
      "name": "Request",
      "methods": [
        "get"
      ],
      "route": "{*path}"
    },
    {
      "type": "http",
      "direction": "out",
      "name": "Response"
    }
  ]
}</pre><p>The <code>"route": "{*path}"</code> bit makes it so that all paths are sent to this Function app. I couldn&#8217;t find much documentation on this wildcard property, but I did find some links that explained this property in general (like <a href="https://millerb.co.uk/2022/03/15/azure-functions-route-prefix.html">this one</a>, for instance). Glad I stumbled upon it via ChatGPT!</p>
<p>With this in place I can access whatever is sent to the function via the <code>$Request.Params.path</code> property (the name <code>path</code> matches whatever is puting in the route definition).</p>
<h3>Back to the issue</h3>
<p>So now I have Azure Front Door redirecting <code>https://olddomain.com/app/#/secret/secretId</code> to my Function App. When redirecting, it will send the browser to <code>&lt;APP_NAME&gt;.azurewebsites.net/</code> and also include <code>app/#/secret/secretId</code>.</p>
<p><a href="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251018-kwpy-scaled.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-8364" src="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251018-kwpy-1024x147.png" alt="" width="660" height="95" srcset="https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251018-kwpy-1024x147.png 1024w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251018-kwpy-300x43.png 300w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251018-kwpy-768x111.png 768w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251018-kwpy-1536x221.png 1536w, https://rakhesh.com/wp-content/uploads/2025/10/SCR-20251018-kwpy-2048x295.png 2048w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a></p>
<p>I know the <code>app/#/secret/secretId</code> part will come through, coz I am not setting anything in the Destination path and Destination fragment, so Front Door will send whatever it gets over. This is why I removed the extra bits from the Function URL, coz if I didn&#8217;t do that I&#8217;d have to put <code>api/&lt;FUNCTION_NAME&gt;/</code> in the Destination path, and I didn&#8217;t want to do that coz there&#8217;s no way to add that <em>and</em> have Front Door append whatever it gets. By leaving it blank, Front Door will send everything over.</p>
<p>And yet, in Azure Function, when I examine the path via the <code>$Request.Params.path</code> property, all I see is &#8220;<code>app/</code>&#8220;. Nothing after that! Odd.</p>
<h3>Fragments</h3>
<p>And now we come to fragments. <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f600.png" alt="😀" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>I had seen the word fragment in Front Door, but hadn&#8217;t paid much attention. But once I got to troubleshooting why the Function App wasn&#8217;t working, I learnt about it. This also explained to me why Front Door wasn&#8217;t working with my original URL way above when I first tried it.</p>
<p>You see, when you have a URL like <code>https://olddomain.com/app/<span style="color: #ff0000;">#/secret/secretId</span></code>, the <strong>bit after the # is what&#8217;s known as a fragment</strong>. We typically see them in web pages when used to send the browser to a specific heading/ id tag of a page. Since they are meant to be specific to things <em>within</em> a page, <strong>browsers don&#8217;t send them to the server</strong>. Because the idea is that the browser will only send a request to the page it wants, get it, and then use the fragment to find what it needs.</p>
<p>This is pretty neat from a privacy point of view, coz as you can guess from the URLs above what I am dealing with are some sort of secrets, and clearly the designers of that tool had security in mind and so they put the secret Id part of the URL within a fragment. So no proxy servers or firewalls will ever see the secret Id, all they will see is <code>https://olddomain.com/app/</code> which presumeably is a JavaScript page, and once that&#8217;s got the page itself will be sent <code>#/secret/secretId</code> and it can use that to show the secret Id. Nothing is captured anywhere. <em>(That&#8217;s my guess at least on how this is used&#8230;)</em></p>
<p>Unfortunately, this isn&#8217;t ideal for me, coz that&#8217;s why 1) Front Door never worked when I tried to match on URLs beginning with <code>https://olddomain.com/app/#/secret/</code> coz it never saw anything after the #, and 2) why Azure Function too cannot see the secret Id. There&#8217;s simply no way for me to get it! Aaargh!</p>
<h3>A bit of JavaScript to the rescue</h3>
<p>But hang on, yes Azure Function can&#8217;t see the full URL, but since it&#8217;s in the browser, presumeably I can use some JavaScript to get it?</p>
<p>Enter ChatGPT. I asked it for some JavaScript code which can be used to extract the URL from a browser and send to a different URL. It gave me the following code:</p><pre class="urvanov-syntax-highlighter-plain-tag">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;meta charset="utf-8" /&gt;
  &lt;title&gt;Redirecting...&lt;/title&gt;
  &lt;script&gt;
    (function() {
      const fragment = window.location.hash ? window.location.hash.substring(1) : "";
      const basePath = "${path}";
      let redirectUrl = "/redirect?path=" + encodeURIComponent(basePath);
      if (fragment) redirectUrl += "&amp;fragment=" + encodeURIComponent(fragment);
      window.location.replace(redirectUrl);
    })();
  &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;p&gt;Redirecting...&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</pre><p>Here&#8217;s what I can do. Azure Function gets called. It can check what the URL it received it (via the <code>$Request.Params.path</code> property). If the path is just &#8220;<code>app/</code>&#8220;, then it sends the above HTML to the browser.</p><pre class="urvanov-syntax-highlighter-plain-tag">Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = 200
    # This is crucial, without the ContentType the receiving browser will treat the HTML as plain text 
    ContentType = "text/html; charset=utf-8" 
    Body = $html
})

exit</pre><p>The browser receives the HTML. Within it is this JavaScript:</p><pre class="urvanov-syntax-highlighter-plain-tag">(function() {
    const fragment = window.location.hash ? window.location.hash.substring(1) : "";
    const basePath = "${path}";
    let redirectUrl = "/redirect?path=" + encodeURIComponent(basePath);
    if (fragment) redirectUrl += "&amp;fragment=" + encodeURIComponent(fragment);
    window.location.replace(redirectUrl);
})();</pre><p>The URL in the browser at this point would be <code>https://&lt;APP_NAME&gt;.azurewebsites.net/app/<span style="color: #800000;">#/secret/secretId</span></code> (the original URL would have been <code>https://olddomain.com/app/<span style="color: #800000;">#/secret/secretId</span></code> which will get redirected by Front Door to <code>https://&lt;APP_NAME&gt;.azurewebsites.net/app/</code> and then the browser will tack on <code><span style="color: #800000;">#/secret/secretId</span></code>).</p>
<p>The <code>window.location.hash</code> property is <a href="https://developer.mozilla.org/en-US/docs/Web/API/Location/hash">the bit after the #</a>. JavaScript can see that coz it is running within the browser in the page that I sent through. The code takes that, and does a redirect to <code>/redirect?path=&lt;whatever is in the URL as a path, in this case /app&gt;&amp;<span style="color: #800000;">fragment=&lt;whatever it extracted as fragment&gt;</span></code>.</p>
<p>This too goes over to my Azure Function, as that&#8217;s the redirect is relative to whatever page the browser is on! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60e.png" alt="😎" class="wp-smiley" style="height: 1em; max-height: 1em;" /> And since the Function is set to receive all URLs sent its way, it is thus called again but this time as <code>https://&lt;APP_NAME&gt;.azurewebsites.net/redirect?path=app&amp;<span style="color: #800000;">fragment=secret/secretId</span></code>. Voila!</p>
<h3>Extract the Secret Id</h3>
<p>Again, the Function can fetch the URL it received it (via the <code>$Request.Params.path</code> property). And if the path is just &#8220;<code>redirect/</code>&#8221; (coz that&#8217;s what we are sending to above), it can extract the parameters that were sent through. These are in the <code>$Request.Query</code> property, so we can get to the fragment by doing:</p>
<div>
<div>
<pre class="urvanov-syntax-highlighter-plain-tag">$fragment = $Request.Query.Fragment</pre><br />
Then do a bit of slice and dice to extract the Secret Id from &#8220;<code>secret/secretId</code>&#8220;, and Bob&#8217;s your uncle!</p>
<p>And then figure out what the new Secret Id would be, and this time send the original bit of HTML I pasted way above that does a redirect to <code>newdomain.com</code>. Phew!</p>
<h3>Using a Managed Identity with Azure Tables</h3>
<p>One of the things I also wanted to do was use Managed Identities when connecting the Function App to Azure Tables. Previously I used to use the <a href="https://www.powershellgallery.com/packages/AzTable/2.1.0">AzTable module</a> but that uses connection strings and I wanted to move away from that.</p>
<p>Using a Managed Identity is kind of straight forward. You need to assign the Managed Identity of the Function App the <code>Storage Table Data Contributor</code> <a href="https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles/storage#storage-table-data-contributor">role</a> on the Table. And then in the Function App:</p><pre class="urvanov-syntax-highlighter-plain-tag"># Get a token
$azToken = ConvertFrom-SecureString -SecureString (Get-AzAccessToken -ResourceType Storage -AsSecureString -ErrorAction Stop).token -AsPlainText -ErrorAction Stop

# Construct headers
$headers = @{
    "Authorization" = "Bearer $azToken"
    "x-ms-version" = "2017-11-09"
    "Accept" = "application/json;odata=nometadata"
}</pre><p>And then do the actual API calls to get data:</p><pre class="urvanov-syntax-highlighter-plain-tag">$uri = "https://$storageAccount.table.core.windows.net/$tableName(PartitionKey='$secretId',RowKey='$secretId')"

$azTableRowObj = Invoke-RestMethod -Uri $uri -Headers $headers -Method GET -ErrorAction Stop</pre><p>Thanks to <a href="https://learn.microsoft.com/en-us/rest/api/storageservices/query-entities">this</a> and <a href="https://learn.microsoft.com/en-us/rest/api/storageservices/querying-tables-and-entities">this</a> Microsoft link for helping me getting started.</p>
<p>One thing I couldn&#8217;t figure out though was how to do a filter without using a PartitionKey and RowKey. The links have instructions on doing that, but it never worked for me&#8230; and I didn&#8217;t bother spending more time as I could search via PartitionKey and RowKey anyways.</p>
</div>
</div>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Code Dependent (Book)</title>
		<link>https://rakhesh.com/books/code-dependent-book/</link>
		
		<dc:creator><![CDATA[rakhesh]]></dc:creator>
		<pubDate>Thu, 16 Oct 2025 10:25:52 +0000</pubDate>
				<category><![CDATA[Books, Audiobooks, Podcasts]]></category>
		<guid isPermaLink="false">https://rakhesh.com/?p=8359</guid>

					<description><![CDATA[Quick shoutout to &#8220;Code Dependent&#8221; by Madhumita Murgia. I stumbled upon it at Waterstones the other day and purchased it on a whim. So glad I did as it was a very enjoyable read. I was half expecting (and not looking forward to) it being a book that bashes AI (or goes the other way &#8230; <a href="https://rakhesh.com/books/code-dependent-book/" class="more-link">Continue reading <span class="screen-reader-text">Code Dependent (Book)</span></a>]]></description>
										<content:encoded><![CDATA[<p>Quick shoutout to <a href="https://www.goodreads.com/book/show/127282778-code-dependent">&#8220;Code Dependent&#8221; by Madhumita Murgia</a>. I stumbled upon it at Waterstones the other day and purchased it on a whim. So glad I did as it was a very enjoyable read.</p>
<p>I was half expecting (and not looking forward to) it being a book that bashes AI (or goes the other way and gushes over it). Instead, this book was very neutral. It went into a lot of AI usage (gig economy, data labelling, profiling people, video surveillance etc.) and had a very balanced view of things. Yes, AI is being used for a lot of harm, but it is also used in some good ways. I liked that.</p>
<p>To me AI is a symptom of the overall issue. I think over time our social structures and institutions have been failing &#8211; not due to immigation or people etc. but more due to lack of investment in them. Things might have been easier in the past for the rich countries at least due to colonialism and such when money was flowing around, but for a long time that hasn&#8217;t been the case and all countries have had to invest from whatever money they have via trade and other means. And this doesn&#8217;t always happen, and so over time the quality of things has gone done. Be it from simple things like replacing the person at the other end of the phone when you call your bank or shop &#8211; first with cheap workers in call centres in India etc. and later with AI &#8211; to bigger things like lack of proper healthcare facilities, doctors etc.</p>
<p>So in all of these cases we look to see how we can get away with the bare minimum. We try and remove the human element from it by trying to codify what is happening &#8211; break a task down to a series of steps (algorithms) &#8211; and then either hand that off to whoever can do it cheaply, or now AI. But the fundamental issue is that we are trying to convert an analog things (humans and the things they do) into something digital or discrete (a bunch of steps, a policy, <em>an algorithm</em>) because that&#8217;s all we can do to try and reduce costs instead of investing more. Try and capture what the <em>essence</em> of what a human is trying to do, then given it to some other human who can do it cheaply (either in a different country or somoene cheaper in country). And then the logical conclusion of this trend is to completely remove the human from the equation and replace them with an AI, because that&#8217;s all we are focussing on now &#8211; the steps, and how we can save costs.</p>
<p>This is why the world just feels shitty nowadays, I think. There&#8217;s less and less of a human touch/ interaction. Even when you get to talk to a human on the other end of a customer support call or shop etc., they have less autonomy because they have a script they must follow. They can&#8217;t make decisions because that&#8217;s what they have been told. And if you push back, you are just told that that&#8217;s the policy.</p>
<p>And this feeling is what Madhumita manages to convey in Code Dependent, though maybe not so explicitly. (These ideas have been going around in my head for a bit coz of all the non-fiction reading I do, especially &#8220;<a href="https://www.goodreads.com/book/show/60165391-survival-of-the-richest">Survival of the Richest</a>&#8221; recently which had similar themes, so my overall feeling of the book was also coloured with this).</p>
<p>A good read, highly recommended!</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
