I was updating a README.md and realized I was about to trigger a pointless pipeline build. Had I Googled it, it might have taken ten minutes to "StackOverflow" the answer. Instead, AI told me to add an exclusion to the YAML file’s trigger, and now I know:
Tuesday, April 14, 2026
Azure Pipelines: Not triggering a build when README.md is edited
Wednesday, January 7, 2026
macOS: Capture Video's Frames using Bash
The blog will cover how to screenshot a video on macOS using Bash. Videos typically run at 24 FPS or 30 FPS, so taking a screenshot every second will likely capture a representative frame of the video. macOS provides a command-line utility, screencapture, that takes screenshots.
The man page for screencapture is viewed as follows:
Below is a screenshot showing the key command-line arguments of screencapture:
When running screencapture from a macOS terminal console, a window may be displayed by the system. Permission will have to be given for Terminal to access the computer’s screen and audio. Similarly, when running screencapture in a Bash script from Visual Studio Code, the same permissions will have to be granted to Visual Studio Code.
To screenshot a video, run the Bash script. Then display the video full screen. The script will capture an image each second. By default, the script runs for 26 minutes, as a great many shows are 24 minutes long. A command line is provided to change the script duration.
If you are reading this, you are a developer. The command line for the script is readable in the comments. The script is less than two hundred lines of code, but most of the work is processing the command line.
Here is the script in its entirety:
Tuesday, December 23, 2025
macOS: Configure Visual Studio Code to Run the Bash Debug Extension
The Bash Debug Extension, as of version 0.3.9, requires at least Bash 4.* or Bash 5.* to be installed. macOS natively has Bash 3.2 installed.
A convenient way to install Bash is with Homebrew. If Homebrew has not previously been installed, it can be installed as follows. From a terminal session, invoke the following to install Homebrew:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
The Homebrew installer provides the following steps to finalize the installation for the current user:
Install Bash (currently 5.3.9) using Homebrew:
brew install bash
To run the latest Bash, specify the pathBash attribute in launch.json as follows:
Monday, September 29, 2025
Git Command-Line: Listing All Untracked Files
When a new folder is added to a local Git repo, "git status" only shows the folder name:
On branch bug/jdnark/1234408-Fix-Automation-Unzip
Untracked files:
(use "git add <file>..." to include in what will be committed)
CICDAutomation/
To see all the files that are untracked, and not just the folder, use the following:
An example of the files that are untracked is as follows:
Monday, September 22, 2025
Visual Studio Code: A launch.json for Python Development
Having spent years as a PowerShell developer, I find myself in need of a launch.json file for Python work. To add the launch.json file, create a new file under .vscode in Visual Studio Code. An example launch.json is as follows:
The configuration, Python: Current File, allows me to debug the current file I have open. The configuration, Python: Upload CVEs, is specific to a script I am debugging (upload_cve_docs.py) and the parameters associated with that script.
Older version of launch.json specified:
Using the above type attribute will display the following message as the attribute value python has been deprecated:
WSL/Ubuntu: Make Visual Studio Code Always Use Your Python Virtual Environment
Recall from WSL: Install Azure OpenAI SDK that in order to install the Azure OpenAI SDK on Ubuntu, a virtual environment had to be used. When running Visual Studio Code and developing with Python, the terminal associated with this virtual environment must be used; otherwise, the Azure OpenAI SDK-related packages will not be found.
This is not an issue when running an interactive terminal. Each time an interactive terminal is opened, .bashrc contains the following line, which facilitates access to the virtual environment:
The Ubuntu instance that is running will always access the virtual environment during development. Every time Visual Studio Code is launched from Ubuntu, the Python interpreter associated with the virtual environment must be used.
To set this behavior globally, as opposed to per-project, open Visual Studio Code from your WSL Ubuntu instance such as:
From Visual Studio Code, press Ctrl+Shift+P (Command Palette) and search for:
The example above is from my personal environment, so use your own specific virtual environment setup.
The python.defaultInterpreterPath setting points Visual Studio Code to your virtual environment. The setting python.terminal.activateEnvironment ensures it is auto-activated in the integrated terminal.
Once these changes have been made, save the file and close it.
Moving forward, every folder you open in Visual Studio Code will default to the virtual environment interpreter automatically.
This can also be configured on a per-folder basis by editing .vscode/settings.json, adding the following lines, and saving the file after modification:
Again, the settings shown above (python.defaultInterpreterPath) are specific to my environment, and you should use your own virtual environment settings.
Sunday, September 21, 2025
AI: Sample Dataset – National Vulnerability Database (NVD) CVE
Any AI needs seed data such as critical business data. With the help of ChatGPT, I created a Python app that downloads records from the National Vulnerability Database (NVD) CVE feed. This data is a structured dump of security vulnerability records retrieved from the REST endpoint:
The file size for all records in 2024 is approximately 100 MB. Be aware that Microsoft's documentation specifies Azure AI Search pricing as follows, where the size limit of the Free tier is 50 MB:
An example record retrieved from the National Vulnerability Database's CVE feed is as follows:
"id": "CVE-2024-12345",
"title": "Buffer overflow in XYZ software before 1.2.3 allows remote code execution.",
"description": "Buffer overflow in XYZ software before 1.2.3 allows remote attackers to execute code.",
"severity": "CRITICAL",
"score": 9.8,
"cwes": ["CWE-120"],
"references": ["https://vendor.com/security/advisory/123"],
"published": "2024-03-05T17:00:00Z",
"last_modified": "2024-05-01T12:34:00Z",
"source": "nvd"
}
The data endpoint rejects too many requests and cannot handle large requests. To work around this:
- A paging strategy was implemented where records were retrieved 120 days at a time.
- A current status checkpoint file, checkpoint.json, was maintained so the query could restart from the failure point.
- Iterations made use of timeouts (time.sleep) between page retrievals and between retries after errors.
On any failure, simply wait a few minutes and the code will restart from the last point of failure.
The Python code is as follows:
Saturday, September 20, 2025
WSL: Install Azure OpenAI SDK
I have a pristine Ubuntu (Ubuntu-24.04) distro running on WSL (see: WSL: Keeping a Pristine (Greenfield) Version of Your Distro). The blog presents the steps required to install Azure OpenAI SDK on this distro.
First, ensure packages are up to date:
sudo apt update
Ubuntu 24.04 blocks installing Python packages system-wide with pip to protect system tools. This means using pip system-wide to install packages will fail with an “externally-managed-environment” error. The correct way is to use a virtual environment (venv), which is a private sandbox for Python and its packages.
To enable venv on Ubuntu, install the package:
To make use of venv, create and activate a virtual environment where the source command activates the virtual environment:
The azure-ai-openai package isn’t publicly available on PyPI, so install the OpenAI Python SDK:
The -U option above ensures the version installed is upgrade to the latest.” → “The -U option above ensures the package is upgraded to the latest version.
Inside Python, paste the following to ensure access to the Azure OpenAI package:
Every time you access Azure OpenAI on this distro instance, the venv must be activated using the following:
WSL: Keeping a Pristine (Greenfield) Version of Your Distro
WSL has a limitation. Once you install a distro using wsl --install, you cannot just install a second copy of the same distro. The way to get around this is to install the latest distro, such as Ubuntu 24.04, and then make a backup of the pristine distro so that it can be duplicated later via import. It seems like something that should just be an option in wsl --install, but alas, it is not.
In this article I will walk you through the steps required to create this pristine copy of a distro. I will also show you how to name your distro in WSL something besides Ubuntu or Ubuntu 24.04.
To demonstrate a new hence pristine instance of a distro must be installed on WSL. This topic was covered in a previous blog WSL: Always Specify the Distro Version When Installing. Moving forward I will not be doing any work on this distro. See the following demarcated n boldface (courtesy of running wsl -l -v):
For example, on the Ubuntu-24.04 distro I will not install any Azure-related packages or Azure AI packages. Ubuntu-24.04 is my pristine/clean/greenfield distro, and any project-specific work will be done by making a copy.
Once a new distro is installed, I like updating the distro to use the latest packages by running:
On my personal machines I like disabling the sudo prompt, which was covered in this is blog, Ubuntu/Linux: Disable sudo Password Prompt. This means that each copy of the distro instance will also have sudo disabled.
Once the pristine/clean/greenfield distro is patched, make a backup of it by following the steps in WSL: Backing Up and Deleting a Distro, and obviously do not delete the current distro.
When I start a new project, such as my Azure AI Foundry work, I will create a new distro named for the project. It will be a suitable name like AzAiUbuntu-24.04, and I will follow the steps here to import an instance of the distro with the aforementioned name (see WSL: Restoring a Distro from a Backup).
To create (import) a project-specific distro I would use these parameters:
- Distro AzZiUbuntu-24.04Host00
- InstallLocation: C:\Users\jann\AppData\Local\wsl\AzAiUbuntu-24.04
- FileName: C:\Backups\20250921Ubuntu-24.04.tar
WSL: Restoring a Distro from a Backup
This article discusses restoring a WSL distro from a backup TAR file. In a previous entry, the backup process for a WSL distro was presented: WSL: Backing Up and Deleting a Distro. Restoring from a backup is a bit more complicated because the wsl --import command requires that the "install location" be specified, but knowing where the default path used by WSL to install virtual disks (*.vhdx files) is important.
Microsoft documentation, Import any Linux distribution to use with WSL, presents the full wsl --import command as follows:
Options:
--version <Version>
--vhd
To see the location where virtual disks are stored, run the following from a PowerShell console window:
An example of the output from the above command is as follows:
From the above output, the default location used by WSL is:
C:\Users\jann\AppData\Local\wsl
Notice the GUID in the path, meaning WSL creates a random folder name — a GUID (e.g., {e3757a3a-1cb5-4208-b9c2-5f6f7490cda8}) — for the distro instance.
C:\Users\jann\AppData\Local\wsl\{e3757a3a-1cb5-4208-b9c2-5f6f7490cda8}
For the sake of example, the following InstallLocation could be used when importing an instance of Ubuntu-24.04:
C:\Users\jann\AppData\Local\wsl\Ubuntu-24.04Host00
The distro name must be unique so run the following comment to see the current distros installed.
An example of the output generated by wsl -l -v is as follows:
From the list of names, choosing Ubuntu-24.04 as the name for the imported distro would be invalid.
For our example, the following parameters will be used:
- Distro Ubuntu-24.04Host00
- InstallLocation: C:\Users\jann\AppData\Local\wsl\Ubuntu-24.04Host00
- FileName: C:\Backups\20250921Ubuntu-24.04.tar
The full command to import the back up is as follows:
wsl --import Ubuntu-24.04Host0 'C:\Users\jann\AppData\Local\wsl\Ubuntu-24.04Host00' 'C:\Backups\20250921Ubuntu-24.04.tar'
The import took tens of seconds compared to the export, which took minutes. Once complete, wsl --import displays status:
After import, always verify by running, wsl -l -v, which shows Ubuntu-24.04Host0 was created:
Friday, September 19, 2025
WSL: Backing Up and Deleting a Distro
Before deleting a WSL distro and , say, upgrading to a new version**,** it is often wise to back up the existing distro. This blog covers the steps to perform this task.
Step 1: List Installed Distros
From a PowerShell console run the following:
This will show you the name, version, and state of each distro. One of my WSL instances shows the following when wsl -l -v is run:
For this example, the distro Ubuntu-22.04 will be backed up and then deleted.
Step 2: Export the Distro (Backup)
The wsl command’s --export option allows a backup of a distro to be saved to a file in TAR format. The command is as follows for my distro, Ubuntu-22.04:
Once initiated, the export operation will display a message such as the following:
Once completed, the export operation will display a message including the size of the exported TAR file:
The backup TAR file can be imported later using the wsl command. The exporting process can take several minutes, unlike deleting a distro which is instantaneous.
Step 3: Delete the Distro
The distro is backed up, so it can safely be deleted as follows with wsl:
Although the command-line option is --unregister, it completely deletes the distro from WSL. No warning prompt will be given. The command just runs nearly instantly:
Unregistering.
The operation completed successfully.
WSL: Always Specify the Distro Version When Installing
docker-desktop Stopped 2
docker-desktop-data Stopped 2
When I installed a few years ago, I used the following command, where the name Ubuntu means “install the latest distro”:
wsl --install -d Ubuntu
It makes more sense to install the distro by specifying the version, such as:
wsl --install -d Ubuntu-24.04
Running wsl -l -v again from PowerShell shows the distros with their version numbers:
* docker-desktop Stopped 2
Ubuntu-22.04 Stopped 2
docker-desktop-data Stopped 2
Ubuntu-24.04 Running 2
QED: Quod Erat Demonstrandum
Visual Studio: Finding Using Statements Added to Source Code by Visual Studio
In a previous post (Visual Studio: Disabling Add Using Statements on Paste), I showed that Visual Studio has a feature that adds using statements to C# files even when a project takes advantage of project-level global usings. And yes, this feature does turn itself back on (see below -- it's back):
Periodically, in a large project, I like searching for these superfluous using statements. The way to do this is to use a regular expression. From Visual Studio, select Find in Files, which is under Edit → Find and Replace → Find in Files (CTRL+SHIFT+F). In the search textbox, paste the following regular expression:
(?m)^using\s+
File types can be *.* or *.cs. Click on "Find All" and purge away.
Below is ChatGPT's breakdown of the regular expression, (?m)^using\s+ :







