ALM Days meet Technical Summit

Die ALM Days – der Community Event für DevOps und ALM im Microsoft Kontext –  wird es in Zukunft in dieser Form nicht mehr geben. Stattdessen wird die Veranstaltung mit der Technical Summit zusammen gelegt.


Die Technical Summit hat sich die letzten Jahre zu der wichtigsten Microsoft Veranstaltung entwickelt. Sie beinhaltet Themen rund um Entwicklung, Cloud Computing, Infrastruktur – und eben auch ALM und DevOps.

Dieses Jahr findet die Summit vom 6. bis 8. Dezember in Darmstadt statt. Als Keynote-Speaker sind dabei:

  • Scott Guthrie (Executive Vice President Cloud)
  • Erich Gamma (Gang of four)
  • Ann Johnson (Vice President Cybersecurity)
  • Donovan Brown (DevOps Program Manager)

Ich denke man sieht an diesem Line-Up, wie wichtige die Konferenz in Deuschland ist.

Natürlich sind auch all die anderen Sprecher, die ihr von den ALM Days kennt dabei. Ich werde einen Vortrag über “Entwurf und Bereitstellung von Software für DevOps-Organisationen” halten.

Ich hoffe, viele von euch dort zu treffen!

How to write web performance tests for SharePoint Online and ADFS

Creating web performance tests in Visual Studio for SharePoint on premise is easy and well documented. But writing them for Office 365 / SharePoint online is another thing. The authentication can be different – depending on you configuration – and there is nearly no documentation available. In my case the SharePoint Online tenant authenticates via ADFS against a Windows Active Directory Domain.

The easiest way to get the authentication running is to record the authentication flow in Visual Studio. Before you start recording the web test, open your browser and make sure you are logged off from Office 365. Then record the login process to your site and edit the web test.

The first thing you have to do is to set your credentials for the test in the properties windows.

Set credentials for your web test

Now find the request to your adfs that ends in /adfs/ls/. Delete all the steps before that – you don’t need them. Remove the referrer and make the url to your adfs, the client request id and the user name context parameters. The extraction rule should be correct.

request adfs token

The next request you have to look for is a post to Delete all requests between the adfs and this one. Remove the referrer. The form post parameters should be correct – if not you have to adjust them according to the image.

Get access token from

The next thing we have to do is a post to /_forms/default.aspx on your SharePoint. This post will redirect you – so make sure to set the expected response url correctly. If you leave this step out you won’t get the authentication cookie!

Post to _forms default.aspx to get access cookie

Visual Studio will now add the cookie to every request. Delete all the other requests and add a new GET request to your desired page.

Request your sharepoint page

To make sure you don’t get redirected you should add a validation rule and validate something on your site. I added a rule and test the site title.

Add validation rule

If you run the test and encounter errors, check that the Set-Cookie ist set correctly after calling the login.srf. It must be in any request.

web test results for sharepoint online

I just started testing SharePoint Online and Office 365 for different customers. So expect more posts to this topic the next months. What’s your experience? Do you use automated tests for SharePoint online?

Restore your nuget packages on build server

Some time ago I wrote about how you can manage your dependencies with nuget. What I left out is how you configure Visual Studio to not check in the packages but to restore them during build on the CI server.

Disable Source Control Integration

To disable source control integration in Visual Studio you have to add a nuget.config to your solution folder. In the file set disableSourceControlIntegration for the solution element to true.

<?xml version="1.0" encoding="utf-8"?>
    <add key="disableSourceControlIntegration" value="true" />

If you use TFSVC you also have to add a file with the name .tfignore add solution level to source control if it does not yet exist. Add a line with \packages to the file.

If you use git then check that your gitignore file contains the following line:


Now you can delete the packages folder from source control. New packages will not added by Visual Studio and VS will automatically restore them for you.

Restore nuget packages on the build server

If your build server is behind a proxy you can configure the proxy in the nuget.config file.

<?xml version="1.0" encoding="utf-8"?>
    <add key="http_proxy" value=http://server:Port />

To enable the build server to find all your packages you have to specify the package sources.

Be extremely careful to specify the URL to corectly! There is a lot of documentation out there that does not work any more. If your URI points to the V3 API you also have to specify protocolVersion=”3”. Check the URL in your Visual Studio Settings in case this changes with a future update. in Visual Studio settings dialog

<?xml version="1.0" encoding="utf-8"?>
    <add key="" value="" protocolVersion="3" />
    <add key="Share" value=\\server\share />
    <add key="NuGet Server" value=http://server/nuget />

