Thursday, May 12, 2022

Xml Schemas/C#: Improving Online Documentation (Open Source Contribution)

While reading a code snippet in Microsoft's documentation, Reading and Writing XML Schemas I noticed the following example code:

The variable of type XmlSchema is named myschema. This is a C# example and prefixing variable names with the term "my" is a coding style associated with VB.NET. 

I edited the page which brought me to Github. Github makes a fork and allowed me to suggest the change by creating a pull request. Here is updated documentation reflecting my accepted change:

Here is the notification that the pull request was merged into the main branch:

Saturday, April 9, 2022

Ubuntu/Linux/Hyper-V: Creating an Ubuntu 20.04 VM can be accessed from Hyper-V's Host Computer

I was assigned a project where a shell script had to be run remotely on an Ubunto 20.04 Virtual Machine (VM). The remote script failed on an Azure VM so I fell back on Hyper-V running on Windows 11. The way I traditionally configured an Ubuntu 20.04 VM did not permit SSH access from the host computer. These are the steps required to set up an Ubuntu 20.04 that can be configured to accept SSH connections from the host computer.

Create VM (Basic Ubuntu Install)

Create VM pre-installing Ubuntu from an Image

1) Download the Ubuntu 20.04 LTS from Download Ubuntu Desktop on the host computer. The format of the image download will be ISO.

2) Launch Hyper-V Manager on the host computer and make sure that the host computer name is selected in the left panel:

3) Select Action | New| Virtual Machine:

4)  Navigate click Next in the New Virtual Machine Wizard under the Specify Name and Location panel is displayed:

5) Enter the name of the virtual machine to be created (the name above is devops02-ubuntu20.04) and click on Next:

By default, Generation 2 VMs cannot use an ISO operating system image for installation. This will be addressed at a later step in the installation process.

6) From the Specify Generation panel select the Generation 2 radio button and click Next:

7) From the Configure Networking panel select Bridge (which allows external access to say the internet and provides access to the internal network, a.k.a. the LAN) which will enable access to the VM from the host computer (the VM will be assigned a local IP address) and click Next:

8) Configure the hard drives and click Next:

9) Specify the location of the Ubuntu install media and click on next:

10) Click Finish on the final setup screen:

Configure Ubuntu to Install from ISO

1) From Hyper-V Manager highlight the VM being setup and from the Actions panel on the right click on Settings:

2) From Settings dialog select Hardware | Security from the pane on the left:

3) Click on OK.

Installing Ubuntu on the VM

1) From Hyper-V Manager, double click on the VM to be set up in order to establish a connection to the VM (opens the connection dialog):

2) From the per-VM connection dialog click on Start:

3) Clicking on Start displays the standard Ubuntu install wizard.

4) Click on Continue and perform the steps required to complete the installation of Ubuntu.

Verify Static IP Address

The previous steps ensured that a VM was assigned a static IP address. In order to verify that this static IP address was assigned, run ifconfig from a terminal on the VM. The installation of ifconfig is presented in the post, Ubuntu/Linux: Retrieving a Computer's IP Address using ifconfig). 

Below is a screenshot showing the output from ifconfig when run from the VM:

The output from running ifconfig (above) shows a static IP address has been assigned to the VM.

Saturday, April 2, 2022

Ubuntu/Linux: Configuring a host to support ssh Connections (Installing OpenSSH Server)

By default, an Ubuntu 20.04 instance does not contain an SSH server and hence there is no ssh access to the machine. To remedy this, install OpenSSH Server by:

1) Install the OpenSSH Server package:

sudo apt-get install -y openssh-server

2) Enable the service using systemctl enable:

sudo systemctl enable ssh

3) Start the service using the systemctrl start command:

sudo systemctl start ssh

4) On a different host, verify that the port for ssh (port 22) is open using the technique described in Ubuntu/Linux: How to tell if a Port is Open on a Remote Host:

echo > /dev/tcp/ && echo "Port 22 (SSH) is open!"

When the above command is invoked and OpenSSH has been installed successfully the following is displayed:

Remember the above command is run on the client host and not the host (remote computer) where OpenSSH server will run.

Ubuntu/Linux: How to tell if a Port is Open on a Remote Host

While trying to get ssh working to a remote host, I encountered the "Connection refused" error message on Ubuntu.  The first step in debugging is to make sure the port is open on the remote host which can be done as follows:

echo > /dev/tcp/<remote host>/<port> && echo "The port is open"

