I have a few old Visual Studio Online (VSO) accounts (dating back to TFSPreview.com days). We use them to collaborate with third parties, it was long overdue that I tidied them up; as a problem historically has been that all access to VSO has been using a Microsoft Accounts (LiveID, MSA), these are hard to police, especially if users mix personal and business ones.
The solution is to link your VSO instance to an Azure Active Directory (AAD). This means that only users listed in the AAD can connect to the VSO instance. As this AAD can be federated to an on-prem company AD it means that the VSO users can be either
- Company domain users
- MSA accounts specifically added to AAD
Either way it gives the AAD administrator an easy way to manage access to VSO. A user with a MSA, even if an administrator in VSO cannot add any unknown users to VSO. For details see MSDN. All straight forward you would think, but it I had a few issues.
The problem was I had setup my VSO accounts using a MSA in the form firstname.lastname@example.org, this was also linked to my MSDN subscription. As part of the VSO/AAD linking process I needed to add the MSA email@example.com to our AAD, but I could not. The AAD was setup for federation of accounts in the mycompany.com domain, so you would have thought I would be OK, but back in our on-prem AD (the one it was federated to) I had firstname.lastname@example.org as an email alias for email@example.com. Thus blocked the adding of the user to AAD, hence I could got link VSO to Azure.
The answer was to
- Add another MSA account to the VSO instance, one unknown to our AD even as an alias e.g. firstname.lastname@example.org
- Make this user the owner of the VSO instance.
- Add the email@example.com MSA to the AAD directory
- Make them an Azure Subscription administrator.
- Login to the Azure portal as this MSA, once this was done the VSO could be linked to the AAD directory.
- I could then make an AAD user (firstname.lastname@example.org) a VSO user and then the VSO owner
- The email@example.com MSA could then be deleted from VSO and AAD
- I could then login to VSO as my firstname.lastname@example.org AAD account, as opposed to the old email@example.com MSA account
Simple wasn’t it!
We still had one problem, and that was firstname.lastname@example.org was showing as a basic user in VSO, if you tried to set it to MSDN eligible flipped back to basic.
The problem here was we had not associated the AAD account email@example.com with the MSA account firstname.lastname@example.org in the MSDN portal (see MSDN).
Once this was done it all worked as expected, VSO picking up that my AAD account had a full MSDN subscription.
I have posted before about using Release Management with Lab Management network isolation. They key is that you must issue a NET USE command at the start of the pipeline to allow the VMs in the isolated environment the ability to see the TFS drops location.
I hit a problem today that a build failed even though I had issued the NET USE.
I got the error
Package location '\\store\drops\Sabs.Main.CI\Sabs.Main.CI_188.8.131.5230\\' does not exist or Deployer user does not have access.
Turns out the problem was I had issued the NET USE as \\store.blackmarble.co.uk\drops not \\store\drops it is vital the names match up. Once I changed this my NET USE all was OK
I don’t normal do posts that are just re-posts of TFS announcements, it is much better to get the information first hand from the original post, but this one is significant for us in Europe…
Up to now there has been a barrier to adoption of VSO that the underlying data will be hosted in the USA. Now there are all the usual Azure Microsoft guarantees about data security, but this has not been enough for some clients for legal, regulatory or their own reasons. This has made VSO a non-starter for many European’s where it at first appears a great match.
As of today you can now choose to host your new VSO account in Europe (Amsterdam data center). It won’t remove everyone's worries of cloud hosting, but certainly is a major step in the right direction from a European point of view, addressing many regulatory barriers.
Unfortunately we will have to wait a few sprints to be able to migrate any existing VSO instances, but you can’t have everything in one go!
For the full details have a look at Brian Harry’s and Jamie Cool’s posts
There has for a long time been an issue that when you try to add a new activity to the toolbox when editing a TFS build workflow Visual Studio can crash. I have seen it many times and never got to the bottom of it. It seems to be machine specific, as one machine can work while another supposedly identical will fail, but I could never track down the issue.
Today I was on a machine that was failing, but …
But I found a workaround in a really old forum post. The workaround is to load the IDE from the command line with the /safemode flag
C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\devenv.exe /safemode
Once you do this you can edit the contents of your toolbox without crashes, and also your template if you wish. The best part is that once you exit the IDE and reload it as normal your new toolbox contents are still there.
Not perfect, but a good workaround
Whilst configuring a Release Management 2013.3 system I came across a confusing error. All seemed OK, the server, client and deployment agents were all installed and seemed to be working, but when I tried to select a build to deploy from both the Team Projects and Build drop downs were empty.
A check of the Windows event log on the server showed the errors
The underlying connection was closed: An unexpected error occurred on a send
The handshake failed due to an unexpected packet format
Turns out the issue was an incorrectly set value when the Release Management server was configured. HTTPS had been incorrectly selected, in fact there was no SSL certificate on the box so HTTPS could not work
As this had been done in error we did not use HTTPS at any other point in the installation. We always used the URL http://typhoontfs:1000 . The strange part of the problem was that the only time this mistake caused a problem was for the Team Project drop down, everything else seemed fine, clients and deployment agents all could see the server.
Once the Release Management server was reconfigured with the correct HTTP setting all was OK
If you want to get your TFS build process to product SSRS RDL files you need to call the vsDevEnv custom activity to run Visual Studio (just like for SSIS packages). On our new TFS2013.3 based build agents this step started to fail, turns out the issue was not incorrect versions of DLLs or a some badly applied update, but that the license for Visual Studio on the build agent had expire.
I found it by looking at diagnostic logs in the TFS build web UI.
To be able to build BI project with Visual Studio you do need a licensed copy of Visual Studio on the build agent. You can use a trial license, but it will expire. Also remember if you license VS by logging in with your MSDN Live ID that too needs to be refreshed from time to time (that is what go me), so better to use a product key.
We have for a long time used the TFSVersion custom build activity to stamp all our TFS builds with a unique version number that matches out build number. However, this only edits the AssemblyInfo.cs file. As we are now building more and more Windows 8 Store Apps we also need to edit the XML in the Package.appxmanifest files used to build the packages too. Just like a Wix MSI project it is a good idea the package version matches some aspect of the assemblies it contains. We need to automate the update of this manifest as people too often forget to increment the version, causing confusion all down the line.
Now I could have written a new TFS custom activity to do the job, or edited the existing one, but both options seemed a poor choice. We all know that custom activity writing is awkward and a pain to support going forward. So I decided to use the hooks in the 2013 generation build process template to just call a custom PowerShell script to do the job.
I added a PreBuildScript.PS1 file as a solution item to my solution.
I placed the following code in the file. It uses the TFS environment variables to get the build location and version; using these to find and edit the manifest files. The only gotcha is files on the build box are read only (it is a server workspace) so the manifest file has to be set it to allow it to be written back too.
# get the build number, we assume the format is Myproject.Main.CI_184.108.40.20690
# where the version is set using the TFSVersion custom build activity (see other posts)
$buildnum = $env:TF_BUILD_BUILDNUMBER.Split('_')
# get the manifest file paths
$files = Get-ChildItem -Path $env:TF_BUILD_BUILDDIRECTORY -Filter "Package.appxmanifest" -Recurse
foreach ($filepath in $files)
Write-Host "Updating the Store App Package '$filepath' to version ' $buildnum '"
# update the identity value
# set the file as read write
Set-ItemProperty $filepath.Fullname -name IsReadOnly -value $false
Note that any output sent via Write-Host will only appear in the diagnostic log of TFS. If you use Write-Error (or errors are thrown) these messages will appear in the build summary, but the build will not fail, but will be marked as a partial success.
Once this file was checked in i was able to reference the file in the build template
The build could not be run and got my Windows 8 Store packages with the required version number
Whilst developing our new set of websites we have been using MSDeploy to package up the websites for deployment to test and production Azure accounts. These deployments were being triggered directly using Visual Studio. Now we know this is not best practice, you don’t want developers shipping to production from their development PCs, so I have been getting around to migrating these projects to Release Management.
I wanted to minimise change, as we like MSDeploy, I just wanted to pass the extra parameters to allow a remote deployment as opposed to a local one using the built in WebDeploy component in Release Management
To do this I created a new component based on the WebDeploy tool. I then altered the arguments to
__WebAppName__.deploy.cmd /y /m:__PublishUrl__" -allowUntrusted /u:"__PublishUser__" /p:"__PublishPassword__" /a:Basic
With these three extra publish parameters I can target the deployment to an Azure instance, assuming WebDeploy is installed on the VM running the Release Management deployment client.
The required values for these parameters can be obtained from the .PublishSettings you download from your Azure web site’s management page. If you open this file in a text editor you can read the values need (bits you need are highlighted in yellow)
<publishData><publishProfile profileName="SomeSite - Web Deploy" publishMethod="MSDeploy" publishUrl="somesite.scm.azurewebsites.net:443" msdeploySite="SomeSite" userName="$SomeSite" userPWD="m1234567890abcdefghijklmnopqrstu" destinationAppUrl=http://somesite.azurewebsites.net SQLServerDBConnectionString="" mySQLDBConnectionString="" hostingProviderForumLink="" controlPanelLink="http://windows.azure.com"><databases/></publishProfile><publishProfile profileName="SomeSite- FTP" publishMethod="FTP" publishUrl=ftp://site.ftp.azurewebsites.windows.net/site/wwwroot ftpPassiveMode="True" userName="SomeSite\$SomeSite" userPWD=”m1234567890abcdefghijklmnopqrstu" destinationAppUrl=http://somesite.azurewebsites.net SQLServerDBConnectionString="" mySQLDBConnectionString="" hostingProviderForumLink="" controlPanelLink="http://windows.azure.com"><databases/></publishProfile></publishData>
These values are used as follows
- WebAppName – This is the name of the MSDeploy package, this is exactly the same as a standard WebDeploy component.
- PublishUrl - We need to add the https and the .axd to the start and end of the url e.g: https://somesite.scm.azurewebsites.net:443/MsDeploy.axd
- PublishUser – e.g: $SomeSite
- PublishPassword – This is set as an encrypted parameter so it cannot be viewed in the Release Management client e.g: m1234567890abcdefghijklmnopqrstu
On top of these parameters, we can still pass in extra parameters to transform the web.config using the setparameters.xml file as detailed in this other post this allowing to complete the steps we need to do the configuration for the various environments in our pipeline.
Whilst developing a new Release Management pipeline I did hit a problem that a component that published MSDeploy packages to Azure started to fail. It had been working then suddenly I started seeing ‘communication with the deployer was lost during deployment’ messages as shown below.
No errors were shown in any logs I could find, and no files appeared on the deployment target (you would expect the files/scripts to be deployed to appear on the machine running a RM Deployment client in the C:\users\[account]\local\temp\RM folder structure).
Rebooting of the Release Management server and deployment client had no effect.
The client in this case was a VM we use to do remote deployments e.g to Azure, SQL clusters etc. Place where we cannot install the RM Deployment Client. So it is used for a number of other pipelines, these were all working, so I doubted it was a communications issue.
In the end, out of frustration, I tried re-adding the component to the workflow and re-entering the parameters. Once this was done, and the old component instances delete, it all leapt into life.
I am not sure why I had the problems, I was trying to remember what I did exactly between the working and failing releases. All I can think is that I may have changed the password parameter to encrypted (I had forgotten to do this at first). Now I should have tried this sooner as I have posted on this error message before. All I can assume is that changing this parameter setting corrupted my component.
I should have read my own blog sooner
Using the process in my previous post you can get a TFS build to create the .CSCFG and .CSPKG files needed to publish a Cloud Service. However, you hit a problem if your solution contains more that one Cloud Service project; as opposed to a single cloud service project with multiple roles, which is not a problem.
The method outlined in the previous post drops the two files into a Packages folder under the drops location. The .CSPKG files are fine, as they have unique names. However there is only one ServiceConfiguration.cscfg, whichever one was created last.
Looking in the cloud service projects I could find no way to rename the ServiceConfiguration file. It looks like it is like a app.config or web.config file i.e. it’s name is hard coded.
The only solution I could find was to add a custom target that is set to run after the publish target. This was added to the end of each .CCPROJ files using a text editor just before the closing </project>
<Target Name="CustomPostPublishActions" AfterTargets="Publish">
<Exec Command="IF '$(BuildingInsideVisualStudio)'=='true' exit 0
echo Post-PUBLISH event: Active configuration is: $(ConfigurationName) renaming the .cscfg file to avoid name clashes
echo Renaming the .CSCFG file to match the project name $(ProjectName).cscfg
ren $(OutDir)Packages\ServiceConfiguration.*.cscfg $(ProjectName).cscfg
<PostBuildEvent>echo NOTE: This project has a post publish event</PostBuildEvent>
Using this I now get unique name for the .CSCFG files as well as for .CSPKG files in my drops location. All ready for Release Management to pickup
- I echo out a message in the post build event too just as a reminder that I have added a custom target that cannot be seen in Visual Studio, so is hard to discover
- I use an if test to make sure the commands are only run on the TFS build box, not on a local build. The main reason for this is the path names are different for local builds as opposed to TFS build. If you do want a rename on a local build you need to change the $(OutDir)Packages path to $(OutDir)app.publish. However, it seemed more sensible to leave the default behaviour occur when running locally