In your build you don’t need the “NuGet Installer” task. It is sufficient to check the “Restore NuGet Packages” check box for your build task – even if you have custom packages sources.

Restore NuGet packages in Visual Studio Build task

Troubleshooting nuget on the build server

If you have problems with restoring packages on the build server – it is really hard to get a verbose output. The best thing you can do is to download the latest nuget.exe and add it to your source control. Then use the NuGet Installer task and specify the path to the exe. Add “-Verbosity detailed” to the NuGet Arguments.

Trouble shooting nuget restore on the build server

This gave me a detailed output of the API calls that are performed by nuget.exe that helped me troubleshooting. I have no idea why this does not work with the default nuget.exe.

Fix Release Management Error ‘Found value ‘aBcD’ with no corresponding key’

I had a strange error with the TFS / VSTeam Release Management and the ‘PowerShell on Target Machines’ task. The error only occurred in some environments:

2016-09-01T15:15:23.8214226Z ##[error]The running command stopped because the preference variable “ErrorActionPreference” or common parameter is set to Stop: Found value ‘aBcD’ with no corresponding key

‘aBcD’ were random characters that gave absolutely no results in google.

After a long analysis I finally found the solution in the diagnostics log on the build server:

15:15:23.799421 InputSessionVariables=$AppPoolPassword=ab,aBcD, $AppPoolUserName=customer\serviceuser
15:15:23.814424 System.Management.Automation.ActionPreferenceStopException: The running command stopped because the preference variable &quot;ErrorActionPreference&quot; or common parameter is set to Stop: Found value 'aBcD' with no corresponding key
   at System.Management.Automation.Runspaces.PipelineBase.Invoke(IEnumerable input)
   at System.Management.Automation.PowerShell.Worker.ConstructPipelineAndDoWork(Runspace rs, Boolean performSyncInvoke)
   at System.Management.Automation.PowerShell.Worker.CreateRunspaceIfNeededAndDoWork(Runspace rsToUse, Boolean isSync)
   at System.Management.Automation.PowerShell.CoreInvokeHelper[TInput,TOutput](PSDataCollection`1 input, PSDataCollection`1 output, PSInvocationSettings settings)
   at System.Management.Automation.PowerShell.CoreInvoke[TInput,TOutput](PSDataCollection`1 input, PSDataCollection`1 output, PSInvocationSettings settings)
   at Microsoft.TeamFoundation.DistributedTask.Handlers.PowerShellHandler.Execute(ITaskContext context, CancellationToken cancellationToken)
   at Microsoft.TeamFoundation.DistributedTask.Worker.JobRunner.RunTask(ITaskContext context, TaskWrapper task, CancellationTokenSource tokenSource)

The problem was in one of the Session Variables of the ‘PowerShell on Target Machines’ task. I used a encrypted variable here to pass in a password. The password contained a comma and therefor was split in two parts and broke the syntax of the command.

PowerShell on Target Machines Session Variables

I fixed this for now by removing the comma from the password – but I think it should be possible to enclose the variables in quotation marks. I will update this post if I find a syntax that works.

12 steps to get started with Mobile DevOps

I prepared my mobile DevOps demo for our roadshow yesterday. I created an end to end scenario with Xamarin, Visual Studio Team Services (VSTS), the Xamarin test cloud and HockeyApp. I was pretty impressed that it only took me a few hours to get everything running. But there were some pitfalls – so here is a step by step guide to get you up and running in a few hours.

1. Install Xamarin

If you haven’t installed Xamarin yet you can do it with the Visual Studio installer. Open Programs and Features, select Visual Studio Enterprise 2015, click change and select modify.

Under Cross Platform Mobile Development select C#/.Net (Xamarin v4.1.0). This will automatically activate some other features like Android SDK.

Install Xamarin 4.1

2. Create your Xamarin project in Visual Studio

Create a new solution in your VSTS repository of the type Blank App (Native Portable).

Create Xamarin Project

This will create four projects: a portable library that is referenced in all other projects, one project for iOS, one project for android and one project for windows phone.

If you hit F5 an Android emulator should come up and display the sample code (an app with a button that counts the clicks on it).

Android emulator

3. Add UITests

To use the Xamarin Test Cloud you have to add UI tests to your project. Add a new project of the type “UI Test App”.


In the class “AppInitializer” add the relative path to the apk package.


Now add a new test that clicks the button and verifies that the text is updated correctly. Note that I’ve added a screenshot to the test after clicking the button.

public void ClickButton()
    app.Tap(x => x.Button("myButton"));

    app.Screenshot("Tab Button");

    var result = app.Query(x => x.Button("myButton").Text("1 clicks!"));

    Assert.IsTrue(result.Any(), "The expected text was not found.");

