• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar

Clatent

Technology | Fitness | Food

  • About
  • Resources
  • Contact

365

First Snowfall of the Season

November 22, 2024 by ClaytonT Leave a Comment

First snowfall in NY! Tell me about the first time PowerShell just clicked… what was that moment?

Mine was adding new users to AD(it’s usually AD or Exchange, right?) and remembering the standard fields needed to be filled out with their default values. Also when we had multiple new hires it was so time consuming clicking through the GUI. That’s when I learned how to create an AD user with a CSV. It was life changing and realized I needed to do more of this.

Now I have a module that is meant to create Microsoft 365 test environments but can be used in production to create users, groups, and much more from an excel file without even having excel on the computer! You can check out the module below.

We all start somewhere and love hearing that light bulb moment that triggers the snowball effect!

365AutomatedLab
Powershell Gallery: https://www.powershellgallery.com/packages/365AutomatedLab/2.11.0
GitHub: https://github.com/DevClate/365AutomatedLab

Tagged With: 365, 365AutomatedLab, AD, Automation, PowerShell

GitHub Actions and PowerShell: The Underdog

November 15, 2024 by ClaytonT Leave a Comment

Remember how I mentioned how GitHub actions are underrated? I’m going to show at a high level how GitHub Actions with PowerShell can save you time and be more efficient.

What does it do?

  • Web scrapes website into PowerShell Object
  • Compares the web scrape to the json “database” file(FidoKeys.json) of all the keys
    • Matches by AAGUID
      • Adds to FidoKeys.json if doesn’t exit
      • Removes from FidoKeys.json if not in the web scrape anymore
    • If New key
      • Checks the first word in the description to see if that matches with the Valid Vendor List(Valid_Vendors.json) and if it matches adds the Vendor
        • If it doesn’t have a valid vendor it will create a GitHub issue for that vendor and key
    • If Existing key
      • Checks to see if any of the properties have changed and updates FidoKeys.json
    • If Missing key
      • If key is no longer in the web scrape, it removes it from FidoKeys.json
  • Updates Merge dates on FidoKeys.json
    • If it checks to see if there are any changes and there are no changes, it only updates databaseLastChecked
    • If it checks to see if there are any changes and there are changes, it updates databaseLastChecked and databaseLastUpdated
  • Creates GitHub Issues for Invalid Vendors
    • If a vendor isn’t in the valid_vendors.json list or if the vendor name is blank, it will automatically create a GitHub issue for that key and invalid vendor name
    • Assigns myself at the owner of the issue
  • Closes GitHub Issues for Valid Vendors
    • If a vendor now matches with a vendor name in valid_vendors.json, then it will automatically close the issue for the now valid vendor
  • Updates merge_log.md
    • It only updates the merge_log.md when a new change occurs from the previous check
  • Updates detailed_log.txt
    • This is written to every time, but if it is the same as previous check it will write “No changes detected during this run”

It does that automatically once every day, I could do it more, but didn’t think it was necessary. Best of all, this is all done for free. Since it is a public repository all GitHub actions are free. Today, I’ll go over the GitHub Action, but I’ll do another post to go into detail on the PowerShell script side.

Let’s start from the beginning. We first have to name the GitHub Action so we will use “Main Entra Merge” in this case as this is for the Main branch and is merging keys for Entra.

name: Main Entra Merge

Then we have to determine when it will run. What I like to do in the beginning is always have a “workflow_dispatch:” as this will always allow you to test it manually and you don’t have to wait for any other triggers. Then in this case I have it run at midnight, and anytime there is a push or pull request to the main branch

on:
  workflow_dispatch:
  schedule:
    - cron: '0 0 * * *'
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

Next, we have to define what OS do we want to run on. I usually only use ubuntu-latest unless I have a real use to use Mac or Windows, as if I remember right, Windows is 3 times the cost to run in Actions, and Mac is 9 times. I know it’s free for me, but why use resources that aren’t needed. You can as well uses different versions of Ubuntu too (GitHub Runners). Also you need to have “jobs:” and then the name of the job or it won’t work. Also spacing is very important with Yaml. It has burned me a few times.

jobs:
  merge-fido-data:
    runs-on: ubuntu-latest

The workflow begins by checking out the repository to the runner using the actions/checkout@v4 action. This step ensures that all necessary files and scripts are available for subsequent steps.

- name: Checkout repository
  uses: actions/checkout@v4
  with:
    fetch-depth: 0
    ref: main

Next, it installs the PSParseHTML PowerShell module, which is essential for parsing HTML content in the scripts that follow.

