<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Tim D&#39;Annecy</title>
    <link>https://tdannecy.me/</link>
    <description>&lt;img src=&#34;https://i.imgur.com/xKRZsEs.png&#34; width=&#34;500&#34;&gt;&lt;br&gt;tdannecy@gmail.com</description>
    <pubDate>Sun, 05 Apr 2026 07:57:11 +0000</pubDate>
    <image>
      <url>https://i.snap.as/PnTxo0BH.gif</url>
      <title>Tim D&#39;Annecy</title>
      <link>https://tdannecy.me/</link>
    </image>
    <item>
      <title>Fix the error &#34;Editing isn&#39;t available because your org hasn&#39;t finished setting up your email domain for M365 notifications yet&#34;</title>
      <link>https://tdannecy.me/fix-the-error-editing-isnt-available-because-your-org-hasnt-finished-setting?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[#Microsoft #Teams&#xA;&#xA;Recently, a user received the following error message in Teams when trying to schedule a webinar and send email notifications:&#xA;&#xA;Screenshot of the error&#xA;&#xA;  Editing isn&#39;t available because your org hasn&#39;t finished setting up your email domain for M365 notifications yet. Contact your admin for help.&#xA;&#xA;From what I could see, the user was licensed correctly and they have the permissions they need in the Teams Events settings. I searched for the text of the error message, but couldn&#39;t find any results on Google.&#xA;&#xA;Here are the steps for how I got it working.&#xA;&#xA;!--more--&#xA;&#xA;After some looking around, I found that Microsoft changed the requirements on February 1, 2026 to require additional setup in M365. &#xA;&#xA;Starting February 1, 2026, organizations using premium custom HTML templates for Teams Events email notifications must set up and verify their sending domain in Microsoft 365. Without this, custom templates can&#39;t be used, and event emails must originate from an authenticated, customer-owned domain.&#xA;&#xA;  Starting February 1, 2026, organizations using premium custom HTML templates for Teams Events email notifications must set up and verify their sending domain in Microsoft 365. Without this, custom templates can&#39;t be used, and event emails must originate from an authenticated, customer-owned domain.&#xA;&#xA;After reading this note, I was able to find the option in the M365 Admin center. &#xA;&#xA;Before getting started, you must have the Global Administrator role in Entra ID/M365, or a custom role with the MSGraph permission microsoft.directory/organization/allProperties/allTasks&#xA;&#xA;The user will need an M365 license with Teams (any Business or Enterprise license: Business Standard, E3, etc.) and a Teams Premium license.&#xA;&#xA;Also, make sure that you have allowed Teams Webinars for the user from the Event settings page: https://admin.teams.microsoft.com/one-policy/settings/events&#xA;&#xA;Navigate to the M365 Admin center: https://admin.cmd.ms/ and click Settings   Org settings&#xA;Search for &#34;Teams&#34;&#xA;Click on the &#34;Send email notifications from your domain&#34; option.&#xA;In the configuration pane, enable the &#34;Use a custom send-from domain address&#34; and add something like &#34;noreply&#34; and select your primary domain. &#xA;Click the Save button.&#xA;&#xA;Screenshot of the M365 Org Settings&#xA;&#xA;After changing this option, it can take about an hour for the changes to take effect. The user may need to restart Teams and/or log out and back in for the policies to refresh.&#xA;&#xA;Additional information &#xA;&#xA;https://learn.microsoft.com/en-us/microsoftteams/manage-email-communications&#xA;https://learn.microsoft.com/en-us/microsoft-365/admin/email/select-domain-to-use-for-email-from-microsoft-365-products?view=o365-worldwide&#xA;&#xA;Footer&#xA;&#xA;a href=&#34;https://remark.as/p/tdannecy.me/fix-the-error-editing-isnt-available-because-your-org-hasnt-finished-setting&#34;Discuss.../a]]&gt;</description>
      <content:encoded><![CDATA[<p><a href="https://tdannecy.me/tag:Microsoft" class="hashtag"><span>#</span><span class="p-category">Microsoft</span></a> <a href="https://tdannecy.me/tag:Teams" class="hashtag"><span>#</span><span class="p-category">Teams</span></a></p>

<p>Recently, a user received the following error message in Teams when trying to schedule a webinar and send email notifications:</p>

<p><img src="https://i.imgur.com/D0XgJG6.png" alt="Screenshot of the error"/></p>

<blockquote><p>Editing isn&#39;t available because your org hasn&#39;t finished setting up your email domain for M365 notifications yet. Contact your admin for help.</p></blockquote>

<p>From what I could see, the user was licensed correctly and they have the permissions they need in the Teams Events settings. I searched for the text of the error message, but couldn&#39;t find any results on Google.</p>

<p>Here are the steps for how I got it working.</p>



<p>After some looking around, I found that <a href="https://learn.microsoft.com/en-us/microsoftteams/manage-email-communications#:~:text=Starting%20February%201%2C%202026%2C%20organizations%20using%20premium%20custom%20HTML%20templates%20for%20Teams%20Events%20email%20notifications%20must%20set%20up%20and%20verify%20their%20sending%20domain%20in%20Microsoft%20365.%20Without%20this%2C%20custom%20templates%20can&#39;t%20be%20used%2C%20and%20event%20emails%20must%20originate%20from%20an%20authenticated%2C%20customer%2Downed%20domain.">Microsoft changed the requirements on February 1, 2026 to require additional setup in M365</a>.</p>

<p><img src="https://i.imgur.com/9hIbw3d.png" alt="Starting February 1, 2026, organizations using premium custom HTML templates for Teams Events email notifications must set up and verify their sending domain in Microsoft 365. Without this, custom templates can&#39;t be used, and event emails must originate from an authenticated, customer-owned domain."/></p>

<blockquote><p>Starting February 1, 2026, organizations using premium custom HTML templates for Teams Events email notifications must set up and verify their sending domain in Microsoft 365. Without this, custom templates can&#39;t be used, and event emails must originate from an authenticated, customer-owned domain.</p></blockquote>

<p>After reading this note, I was able to find the option in the M365 Admin center.</p>

<p>Before getting started, you must have the <strong>Global Administrator</strong> role in Entra ID/M365, or a custom role with the MSGraph permission <code>microsoft.directory/organization/allProperties/allTasks</code></p>

<p>The user will need an <strong>M365 license</strong> with Teams (any Business or Enterprise license: Business Standard, E3, etc.) and a <strong>Teams Premium</strong> license.</p>

<p>Also, make sure that you have allowed Teams Webinars for the user from the <strong>Event settings</strong> page: <a href="https://admin.teams.microsoft.com/one-policy/settings/events">https://admin.teams.microsoft.com/one-policy/settings/events</a></p>
<ol><li>Navigate to the M365 Admin center: <a href="https://admin.cmd.ms/">https://admin.cmd.ms/</a> and click <strong>Settings &gt; Org settings</strong></li>
<li>Search for “Teams”</li>
<li>Click on the “Send email notifications from your domain” option.</li>
<li>In the configuration pane, enable the “Use a custom send-from domain address” and add something like “noreply” and select your primary domain.</li>
<li>Click the <strong>Save</strong> button.</li></ol>

<p><img src="https://i.imgur.com/sTM19Mx.png" alt="Screenshot of the M365 Org Settings"/></p>

<p>After changing this option, it can take about an hour for the changes to take effect. The user may need to restart Teams and/or log out and back in for the policies to refresh.</p>

<h2 id="additional-information" id="additional-information">Additional information</h2>
<ul><li><a href="https://learn.microsoft.com/en-us/microsoftteams/manage-email-communications">https://learn.microsoft.com/en-us/microsoftteams/manage-email-communications</a></li>
<li><a href="https://learn.microsoft.com/en-us/microsoft-365/admin/email/select-domain-to-use-for-email-from-microsoft-365-products?view=o365-worldwide">https://learn.microsoft.com/en-us/microsoft-365/admin/email/select-domain-to-use-for-email-from-microsoft-365-products?view=o365-worldwide</a></li></ul>

<p><img src="https://i.imgur.com/fqURyMg.gif?style=center" alt="Footer"/></p>

<p><a href="https://remark.as/p/tdannecy.me/fix-the-error-editing-isnt-available-because-your-org-hasnt-finished-setting">Discuss...</a></p>
]]></content:encoded>
      <guid>https://tdannecy.me/fix-the-error-editing-isnt-available-because-your-org-hasnt-finished-setting</guid>
      <pubDate>Fri, 13 Mar 2026 14:42:22 +0000</pubDate>
    </item>
    <item>
      <title>Change the VS Code terminal directory with a keyboard shortcut </title>
      <link>https://tdannecy.me/change-the-vs-code-terminal-directory-with-a-keyboard-shortcut?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[#VSCode #PowerShell #Windows&#xA;&#xA;I love VS Code. It&#39;s got all of the features and tools that I need for coding and testing.&#xA;&#xA;When I&#39;m working on a file in the Editor pane and I want to run it or test a command in the Integrated Terminal, I have to manually navigate to the folder where the with a series of cd commands and Tab autocompletes. &#xA;&#xA;If I exit or restart the Terminal, the working directory switches back to the root of my workspace and I have to repeat the process over again.&#xA;&#xA;I have to deal with this annoying quirk dozens of times during the day and it gets very repetitive to keep typing cd.&#xA;&#xA;To make my life easier, I added the keyboard shortcut Ctrl+Alt+c on my Windows machine to change the Integrated Terminal&#39;s working directory to the folder of the file I&#39;m currently editing. This shortcut basically sends the command cd &#39;directory of the current file&#39; so I don&#39;t have to keep typing it.&#xA;&#xA;!--more--&#xA;&#xA;Run this script in the VS Code Integrated Terminal with PowerShell:&#xA;&#xA;$json = @&#39;&#xA;// Place your key bindings in this file to override the defaults&#xA;[&#xA;    {&#xA;        &#34;key&#34;: &#34;ctrl+alt+c&#34;,&#xA;        &#34;command&#34;: &#34;workbench.action.terminal.sendSequence&#34;,&#xA;        &#34;args&#34;: {&#xA;            &#34;text&#34;: &#34;cd \&#34;${fileDirname}\&#34;\u000D&#34;&#xA;        },&#xA;        &#34;when&#34;: &#34;editorTextFocus&#34;&#xA;    }&#xA;]&#xA;&#39;@&#xA;&#xA;Set-Content -Path &#34;$env:APPDATA\Code\User\keybindings.json&#34; -Value $json -Encoding UTF8&#xA;&#xA;After running this code in the Integrated Terminal, open the Command Palette (Ctrl+Shift+p), type and run &#34;Developer: Reload Window&#34;. This will reload Code and apply the new shortcuts.&#xA;&#xA;Now, you can use the keyboard shortcut Ctrl+Alt+c to quickly change the Integrated Terminal&#39;s working directory to the folder of the file you&#39;re currently editing.&#xA;&#xA;Footer image&#xA;&#xA;a href=&#34;https://remark.as/p/tdannecy.me/change-the-vs-code-terminal-directory-with-a-keyboard-shortcut&#34;Discuss.../a]]&gt;</description>
      <content:encoded><![CDATA[<p><a href="https://tdannecy.me/tag:VSCode" class="hashtag"><span>#</span><span class="p-category">VSCode</span></a> <a href="https://tdannecy.me/tag:PowerShell" class="hashtag"><span>#</span><span class="p-category">PowerShell</span></a> <a href="https://tdannecy.me/tag:Windows" class="hashtag"><span>#</span><span class="p-category">Windows</span></a></p>

<p>I love <a href="https://code.visualstudio.com">VS Code</a>. It&#39;s got all of the features and tools that I need for coding and testing.</p>

<p>When I&#39;m working on a file in the Editor pane and I want to run it or test a command in the Integrated Terminal, I have to manually navigate to the folder where the with a series of <code>cd</code> commands and <code>Tab</code> autocompletes.</p>

<p>If I exit or restart the Terminal, the working directory switches back to the root of my workspace and I have to repeat the process over again.</p>

<p>I have to deal with this annoying quirk dozens of times during the day and it gets very repetitive to keep typing <code>cd</code>.</p>

<p>To make my life easier, I added the keyboard shortcut <code>Ctrl</code>+<code>Alt</code>+<code>c</code> on my Windows machine to change the Integrated Terminal&#39;s working directory to the folder of the file I&#39;m currently editing. This shortcut basically sends the command <code>cd &#39;directory of the current file&#39;</code> so I don&#39;t have to keep typing it.</p>



<p>Run this script in the VS Code Integrated Terminal with PowerShell:</p>

<pre><code class="language-powershell">$json = @&#39;
// Place your key bindings in this file to override the defaults
[
    {
        &#34;key&#34;: &#34;ctrl+alt+c&#34;,
        &#34;command&#34;: &#34;workbench.action.terminal.sendSequence&#34;,
        &#34;args&#34;: {
            &#34;text&#34;: &#34;cd \&#34;${fileDirname}\&#34;\u000D&#34;
        },
        &#34;when&#34;: &#34;editorTextFocus&#34;
    }
]
&#39;@

Set-Content -Path &#34;$env:APPDATA\Code\User\keybindings.json&#34; -Value $json -Encoding UTF8
</code></pre>

<p>After running this code in the Integrated Terminal, open the Command Palette (<code>Ctrl</code>+<code>Shift</code>+<code>p</code>), type and run “Developer: Reload Window”. This will reload Code and apply the new shortcuts.</p>

<p>Now, you can use the keyboard shortcut <code>Ctrl</code>+<code>Alt</code>+<code>c</code> to quickly change the Integrated Terminal&#39;s working directory to the folder of the file you&#39;re currently editing.</p>

<p><img src="https://i.imgur.com/fiGARJs.gif" alt=""/></p>

<p><img src="https://i.imgur.com/vSp7N8O.gif?style=center" alt="Footer image"/></p>

<p><a href="https://remark.as/p/tdannecy.me/change-the-vs-code-terminal-directory-with-a-keyboard-shortcut">Discuss...</a></p>
]]></content:encoded>
      <guid>https://tdannecy.me/change-the-vs-code-terminal-directory-with-a-keyboard-shortcut</guid>
      <pubDate>Thu, 09 Oct 2025 13:20:28 +0000</pubDate>
    </item>
    <item>
      <title>Hide VSCode warning for PSUseApprovedVerbs</title>
      <link>https://tdannecy.me/hide-vscode-warning-for-psuseapprovedverbs?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[#VSCode #PowerShell #Windows #MacOS&#xA;&#xA;I use VSCode for all my coding. One thing I appreciate about the PowerShell module in VSCode is how it recommends best practices inline with my script. &#xA;&#xA;One of the recommended best practices for PowerShell is to use a list of approved verbs that define which words can be used in functions. This makes sense--I love the way PowerShell uses the Verb-Noun structure to keep things standardized and avoid confusion. &#xA;&#xA;Sometimes the recommended list of verbs doesn&#39;t include what I&#39;m trying to do, like &#34;Check&#34; or &#34;Verify&#34;. When I write a function using an unapproved verb, VSCode puts an orange squiggly line and these alerts get counted with others that I would consider more important:&#xA;&#xA;This makes my VSCode environment noisy and it can be difficult to sift through all the alerts to try to identify real issues. After some digging, I found a way to hide these alerts without turning off the whole PSScriptAnalyzer feature.&#xA;&#xA;  Note: In the code examples, I&#39;ve removed the signature blocks. Don&#39;t change or delete this section in your environment--If you do, you&#39;ll need to re-install the PowerShell extension and/or VSCode.&#xA;&#xA;!--more--&#xA;&#xA;Windows&#xA;&#xA;On Windows, the configuration file for this feature is located at C:\Users\USERNAME\.vscode\extensions\ms-vscode.powershell-2025.0.0\examples\PSScriptAnalyzerSettings.psd1 &#xA;&#xA;Open the file and move the PSUseApprovedVerbs from IncludeRules into the ExcludeRules section.&#xA;&#xA;Here is my updated PSScriptAnalyzerSettings.psd1 file:&#xA;&#xA;@{&#xA;    # ...&#xA;    IncludeRules = @(&#39;PSAvoidDefaultValueSwitchParameter&#39;,&#xA;                     &#39;PSMisleadingBacktick&#39;,&#xA;                     &#39;PSMissingModuleManifestField&#39;,&#xA;                     &#39;PSReservedCmdletChar&#39;,&#xA;                     &#39;PSReservedParams&#39;,&#xA;                     &#39;PSShouldProcess&#39;,&#xA;                     &#39;PSAvoidUsingCmdletAliases&#39;,&#xA;                     &#39;PSUseDeclaredVarsMoreThanAssignments&#39;)&#xA;&#xA;    # ...&#xA;    ExcludeRules = @(&#39;PSUseApprovedVerbs&#39;)&#xA;    # ...&#xA;}&#xA;&#xA;MacOS&#xA;&#xA;On MacOS, the configuration file is here: /Users/USERNAME/.vscode/extensions/ms-vscode.powershell-2025.0.0/modules/PSScriptAnalyzer/1.23.0/Settings/CmdletDesign.psd1&#xA;&#xA;  Note: Your module version might be different, so verify you have the correct path.&#xA;&#xA;Comment out the &#39;PSUseApprovedVerbs&#39; word like this:&#xA;&#xA;@{&#xA;    IncludeRules=@( #&#39;PSUseApprovedVerbs&#39;,&#xA;                   &#39;PSReservedCmdletChar&#39;,&#xA;                   &#39;PSReservedParams&#39;,&#xA;                   &#39;PSShouldProcess&#39;,&#xA;                   &#39;PSUseShouldProcessForStateChangingFunctions&#39;,&#xA;                   &#39;PSUseSingularNouns&#39;,&#xA;                   &#39;PSMissingModuleManifestField&#39;,&#xA;                   &#39;PSAvoidDefaultValueSwitchParameter&#39;)&#xA;}&#xA;...&#xA;&#xA;Conclusion&#xA;&#xA;After updating the file, restart VSCode. This should prevent that pesky popup and the alerts from appearing.&#xA;&#xA;Footer image&#xA;&#xA;a href=&#34;https://remark.as/p/tdannecy.me/hide-vscode-warning-for-psuseapprovedverbs&#34;Discuss.../a]]&gt;</description>
      <content:encoded><![CDATA[<p><a href="https://tdannecy.me/tag:VSCode" class="hashtag"><span>#</span><span class="p-category">VSCode</span></a> <a href="https://tdannecy.me/tag:PowerShell" class="hashtag"><span>#</span><span class="p-category">PowerShell</span></a> <a href="https://tdannecy.me/tag:Windows" class="hashtag"><span>#</span><span class="p-category">Windows</span></a> <a href="https://tdannecy.me/tag:MacOS" class="hashtag"><span>#</span><span class="p-category">MacOS</span></a></p>

<p>I use VSCode for all my coding. One thing I appreciate about the PowerShell module in VSCode is how it recommends best practices inline with my script.</p>

<p>One of the recommended best practices for PowerShell is to use <a href="https://learn.microsoft.com/en-us/powershell/scripting/developer/cmdlet/approved-verbs-for-windows-powershell-commands?view=powershell-7.5">a list of approved verbs</a> that define which words can be used in functions. This makes sense—I love the way PowerShell uses the <code>Verb-Noun</code> structure to keep things standardized and avoid confusion.</p>

<p>Sometimes the recommended list of verbs doesn&#39;t include what I&#39;m trying to do, like “Check” or “Verify”. When I write a function using an unapproved verb, VSCode puts an orange squiggly line and these alerts get counted with others that I would consider more important:</p>

<p><img src="https://i.imgur.com/kpBQ1Yr.png" alt=""/></p>

<p>This makes my VSCode environment noisy and it can be difficult to sift through all the alerts to try to identify real issues. After some digging, I found a way to hide these alerts without turning off the whole <code>PSScriptAnalyzer</code> feature.</p>

<blockquote><p><strong>Note:</strong> In the code examples, I&#39;ve removed the signature blocks. Don&#39;t change or delete this section in your environment—If you do, you&#39;ll need to re-install the PowerShell extension and/or VSCode.</p></blockquote>



<h2 id="windows" id="windows">Windows</h2>

<p>On Windows, the configuration file for this feature is located at <code>C:\Users\USERNAME\.vscode\extensions\ms-vscode.powershell-2025.0.0\examples\PSScriptAnalyzerSettings.psd1</code></p>

<p>Open the file and move the <code>PSUseApprovedVerbs</code> from IncludeRules into the ExcludeRules section.</p>

<p>Here is my updated <code>PSScriptAnalyzerSettings.psd1</code> file:</p>

<pre><code class="language-powershell">@{
    # ...
    IncludeRules = @(&#39;PSAvoidDefaultValueSwitchParameter&#39;,
                     &#39;PSMisleadingBacktick&#39;,
                     &#39;PSMissingModuleManifestField&#39;,
                     &#39;PSReservedCmdletChar&#39;,
                     &#39;PSReservedParams&#39;,
                     &#39;PSShouldProcess&#39;,
                     &#39;PSAvoidUsingCmdletAliases&#39;,
                     &#39;PSUseDeclaredVarsMoreThanAssignments&#39;)

    # ...
    ExcludeRules = @(&#39;PSUseApprovedVerbs&#39;)
    # ...
}
</code></pre>

<h2 id="macos" id="macos">MacOS</h2>

<p>On MacOS, the configuration file is here: <code>/Users/USERNAME/.vscode/extensions/ms-vscode.powershell-2025.0.0/modules/PSScriptAnalyzer/1.23.0/Settings/CmdletDesign.psd1</code></p>

<blockquote><p>Note: Your module version might be different, so verify you have the correct path.</p></blockquote>

<p>Comment out the <code>&#39;PSUseApprovedVerbs&#39;</code> word like this:</p>

<pre><code class="language-powershell">@{
    IncludeRules=@( #&#39;PSUseApprovedVerbs&#39;,
                   &#39;PSReservedCmdletChar&#39;,
                   &#39;PSReservedParams&#39;,
                   &#39;PSShouldProcess&#39;,
                   &#39;PSUseShouldProcessForStateChangingFunctions&#39;,
                   &#39;PSUseSingularNouns&#39;,
                   &#39;PSMissingModuleManifestField&#39;,
                   &#39;PSAvoidDefaultValueSwitchParameter&#39;)
}
# ...
</code></pre>

<h2 id="conclusion" id="conclusion">Conclusion</h2>

<p>After updating the file, restart VSCode. This should prevent that pesky popup and the alerts from appearing.</p>

<p><img src="https://i.imgur.com/Lgs7KOX.png" alt=""/></p>

<p><img src="https://i.imgur.com/YxlLByR.gif?style=center" alt="Footer image"/></p>

<p><a href="https://remark.as/p/tdannecy.me/hide-vscode-warning-for-psuseapprovedverbs">Discuss...</a></p>
]]></content:encoded>
      <guid>https://tdannecy.me/hide-vscode-warning-for-psuseapprovedverbs</guid>
      <pubDate>Tue, 22 Apr 2025 22:01:13 +0000</pubDate>
    </item>
    <item>
      <title>Betweenle - Nebula Bytes game remake</title>
      <link>https://tdannecy.me/betweenle-nebula-bytes-game-remake?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[#Pico8 #game&#xA;&#xA;Over the past few weeks, I&#39;ve been working on a demake of the Nebula Bytes Betweenle game in Pico8.&#xA;&#xA;There are some bugs in the way the scale is calculated and I want to add a two player mode, but it&#39;s ready for play now!&#xA;&#xA;Play it here: https://www.lexaloffle.com/bbs/?tid=147870&#xA;&#xA;iframe src=&#34;https://www.lexaloffle.com/bbs/widget.php?pid=tdannecybetweenle&#34; allowfullscreen width=&#34;621&#34; height=&#34;513&#34; style=&#34;border:none; overflow:hidden&#34;/iframe&#xA;&#xA;Footer&#xA;&#xA;a href=&#34;https://remark.as/p/tdannecy.me/betweenle-nebula-bytes-game-remake&#34;Discuss.../a]]&gt;</description>
      <content:encoded><![CDATA[<p><a href="https://tdannecy.me/tag:Pico8" class="hashtag"><span>#</span><span class="p-category">Pico8</span></a> <a href="https://tdannecy.me/tag:game" class="hashtag"><span>#</span><span class="p-category">game</span></a></p>

<p>Over the past few weeks, I&#39;ve been working on a demake of the <a href="https://betweenle.com">Nebula Bytes Betweenle game</a> in <a href="https://www.lexaloffle.com/pico-8.php">Pico8</a>.</p>

<p>There are some bugs in the way the scale is calculated and I want to add a two player mode, but it&#39;s ready for play now!</p>

<p>Play it here: <a href="https://www.lexaloffle.com/bbs/?tid=147870">https://www.lexaloffle.com/bbs/?tid=147870</a></p>

<p><img src="https://www.lexaloffle.com/bbs/cposts/td/tdannecy_betweenle-0.p8.png" alt=""/></p>

<p><img src="https://i.imgur.com/5MNj4k4.jpeg" alt=""/></p>

<iframe src="https://www.lexaloffle.com/bbs/widget.php?pid=tdannecy_betweenle" allowfullscreen="" width="621" height="513" style="border:none; overflow:hidden"></iframe>

<p><img src="https://i.imgur.com/fqURyMg.gif?style=center" alt="Footer"/></p>

<p><a href="https://remark.as/p/tdannecy.me/betweenle-nebula-bytes-game-remake">Discuss...</a></p>
]]></content:encoded>
      <guid>https://tdannecy.me/betweenle-nebula-bytes-game-remake</guid>
      <pubDate>Sun, 16 Mar 2025 17:16:15 +0000</pubDate>
    </item>
    <item>
      <title>Certified - Microsoft Cybersecurity Architect Expert</title>
      <link>https://tdannecy.me/certified-microsoft-cybersecurity-architect-expert?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[certification&#xA;&#xA;Kicking off 2025 with a certification! Just passed the SC-100 Exam and I am now a Microsoft Certified: Cybersecurity Architect Expert.&#xA;&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p><a href="https://tdannecy.me/tag:certification" class="hashtag"><span>#</span><span class="p-category">certification</span></a></p>

<p>Kicking off 2025 with a certification! Just passed the SC-100 Exam and I am now a Microsoft Certified: Cybersecurity Architect Expert.</p>

<p><img src="https://i.imgur.com/6sOr02x.png" alt=""/></p>
]]></content:encoded>
      <guid>https://tdannecy.me/certified-microsoft-cybersecurity-architect-expert</guid>
      <pubDate>Mon, 06 Jan 2025 16:36:32 +0000</pubDate>
    </item>
    <item>
      <title>Configure WhenIWork SAML SSO in Entra ID</title>
      <link>https://tdannecy.me/configure-wheniwork-saml-sso-in-entra-id?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[#Entra #AzureAD&#xA;&#xA;I&#39;ve been working with a company that uses When I Work for employee scheduling and time tracking. This week, they wanted to onboard the service to Entra ID so that users can have a seamless sign on experience through their Microsoft account and the IT admins can secure logins with Conditional Access and other features in the M365 platform.&#xA;&#xA;In my experience, every time I setup SAML Single Sign-On with SaaS apps in Entra ID, the language to get the integration setup is all over the place. Entity IDs, ACS, Issuer URLs, Endpoint URLs, Consumer URLs, Authority URLs, OAuth token endpoints--it&#39;s very confusing and changes for each service.&#xA;&#xA;For this project, we couldn&#39;t find a guide for onboarding WhenIWork to Entra ID for Single Sign-On, so I wanted to write these steps down for other admins who need it. Big thanks to Sam Guerra for figuring this out.&#xA;&#xA;!--more--&#xA;&#xA;To make these changes, you&#39;ll need these permissions at the minimum:&#xA;&#xA;Entra ID - Application Administrator Role (or Global Administrator)&#xA;WhenIWork - Admin Role&#xA;&#xA;If you&#39;re running Windows, you will also need Local Admin permissions to install the OpenSSL package on your PC (more info below).&#xA;&#xA;Setup the Enterprise Application in Entra ID&#xA;&#xA;First, navigate to the Entra ID/Azure AD portal: https://azad.cmd.ms/ &#xA;&#xA;Search for and open up the &#34;Enterprise Application&#34; blade. Click the &#34;New Application&#34; button:&#xA;&#xA;Click the &#34;Create your own application&#34; button. Add a descriptive title like &#34;When I Work SSO&#34;, &#34;WhenIWork&#34; or something similar, then click the &#34;Create&#34; button:&#xA;&#xA;Update the SAML attributes&#xA;&#xA;WhenIWork requires the Unique User Attribute in Entra ID to be set as &#34;user.Mail&#34; instead of the default &#34;user.userPrincipalName&#34;.&#xA;&#xA;To change this, scroll down to section 2 &#34;Attributes &amp; Claims&#34; and click the &#34;Edit&#34; button: &#xA;&#xA;Click on the row &#34;Unique User Identifier (Name ID)&#34;:&#xA;&#xA;Change the &#34;Source attribute&#34; dropdown and set it to &#34;user.mail&#34;:&#xA;&#xA;Save all of the changes and return to the WhenIWork &#34;Single sign-on&#34; blade.&#xA;&#xA;Add information from WhenIWork to Entra ID&#xA;&#xA;When your Enterprise Application is setup, we will need to get some information from WhenIWork using an account with Admin permissions.&#xA;&#xA;Open the following URL in a new tab https://appx.wheniwork.com/settings/saml and login, or open the WhenIWork admin console, login, and navigate to the Gear icon   General Settings at the top right of the page:&#xA;&#xA;Then, select the &#34;SAML SSO&#34; option from the menu on the left: &#xA;&#xA;In the other tab with Entra ID, navigate to the SSO blade located at Manage   Single sign-on and click the &#34;SAML&#34; option:&#xA;&#xA;To make things easier, move the WhenIWork SAML window on the left side of the screen, and the Entra ID Enterprise Application page to the right. &#xA;&#xA;Copy the following values from WhenIWork over to the Entra ID &#34;Basic SAML Configuration&#34; page and click the &#34;Save&#34; button when finished.&#xA;&#xA;| WhenIWork    | Entra ID                                   | Format                                                                   |&#xA;| ------------ | ------------------------------------------ | ------------------------------------------------------------------------ |&#xA;| Entity ID    | Identifier (Entity ID)                     | https://saml.wheniwork.com/5 digit WhenIWork customer ID               |&#xA;| Consumer URL | Reply URL (Assertion Consumer Service URL) | https://app.wheniwork.com/rest/saml/auth/5 digit WhenIWork customer ID |&#xA;&#xA;Add information from Entra ID to WhenIWork&#xA;&#xA;Now that you&#39;ve added the information to Entra from WhenIWork, you will need to add some information in the other direction.&#xA;&#xA;In Entra ID, navigate back to the Single sign-on blade and scroll down to the fourth section on the &#34;SAML-based Sign-on&#34; page. Copy the following values from Entra ID over into WhenIWork:&#xA;&#xA;| Entra ID                   | WhenIWork              | Format                                                                                                              |&#xA;| -------------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------- |&#xA;| Login URL                  | Endpoint URL (SSO)     | https://login.microsoftonline.com/36 character Entra Tenant ID/saml2                                          |&#xA;| Microsoft Entra Identifier | Issuer URL (Entity ID) | https://sts.windows.net/36 character Entra Tenant ID/ /br(Be sure to include the / backslash at the end.) |&#xA;&#xA;Get the certificate fingerprint&#xA;&#xA;Download the Certificate file. In the Entra ID tab, navigate to the &#34;Single sign-on&#34; blade of the Enterprise Application, scroll down to section 3 &#34;SAML Certificates&#34; and download the &#34;Certificate (Base 64)&#34; file in the .cer format.&#xA;&#xA;Now, you&#39;ll need to get the Certificate Fingerprint (not the Thumbprint listed in Entra ID) from the .cer file. This is a bit of a pain and requires some manual intervention.&#xA;&#xA;Here are the instructions for both Windows and MacOS to generate the fingerprint:&#xA;&#xA;Windows&#xA;&#xA;  These steps were performed on Windows 11.&#xA;&#xA;On a Windows PC, you will need to download and run an OpenSSL application to generate the fingerprint.&#xA;&#xA;Open a new tab and download the Win64OpenSSLLight EXE file directly from this link: https://slproweb.com/download/Win64OpenSSLLight-340.exe&#xA;&#xA;Alternatively, navigate to the product page and download the version you need: https://slproweb.com/products/Win32OpenSSL.html&#xA;&#xA;Install the EXE file and open the app from the Start menu named &#34;win64 OpenSSL Command Prompt:&#xA;&#xA;Run the following command to generate the thumbprint, changing the -in location to where you downloaded the file:&#xA;&#xA;openssl x509 -fingerprint -sha256 -in &#34;C:\Users\TimDAnnecy\Downloads\When I Work.cer&#34;&#xA;&#xA;Copy the output to the clipboard:&#xA;&#xA;Now, you need to remove the : colon characters from the Fingerprint string.&#xA;&#xA;You can do this manually, or by pasting it into Notepad and using the Find &amp; Replace tool (Ctrl + H) to &#34;Replace all&#34; and remove all colon characters. Once cleaned up, Copy the Fingerprint to the clipboard.&#xA;&#xA;Now, you need to remove the : colon characters from the Fingerprint string.&#xA;&#xA;You can do this manually, or by pasting it into Text Edit and using the Find &amp; Replace tool (Ctrl + H) to &#34;Replace all&#34; and remove all colon characters. Once cleaned up, Copy the Fingerprint back to the clipboard.&#xA;&#xA;MacOS&#xA;&#xA;  Note: These steps were performed on MacOS Sequoia 15.2 (24C98)&#xA;&#xA;On a Mac, the OpenSSL app is pre-installed and you can generate the thumbprint with a single command.&#xA;&#xA;Open the Terminal app and run the following command, changing the location to where you downloaded the file:&#xA;&#xA;openssl x509 -fingerprint -sha256 -in /Users/tim/Downloads/When\ I\ Work.cer&#xA;&#xA;Copy the Fingerprint output to the clipboard:&#xA;&#xA;Now, you need to remove the : colon characters from the Fingerprint string.&#xA;&#xA;You can do this manually, or by pasting it into TextEdit and using the Find &amp; Replace tool (Command + F) to &#34;Replace all&#34; and remove all colon characters. Once cleaned up, Copy the Fingerprint back to the clipboard.&#xA;&#xA;Paste the Fingerprint into WhenIWork&#xA;&#xA;Once you have the Fingerprint copied to the clipboard, return to the WhenIWork SAML page and paste the value into the &#34;Certificate Fingerprint (SAML)&#34; field and click the &#34;Save&#34; button. &#xA;&#xA;Test the integration&#xA;&#xA;Now that the attributes have been added in WhenIWork and in Entra ID, test to make sure the configuration is working by clicking the &#34;Test this application&#34; button:&#xA;&#xA;Click the &#34;Test sign-in&#34; button. If everything comes back successfully, you&#39;ve configured the Entra ID side correctly.&#xA;&#xA;Try signing into WhenIWork by navigating to the app in the M365 Waffle menu:&#xA;&#xA;Alternatively, navigate to the main WhenIWork homepage and click the &#34;Login&#34; link that the top right: https://wheniwork.com&#xA;&#xA;On the login page, click the &#34;Third Party Connect&#34; button:&#xA;&#xA;Choose &#34;SAML&#34;:&#xA;&#xA;Type the company name, account ID, or subdomain and click the &#34;Login&#34; button. &#xA;&#xA;  Note:  If you don&#39;t know the Account ID, you can get it by signing in with your Admin account (non-SSO sign in) and navigating to Gear icon   General Settings at the top right of the page. This information is in the Account ID field.&#xA;&#xA;If SAML is configured correctly, you&#39;ll get the Entra ID sign in flow and can sign in using your Microsoft account.&#xA;&#xA;Conclusion&#xA;&#xA;Thanks again to Sam Guerra for figuring out the certificates in this flow.&#xA;&#xA;a href=&#34;https://remark.as/p/tdannecy.me/configure-wheniwork-saml-sso-in-entra-id&#34;Discuss.../a]]&gt;</description>
      <content:encoded><![CDATA[<p><a href="https://tdannecy.me/tag:Entra" class="hashtag"><span>#</span><span class="p-category">Entra</span></a> <a href="https://tdannecy.me/tag:AzureAD" class="hashtag"><span>#</span><span class="p-category">AzureAD</span></a></p>

<p>I&#39;ve been working with a company that uses <a href="https://wheniwork.com">When I Work</a> for employee scheduling and time tracking. This week, they wanted to onboard the service to Entra ID so that users can have a seamless sign on experience through their Microsoft account and the IT admins can secure logins with Conditional Access and other features in the M365 platform.</p>

<p><img src="https://i.imgur.com/5qckznC.png" alt=""/></p>

<p>In my experience, every time I setup SAML Single Sign-On with SaaS apps in Entra ID, the language to get the integration setup is all over the place. Entity IDs, ACS, Issuer URLs, Endpoint URLs, Consumer URLs, Authority URLs, OAuth token endpoints—it&#39;s very confusing and changes for each service.</p>

<p>For this project, we couldn&#39;t find a guide for onboarding WhenIWork to Entra ID for Single Sign-On, so I wanted to write these steps down for other admins who need it. Big thanks to <a href="https://www.linkedin.com/in/samuel-guerra-b62b641a0/">Sam Guerra</a> for figuring this out.</p>



<p>To make these changes, you&#39;ll need these permissions at the minimum:</p>
<ul><li>Entra ID – Application Administrator Role (or Global Administrator)</li>
<li>WhenIWork – Admin Role</li></ul>

<p>If you&#39;re running Windows, you will also need Local Admin permissions to install the OpenSSL package on your PC (more info below).</p>

<h2 id="setup-the-enterprise-application-in-entra-id" id="setup-the-enterprise-application-in-entra-id">Setup the Enterprise Application in Entra ID</h2>

<p>First, navigate to the Entra ID/Azure AD portal: <a href="https://azad.cmd.ms/">https://azad.cmd.ms/</a></p>

<p>Search for and open up the “Enterprise Application” blade. Click the “New Application” button:</p>

<p><img src="https://i.imgur.com/JzhGcOp.png" alt=""/></p>

<p>Click the “Create your own application” button. Add a descriptive title like “When I Work SSO”, “WhenIWork” or something similar, then click the “Create” button:</p>

<p><img src="https://i.imgur.com/0J8MD6J.png" alt=""/></p>

<h2 id="update-the-saml-attributes" id="update-the-saml-attributes">Update the SAML attributes</h2>

<p>WhenIWork requires the Unique User Attribute in Entra ID to be set as “user.Mail” instead of the default “user.userPrincipalName”.</p>

<p>To change this, scroll down to section 2 “Attributes &amp; Claims” and click the “Edit” button:</p>

<p><img src="https://i.imgur.com/qYzroJq.png" alt=""/></p>

<p>Click on the row “Unique User Identifier (Name ID)”:</p>

<p><img src="https://i.imgur.com/KYQhu1j.png" alt=""/></p>

<p>Change the “Source attribute” dropdown and set it to “user.mail”:</p>

<p><img src="https://i.imgur.com/HCj0k0o.png" alt=""/></p>

<p>Save all of the changes and return to the WhenIWork “Single sign-on” blade.</p>

<h2 id="add-information-from-wheniwork-to-entra-id" id="add-information-from-wheniwork-to-entra-id">Add information from WhenIWork to Entra ID</h2>

<p>When your Enterprise Application is setup, we will need to get some information from WhenIWork using an account with Admin permissions.</p>

<p>Open the following URL in a new tab <a href="https://appx.wheniwork.com/settings/saml">https://appx.wheniwork.com/settings/saml</a> and login, or open the WhenIWork admin console, login, and navigate to the <strong>Gear icon &gt; General Settings</strong> at the top right of the page:</p>

<p><img src="https://i.imgur.com/JIKRUen.png" alt=""/></p>

<p>Then, select the “SAML SSO” option from the menu on the left:</p>

<p><img src="https://i.imgur.com/NZvvvOF.png" alt=""/></p>

<p>In the other tab with Entra ID, navigate to the SSO blade located at <strong>Manage &gt; Single sign-on</strong> and click the “SAML” option:</p>

<p><img src="https://i.imgur.com/DHn0Ngr.png" alt=""/></p>

<p>To make things easier, move the WhenIWork SAML window on the left side of the screen, and the Entra ID Enterprise Application page to the right.</p>

<p>Copy the following values from WhenIWork over to the Entra ID “Basic SAML Configuration” page and click the “Save” button when finished.</p>

<table>
<thead>
<tr>
<th>WhenIWork</th>
<th>Entra ID</th>
<th>Format</th>
</tr>
</thead>

<tbody>
<tr>
<td>Entity ID</td>
<td>Identifier (Entity ID)</td>
<td><a href="https://saml.wheniwork.com/">https://saml.wheniwork.com/</a>&lt;5 digit WhenIWork customer ID&gt;</td>
</tr>

<tr>
<td>Consumer URL</td>
<td>Reply URL (Assertion Consumer Service URL)</td>
<td><a href="https://app.wheniwork.com/rest/saml/auth/">https://app.wheniwork.com/rest/saml/auth/</a>&lt;5 digit WhenIWork customer ID&gt;</td>
</tr>
</tbody>
</table>

<p><img src="https://i.imgur.com/kR69W3J.png" alt=""/></p>

<h2 id="add-information-from-entra-id-to-wheniwork" id="add-information-from-entra-id-to-wheniwork">Add information from Entra ID to WhenIWork</h2>

<p>Now that you&#39;ve added the information to Entra from WhenIWork, you will need to add some information in the other direction.</p>

<p>In Entra ID, navigate back to the Single sign-on blade and scroll down to the fourth section on the “SAML-based Sign-on” page. Copy the following values from Entra ID over into WhenIWork:</p>

<table>
<thead>
<tr>
<th>Entra ID</th>
<th>WhenIWork</th>
<th>Format</th>
</tr>
</thead>

<tbody>
<tr>
<td>Login URL</td>
<td>Endpoint URL (SSO)</td>
<td><a href="https://login.microsoftonline.com/**">https://login.microsoftonline.com/**</a>&lt;36 character Entra Tenant ID&gt;**/saml2</td>
</tr>

<tr>
<td>Microsoft Entra Identifier</td>
<td>Issuer URL (Entity ID)</td>
<td><a href="https://sts.windows.net/**">https://sts.windows.net/**</a>&lt;36 character Entra Tenant ID&gt;**/ </br>(Be sure to include the <code>/</code> backslash at the end.)</td>
</tr>
</tbody>
</table>

<p><img src="https://i.imgur.com/NtOl0YY.png" alt=""/></p>

<h2 id="get-the-certificate-fingerprint" id="get-the-certificate-fingerprint">Get the certificate fingerprint</h2>

<p>Download the Certificate file. In the Entra ID tab, navigate to the “Single sign-on” blade of the Enterprise Application, scroll down to section 3 “SAML Certificates” and download the “Certificate (Base 64)” file in the <code>.cer</code> format.</p>

<p>Now, you&#39;ll need to get the Certificate Fingerprint (not the Thumbprint listed in Entra ID) from the <code>.cer</code> file. This is a bit of a pain and requires some manual intervention.</p>

<p>Here are the instructions for both Windows and MacOS to generate the fingerprint:</p>

<h3 id="windows" id="windows">Windows</h3>

<blockquote><p>These steps were performed on Windows 11.</p></blockquote>

<p>On a Windows PC, you will need to download and run an OpenSSL application to generate the fingerprint.</p>

<p>Open a new tab and download the Win64OpenSSL<em>Light EXE file directly from this link: <a href="https://slproweb.com/download/Win64OpenSSL">https://slproweb.com/download/Win64OpenSSL</a></em>Light-3<em>4</em>0.exe</p>

<p>Alternatively, navigate to the product page and download the version you need: <a href="https://slproweb.com/products/Win32OpenSSL.html">https://slproweb.com/products/Win32OpenSSL.html</a></p>

<p>Install the EXE file and open the app from the Start menu named “win64 OpenSSL Command Prompt:</p>

<p><img src="https://i.imgur.com/lht1qSD.png" alt=""/></p>

<p>Run the following command to generate the thumbprint, changing the <code>-in</code> location to where you downloaded the file:</p>

<p><code>openssl x509 -fingerprint -sha256 -in &#34;C:\Users\TimDAnnecy\Downloads\When I Work.cer&#34;</code></p>

<p>Copy the output to the clipboard:</p>

<p><img src="https://i.imgur.com/gPMxmpI.png" alt=""/></p>

<p>Now, you need to remove the <code>:</code> colon characters from the Fingerprint string.</p>

<p>You can do this manually, or by pasting it into Notepad and using the Find &amp; Replace tool (<code>Ctrl + H</code>) to “Replace all” and remove all colon characters. Once cleaned up, Copy the Fingerprint to the clipboard.</p>

<p><img src="https://i.imgur.com/WROQWb4.png" alt=""/></p>

<p>Now, you need to remove the <code>:</code> colon characters from the Fingerprint string.</p>

<p>You can do this manually, or by pasting it into Text Edit and using the Find &amp; Replace tool (<code>Ctrl + H</code>) to “Replace all” and remove all colon characters. Once cleaned up, Copy the Fingerprint back to the clipboard.</p>

<h3 id="macos" id="macos">MacOS</h3>

<blockquote><p>Note: These steps were performed on MacOS Sequoia 15.2 (24C98)</p></blockquote>

<p>On a Mac, the OpenSSL app is pre-installed and you can generate the thumbprint with a single command.</p>

<p>Open the Terminal app and run the following command, changing the location to where you downloaded the file:</p>

<p><code>openssl x509 -fingerprint -sha256 -in /Users/tim/Downloads/When\ I\ Work.cer</code></p>

<p>Copy the Fingerprint output to the clipboard:</p>

<p><img src="https://i.imgur.com/iN754HB.png" alt=""/></p>

<p>Now, you need to remove the <code>:</code> colon characters from the Fingerprint string.</p>

<p>You can do this manually, or by pasting it into TextEdit and using the Find &amp; Replace tool (<code>Command + F</code>) to “Replace all” and remove all colon characters. Once cleaned up, Copy the Fingerprint back to the clipboard.</p>

<p><img src="https://i.imgur.com/9vhvvkr.png" alt=""/></p>

<h2 id="paste-the-fingerprint-into-wheniwork" id="paste-the-fingerprint-into-wheniwork">Paste the Fingerprint into WhenIWork</h2>

<p>Once you have the Fingerprint copied to the clipboard, return to the WhenIWork SAML page and paste the value into the “Certificate Fingerprint (SAML)” field and click the “Save” button.</p>

<p><img src="https://i.imgur.com/TqS4OsS.png" alt=""/></p>

<h2 id="test-the-integration" id="test-the-integration">Test the integration</h2>

<p>Now that the attributes have been added in WhenIWork and in Entra ID, test to make sure the configuration is working by clicking the “Test this application” button:</p>

<p><img src="https://i.imgur.com/9oDrw5s.png" alt=""/></p>

<p>Click the “Test sign-in” button. If everything comes back successfully, you&#39;ve configured the Entra ID side correctly.</p>

<p><img src="https://i.imgur.com/faCPE1F.png" alt=""/></p>

<p>Try signing into WhenIWork by navigating to the app in the M365 Waffle menu:</p>

<p><img src="https://i.imgur.com/IX7bf0G.png" alt=""/></p>

<p>Alternatively, navigate to the main WhenIWork homepage and click the “Login” link that the top right: <a href="https://wheniwork.com">https://wheniwork.com</a></p>

<p><img src="https://i.imgur.com/uippo6V.png" alt=""/></p>

<p>On the login page, click the “Third Party Connect” button:</p>

<p><img src="https://i.imgur.com/0ujNjAG.png" alt=""/></p>

<p>Choose “SAML”:</p>

<p><img src="https://i.imgur.com/eRaQrka.png" alt=""/></p>

<p>Type the company name, account ID, or subdomain and click the “Login” button.</p>

<p><img src="https://i.imgur.com/mGv8WWT.png" alt=""/></p>

<blockquote><p>Note:  If you don&#39;t know the Account ID, you can get it by signing in with your Admin account (non-SSO sign in) and navigating to <strong>Gear icon &gt; General Settings</strong> at the top right of the page. This information is in the Account ID field.</p></blockquote>

<p>If SAML is configured correctly, you&#39;ll get the Entra ID sign in flow and can sign in using your Microsoft account.</p>

<h2 id="conclusion" id="conclusion">Conclusion</h2>

<p>Thanks again to <a href="https://www.linkedin.com/in/samuel-guerra-b62b641a0/">Sam Guerra</a> for figuring out the certificates in this flow.</p>

<p><img src="https://i.imgur.com/Cj1jrIZ.gif?style=center" alt=""/></p>

<p><a href="https://remark.as/p/tdannecy.me/configure-wheniwork-saml-sso-in-entra-id">Discuss...</a></p>
]]></content:encoded>
      <guid>https://tdannecy.me/configure-wheniwork-saml-sso-in-entra-id</guid>
      <pubDate>Sat, 07 Dec 2024 02:44:23 +0000</pubDate>
    </item>
    <item>
      <title>Get Lenovo device warranty information with PowerShell</title>
      <link>https://tdannecy.me/get-lenovo-device-warranty-information-with-powershell?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[PowerShell&#xA;&#xA;A client I&#39;ve been working with needed a way to check the warranty status of thousands of Lenovo laptops they own. The end goal was to import the warranty expiration dates into Freshservice so they can estimate device lifecycles and find out which users needed laptop replacements.&#xA;&#xA;Right now, Lenovo doesn&#39;t offer an API that could do this and I would need to look up each laptop one-by-one. &#xA;&#xA;To solve this problem and avoid manual lookups, I wrote a short PowerShell script that takes the serial number, scrapes Lenovo&#39;s warranty check page and gets the warranty information for the device, then outputs to a PowerShell object with the regular and upgrade warranty statuses and the end dates.&#xA;&#xA;In my use case, I exported all devices from Intune into a .csv file, filtered on all Lenovo devices, then ran the Get-LenovoWarrantyInformation script against all of them in a for loop. I exported to a clean .csv file that I could then upload into the Freshservice inventory.&#xA;&#xA;!--more--&#xA;&#xA;Here&#39;s the script:&#xA;&#xA;Get-LenovoWarrantyInformation.ps1&#xA;Get Lenovo warranty information via web scrape using serial number.&#xA;Example: Get-LenovoWarrantyInformation -SerialNumber &#39;BLAH&#39;&#xA;Tim D&#39;Annecy 2024&#xA;&#xA;function Get-LenovoWarrantyInformation {&#xA;    param (&#xA;        [Parameter(Mandatory = $true)]&#xA;        [string]$SerialNumber&#xA;    )&#xA;&#xA;    $Url = &#34;https://csp.lenovo.com/ibapp/il/WarrantyStatus.jsp?serial=$($SerialNumber)&#34;&#xA;&#xA;    $htmlContent = Invoke-WebRequest -Uri $Url -UseBasicParsing&#xA;    $parsedHtml = $htmlContent.Content&#xA;    $WarrantyStatus = [regex]::Match($parsedHtml, &#34;Status:&amp;nbsp;\/bspan::IgnoreCase).Groups[1].Value.Trim()&#xA;    $WarrantyEndDate = [regex]::Match($parsedHtml, &#39;End Date:&amp;nbsp;\/b(.?)\/td&#39;, [System.Text.RegularExpressions.RegexOptions]::IgnoreCase).Groups[1].Value.Trim()&#xA;    $UpgradeWarrantyStatus = [regex]::Match($parsedHtml, &#34;Upgrade Warranty Information.?Status:&amp;nbsp;\/bspan::Singleline).Groups[1].Value.Trim()&#xA;    $UpgradeWarrantyEndDate = [regex]::Match($parsedHtml, &#39;Upgrade Warranty Information.?End Date:&amp;nbsp;\/b(.?)\/td&#39;, [System.Text.RegularExpressions.RegexOptions]::Singleline).Groups[1].Value.Trim()&#xA;    $UpgradeWarrantyExcluding = [regex]::Match($parsedHtml, &#39;Upgrade Warranty Information.?Excluding:&amp;nbsp;\/b(.?)\/td&#39;, [System.Text.RegularExpressions.RegexOptions]::Singleline).Groups[1].Value.Trim()&#xA;&#xA;    $WarrantyInfo = [PSCustomObject]@{&#xA;        SerialNumber             = $SerialNumber&#xA;        WarrantyStatus            = if ($WarrantyStatus) { $WarrantyStatus } else { &#39;N/A&#39; }&#xA;        WarrantyEndDate          = if ($WarrantyEndDate) { $WarrantyEndDate } else { &#39;N/A&#39; }&#xA;        UpgradeWarrantyStatus     = if ($UpgradeWarrantyStatus) { $UpgradeWarrantyStatus } else { &#39;N/A&#39; }&#xA;        UpgradeWarrantyEndDate   = if ($UpgradeWarrantyEndDate) { $UpgradeWarrantyEndDate } else { &#39;N/A&#39; }&#xA;        UpgradeWarrantyExcluding = if ($UpgradeWarrantyExcluding) { $UpgradeWarrantyExcluding } else { &#39;N/A&#39; }&#xA;    }&#xA;&#xA;    return $WarrantyInfo&#xA;}&#xA;&#xA;Also available on GitHub Gist: &#xA;&#xA;https://gist.github.com/tdannecy/f2afa3a551cdf7860b5fb6aca3a3c6e6&#xA;&#xA;There is no error catching or rate limiting for the script, so run at your own risk!&#xA;&#xA;I hope this is helpful as a workaround, since Lenovo doesn&#39;t offer a proper API and this saved me a lot of time.&#xA;&#xA;Footer image&#xA;&#xA;a href=&#34;https://remark.as/p/tdannecy.me/get-lenovo-device-warranty-information-with-powershell&#34;Discuss.../a]]&gt;</description>
      <content:encoded><![CDATA[<p><a href="https://tdannecy.me/tag:PowerShell" class="hashtag"><span>#</span><span class="p-category">PowerShell</span></a></p>

<p>A client I&#39;ve been working with needed a way to check the warranty status of thousands of Lenovo laptops they own. The end goal was to import the warranty expiration dates into Freshservice so they can estimate device lifecycles and find out which users needed laptop replacements.</p>

<p>Right now, Lenovo doesn&#39;t offer an API that could do this and I would need to look up each laptop one-by-one.</p>

<p>To solve this problem and avoid manual lookups, I wrote a short PowerShell script that takes the serial number, scrapes Lenovo&#39;s warranty check page and gets the warranty information for the device, then outputs to a PowerShell object with the regular and upgrade warranty statuses and the end dates.</p>

<p>In my use case, I exported all devices from Intune into a .csv file, filtered on all Lenovo devices, then ran the Get-LenovoWarrantyInformation script against all of them in a <code>for</code> loop. I exported to a clean .csv file that I could then upload into the Freshservice inventory.</p>



<p>Here&#39;s the script:</p>

<pre><code class="language-powershell"># Get-LenovoWarrantyInformation.ps1
# Get Lenovo warranty information via web scrape using serial number.
# Example: Get-LenovoWarrantyInformation -SerialNumber &#39;BLAH&#39;
# Tim D&#39;Annecy 2024

function Get-LenovoWarrantyInformation {
    param (
        [Parameter(Mandatory = $true)]
        [string]$SerialNumber
    )

    $Url = &#34;https://csp.lenovo.com/ibapp/il/WarrantyStatus.jsp?serial=$($SerialNumber)&#34;

    $htmlContent = Invoke-WebRequest -Uri $Url -UseBasicParsing
    $parsedHtml = $htmlContent.Content
    $WarrantyStatus = [regex]::Match($parsedHtml, &#34;Status:&amp;nbsp;&lt;\/b&gt;&lt;span[^&gt;]*&gt;&lt;b&gt;(.*?)&lt;\/b&gt;&#34;, [System.Text.RegularExpressions.RegexOptions]::IgnoreCase).Groups[1].Value.Trim()
    $WarrantyEndDate = [regex]::Match($parsedHtml, &#39;End Date:&amp;nbsp;&lt;\/b&gt;(.*?)&lt;\/td&gt;&#39;, [System.Text.RegularExpressions.RegexOptions]::IgnoreCase).Groups[1].Value.Trim()
    $UpgradeWarrantyStatus = [regex]::Match($parsedHtml, &#34;Upgrade Warranty Information.*?Status:&amp;nbsp;&lt;\/b&gt;&lt;span[^&gt;]*&gt;&lt;b&gt;(.*?)&lt;\/b&gt;&#34;, [System.Text.RegularExpressions.RegexOptions]::Singleline).Groups[1].Value.Trim()
    $UpgradeWarrantyEndDate = [regex]::Match($parsedHtml, &#39;Upgrade Warranty Information.*?End Date:&amp;nbsp;&lt;\/b&gt;(.*?)&lt;\/td&gt;&#39;, [System.Text.RegularExpressions.RegexOptions]::Singleline).Groups[1].Value.Trim()
    $UpgradeWarrantyExcluding = [regex]::Match($parsedHtml, &#39;Upgrade Warranty Information.*?Excluding:&amp;nbsp;&lt;\/b&gt;(.*?)&lt;\/td&gt;&#39;, [System.Text.RegularExpressions.RegexOptions]::Singleline).Groups[1].Value.Trim()

    $WarrantyInfo = [PSCustomObject]@{
        SerialNumber             = $SerialNumber
        WarrantyStatus            = if ($WarrantyStatus) { $WarrantyStatus } else { &#39;N/A&#39; }
        WarrantyEndDate          = if ($WarrantyEndDate) { $WarrantyEndDate } else { &#39;N/A&#39; }
        UpgradeWarrantyStatus     = if ($UpgradeWarrantyStatus) { $UpgradeWarrantyStatus } else { &#39;N/A&#39; }
        UpgradeWarrantyEndDate   = if ($UpgradeWarrantyEndDate) { $UpgradeWarrantyEndDate } else { &#39;N/A&#39; }
        UpgradeWarrantyExcluding = if ($UpgradeWarrantyExcluding) { $UpgradeWarrantyExcluding } else { &#39;N/A&#39; }
    }

    return $WarrantyInfo
}
</code></pre>

<p>Also available on GitHub Gist: </p>

<p><script src="https://gist.github.com/tdannecy/f2afa3a551cdf7860b5fb6aca3a3c6e6.js"></script></p>

<p>There is no error catching or rate limiting for the script, so run at your own risk!</p>

<p>I hope this is helpful as a workaround, since Lenovo doesn&#39;t offer a proper API and this saved me a lot of time.</p>

<p><img src="https://i.imgur.com/3GiSIEw.gif?style=center" alt="Footer image"/></p>

<p><a href="https://remark.as/p/tdannecy.me/get-lenovo-device-warranty-information-with-powershell">Discuss...</a></p>
]]></content:encoded>
      <guid>https://tdannecy.me/get-lenovo-device-warranty-information-with-powershell</guid>
      <pubDate>Wed, 04 Dec 2024 13:12:34 +0000</pubDate>
    </item>
    <item>
      <title>Configure an OAuth Linked Service for Salesforce in Azure Data Factory</title>
      <link>https://tdannecy.me/configure-an-oauth-linked-service-for-salesforce-in-azure-data-factory?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[#AzureAD #Entra #AzureDataFactory&#xA;&#xA;I recently received a request to update the Azure Data Factory Linked Service connector to Salesforce. When they login, they get the following warning message:&#xA;&#xA;  Your Data Factory has pipelines that are still utilizing the legacy connector versions. Please kindly upgrade to the latest connector version at your earliest convenience. For your reference, you can view all the relevant linked services here.&#xA;&#xA;When I click on the &#34;View all&#34; link, I can see that there&#39;s a Linked Service with the &#34;Salesforce (Legacy)&#34; type listed:&#xA;&#xA;This post will discuss the steps for upgrading this connector to use the modern OAuth method for authentication and how to update your Azure Data Factory flows with the new Salesforce connector.&#xA;&#xA;!--more--&#xA;&#xA;To perform these actions, you will need at least the following permissions:&#xA;&#xA;Contributor access to the Azure Data Factory&#xA;System Administrator profile in Salesforce&#xA;&#xA;Prepare Salesforce configuration&#xA;&#xA;To begin, we have to configure Salesforce to use an app for OAuth authentication.&#xA;&#xA;Login to Salesforce and navigate to Settings   Setup&#xA;&#xA;Navigate to Apps   App Manager&#xA;&#xA;Click &#34;New Connected App&#34;&#xA;&#xA;Select &#34;Create an External Client App&#34; and click the &#34;Continue&#34; button.&#xA;&#xA;I the popup, enter a name like &#34;Azure Data Factory&#34; and fill in the required contact information.&#xA;&#xA;Expand the option for &#34;API (Enable OAuth Settings&#34; and check the box for &#34;Enable OAuth&#34;.&#xA;&#xA;img&#xA;&#xA;In the &#34;Callback URL&#34; field, enter both URLs:&#xA;&#xA;https://adf.azure.com/&#xA;https://*.azure.com&#xA;&#xA;In the OAuth Scopes section, add the following permissions to the right side:&#xA;&#xA;Full access (full)&#xA;Perform requests at any time (refreshtoken, offlineaccess)&#xA;&#xA;Check the box &#34;Enable Client Credentials Flow&#34; and accept the confirmation popup.&#xA;&#xA;Once completed, click &#34;Create&#34;.&#xA;&#xA;Return to the External Client App Manager page. Click on the arrow next to your Azure Data Factory app, and click &#34;Edit Policies&#34;.&#xA;&#xA;10. Expand the &#34;OAuth Policies&#34; section.&#xA;&#xA;Edit the Run As (Username) field with the login name for the Service Account in Salesforce. This Service Account should have the &#34;Salesforce Integration&#34; User License applied to it.&#xA;&#xA;Click the &#34;Save&#34; button when finished.&#xA;&#xA;11. Now that the Connected App is created, retrieve the Key and Secret for Azure Data Factory.&#xA;&#xA;Inside the External Client App Manager menu for your Azure Data Factory app, navigate to the Settings tab. Expand the &#34;OAuth Policies&#34; section and click &#34;Consumer Key and Secret&#34;.&#xA;&#xA;12. Copy both values to a Notepad document or other scratch pad.&#xA;&#xA;These values will be used to configure Azure Data Factory.&#xA;&#xA;Configure Azure Data Factory&#xA;&#xA;Now that the Salesforce side is configured, you can create a new Linked Service in Azure Data Factory to connect.&#xA;&#xA;13. Navigate to Azure Data Factory: https://adf.azure.com/&#xA;&#xA;Navigate to Manage   Linked services   New&#xA;&#xA;14. Search for and select &#34;Salesforce&#34;:&#xA;&#xA;15. Name the Linked Service &#34;Salesforce&#34; and enter the Salesforce Environment URL, formatted like https://tenant.my.salesforce.com/or a Sandbox environment, use: https://tenant.sandbox.my.salesforce.com/&#xA;&#xA;16. Copy and paste the values from Salesforce into Azure Data Factory:&#xA;&#xA;Consumer Key = Client ID&#xA;Consumer Secret = Client secret&#xA;&#xA;Set the Salesforce API version to: 54.0&#xA;&#xA;17. Click the &#34;Test connection&#34; button to ensure it&#39;s working, then click the &#34;Create&#34; button to save the Linked Service.&#xA;&#xA;Update Azure Data Factory resources&#xA;&#xA;Now that the new Linked Service is added, you will need to update all of the legacy resources that use that Linked Service.&#xA;&#xA;18. Navigate to Manage   Linked Services and click on the &#34;Salesforce (Legacy)&#34; Linked Service.&#xA;&#xA;In the pane to the right, these Datasets will need to be updated by clicking on the item, and changing the configuration.&#xA;&#xA;19. Update each of the related objects by changing the Linked Service in the dropdown to the new Salesforce connection.&#xA;&#xA;Be sure to make sure all of your Pipelines are using this new Linked Service and that there are no query issues. Once you&#39;re sure, you can delete the old Linked Service for &#34;Salesforce (Legacy)&#34;.&#xA;&#xA;References &#xA;&#xA;Configure Azure Data Factory for Salesforce 2024 (datatoolspro.com) [A]&#xA;&#xA;Linked services - Azure Data Factory &amp; Azure Synapse | Microsoft Learn&#xA;Copy data from and to Salesforce - Azure Data Factory &amp; Azure Synapse | Microsoft Learn&#xA;&#xA;Footer image&#xA;&#xA;a href=&#34;https://remark.as/p/tdannecy.me/configure-an-oauth-linked-service-for-salesforce-in-azure-data-factory&#34;Discuss.../a]]&gt;</description>
      <content:encoded><![CDATA[<p><a href="https://tdannecy.me/tag:AzureAD" class="hashtag"><span>#</span><span class="p-category">AzureAD</span></a> <a href="https://tdannecy.me/tag:Entra" class="hashtag"><span>#</span><span class="p-category">Entra</span></a> <a href="https://tdannecy.me/tag:AzureDataFactory" class="hashtag"><span>#</span><span class="p-category">AzureDataFactory</span></a></p>

<p>I recently received a request to update the Azure Data Factory Linked Service connector to Salesforce. When they login, they get the following warning message:</p>

<p><img src="https://i.imgur.com/3L9xFwR.png" alt=""/></p>

<blockquote><p>Your Data Factory has pipelines that are still utilizing the legacy connector versions. Please kindly upgrade to the latest connector version at your earliest convenience. For your reference, you can view all the relevant linked services here.</p></blockquote>

<p>When I click on the “View all” link, I can see that there&#39;s a Linked Service with the “Salesforce (Legacy)” type listed:</p>

<p><img src="https://i.imgur.com/15AkHFH.png" alt=""/></p>

<p>This post will discuss the steps for upgrading this connector to use the modern OAuth method for authentication and how to update your Azure Data Factory flows with the new Salesforce connector.</p>



<p>To perform these actions, you will need at least the following permissions:</p>
<ul><li><strong>Contributor</strong> access to the Azure Data Factory</li>
<li><strong>System Administrator</strong> profile in Salesforce</li></ul>

<h2 id="prepare-salesforce-configuration" id="prepare-salesforce-configuration">Prepare Salesforce configuration</h2>

<p>To begin, we have to configure Salesforce to use an app for OAuth authentication.</p>
<ol><li>Login to Salesforce and navigate to <strong>Settings &gt; Setup</strong></li></ol>

<p><img src="https://i.imgur.com/NafNCxl.png" alt=""/></p>
<ol><li>Navigate to <strong>Apps &gt; App Manager</strong></li></ol>

<p><img src="https://i.imgur.com/32dSMQJ.png" alt=""/></p>
<ol><li>Click “New Connected App”</li></ol>

<p><img src="https://i.imgur.com/8ucjsGH.png" alt=""/></p>
<ol><li>Select “Create an External Client App” and click the “Continue” button.</li></ol>

<p><img src="https://i.imgur.com/PucurIW.png" alt=""/></p>
<ol><li>I the popup, enter a name like “Azure Data Factory” and fill in the required contact information.</li></ol>

<p><img src="https://i.imgur.com/PpnnZ2O.png" alt=""/></p>
<ol><li>Expand the option for “API (Enable OAuth Settings” and check the box for “Enable OAuth”.</li></ol>

<p><img src="https://i.imgur.com/pps389K.png" alt="img"/></p>
<ol><li>In the “Callback URL” field, enter both URLs:</li></ol>
<ul><li><code>https://adf.azure.com/</code></li>
<li><code>https://*.azure.com</code></li></ul>

<p>In the OAuth Scopes section, add the following permissions to the right side:</p>
<ul><li>Full access (full)</li>
<li>Perform requests at any time (refresh<em>token, offline</em>access)</li></ul>

<p><img src="https://i.imgur.com/1NM52X1.png" alt=""/></p>
<ol><li>Check the box “Enable Client Credentials Flow” and accept the confirmation popup.</li></ol>

<p>Once completed, click “Create”.</p>

<p><img src="https://i.imgur.com/krTp3Fa.png" alt=""/></p>
<ol><li>Return to the External Client App Manager page. Click on the arrow next to your Azure Data Factory app, and click “Edit Policies”.</li></ol>

<p><img src="https://i.imgur.com/PiD9Nll.png" alt=""/></p>
<ol><li>Expand the “OAuth Policies” section.</li></ol>

<p>Edit the <strong>Run As (Username)</strong> field with the login name for the Service Account in Salesforce. This Service Account should have the “Salesforce Integration” User License applied to it.</p>

<p>Click the “Save” button when finished.</p>

<p><img src="https://i.imgur.com/dF0OiwP.png" alt=""/></p>
<ol><li>Now that the Connected App is created, retrieve the Key and Secret for Azure Data Factory.</li></ol>

<p>Inside the External Client App Manager menu for your Azure Data Factory app, navigate to the Settings tab. Expand the “OAuth Policies” section and click “Consumer Key and Secret”.</p>

<p><img src="https://i.imgur.com/ayeP92X.png" alt=""/></p>
<ol><li>Copy both values to a Notepad document or other scratch pad.</li></ol>

<p>These values will be used to configure Azure Data Factory.</p>

<p><img src="https://i.imgur.com/mQRr2yI.png" alt=""/></p>

<h2 id="configure-azure-data-factory" id="configure-azure-data-factory">Configure Azure Data Factory</h2>

<p>Now that the Salesforce side is configured, you can create a new Linked Service in Azure Data Factory to connect.</p>
<ol><li>Navigate to Azure Data Factory: <a href="https://adf.azure.com/">https://adf.azure.com/</a></li></ol>

<p>Navigate to <strong>Manage &gt; Linked services &gt; New</strong></p>

<p><img src="https://i.imgur.com/UZfD09c.png" alt=""/></p>
<ol><li>Search for and select “Salesforce”:</li></ol>

<p><img src="https://i.imgur.com/zvbDd2f.png" alt=""/></p>
<ol><li>Name the Linked Service “Salesforce” and enter the Salesforce Environment URL, formatted like <code>https://tenant.my.salesforce.com/</code>or a Sandbox environment, use: <code>https://tenant.sandbox.my.salesforce.com/</code></li></ol>

<p><img src="https://i.imgur.com/X5QWcem.png" alt=""/></p>
<ol><li>Copy and paste the values from Salesforce into Azure Data Factory:</li></ol>
<ul><li>Consumer Key = Client ID</li>
<li>Consumer Secret = Client secret</li></ul>

<p>Set the Salesforce API version to: <code>54.0</code></p>

<p><img src="https://i.imgur.com/aItgAs5.png" alt=""/></p>
<ol><li>Click the “Test connection” button to ensure it&#39;s working, then click the “Create” button to save the Linked Service.</li></ol>

<p><img src="https://i.imgur.com/46HCEGy.png" alt=""/></p>

<h2 id="update-azure-data-factory-resources" id="update-azure-data-factory-resources">Update Azure Data Factory resources</h2>

<p>Now that the new Linked Service is added, you will need to update all of the legacy resources that use that Linked Service.</p>
<ol><li>Navigate to <strong>Manage &gt; Linked Services</strong> and click on the “Salesforce (Legacy)” Linked Service.</li></ol>

<p>In the pane to the right, these Datasets will need to be updated by clicking on the item, and changing the configuration.</p>

<p><img src="https://i.imgur.com/1KnlMWe.png" alt=""/></p>
<ol><li>Update each of the related objects by changing the Linked Service in the dropdown to the new Salesforce connection.</li></ol>

<p><img src="https://i.imgur.com/spwzLz5.png" alt=""/></p>

<p>Be sure to make sure all of your Pipelines are using this new Linked Service and that there are no query issues. Once you&#39;re sure, you can delete the old Linked Service for “Salesforce (Legacy)”.</p>

<h2 id="references" id="references">References</h2>
<ul><li><p><a href="https://datatoolspro.com/tutorials/azure-data-factory-for-salesforce/">Configure Azure Data Factory for Salesforce 2024 (datatoolspro.com)</a> [<a href="https://archive.today/zlIhp">A</a>]</p></li>

<li><p><a href="https://learn.microsoft.com/en-us/azure/data-factory/concepts-linked-services?tabs=data-factory">Linked services – Azure Data Factory &amp; Azure Synapse | Microsoft Learn</a></p></li>

<li><p><a href="https://learn.microsoft.com/en-us/azure/data-factory/connector-salesforce?tabs=data-factory">Copy data from and to Salesforce – Azure Data Factory &amp; Azure Synapse | Microsoft Learn</a></p></li></ul>

<p><img src="https://i.imgur.com/3GiSIEw.gif?style=center" alt="Footer image"/></p>

<p><a href="https://remark.as/p/tdannecy.me/configure-an-oauth-linked-service-for-salesforce-in-azure-data-factory">Discuss...</a></p>
]]></content:encoded>
      <guid>https://tdannecy.me/configure-an-oauth-linked-service-for-salesforce-in-azure-data-factory</guid>
      <pubDate>Wed, 16 Oct 2024 17:54:09 +0000</pubDate>
    </item>
    <item>
      <title>Happy Hour at Boxyard RTP</title>
      <link>https://tdannecy.me/happy-hour-at-boxyard-rtp?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[work&#xA;&#xA;Last week after our All Hands Meeting, I joined my CREO coworkers at Boxyard RTP for Happy Hour.&#xA;&#xA;Seeing people in person is great and the charcuterie was delicious!]]&gt;</description>
      <content:encoded><![CDATA[<p><a href="https://tdannecy.me/tag:work" class="hashtag"><span>#</span><span class="p-category">work</span></a></p>

<p><img src="https://i.imgur.com/iLWme6k.jpeg" alt=""/></p>

<p>Last week after our All Hands Meeting, I joined my <a href="https://creoconsulting.com">CREO</a> coworkers at Boxyard RTP for Happy Hour.</p>

<p>Seeing people in person is great and the <a href="https://boxyard.rtp.org/vendors/meat-and-graze/">charcuterie</a> was delicious!</p>
]]></content:encoded>
      <guid>https://tdannecy.me/happy-hour-at-boxyard-rtp</guid>
      <pubDate>Fri, 27 Sep 2024 14:15:35 +0000</pubDate>
    </item>
    <item>
      <title>Connections - NYT game demake</title>
      <link>https://tdannecy.me/connections-nyt-game-demake?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[#Pico8 #game&#xA;&#xA;Over the weekend, I finished coding a demake of the New York Times Connections game in Pico8.&#xA;&#xA;There are a lot of bugs in the code right now, but it&#39;s playable and I was able to squeeze in the puzzles from July, August, and the first week of September and came right under the Pico8 cartridge size limit.&#xA;&#xA;Play it here! https://www.lexaloffle.com/bbs/?tid=144092&#xA;&#xA;iframe src=&#34;https://www.lexaloffle.com/bbs/widget.php?pid=tdannecyconnections1&#34; allowfullscreen width=&#34;621&#34; height=&#34;513&#34; style=&#34;border:none; overflow:hidden&#34;/iframe&#xA;&#xA;Footer&#xA;&#xA;a href=&#34;https://remark.as/p/tdannecy.me/connections-nyt-game-demake&#34;Discuss.../a]]&gt;</description>
      <content:encoded><![CDATA[<p><a href="https://tdannecy.me/tag:Pico8" class="hashtag"><span>#</span><span class="p-category">Pico8</span></a> <a href="https://tdannecy.me/tag:game" class="hashtag"><span>#</span><span class="p-category">game</span></a></p>

<p>Over the weekend, I finished coding a demake of the <a href="https://www.nytimes.com/games/connections">New York Times Connections game</a> in <a href="https://www.lexaloffle.com/pico-8.php">Pico8</a>.</p>

<p>There are a lot of bugs in the code right now, but it&#39;s playable and I was able to squeeze in the puzzles from July, August, and the first week of September and came right under the Pico8 cartridge size limit.</p>

<p>Play it here! <a href="https://www.lexaloffle.com/bbs/?tid=144092">https://www.lexaloffle.com/bbs/?tid=144092</a></p>

<p><img src="https://www.lexaloffle.com/bbs/cposts/td/tdannecy_connections_1-1.p8.png" alt=""/></p>

<p><img src="https://i.imgur.com/Zfru1H2.jpeg" alt=""/></p>

<iframe src="https://www.lexaloffle.com/bbs/widget.php?pid=tdannecy_connections_1" allowfullscreen="" width="621" height="513" style="border:none; overflow:hidden"></iframe>

<p><img src="https://i.imgur.com/fqURyMg.gif?style=center" alt="Footer"/></p>

<p><a href="https://remark.as/p/tdannecy.me/connections-nyt-game-demake">Discuss...</a></p>
]]></content:encoded>
      <guid>https://tdannecy.me/connections-nyt-game-demake</guid>
      <pubDate>Mon, 09 Sep 2024 15:05:38 +0000</pubDate>
    </item>
  </channel>
</rss>