4. Create keystore file

To use the HockeyApp for distribution it is required to sign the package in the build. To sign the package we have to add a keystore to the project. Open a command prompt and navigate to your solution folder. Expand the %PATH% to include your version of the JRE. Start keytool with the following arguments:

$ set path=%path%;C:\Program Files (x86)\Java\jre1.8.0_45\bin
$ keytool -genkey -v -keystore my-release-key.keystore -sigalg SHA1withDSA -keyalg DSA -keysize 1024

Enter the passwords and data that is needed for the certificate. After the keystore was execute the following command:

$ keytool -keystore .\my-release-key.keystore -list -v

Note the alias for later user.

Add the keystore to your repository and commit and push all your changes to your Visual Studio Team Services project.

5. Create your team build

If you don’t have a Xamarin account yet, then sign up for it now. You will need the email and password during the build creation.

Open your project in VSTS and create a new build from the Xamarin.Android template.

Create Xamarin.Android build

Go to the variables tab and add some variables:

  • XAccount: the Xamarin Account email
  • XPass: the Xamarin Account password
  • KeyPass: password key for key (see step 4)
  • optional: key store password if different (see step 4)
  • KeyAlias: alias for key (see step 4)

Add variables to the build

For the “Activate Xamarin license” and “Deactivate Xamarin license” tasks set the email and password to $(XAccount) and $(XPassword).

Add a “Copy file task” before the signing task and copy the keystore to the binaries directory.

Copy file task

Enable Jarsigning and Zipalign in the “Signing and aligning APK file(s)” task. Note that the path to the keystore contains the project name – depending on the copy file task and your project structure! I’ve used the same password for the keystore and the key. If you have different passwords you have to use the corresponding variable here.

Enable Jarsigning and Zipalign

Log in to and get the API key for your team.

Get Xamarin Test Cloud API Key

Create a new test run.

New test run

Select the devices that you want to run the tests on and follow the wizard to the last page. You only need the devices string. Copy the string and cancel the wizard.

Get devices string

Go back to your build and enter the data gathered (API key, device string) in the Xamarin Test Cloud task.

Enter values in xamarin test cloud task

The see the test output in the build results you have to add a publish test results task to the build.


Publish the results directory ($(build.binariesdirectory)\$(build.configuration)) to the drop artifact.

Publish artifacts

Run the build and verify that everything works as expected.

6. Link HockeyApp to you VSTS project

Login to and create a API token with full access. You find this under “Account Settings” / “API Tokens”.

Get API Token in HockeyApp

Go to the settings of your VSTS team project and create a new service endpoint with the API key you just created.

Set HockeyApp Service in VSTS

7. Create a release definition

Create an empty release definition. Enable continuous deployment and keep the rest of the default values in wizard.

Create a release definition

Link your build to the release definition.

Link build output to the release

Add an environment and add a HockeyApp task. Select the service endpoint from step 6 and browse to your .apk file from the build output. Select if you want to notify users or make the release mandatory.

Add environment and HockeyApp task

Deploy the latest build with the release definition to create the app in HockeyApp.

8. Install Hockey App on your Android phone

Allow installation of apps on your Android phone. You can enable this in Settings –> Security –> Allow unknown sources. Now install the app. The app is not in the store – you have to install it from HockeyApp web site.

Launch the app and sign in with your credentials. You should now see your app. Install and run it on your phone.

9. Enable Crash and Update Reporting in your Project

To enable crash reporting and update notification we have to add some code to the project. Before we do this we have to log in to the HockeyApp web site and get the app id that was automatically generated during your release.

Get HockeyApp App Id

Now open your solution and add the nuget HockeySDK.Xamarin to your Android project. Register the app with the CrashManager and UpdateManager.

[Activity (Label = "DemoApp1.Droid", MainLauncher = true, Icon = "@drawable/Icon")]
public class MainActivity : Activity
	int count = 1;

	protected override void OnCreate (Bundle bundle)
		base.OnCreate (bundle);

		// ...

        CrashManager.Register(this, "<app id>");
        UpdateManager.Register(this, "<app id>");

    protected override void OnPause()


    protected override void OnDestroy()


10. Enable VSTS Integration in HockeyApp

To receive feedback and crash reports in VSTS we have to enable the integration in HockeyApp. You enable this under Manage App / Visual Studio Team Services.

Enbale VSTS integration in HockeyApp

11. Enable Feedback

To allow the user to send feedback we have to add a new button. Add a feedback button in Main.axml. Add the caption to Strings.xml.