Checking to see if ssh (port 20) is open on a host ( is simply:

To verify script snippet works I did tested it against HTTPS (port 443) on a well know host (

Ubuntu/Linux: Retrieving a Computer's IP Address using ifconfig

Consider the case where a developer wants to ssh from a host computer to a Ubuntu client running in Hyper-V. The most fundamental way to access the client machine via ssh is using its IP address. Linux's ifconfig utility is short for interface config.

The ifconfig utility is part of the net-tools package. To install this package on Ubutu use apt-get as follows:

sudo apt-get update -y
sudo apt-get install -y net-tools

An example of ifconfig being invoked is as follows where the computer's IP is shown to be 10.0.37:

Ubuntu/Linux: Disable sudo Password Prompt

When running scripts as sudo, it is convenient not to be prompted for a user's password. Password prompts defeat automation so this post will demonstrate how to disable the password prompt associated with the sudo command.

The command sudo date is often used to determine if invoking sudo will prompt the user to enter their password (as follows):

Above, it can clearly be seen how the sudo before the date command causes a password prompt for the password of user devops. 

The sudo command allows commands to be elevated and run as root. In order to use the sudo command, a user must be part of the sudo group. The following post demonstrates how to add a user to the sudo group: Ubuntu: Adding a user to the sudo group.

To disable the sudo caused password prompt invoke the command

sudo visudo

Running the above command does require a user to enter their password in response to sudo (hopefully for the last time):

The visudo command is an editor for the /etc/sudoers file. visudo validates the sudoers file's format on save. The man page for the sodoers file can be found at Sudoers Manual.

visudo brings the sudoers file up in an editor:

To suppress the password for a specif member of the sudo group, add the following text under the line %sudo  ALL=(ALL:ALL) ALL:

<user name here> ALL=(ALL) NOPASSWD: ALL

For the case of a user named, devops, the following line would be added in the editor:


The reason for putting the new line after the line containing %sudo  ALL=(ALL:ALL) ALL is explained in the sodoer man page (referenced above):

The sudoer file being edited by visudo will look as follows:

Use ctrl-s to save the file and cttrl-x to exit the editor.

Once the sudoer file has been edited correctly and saved, a user should no longer be prompted to enter a password when invoking the sudo command.

Ubuntu/Linux: Adding a user to the sudo group

Members of the sudo group can execute any command as root user using the sudo command:

sudo date

The command above invokes the date command with root privileges.

In order to add a user to the sudo group, invoke the following from a terminal:

sudo usermod -aG sudo <username>

The leading sudo runs the usermod command as root. Depending on how a user is configured, the sudo command may prompt the user to enter a password.

To add a user named, devops, to the sudo group invoke the following command:

sudo usermod -aG sudo devops

Thursday, March 31, 2022

Google Sheets: Pasting Delimited Data

The National Emergency Medicine Services Information System (NEMSIS) is a data standard for patient care information corresponding to a 911 call or other emergency care situations(such as being treated for a medical condition at a NASCAR event). The schemas associated with NEMSIS are delineated as federal (national) and state. The elements of this schema are defined at Required National and Recommended State Elements (V3.5.0) where the definitions are a value separated list where the separator is the vertical bar (|) character.

An example of this data is as follows:

Rather than save the data to a file and then import, the data can simply be cut and pasted into a clean Google Sheet:

Notice the past icon (the clipboard) with a down triangle indicating a menu. Clicking on the down triangle displays a menu from which Split text to columns should be selected:

Clicking on Split text to columns displays the following:

Clicking on Detect automatically displays the following:

In the Custom separator textbox enter a vertical bar:

Click on enter and the delimited data will populate the columns using the vertical bar character as a separator:

As an alternative, the Data menu contains Split text into columns which could have been used to separate the data using the vertical bar.

The delimited data values each contain a leading and trailing single quote. To remove these click the top left of the sheet (to the left of A and above 1) to select all data elements:

From the Edit menu select Find and replace:

Using Find and replace the single quotes can be removed:

Tuesday, March 15, 2022

Wednesday, February 9, 2022

Docker: Containerizing a Visual Studio 2022 .NET Core Console Application with Docker

When a .NET 6, ASP.NET Core project is created by Visual Studio 2022 an "Enable Docker" checkbox is provided as part of the project creation wizard. Simply checking the "Enable Docker" checkbox adds Docker support to the ASP.NET core web application.

Other Visual Studio 2022 project types including .NET Core console projects are not afforded the option to enable Docker support during project creation. This post demonstrates how to add Docker support to a Windows .NET Core console application support created with Visual Studio 2022. Additionally this post will drill down into the changes made the project and solution when Docker support is added.

Microsoft does provide an excellent tutorial on how to create a .NET Core console application using Visual Studio Code, Tutorial: Containerize a .NET app. The aforementioned tutorial shows there are significantly more manual steps to Dockerize a console project using Visual Studio Code compared to Visual Studio 2022 (just a few clicks).

The steps to add Docker support to a console application are as follows:

1) Create a .NET Core console application (see: Docker: Create a .NET Core (.NET 6) Console Application in Visual Studio 2022 for future Containerization)

2) Setup the console application to be published (see: Docker: Publishing a .NET Core (.NET 6) Console Application with Visual Studio 2022 (a Containerization Prereq)). Technically a Docker Support can be added without configuring publish for the project but it is cleaner to configure publishing for the project.

