{"id":4993,"date":"2012-05-31T17:57:00","date_gmt":"2012-05-31T17:57:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/visualstudioalm\/2012\/05\/31\/how-to-configure-features-for-dozens-of-team-projects\/"},"modified":"2019-02-14T17:59:22","modified_gmt":"2019-02-15T01:59:22","slug":"how-to-configure-features-for-dozens-of-team-projects","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/devops\/how-to-configure-features-for-dozens-of-team-projects\/","title":{"rendered":"How to Configure Features for dozens of team projects"},"content":{"rendered":"<p>In a<span> <a href=\"http:\/\/blogs.msdn.com\/b\/visualstudioalm\/archive\/2012\/05\/31\/deep-dive-on-configure-features.aspx\">previous post<\/a><\/span>, I have told you how the Configure Features wizard works to upgrade the team projects on your TFS server. It works great. However if you are an administrator of dozens of team projects, you don&#8217;t want to walk through the wizard for each team project. Luckily we have a solution for you, which is outlined in this post.<\/p>\n<p>You can either <a href=\"https:\/\/devblogs.microsoft.com\/00\/00\/00\/45\/92\/3312.Code.zip\">download the source code<\/a> or execute the following steps.<\/p>\n<h2>Create and run the application<\/h2>\n<ol>\n<li>Open Visual Studio 2012<\/li>\n<li>Create a new &#8220;C# Console Application&#8221; Project<\/li>\n<li>Open the folder <em>C:\\Program Files\\Microsoft Team Foundation Server 11.0\\Application Tier\\Web Services\\bin<\/em> on the <strong>Application Tier<\/strong>.<\/li>\n<li>Copy the following files over to your local machine and add a reference to these local copies of the assembly\n<ul>\n<li>Microsoft.TeamFoundation.Framework.Server.dll<\/li>\n<li>Microsoft.TeamFoundation.Server.Core.dll (Required if 2012 Update 2 was installed)<\/li>\n<li>Microsoft.TeamFoundation.Server.WebAccess.WorkItemTracking.Common.dll<\/li>\n<\/ul>\n<\/li>\n<li>Add references to the following assemblies. These are located in the folder <em>C:\\Program Files (x86)\\Microsoft Visual Studio 11.0\\Common7\\IDE\\ReferenceAssemblies\\v2.0<\/em>\n<ul>\n<li>Microsoft.TeamFoundation.Client.dll<\/li>\n<li>Microsoft.TeamFoundation.Common.dll<\/li>\n<li>Microsoft.TeamFoundation.WorkItemTracking.Client.dll<\/li>\n<\/ul>\n<\/li>\n<li>Open program.cs and overwrite the contents of the file with the following code and change the highlighted url.<\/li>\n<li>Copy your application to C:\\Program Files\\Microsoft Team Foundation Server 11.0\\Application Tier\\Web Services\\bin on the <strong>Application Tier<\/strong> and run it from there.\n<div id=\"codeSnippetWrapper\" style=\"margin: 20px 0px 10px;padding: 4px;border: 1px solid silver;width: 97.5%;text-align: left;line-height: 12pt;overflow: auto;font-family: 'Courier New', courier, monospace;font-size: 8pt;cursor: text;direction: ltr;max-height: 20000px;background-color: #f4f4f4\">\n<div id=\"codeSnippet\" style=\"padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\"><span style=\"color: #0000ff\">using<\/span> System;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\"><span style=\"color: #0000ff\">using<\/span> System.Collections.Generic;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\"><span style=\"color: #0000ff\">using<\/span> System.Linq;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\"><span style=\"color: #0000ff\">using<\/span> System.Net;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\"><span style=\"color: #0000ff\">using<\/span> Microsoft.TeamFoundation.Client;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\"><span style=\"color: #0000ff\">using<\/span> Microsoft.TeamFoundation.Framework.Server;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\"><span style=\"color: #0000ff\">using<\/span> Microsoft.TeamFoundation.Integration.Server;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\"><span style=\"color: #0000ff\">using<\/span> Microsoft.TeamFoundation.Server;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\"><span style=\"color: #0000ff\">using<\/span> Microsoft.TeamFoundation.Server.WebAccess.WorkItemTracking.Common;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">&nbsp;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">&nbsp;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\"><span style=\"color: #0000ff\">namespace<\/span> FeatureEnablement<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">{<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">    <span style=\"color: #0000ff\">class<\/span> Program<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">    {<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">        <span style=\"color: #0000ff\">static<\/span> <span style=\"color: #0000ff\">void<\/span> Main(<span style=\"color: #0000ff\">string<\/span>[] args)<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">        {<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">            <span style=\"color: #0000ff\">string<\/span> urlToCollection = <span style=\"color: #006080\">@\"http:\/\/remi8:8080\/tfs\/defaultcollection\"<\/span>;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">            Guid instanceId;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">&nbsp;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">            <span style=\"color: #008000\">\/\/ Get the TF Request Context<\/span><\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">            <span style=\"color: #0000ff\">using<\/span> (DeploymentServiceHost deploymentServiceHost = GetDeploymentServiceHost(urlToCollection, <span style=\"color: #0000ff\">out<\/span> instanceId))<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">            {<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">                <span style=\"color: #0000ff\">using<\/span> (TeamFoundationRequestContext context = GetContext(deploymentServiceHost, instanceId))<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">                {<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">                    <span style=\"color: #008000\">\/\/ For each team project in the collection<\/span><\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">                    CommonStructureService css = context.GetService&lt;CommonStructureService&gt;();<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">                    <span style=\"color: #0000ff\">foreach<\/span> (var project <span style=\"color: #0000ff\">in<\/span> css.GetWellFormedProjects(context))<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">                    {<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">                        <span style=\"color: #008000\">\/\/ Run the 'Configuration Features Wizard'<\/span><\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">                        ProvisionProjectFeatures(context, project);<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">                    }<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">                }<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">            }<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">        }<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">&nbsp;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">        <span style=\"color: #0000ff\">private<\/span> <span style=\"color: #0000ff\">static<\/span> DeploymentServiceHost GetDeploymentServiceHost(<span style=\"color: #0000ff\">string<\/span> urlToCollection, <span style=\"color: #0000ff\">out<\/span> Guid instanceId)<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">        {<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">            <span style=\"color: #0000ff\">using<\/span> (var teamProjectCollection = <span style=\"color: #0000ff\">new<\/span> TfsTeamProjectCollection(<span style=\"color: #0000ff\">new<\/span> Uri(urlToCollection), CredentialCache.DefaultCredentials))<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">            {<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">                <span style=\"color: #0000ff\">const<\/span> <span style=\"color: #0000ff\">string<\/span> connectionStringPath = <span style=\"color: #006080\">\"\/Configuration\/Database\/Framework\/ConnectionString\"<\/span>;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">                var registry = teamProjectCollection.ConfigurationServer.GetService&lt;Microsoft.TeamFoundation.Framework.Client.ITeamFoundationRegistry&gt;();<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">                <span style=\"color: #0000ff\">string<\/span> connectionString = registry.GetValue(connectionStringPath);<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">                instanceId = teamProjectCollection.InstanceId;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">&nbsp;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">                <span style=\"color: #008000\">\/\/ Get the system context<\/span><\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">                TeamFoundationServiceHostProperties deploymentHostProperties = <span style=\"color: #0000ff\">new<\/span> TeamFoundationServiceHostProperties();<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">                deploymentHostProperties.ConnectionString = connectionString;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">                deploymentHostProperties.HostType = TeamFoundationHostType.Application | TeamFoundationHostType.Deployment;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">                <span style=\"color: #0000ff\">return<\/span> <span style=\"color: #0000ff\">new<\/span> DeploymentServiceHost(deploymentHostProperties, <span style=\"color: #0000ff\">false<\/span>);<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">            }<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">        }<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">&nbsp;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">        <span style=\"color: #0000ff\">private<\/span> <span style=\"color: #0000ff\">static<\/span> TeamFoundationRequestContext GetContext(DeploymentServiceHost deploymentServiceHost, Guid instanceId)<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">        {<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">            <span style=\"color: #0000ff\">using<\/span> (TeamFoundationRequestContext deploymentRequestContext = deploymentServiceHost.CreateSystemContext())<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">            {<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">                <span style=\"color: #008000\">\/\/ Get the identity for the tf request context<\/span><\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">                TeamFoundationIdentityService ims = deploymentRequestContext.GetService&lt;TeamFoundationIdentityService&gt;();<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">                TeamFoundationIdentity identity = ims.ReadRequestIdentity(deploymentRequestContext);<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">&nbsp;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">                <span style=\"color: #008000\">\/\/ Get the tf request context<\/span><\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">                TeamFoundationHostManagementService hostManagementService = deploymentRequestContext.GetService&lt;TeamFoundationHostManagementService&gt;();<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">&nbsp;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">                <span style=\"color: #0000ff\">return<\/span> hostManagementService.BeginUserRequest(deploymentRequestContext, instanceId, identity.Descriptor);<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">            }<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">        }<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">&nbsp;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">        <span style=\"color: #0000ff\">private<\/span> <span style=\"color: #0000ff\">static<\/span> <span style=\"color: #0000ff\">void<\/span> ProvisionProjectFeatures(TeamFoundationRequestContext context, CommonStructureProjectInfo project)<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">        {<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">            <span style=\"color: #008000\">\/\/ Get the Feature provisioning service (\"Configure Features\")<\/span><\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">            ProjectFeatureProvisioningService projectFeatureProvisioningService = context.GetService&lt;ProjectFeatureProvisioningService&gt;();<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">&nbsp;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">            <span style=\"color: #0000ff\">if<\/span> (!projectFeatureProvisioningService.GetFeatures(context, project.Uri.ToString()).Where(f =&gt; (f.State == ProjectFeatureState.NotConfigured &amp;&amp; !f.IsHidden)).Any())<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">            {<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">                <span style=\"color: #008000\">\/\/ When the team project is already fully or partially configured, report it<\/span><\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">                Console.WriteLine(<span style=\"color: #006080\">\"{0}: Project is up to date.\"<\/span>, project.Name);<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">            }<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">            <span style=\"color: #0000ff\">else<\/span><\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">            {<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">                <span style=\"color: #008000\">\/\/ find the valid process templates<\/span><\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">                IEnumerable&lt;IProjectFeatureProvisioningDetails&gt; projectFeatureProvisioningDetails = projectFeatureProvisioningService.ValidateProcessTemplates(context, project.Uri);<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">&nbsp;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">                <span style=\"color: #0000ff\">int<\/span> validProcessTemplateCount = projectFeatureProvisioningDetails.Where(d =&gt; d.IsValid).Count();<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">&nbsp;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">                <span style=\"color: #0000ff\">if<\/span> (validProcessTemplateCount == 0)<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">                {<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">                    <span style=\"color: #008000\">\/\/ when there are no valid process templates found<\/span><\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">                    Console.WriteLine(<span style=\"color: #006080\">\"{0}: No valid process template found!\"<\/span>);<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">                }<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">                <span style=\"color: #0000ff\">else<\/span> <span style=\"color: #0000ff\">if<\/span> (validProcessTemplateCount == 1)<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">                {<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">                    <span style=\"color: #008000\">\/\/ at this point, only one process template without configuration errors is found<\/span><\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">                    <span style=\"color: #008000\">\/\/ configure the features for this team project<\/span><\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">                    IProjectFeatureProvisioningDetails projectFeatureProvisioningDetail = projectFeatureProvisioningDetails.ElementAt(0);<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">                    projectFeatureProvisioningService.ProvisionFeatures(context, project.Uri.ToString(), projectFeatureProvisioningDetail.ProcessTemplateId);<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">&nbsp;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">                    Console.WriteLine(<span style=\"color: #006080\">\"{0}: Configured using settings from {1}.\"<\/span>, project.Name, projectFeatureProvisioningDetail.ProcessTemplateName);<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">                }<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">                <span style=\"color: #0000ff\">else<\/span> <span style=\"color: #0000ff\">if<\/span> (validProcessTemplateCount &gt; 1)<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">                {<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">                    <span style=\"color: #008000\">\/\/ when multiple process templates found that closely match, report it<\/span><\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">                    Console.WriteLine(<span style=\"color: #006080\">\"{0}: Multiple valid process templates found!\"<\/span>, project.Name);<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">                }<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">            }<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">        }<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white\">    }<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4\">}<\/pre>\n<p><!--CRLF--><\/div>\n<\/div>\n<\/li>\n<\/ol>\n<p><strong>NOTE: <\/strong>You need to run the code on a machine that has the Application Tier installed. So if you have Visual Studio on the Team Foundation Server you can run the code, else compile the code, copy the application to your Application Tier and run it from there.<\/p>\n<h2>Understand the application<\/h2>\n<p>The first four private methods (<em>GetTfsTeamProjectCollection, GetDeploymentServiceHost, GetDeploymentRequestContext and GetTeamFoundationRequestContext<\/em>) are only to create a requestContext, which you need to run the Configure Features. When we drill deeper into the ConfigureFeatures method. The method is using the class ProjectFeatureProvisioningService which is the service to Configure Features. Feature subscribe to that service, and the features that are subscribed is currently hard coded. Each feature implements an interface, including it is a hidden feature (that means that it is not critical to be configured), their State (NotConfigured, PartiallyConfigured or FullyConfigured), the Validation and the Provisioning.<\/p>\n<p>The first step is to determine whether the team project needs to be configured. So we ask if all features are either configured (partially or fully) or hidden.<\/p>\n<blockquote>\n<p><em>if (projectFeatureProvisioningService.GetFeatures(context, project.Uri.ToString()).All(f =&gt; (f.State != ProjectFeatureState.NotConfigured || f.IsHidden)))<\/em><\/p>\n<\/blockquote>\n<p>Then it is validating all the process templates. During the validation the service is determining whether the settings stored in the process template can be applied to the current team project. Take a look at the <span><a href=\"http:\/\/blogs.msdn.com\/b\/visualstudioalm\/archive\/2012\/05\/31\/deep-dive-on-configure-features.aspx\">deep dive post<\/a><\/span> if you want to know more about the Validation process.<\/p>\n<blockquote>\n<p><em>IEnumerable&lt;IProjectFeatureProvisioningDetails&gt; projectFeatureProvisioningDetails = projectFeatureProvisioningService.ValidateProcessTemplates(context, project.Uri);<\/em><\/p>\n<\/blockquote>\n<p>That method returns the validation details, which contains information like whether the process template is valid and the errors and warnings that it encountered during the validation. It counts the number of valid process templates, and acts upon it.<\/p>\n<blockquote>\n<p><em>int validProcessTemplateCount = projectFeatureProvisioningDetails.Where(d =&gt; d.IsValid).Count();<\/em><\/p>\n<\/blockquote>\n<p>The current implementation logs a text message to the console window when there is no or multiple valid process templates, but you can use the details to find out why process templates are invalid in case a team project.<\/p>\n<blockquote>\n<p><em>if (validProcessTemplateCount == 0) <br \/>{ <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \/\/ when there are no valid process templates found <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(&#8220;{0}: No valid process template found!&#8221;, project.Name); <br \/>} <br \/>&#8230; <br \/>else if (validProcessTemplateCount &gt; 1) <br \/>{ <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \/\/ when multiple process templates found that closely match, report it <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(&#8220;{0}: Multiple valid process templates found!&#8221;, project.Name); <br \/>}<\/em><\/p>\n<\/blockquote>\n<p>If there is only one valid process template, the current implementation provisions that team project to configure the new features for TFS 2012.<\/p>\n<blockquote>\n<p><em>else if (validProcessTemplateCount == 1) <br \/>{ <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \/\/ at this point, only one process template without configuration errors is found <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \/\/ configure the features for this team project <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IProjectFeatureProvisioningDetails projectFeatureProvisioningDetail = projectFeatureProvisioningDetails.ElementAt(0); <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; projectFeatureProvisioningService.ProvisionFeatures(context, project.Uri.ToString(), projectFeatureProvisioningDetail.ProcessTemplateId); <\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(&#8220;{0}: Configured using settings from {1}.&#8221;, project.Name, projectFeatureProvisioningDetail.ProcessTemplateName); <br \/>}<\/em><\/p>\n<\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>In a previous post, I have told you how the Configure Features wizard works to upgrade the team projects on your TFS server. It works great. However if you are an administrator of dozens of team projects, you don&#8217;t want to walk through the wizard for each team project. Luckily we have a solution for [&hellip;]<\/p>\n","protected":false},"author":111,"featured_media":45953,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[227,253,1],"tags":[],"class_list":["post-4993","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-agile","category-azure-devops-server","category-devops"],"acf":[],"blog_post_summary":"<p>In a previous post, I have told you how the Configure Features wizard works to upgrade the team projects on your TFS server. It works great. However if you are an administrator of dozens of team projects, you don&#8217;t want to walk through the wizard for each team project. Luckily we have a solution for [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts\/4993","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/users\/111"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/comments?post=4993"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts\/4993\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/media\/45953"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/media?parent=4993"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/categories?post=4993"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/tags?post=4993"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}