Publishing TESTNG test results into Azure DevOps

At the moment, Azure DevOps supports the following results formats include CTest, JUnit (including PHPUnit), NUnit 2, NUnit 3, Visual Studio Test (TRX), and xUnit 2. Unfortunately, it does not support TESTNG test results format. The good news, however, is that TESTNG also produces JUnit test results in a separate junitreports folder. So, we can publish TESTNG test results in JUnit format instead.

To do that, just change Test results files field under JUnit Test Results section to **/junitreports/TEST-*.xml.

How to Check Who are Global Admins in your Azure AD with PowerShell

You can use the following PowerShell snippet to quickly check who are the Global Administrators in your Azure AD:

$role = Get-AzureADDirectoryRole | Where-Object {$_.displayName -eq 'Company Administrator'}

Get-AzureADDirectoryRoleMember -ObjectId $role.ObjectId

That's it. It's that easy

Connect XAML Build Controller to Azure DevOps

Recently I've run into the situation where I needed to configure good old XAML build controller to connect to Azure DevOps, but my attempts kept failing. When I start the build service, first starts successfully and then stops with error TF300063. Every single time. Very annoying.

I have tried to troubleshoot the issue. Checked and double checked the permissions. Reset the client cache. Tried some other things, but nothing helped. Then, I've decided for the fun of it to try to connect XAML Build controller using old Azure DevOps/VSTS URL (orgname.visualstudio.com) instead of new Azure DevOps URL (dev.azure.com/orgname). And it worked! Hurray!

It appears that because XAML builds are soon to be deprecated feature, XAML build controller feature have not been updated to work with the new URL. They work just fine with the old URL though. So, until you migrate your XAML builds to new builds (and, you really should do that), you can keep using the old Azure DevOps/VSTS URL (orgname.visualstudio.com) to have your old XAML build controllers working with brand new Azure DevOps.

A supported task execution handler was not found

If you're getting "A supported task execution handler was not found. The task does not carry an implementation that is compatible with your current operating system 'Windows(X86)'. Contact the task author for more details." error in your build or release pipelines in Azure DevOps, then it's most likely because you have a 32 bit version of the agent installed on 64 bit operating system. When that happens Agent.OSArchitecture build variable is mistakenly set to 32 instead of 64. To fix this issue, just install 64 bit version of the agent instead. That should fix the issue.

Hope this helps.

Migrating from TFS to Azure DevOps from behind a corporate proxy

If you're behind a corporate proxy and trying to migrate TFS to Azure DevOps using tfsmigrator.exe command, then most likely your tfsmigrator prepare command might fail with "AAD Timeout Exception" exception. This error means that the requests to AAD to find the matching AAD identities for users in your collection timed out. TfsMIgrator troubleshooting guide has a number of solutions that you can try to mitigate the issue. Depending on your environment those solutions might not work. At the moment, another possible solution is missing from this troubleshooting guide. This is what this blog post is about.

Another reason for AAD Timeout Exception is that you're running behind a corporate proxy. If you are using an outbound proxy for connecting to the Internet, the following setting in the C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config file must be added. This text must be entered at the bottom of the file. In this code, represents the actual proxy IP address or host name.

<system.net>

<defaultProxy>

<proxy

usesystemdefault="true"

proxyaddress="http://<PROXYADDRESS>:<PROXYPORT>"

bypassonlocal="true"

/>

</defaultProxy>

</system.net>

 

So, update your machine.config file, re-launch your command line and try tfsmigator prepare command one more time. It should work this time. Hope this helps.

Create Azure VM without a Public IP using Azure CLI

You really shouldn't create Azure virtual machines with public IP addresses unless you need it to communicate with outside world. Instead use VPN or ExpressRoute to connect to the virtual machine using private IP address. To create Azure VM without a public IP address using Azure CLI use the following command:

az vm create --resource-group TEST --name TESTVM --public-ip-address ""

Yes, just use empty quotes to create your VM without a public IP address. If you do not specify --public-ip-address option then Azure CLI will create a new public IP address and assign it to your VM.

Another gotcha is that the above-mentioned command only works if you run in in the command line or bash. If you're running your Azure CLI commands from within PowerShell, then you need to wrap empty quotes one more time. So the command will look as such:

az vm create --resource-group TEST --name TESTVM --public-ip-address '""'

Apparently, PowerShell swallows empty quotes and never passes them to Azure CLI command, so if you don't wrap the quotes again in PowerShell window, you will end up a virtual machine with a public IP address, which is frustrating.

Hope this helps.

P.S. : If you need your virtual machine to have a public IP address, please do not forget to secure that VM using network security group and such…

 

Configure TFS Search in Multi-Application Tier Scenario

If your TFS environment has multiple load balanced application tiers, then it's recommended to configure TFS Search (aka. ElasticSearch) on a separate server. That way you have a dedicated machine to index your TFS content. See https://docs.microsoft.com/en-ca/vsts/project/search/administration?view=vsts#separate-server for more information.

But, in some cases, dedicating a separate server just for search might be an overkill or inefficient. If you want to configure TFS search to run on one of the existing TFS application tiers, do the following:

If you're starting fresh:

  1. Setup Search (ES) using the Configure-TFSSearch.ps1 ("%Program Files%\Microsoft Team Foundation Server 2018\Search\zip\Configure-TFSSearch.ps1") script in one of the application tier servers. For example, App1 server.
  2. Configure Search suing the remote search option (even though search was setup in the same machine as AT) and use the http://{App1}:9200 URL.
  3. Make sure http://{App1}:9200 is accessible from all application tier servers.

Give it some time for search to index the TFS content.

   

If you already have search configured:

  1. Cleanup the index data and remove/uninstall the ElasticSearch service.
  2. Backup TFS Configuration database then delete the '%SearchPlatformConnectionString\%' entries from TFS configuration database. Obviously, be careful when making changes directly to the database. In the TFS Configuration DB, run the following query:
    SELECT * FROM [Tfs_Configuration].[dbo].[tbl_RegistryItems] where ChildItem like '%SearchPlatformConnectionString\%'

    You should see the RegValue entries as http://localhost:9200. Modify these registry values to http://{App1}:9200
  3. Configure Elastic Search using the Configure-TFSSearch.ps1 ("%Program Files%\Microsoft Team Foundation Server 2018\Search\zip\Configure-TFSSearch.ps1") script in one of the application tier servers again
  4. Cleanup all collection DB tables as mentioned here.
  5. Re-configure Search using the remote search option (even though search was setup in the same machine as AT) and use the http://{App1}:9200 URL.
  6. Make sure http://{App1}:9200 is accessible from all application tier servers.

This approach will re-index the collections again.

Hope this helps.

Error During TFS Search Configuration

If you're experiencing "VS403185: An unknown error has occurred during Search configuration" error when configuring search using TFS configuration wizard, then most likely you have attempted to configure search to run using a domain account. At this point, when using TFS Configuration wizard, search can only be configured to run as to run as NT AUTHORITY\NETWORK SERVICE. So, change the search service account to NT AUTHORITY\NETWORK SERVICE and things should go back to normal.

Obviously, you can still configure search in TFS 2018 with custom credentials for Elastic Search. You just need to configure search separately from application tier configuration. So, uncheck the Search configuration checkbox option in the TFS Configuration wizard and proceed. Once the TFS is configured, go to the Search tab and proceed with its configuration using custom credentials.

Redirecting TFS traffic from /tfs to / root site

A while back I wrote a blog post on how to get rid of /tfs in TFS URL. Now, I would like to expand on that blog post and write about how to redirect TFS traffic from /tfs to / root of the site once you got rid of /tfs from the URL. To do that you need to do the following:

  1. Install URLRewrite module from https://www.iis.net/downloads/microsoft/url-rewrite
  2. Add the following section to the web.config of the TFS server

    <rewrite>

      <rules>

                <clear />

                <rule name="Redirect HTTP to HTTPS" enabled="true" stopProcessing="true">

                    <match url="(.*)" ignoreCase="true" />

                    <conditions logicalGrouping="MatchAll" trackAllCaptures="true">

                        <add input="{HTTPS}" pattern="off" />

                        <add input="{HTTP_HOST}" pattern="([^/:]*?):[^/]*?" />

                    </conditions>

                    <action type="Redirect" url="https://TFSURL.FQDN/{R:1}" appendQueryString="false" />

                </rule>

                <rule name="Redirect TFS traffic" stopProcessing="true">

                    <match url="tfs\/(.*)" />

                    <action type="Redirect" url="https:// TFSURL.FQDN /{R:1}" appendQueryString="false" />

                </rule>

      </rules>

    </rewrite>

 

First rule is redirecting all traffic to HTTPS, and second rule redirects all /tfs traffic to / root site of the TFS. If you don't have HTTPS, then simply remove the first rule and replace HTTPS with HTTP in the second. Obviously, replace TFSRUL.FQDN with your TFS public URL.

Installing Git from source on RedHat Linux machine

When you do DevOps work, you deal with all kinds of tools and operating systems. Today, we'll talk about Linux and Git. With my Linux days behind me (or in front of me because you never know where technology will go), I was surprised that yum update git command did not update Git client on Linux box. After a bit of digging, I've found out what do you need to do to upgrade Git client on Linux.

Uninstall existing Git client:

sudo yum remove git

 

Install dependencies:

sudo yum install curl-devel expat-devel gettext-devel

sudo yum install gcc openssl-devel zlib-devel perl-ExtUtils-MakeMaker

 

Install Git:

cd /usr/src

wget https://www.kernel.org/pub/software/scm/git/git-2.16.2.tar.gz (feel free to substitute this link with the link to the other version of Git client)

tar xzf git-2.16.2.tar.gz

cd git-2.16.2

sudo make prefix=/usr/local/git all

sudo make prefix=/usr/local/git install

sudo –i

echo "export PATH=$PATH:/usr/local/git/bin" >> /etc/bashrc

exit

source /etc/bashrc

 

That's it. Check the version of Git client by running "git –version". You should get: git version 2.16.2

By the way, these steps should also on Linux CentOS and Fedora (and any other ReadHat Linux flavour out there)