3) Right click on the .NET Core console project in Solution Explorer (project ForensicDataPusher) and select Add | Docker Support:

4) Once Add | Docker Support is selected the Docker File Options dialog is displayed:

5) Chose the Target OS. For this example Windows will be selected.

Changes Made by invoking "Docker support"

The following write up from Microsoft describes the changes selecting "Docker support" makes to the project Visual Studio Container Tools for Docker (to quote):

The Dockerfile created by clicking on "Docker support" is as follows:

The .dockerignore file is created at the solution level. The .dockerignore file is not visible in Solution Explorer unless it is explicitly added (right click on the solution in Solution Explorer and select Add | Existing Item). The contents of the .dockerignore file created are as follows:

Visual Studio 2022's standard toolbar looks as follows before Docker support was added:

Visual Studio 2022's standard toolbar looks as follows after Docker support is added:

The startup project command changed from ForensicDataPusher (build the solution) to Docker (deploy to Docker).

The ForensicDataPusher .csproj is changed as follows (see the line demarcated in boldface)

Microsoft documents the DockerDefaultTargetOS project element in Container Tools build properties as follows:

Docker: Publishing a .NET Core (.NET 6) Console Application with Visual Studio 2022 (a Containerization Prereq)

Before a Docker image can be created that hosts an application (such as a console app created with Visual Studio 2022), the artifacts (files) needed to run the application must be created. The process for creating the artifcatds needed to run an application is called publishing. Simply put, an application must be published before it can be copied to a Docker image and the application subsequently containerized.

The console application to be published was created in the post Docker: Create a .NET 6 Console Application in Visual Studio 2022 for future Containerization. The newly created project and the solution that contains the project are as follows (opened in Visual Studio 2022):

Configure Publishing

To configure publishing the project, right-click on the project in Solution Explorer and select Publish from the context menu:

The first time the Publish menu item is selected, a wizard is displayed that allows the configuration associated with publishing to be set up. Subsequently clicking on publish will build the project and copy the files that are needed to run the console application to a target folder.

When the Publish menu item is selected for the first time for a given project, the Publish dialog is displayed as follows:

From the Publish menu, select target, Folder, and click Next which still displays the Publish dialog but allows the "Specific target" to be selected (see below): 

For the "Specific target," select Folder and click Next which expands the Publish dialog to include Location as follows:

The "Folder location" is filled in by default with bin\Release\net6.0\publish\. This means that the artifacts required to run the application will be placed in this folder.

Click Finish to complete the configuration of the publishing for the console application. The 


To publish the project (after publishing has been configured), right-click on the project in Solution Explorer and select Publish from the context menu which displays the Publish dialog. It is also possible to initiate publishing using Visual Studio 2022's menus and selectin gthe  Build | Publish Selection menu item:

After clikcing on the "Publish Select" menu item, the Publish dialog is displayed as follows:

To the right side of the dialog is a Publish button. Clicking on the Publish button will publish the application by creating the set of files needed to run the application and placing them under the target location (bin\Release\net6.0\Publish).

After a project is published, the Publish dialog is update and will show and entry for "Publish succeeded" or "Publish failed" (see below):

The Publish button was clicked and it is important to note that Visual Studio's current Solution Configuration was set to Debug:

When the Publish button was clicked, a build was run which built Release as the publishing process is associated with the Release Soluiton Configuration. After the build succeeded, the file required to run the application were copied to the publish folder.

The built output shows that publishing invoked a Release build even though the Solution Configuration was set to Debug:

Publishing Configuration File

The file used to store publishing configuration information is FolderProfile.pubxml. This file is found in the project's Properties\PublishProfiles folder: 

The contents of FolderProfile.pubxml reflect the configuraton specified when publishign was setup:

Publish Folder

As discussed in "Visual Studio: Displaying all Files in Solution Explorer," Visual Studio 2022 does not show bin/obj files by default. The published files are under bin folder so to see the files from Solution Explorer toggle on the "Show all Files" button and navigage in Solution Explorere to the publish folder (bin\Release\net6.0\publish):