- name: Install PSParseHTML Module
  shell: pwsh
  run: Install-Module -Name PSParseHTML -Force -Scope CurrentUser

The workflow runs a series of custom PowerShell scripts that perform data validation and merging:

  • Validation Scripts: Test-GHValidVendor.ps1 and Test-GHAAGUIDExists.ps1 ensure that the vendor information and AAGUIDs are valid.
  • Data Export and Merge: Export-GHEntraFido.ps1 exports data from Microsoft Entra, and Merge-GHFidoData.ps1 merges it with existing data.
- name: Run Merge-GHFidoData Script
  shell: pwsh
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    GITHUB_REPOSITORY: ${{ github.repository }}
  run: |
    Import-Module PSParseHTML
    . ./Scripts/Test-GHValidVendor.ps1
    . ./Scripts/Test-GHAAGUIDExists.ps1
    . ./Scripts/Export-GHEntraFido.ps1
    . ./Scripts/Merge-GHFidoData.ps1
- name: Read Environment Variables
 shell: bash
 run: |
 if [ -f ./Scripts/env_vars.txt ]; then
 echo "Setting environment variables from env_vars.txt"
 cat ./Scripts/env_vars.txt >> $GITHUB_ENV
 else
 echo "env_vars.txt not found."
 fi

For transparency, the workflow outputs the values of key environment variables, aiding in debugging and verification. This could be removed, but leaving for now for testing.

- name: Debug - Display ISSUE_ENTRIES, KEYS_NOW_VALID, and VENDORS_NOW_VALID Environment Variables
 shell: bash
 run: |
 echo "ISSUE_ENTRIES: $ISSUE_ENTRIES"
 echo "KEYS_NOW_VALID: $KEYS_NOW_VALID"
 echo "VENDORS_NOW_VALID: $VENDORS_NOW_VALID"

Utilizing actions/github-script@v6, the workflow runs a JavaScript script that automates issue creation and closure based on validation results.

  • Creates Issues: For any data discrepancies found.
  • Closes Issues: If previously reported issues are now resolved.
  • Assigns Issues: Automatically assigns issues to DevClate for certain labels.
- name: Close Fixed Issues and Create New Issues
      uses: actions/github-script@v6
      with:
        github-token: ${{ secrets.GITHUB_TOKEN }}
        script: |
          const issueEntriesRaw = process.env.ISSUE_ENTRIES || '';
          const issueEntries = issueEntriesRaw.split('%0A').map(entry => decodeURIComponent(entry)).filter(entry => entry.trim() !== '');
          if (issueEntries.length === 0) {
            console.log('No new issue entries found.');
          } else {
            for (const entry of issueEntries) {
              const parts = entry.split('|');
              if (parts.length < 2) {
                console.error(`Invalid entry format: ${entry}`);
                continue;
              }
              const [issueTitle, issueBody, issueLabel] = parts;
              console.log(`Processing issue: ${issueTitle}`);
              const { data: issues } = await github.rest.issues.listForRepo({
                owner: context.repo.owner,
                repo: context.repo.repo,
                state: 'open',
                labels: 'auto-generated',
              });
              const existingIssue = issues.find(issue => issue.title === issueTitle);
              if (!existingIssue) {
                const assignees = [];
                if (issueLabel === 'InvalidVendor' || issueLabel === 'DuplicateEntry') {
                  assignees.push('DevClate');
                }
                await github.rest.issues.create({
                  owner: context.repo.owner,
                  repo: context.repo.repo,
                  title: issueTitle,
                  body: issueBody,
                  labels: issueLabel ? ['auto-generated', issueLabel] : ['auto-generated'],
                  assignees: assignees,
                });
                console.log(`Issue created: ${issueTitle}`);
              } else {
                console.log(`Issue already exists: ${issueTitle}`);
              }
            }
          }

          // Close issues for keys (AAGUIDs) that are now valid
          const keysNowValidRaw = process.env.KEYS_NOW_VALID || '';
          const keysNowValid = keysNowValidRaw.split('%0A').map(entry => decodeURIComponent(entry)).filter(entry => entry.trim() !== '');
          if (keysNowValid.length === 0) {
            console.log('No keys have become valid.');
          } else {
            console.log('Keys that are now valid:', keysNowValid);
            for (const aaguid of keysNowValid) {
              const { data: issues } = await github.rest.issues.listForRepo({
                owner: context.repo.owner,
                repo: context.repo.repo,
                state: 'open',
                labels: ['auto-generated', 'InvalidVendor'],
                per_page: 100,
              });
              for (const issue of issues) {
                if (issue.title.includes(aaguid)) {
                  await github.rest.issues.update({
                    owner: context.repo.owner,
                    repo: context.repo.repo,
                    issue_number: issue.number,
                    state: 'closed',
                    state_reason: 'completed',
                  });
                  await github.rest.issues.createComment({
                    owner: context.repo.owner,
                    repo: context.repo.repo,
                    issue_number: issue.number,
                    body: `The vendor for key with AAGUID '${aaguid}' is now valid. This issue is being closed automatically.`,
                  });
                  console.log(`Closed issue for key with AAGUID: ${aaguid}`);
                }
              }
            }
          }