Add feedback button

Register the app with the FeedbackManager and add a delegate to the click event of the button that calls the ShowFeedbackActivity method of the FeedbackManager.

Button feedbackButton = FindViewById<Button>(Resource.Id.myFeedbackButton);

feedbackButton.Click += delegate

FeedbackManager.Register(this, "<app id>");

12. End to end test

Everything should be ready at this point and you can start an end 2 end test. Add a “bug” to MainActivity.cs that crashes the app if you click the button 5 times.

button.Click += delegate

    if (count == 5)
        throw new InvalidOperationException("This is a bug that crashes the application.");

    button.Text = string.Format("{0} clicks!", count++);

Also update the version number to see if the update notification works.

Update app version

If your build is set to continuous integration it is automatically triggered. The build runs the UI tests in the cloud and displays the test result in your build overview.

Build with xamarin test results

Go to and open your app. You can see more details here including the screenshots of your app that you added to the tests.

Xamarin Test Cloud Result Overview

Xamarin Test Cloud Result Screenshots

If your release was set to continuous deployment your app was automatically deployed to your first environment using the hockey app. Launch the app on your phone. It should automatically detect the update. Install the update.

Update app

Now crash the app by click the first button 5 times. If you start the app again you can send the crash report to hockey app.

Send crash report

The crash report is automatically added as a bug to your team project.

Bug for crash in VSTS

Now push the “Send Feedback button” and fill out all the required fields in the form.


The feedback will be added to VSTS as a task.

Feedback task in VSTS


I was really impressed how easy it was to get the complete mobile DevOps lifecycle implemented. I hope this gives you a good start up if you want to start to play around with mobile DevOps and continuous deployment of cross platform apps. If you have problems with some steps just leave me a comment and I will try to help.

Get a list of all Releases in TFS or Visual Studio Team Services

I have a customer that is transitioning from the old version of Release Management to the new one. The question today was, how he can get an overview of all releases in all projects that are going on.

I don’t think this is possible yet with the UI – so I cam up with a small script that uses the REST API to get the releases. The script gets all projects for a project collection and retrieves all the releases for each project. It then sorts the output and displays it as a table.

You could also dump it to a json and display it in a html site if you want to display the releases in a dashboard.

Param (
    [Parameter(Mandatory=$true, Position=0)]

$projectsResult = Invoke-RestMethod "$ProjectCollection/_apis/projects?api-version=1.0" -Method Get -UseDefaultCredentials

$releases = @()

$projectsResult.value | % {

    $project = $

    $url = "$ProjectCollection/$project/_apis/release/releases?api-version=2.2-preview.1"

    $result = Invoke-RestMethod $url -Method Get -UseDefaultCredentials

    if ($result.count -gt 0){
        $result.value | % {
            $releases += [pscustomobject]@{ 
                Project = $project 
                Name = $_.Name 
                Status = $_.status
                CreatedOn = [datetime]$_.createdOn
                ModifiedOn = [datetime]$_.modifiedOn 

$releases | Sort-Object -Property ModifiedOn -Descending | Format-Table -AutoSize

If you want to use the same technique in VSTS you have to create a personal access token first. The good thing with personal access tokens is, that you can restrict access to certain features (like Release (read)) and revoke access later.

To create the token click under you Name on My Security and create the token with the correct permissions (see image).

Create personal access token in VSTS VSO

Copy the personal access token and use it as a parameter to the script.

Copy personal access token

Here is the script to get the releases in VSTS.

Param (
    [Parameter(Mandatory=$true, Position=0)]

    [Parameter(Mandatory=$true, Position=1)]

$passkey = ":$($Accesstoken)"
$encodedKey = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($passkey))
$token = "Basic $encodedKey"

$projectsResult = Invoke-RestMethod "https://$" -Method Get  -Headers @{ Authorization = $token }

$releases = @()

$projectsResult.value | % {

    $project = $

    $url = "https://$$project/_apis/release/releases?api-version=3.0-preview.2"

    $result = Invoke-RestMethod $url -Method Get -Headers @{ Authorization = $token }

    if ($result.count -gt 0){

        $result.value | % {
            $releases += [pscustomobject]@{ 
                Project = $project 
                Name = $_.Name 
                Status = $_.status
                CreatedOn = [datetime]$_.createdOn
                ModifiedOn = [datetime]$_.modifiedOn 

$releases | Sort-Object -Property ModifiedOn -Descending | Format-Table -AutoSize

Note that the URL points to and that the api version is also different.

If one of the scripts does not work then check the current state of the api version in the REST documentation.