The workflow extracts the newest entries from merge_log.md and detailed_log.txt and appends them to the GitHub Actions summary for easy access.

- name: Display Merge Log
  shell: bash
  run: |
    # Extract and format logs

Configuring Git ensures that any commits made by the workflow are properly attributed.

- name: Configure Git
  run: |
    git config --global user.name 'D--ate'
    git config --global user.email 'c---@--t.com'

Finally, the workflow commits the changes made to the data and logs, pushing them back to the main branch.

- name: Commit changes
 run: |
 git add Assets/FidoKeys.json merge_log.md detailed_log.txt
 git commit -m "Update Fidokeys.json, merge_log.md, and detailed_log.txt" || echo "No changes to commit"

- name: Push changes
 uses: ad-m/github-push-action@v0.6.0
 with:
 github_token: ${{ secrets.GITHUB_TOKEN }}
 branch: main

And that’s it! It’s completely ok to not fully understand it, but wanted to give you a quick breakdown on how it works in case you have a project that you are working on or have been holding off because you didn’t know this is possible. If you have any tips, I’d be glad to talk as well as I’m always open for improvement and learning new ideas.

If you want to see this in action check out https://github.com/DevClate/EntraFIDOFinder

I do have a PowerShell module that works with this and allows you to find/filter which FIDO2 Keys are Entra Attestation approved, that can be downloaded there or on the PowerShell Gallery

And I even made an interactive website as well at https://devclate.github.io/EntraFIDOFinder/Explorer/

I will be doing a breakdown of the PowerShell of this in part 2!

Hope this was helpful and have a great day!

Tagged With: 365, Automation, Entra, FIDO2, GitHub Actions, PowerShell, Reporting

October 14, 2024 – Tomorrow is MFA Enforcement day and we have our first FIDO2 key update

October 14, 2024 by ClaytonT Leave a Comment

Today is the last day before Phase 1 of MFA Enforcement of Microsoft portals being turned on. This includes break glass accounts as well, so make sure you have your FIDO keys, Certs, or a dedicated computer with Windows Hello for Business setup.

You can learn more of the details at Microsoft Learn – https://learn.microsoft.com/en-us/entra/identity/authentication/concept-mandatory-multifactor-authentication

If you want to see what accounts will be affected, check out Daniel Bradley’s great blog at https://ourcloudnetwork.com/how-to-assess-the-impact-of-mfa-enforcement-in-azure/

This past Saturday we had our first update to the FIDO2 key database. The OneSpan DIGIPASS FX1 BIO now has been approved for NFC. It looks like it was updated later on Friday as the page shows last updated on the 11th, but when I had checked that morning there wasn’t an update.

Also, I’ve updated the module to show the change in database as well as when you check which version of the database you have it automatically tells you if it is outdated instead of needing to then run the -NewVersion parameter.

Added Cmdlet Get-FIDODbLog which will show you the database merge log so you don’t have to go to the web to see it and will have it right in your terminal.

PowerShell Gallery: https://www.powershellgallery.com/packages/EntraFIDOFinder/0.0.10
GitHub: https://github.com/DevClate/EntraFIDOFinder
Interactive Key Explorer: https://devclate.github.io/EntraFIDOFinder/Explorer/

Hope this helps with your security journey, and if there is anyway I can help, please feel free to reach out.

Tagged With: 365, Azure, Entra, FIDO2, PowerShell, Security

EntraFIDOFinder Update

October 9, 2024 by ClaytonT Leave a Comment

October 15, is less than a week away for the MFA requirement on certain 365 Apps. Please make sure you are all set by then. Make sure to go through all your accounts, especially those old ones that you rarely ever touch, and see if you still need it or what is the best way to protect it now. For some you will be able to delete and others you will need something such as a cert, FIDO2 key, or Windows Hello for Business. For those that will need a FIDO2 key, I’ve pulled from Microsoft Learn the current Attestation capable FIDO2 keys that are compatible with Entra. The database may say that it was last updated September 30, 2024, but I reviewed it today(Oct 9th) and the list still hasn’t changed. Once they do update it, I’ll update mine as well as show the changes.

With that said, I’ve now created a function called Show-FIDODbVersion that will show you what your current version is, and if you use Show-FIDODbVersion -NewestVersion, it will show you the newest version out. Would you rather me, show the difference as soon as you run Show-FIDODbVersion if there is or do you want them seperate?

Also working on automating the update process so that it can be checked daily with minimal intervention.

Are there any other features you’d like to see? I’m going to be adding at least vendor links and I’ve been trying to find pricing, but more than a handful of them do not even show pricing and not sure how valuable it will be if only a few of the vendors have pricing. How critical is cost to you?

I hope EntraFIDOFinder has been useful for you, and I can’t believe it has over 100 downloads already. I wasn’t even going to publish this, but figured there was someone else out there that didn’t want to just look at a static website and scroll through, so that is why I created the module and the interactive webpage.

PowerShell Gallery: EntraFIDOFinder
GitHub: EntraFIDOFinder
EntraFIDOFinder Explorer

Enjoy your day and get secure!

Tagged With: 365, AD, Automation, Entra, FIDO2, PowerShell, Reporting, Security

EntraFIDOFinder: Web Version now available

October 2, 2024 by ClaytonT Leave a Comment

Yes, I know it may seem counter productive to make a web version of it, but I wanted to have an interactive web version so that it is easier for people to use then Microsoft’s version. The data is the same as the PowerShell version and will be updated at the same time as they are pulling from the same source.

Functionality:

  • Search by Vendor
  • Filter by USB, NFC, BIO, and BLE

Web Version: EntraFIDOFinder
PowerShell Version: EntraFIDOFinder

Let me know what you think, and have a great day!

Tagged With: 365, Entra, FIDO2, PowerShell, Reporting, Security

EntraFIDOFinder – New PowerShell Module

September 30, 2024 by ClaytonT Leave a Comment

After so much interest from my post on Friday, I figured I’d do one better and make a PowerShell module that does it for you. So now you will be able to find which FIDO2 keys are attestation compatible with Entra right from your terminal. In the very near future I will have individual functions for exporting to Excel, CSV, Markdown, and PDF, but know a lot of people like to customize that themselves. I even put a few quick pointers on GitHub for it too, but will be doing tutorials shortly as well.

I’m still cleaning up the GitHub, but it is in the PowerShell Gallery and on GitHub at the links below.

You are able to search by Brand and/or device type such as USB, NFC, BLE, or BIO. These values are all parameter validated so if you do not see a brand that you have, then currently it is not compatible. Here is also the original link I shared on Friday Microsoft Learn FIDO2 Hardware Attestation.

Let me know what you think and do you find it useful. There are a few other features I want to add, but open to any other suggestions or do you think it is good as is?

And don’t forget the mid Oct deadline is coming up quickly for Entra admin portals, good luck!

PowerShell Gallery: EntraFIDOFinder
GitHub: EntraFIDOFinder

Tagged With: 365, Automation, AzureAD, Entra, MFA, PowerShell, Security, SSO

  • « Go to Previous Page
  • Page 1
  • Page 2
  • Page 3
  • Page 4
  • Page 5
  • Page 6
  • Interim pages omitted …
  • Page 9
  • Go to Next Page »

Primary Sidebar

Clayton Tyger

Tech enthusiast dad who has lost 100lbs and now sometimes has crazy running/biking ideas. Read More…

Find Me On

  • Email
  • GitHub
  • Instagram
  • LinkedIn
  • Twitter

Recent Posts

  • EntraFIDOFinder: New Web UI and Over 70 New Authenticators
  • January 19, 2026 Updates to EntraFIDOFinder
  • v0.0.20 EntraFIDOFinder is out
  • EntraFIDOFinder Update
  • Did you know: SSPR/Password Reset Edition

Categories

  • 365
  • Active Directory
  • AI
  • AzureAD
  • BlueSky
  • Cim
  • Dashboards
  • Documentation
  • Entra
  • Get-WMI
  • Learning
  • Module Monday
  • Nutanix
  • One Liner Wednesday
  • Passwords
  • PDF
  • Planner
  • PowerShell
  • Read-Only Friday
  • Reporting
  • Security
  • Windows
  • WSUS

© 2026 Clatent