<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Marcelo E Silva</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/alming/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/alming/feed.xml</link>
    <description>Application Lifecycle Management, Development and other cool stuff</description>
    <lastBuildDate>Wed, 17 Apr 2019 03:45:55 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Integrating Selenium tests in a release pipeline in VSTS and TFS 2018</title>
      <link>https://docs.microsoft.com/archive/blogs/alming/integrating-selenium-tests-in-a-release-pipeline</link>
      <pubDate>Wed, 07 Mar 2018 14:49:28 GMT</pubDate>
      <dc:creator><![CDATA[Marcelo E Silva]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/alming/?p=355</guid>
      <description><![CDATA[Today, I'd like to show you a proof-of-concept I created for one of my customers where we implement...]]></description>
      <content:encoded><![CDATA[Today, I'd like to show you a proof-of-concept I created for one of my customers where we implement User Interface (UI) test automation into a Continuous Integration/Continuous Delivery (CI/CD) pipeline in Visual Studio Team Services (VSTS).

First, a little background on the problem we're trying to solve: my customer wanted to introduce automated testing into their CI/CD pipeline. The conversation when in the direction of integrating Unit Tests and doing automated Integration Tests. We did implement some unit tests and integrated them into the solution and the release pipeline.

However, there are clear challenges on implementing unit tests on legacy code. Can you justify the time/effort to implement a good set of unit tests on legacy code? I'm not going to go deep into this topic, which is worth a blog post on its own. Suffice to say that, most teams choose to do a gradual implementation of unit tests as bugs are fixed and technical debt is paid.

Some teams find it easier to start implementing UI "smoke tests", in parallel with the effort of gradually implementing unit tests. In this example, we cover the scenario where we have automated deployments, but the developers perform smoke tests to make sure the application was successfully deployed. These tests can be simple, like: going to the home page of a web app, clicking on a link that requires database connectivity, running a report, etc.

I'll be using the famously old TailSpin Toys web app for this. It's a simple web app where you can buy paper planes. The idea is that we want to run a couple of smoke tests:
<ul>
 	<li>Browse one of the products and make sure the data retrieved from the database is correct</li>
 	<li>Add a product to the shopping cart, fill out the order and make sure the total is greater than zero</li>
</ul>
First, what we do is we create a Unit Test project in Visual Studio, adding the following Nuget packages. I'm using MSTest framework, but you can use any other framework of your choice:

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/Capture1.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2018/03/Capture1.jpg" alt="" width="958" height="459" class="alignnone size-full wp-image-375" /></a>

Note that, you only need the PhantomJS packages and Selenium.WebDriver. The other ones are there so I (or you) can execute the tests in a Chrome, IE or Firefox window and see it executing for debugging/test purposes.

Next, jumping into our C# class that hosts the tests, we have the following:

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/Capture2.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2018/03/Capture2.jpg" alt="" width="808" height="391" class="alignnone size-full wp-image-385" /></a>

This method runs once the before all the tests in this C# class run and, in this case, I chose to use it to initialize the test URL to be used and to initialize the PhantomJSDriver.

Next, we go to the TestInitialize method, where it runs before every single test in this class:

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/Capture3.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2018/03/Capture3.jpg" alt="" width="881" height="220" class="alignnone size-full wp-image-395" /></a>

Here, before every test, we make sure the ImplicitWait is reset to 30 seconds and that we navigate back to the home page. If you want to run the test in a virtual maximized window, you can do that by using the Window.Maximize() method seen above. This might come in handy if you have a web page that doesn't fit well in a small window, or better yet, you want to test your responsive design and then can set the window size to an iPad Mini for example:

<code>_driver.Manage().Window.Size = new System.Drawing.Size(1024, 768);</code>

<code></code>
The first test method is the Browse scenario where we test for the data in the description field:

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/Capture4.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2018/03/Capture4-1024x505.jpg" alt="" width="1024" height="505" class="alignnone size-large wp-image-405" /></a>

Let's dissect this test method:
<ul>
 	<li>TestCategory attribute: I set this as to differentiate the smoke tests from other types of tests in the same project. I can then tell VSTS to only run tests with this category during a release, not during a build. You can also use different projects.</li>
 	<li>The test consists, basically of finding the element (anchor in this case) where id=model and click on it. Then we click on the first product in the list, extract its description and check whether it's a non-null string with length &gt; 0.</li>
 	<li>I have used XPath to find the elements, but you can also find elements by ID, tags, etc.</li>
 	<li>I have added steps to take screenshots before each step. One takes the screenshot and saves it as a JPG file while the other adds it to the results file. The latter is an important step as it will allow you to see the screenshots in the Test hub in VSTS</li>
</ul>
Here's the other method where we add a product to cart, fill out the order form and check the total price is &gt; 0:

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/Capture5.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2018/03/Capture5-1024x504.jpg" alt="" width="1024" height="504" class="alignnone size-large wp-image-415" /></a>
<ul>
 	<li>This one has a good set of examples on how to find elements using different methods</li>
 	<li>Notice that it now becomes important for you to make the web app "testable" by making it easy for someone writing UI tests to find and identify the elements in the DOM.</li>
</ul>
If you have Chrome, you can use one option for finding out what the XPath is for a giving element, by inspecting it and copying the XPath to the clipboard:

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/Capture6.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2018/03/Capture6.jpg" alt="" width="659" height="701" class="alignnone size-full wp-image-425" /></a>

Now, when this is checked in to my project in VSTS, it kicks off a build. In that build, I make sure that no smoke tests are executed:

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/Capture7.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2018/03/Capture7-1024x718.jpg" alt="" width="1024" height="718" class="alignnone size-large wp-image-435" /></a>

Now, on my release definition that's used to deploy the application, I have two environments: QA and Prod:

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/Capture8.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2018/03/Capture8.jpg" alt="" width="907" height="321" class="alignnone size-full wp-image-445" /></a>

In this example, I chose to run the smoke tests in the QA environment after deployment, and in Prod after deployment targeting the staging slot. Once the tests pass in staging, there's a manual approval step where we proceed to swap slots and make the deployment official.

Note that, when the smoke tests are executed, we make sure we only run them, not any other Unit tests by selecting the proper category:

QA process:

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/Capture9.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2018/03/Capture9.jpg" alt="" width="981" height="609" class="alignnone size-full wp-image-455" /></a>

Production process:

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/Capture10.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2018/03/Capture10.jpg" alt="" width="641" height="704" class="alignnone size-full wp-image-456" /></a>

Once we trigger the release for QA, it runs successfully, and we can see the test results:

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/Capture11.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2018/03/Capture11.jpg" alt="" width="822" height="214" class="alignnone size-full wp-image-465" /></a>

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/Capture12.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2018/03/Capture12-1024x489.jpg" alt="" width="1024" height="489" class="alignnone size-large wp-image-475" /></a>

&nbsp;

And we can see screenshots of the smoke tests as well. The sequence below is the add to cart test:

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/Add_ProductToCart_OrderTotalGreaterThan0_1.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2018/03/Add_ProductToCart_OrderTotalGreaterThan0_1.jpg" alt="" width="950" height="700" class="alignnone size-full wp-image-485" /></a>

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/Add_ProductToCart_OrderTotalGreaterThan0_2.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2018/03/Add_ProductToCart_OrderTotalGreaterThan0_2.jpg" alt="" width="950" height="933" class="alignnone size-full wp-image-495" /></a>

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/Add_ProductToCart_OrderTotalGreaterThan0_3.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2018/03/Add_ProductToCart_OrderTotalGreaterThan0_3-675x1024.jpg" alt="" width="675" height="1024" class="alignnone size-large wp-image-505" /></a>

There you have it.

Now, as a follow-up to this, I'm planning on showing how to do a similar case for a Win32 app test on Windows 10 using an Azure VM as test bed. This will include installing and using Appium.]]></content:encoded>
    </item>
    <item>
      <title>Using web.config transforms and Release Manager - TFS 2017/Team Services edition</title>
      <link>https://docs.microsoft.com/archive/blogs/alming/using-web-config-transforms-and-release-manager-tfs-2017team-services-edition</link>
      <pubDate>Thu, 09 Feb 2017 21:37:08 GMT</pubDate>
      <dc:creator><![CDATA[Marcelo E Silva]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/alming/?p=85</guid>
      <description><![CDATA[This is a follow-up to an old post on Using Web.Config transforms and Release Manager that I did...]]></description>
      <content:encoded><![CDATA[This is a follow-up to an old post on <a href="https://blogs.msdn.microsoft.com/alming/2015/01/19/using-web-config-transformations-and-release-manager/">Using Web.Config transforms and Release Manager</a> that I did some time ago. That post was done on TFS 2015 and using the now "old" architecture of Release Management.

This post will follow the same idea of deploying an application to Azure (App Service), but this time using Visual Studio Team Services and its Build/Release system. This can be easily translated to TFS 2017 RTM, the latest TFS version at the time of this writing.

I'll be using an old MVC app (TailspinToys) as an example and will be focusing on the web.config changes only. I'll check if I can post the source code for this later, but this is an old app that I used to expedite the work on writing this, so you might want to use a newer framework.

First, from a developers perspective, I want to make sure my app runs on my laptop and uses my LocalDB as database server. This way, I can have a full test bed for my work before I deploy it to Azure. My web.config, by default, points to my LocalDB:

<a href="https://msdnshared.blob.core.windows.net/media/2017/02/webconfig.jpg"><img width="1024" height="531" class="size-large wp-image-95" alt="Web.Config pointing to LocalDB" src="https://msdnshared.blob.core.windows.net/media/2017/02/webconfig-1024x531.jpg" /></a>

The debug transform doesn't need any changes:

<a href="https://msdnshared.blob.core.windows.net/media/2017/02/web.debug_.config.jpg"><img width="1024" height="513" class="size-large wp-image-105" alt="Web.Debug.Config with no transforms" src="https://msdnshared.blob.core.windows.net/media/2017/02/web.debug_.config-1024x513.jpg" /></a>

Running the application locally, you should get:

[caption id="attachment_115" align="alignnone" width="1024"]<a href="https://msdnshared.blob.core.windows.net/media/2017/02/tailspintoys_local.jpg"><img width="1024" height="517" class="size-large wp-image-115" alt="TailspinToys running locally on developer's machine" src="https://msdnshared.blob.core.windows.net/media/2017/02/tailspintoys_local-1024x517.jpg" /></a> TailspinToys running locally on developer's machine[/caption]

If you don't have the infrastructure setup on Azure yet, this is a good time to do it. I won't go into too much detail on how to create a <a href="https://docs.microsoft.com/en-us/azure/app-service-web/app-service-web-overview">web app </a>and <a href="https://docs.microsoft.com/en-us/azure/sql-database/sql-database-technical-overview">Azure SQL database</a>, but there is good documentation on the web on how to do it.

In this example, I'll create two web app/sql pairs: one for QA, another for Prod. In prod, we'll have two slots, just for fun.

[caption id="attachment_125" align="alignnone" width="1024"]<a href="https://msdnshared.blob.core.windows.net/media/2017/02/azure_infrastructure.jpg"><img width="1024" height="576" class="size-large wp-image-125" alt="Azure environments" src="https://msdnshared.blob.core.windows.net/media/2017/02/azure_infrastructure-1024x576.jpg" /></a> Azure environments[/caption]

We can now create a web.config transform to "tokenize" the connection string. This token will then be replaced at deployment time.

In the example below, we created in Visual Studio a configuration called "Azure" and created the corresponding transform (by right-clicking on the web.config and selecting "add web config transform"):

[caption id="attachment_155" align="alignnone" width="1024"]<a href="https://msdnshared.blob.core.windows.net/media/2017/02/web-azure-config-tokenized.jpg"><img width="1024" height="579" class="size-large wp-image-155" alt="Web config for Azure with tokenized connection string" src="https://msdnshared.blob.core.windows.net/media/2017/02/web-azure-config-tokenized-1024x579.jpg" /></a> Web config for Azure with tokenized connection string[/caption]

Notice that I used "__" as token delimiter. It's not a requirement anymore, but I kept the same syntax used in the previous Release Management versions.

Code is committed and pushed to VSTS. Now we have to setup a build for the QA environment:

[caption id="attachment_165" align="alignnone" width="1024"]<a href="https://msdnshared.blob.core.windows.net/media/2017/02/build-variables.jpg"><img width="1024" height="478" class="size-large wp-image-165" alt="Build variables specifying &quot;Azure&quot; configuration to build" src="https://msdnshared.blob.core.windows.net/media/2017/02/build-variables-1024x478.jpg" /></a> Build variables specifying "Azure" configuration to build[/caption]

&nbsp;

[caption id="attachment_185" align="alignnone" width="1024"]<a href="https://msdnshared.blob.core.windows.net/media/2017/02/build-repository-source.jpg"><img width="1024" height="603" class="size-large wp-image-185" alt="Repository setting to pull code from a specific branch" src="https://msdnshared.blob.core.windows.net/media/2017/02/build-repository-source-1024x603.jpg" /></a> Repository setting to pull code from a specific branch[/caption]

&nbsp;

Notice that I also used some MSBuild arguments to make sure we get the properly packaged output. In this case I used <code>/p:DeployOnBuild=True</code>

In the copy artifacts steps, I specify all the files I need for deployment:
<code>**\Package\*.zip
**\Package\*.cmd
**\Package\*.xml
**\output\*.dacpac</code>

[caption id="attachment_325" align="alignnone" width="1024"]<a href="https://msdnshared.blob.core.windows.net/media/2017/02/build-steps-publish-artifacts.jpg"><img width="1024" height="472" class="size-large wp-image-325" alt="Artifacts to be published" src="https://msdnshared.blob.core.windows.net/media/2017/02/build-steps-publish-artifacts-1024x472.jpg" /></a> Artifacts to be published[/caption]

Once the build is successfully executed, we can see the artifacts published and ready to be used:

[caption id="attachment_315" align="alignnone" width="1024"]<a href="https://msdnshared.blob.core.windows.net/media/2017/02/build-artifacts.jpg"><img width="1024" height="748" class="size-large wp-image-315" alt="Build artifacts created after successful build" src="https://msdnshared.blob.core.windows.net/media/2017/02/build-artifacts-1024x748.jpg" /></a> Build artifacts created after successful build[/caption]

Let's download the folder "Package" with all the web deploy files and examine the SetParameters file:

[caption id="attachment_335" align="alignnone" width="1024"]<a href="https://msdnshared.blob.core.windows.net/media/2017/02/parameter-file.jpg"><img width="1024" height="188" class="size-large wp-image-335" alt="Parameters.xml file" src="https://msdnshared.blob.core.windows.net/media/2017/02/parameter-file-1024x188.jpg" /></a> Parameters.xml file[/caption]

Notice that our tokenized connection string is created for us here. If you'd like to add more parameters, even if not in web.config take a look at <a href="https://msdn.microsoft.com/en-us/library/ff398068(v=vs.110).aspx">this article</a>.

Next step is for us to create a release definition that deploys the web app and database to the QA and Production environments we created earlier. The definition will replace the tokenized config set in the parameters with the correct connection string to the corresponding database.

The steps to deploy to QA should be:

<a href="https://msdnshared.blob.core.windows.net/media/2017/02/release-qa-step1.jpg"><img width="1024" height="584" class="alignnone size-large wp-image-225" alt="release-qa-step1" src="https://msdnshared.blob.core.windows.net/media/2017/02/release-qa-step1-1024x584.jpg" /></a>

<a href="https://msdnshared.blob.core.windows.net/media/2017/02/Release-qa-step2.jpg"><img width="1024" height="623" class="alignnone size-large wp-image-235" alt="release-qa-step2" src="https://msdnshared.blob.core.windows.net/media/2017/02/Release-qa-step2-1024x623.jpg" /></a>

&nbsp;

<a href="https://msdnshared.blob.core.windows.net/media/2017/02/release-qa-step3.jpg"><img width="1024" height="620" class="alignnone size-large wp-image-236" alt="release-qa-step3" src="https://msdnshared.blob.core.windows.net/media/2017/02/release-qa-step3-1024x620.jpg" /></a>

A couple of points here:
<ul>
 	<li>I used one of the replace token tasks available on the VSTS marketplace. You can use any other, just make sure you know how to configure them to identify the tokens</li>
 	<li>Notice that I specify the token delimiters as "__". In this task you can use anything. I kept the "old" setup to make it simple.</li>
 	<li>I specify the parameters file directly (full path) but you don't have to. Same for the package zip</li>
</ul>
The variables are set at QA environment level. Notice the variable with the same name as the token, without the "__":

<a href="https://msdnshared.blob.core.windows.net/media/2017/02/qa-environment-variables.jpg"><img width="1024" height="702" class="alignnone size-large wp-image-215" alt="qa-environment-variables" src="https://msdnshared.blob.core.windows.net/media/2017/02/qa-environment-variables-1024x702.jpg" /></a>

The production environment will be very similar, but this time we want to accomplish a couple more things:
<ul>
 	<li>Deploy only if QA is successful</li>
 	<li>Deploy to staging slot first then wait for manual confirmation</li>
 	<li>Swap staging and prod slots for final deployment</li>
</ul>
The production deployment steps will then look something like this:

<a href="https://msdnshared.blob.core.windows.net/media/2017/02/release-prod-manual-interv.jpg"><img width="1024" height="541" class="alignnone size-large wp-image-205" alt="release-prod-manual-interv" src="https://msdnshared.blob.core.windows.net/media/2017/02/release-prod-manual-interv-1024x541.jpg" /></a> <a href="https://msdnshared.blob.core.windows.net/media/2017/02/release-prod-swap-slot.jpg"><img width="1024" height="568" class="alignnone size-large wp-image-195" alt="release-prod-swap-slot" src="https://msdnshared.blob.core.windows.net/media/2017/02/release-prod-swap-slot-1024x568.jpg" /></a>

Notice:
<ul>
 	<li>Variables are the same as in QA, but with production values (server names, etc)</li>
 	<li>Manual intervention step is created. Here you should consider whether you really need manual intervention or even better: automate smoke tests to run against the staging environment and proceed with slot swap only if those tests pass</li>
 	<li>There's no swap for the prod DB, which is deployed regardless. It may be better to consider creating a staging DB to be used or use a refactoring pattern for DB changes that allows for deployments that don't break the existing application running in production</li>
 	<li>The swap slot step has an inline PowerShell script. You can choose to check that in as code and have a task call that script instead.</li>
</ul>
Running the release we get the app deployed and running in the QA environment:

<a href="https://msdnshared.blob.core.windows.net/media/2017/02/app-running-in-qa.jpg"><img width="1024" height="538" class="alignnone size-large wp-image-345" alt="app-running-in-qa" src="https://msdnshared.blob.core.windows.net/media/2017/02/app-running-in-qa-1024x538.jpg" /></a>

If we go to the Kudu console for the web app in QA, we see that our web.config transformation happened without issues:

<a href="https://msdnshared.blob.core.windows.net/media/2017/02/web-config-in-qa-env.jpg"><img width="1024" height="799" class="alignnone size-large wp-image-245" alt="web-config-in-qa-env" src="https://msdnshared.blob.core.windows.net/media/2017/02/web-config-in-qa-env-1024x799.jpg" /></a>

Now, in production is the same pattern. The only difference is that the app is deployed first to the staging slot.

Running in staging slot:

<a href="https://msdnshared.blob.core.windows.net/media/2017/02/app-running-in-prod-env-staging-slot.jpg"><img width="1024" height="562" class="alignnone size-large wp-image-295" alt="app-running-in-prod-env-staging-slot" src="https://msdnshared.blob.core.windows.net/media/2017/02/app-running-in-prod-env-staging-slot-1024x562.jpg" /></a>

But not yet in production slot:

<a href="https://msdnshared.blob.core.windows.net/media/2017/02/app-not-yet-running-on-prod-slot.jpg"><img width="1024" height="420" class="alignnone size-large wp-image-285" alt="app-not-yet-running-on-prod-slot" src="https://msdnshared.blob.core.windows.net/media/2017/02/app-not-yet-running-on-prod-slot-1024x420.jpg" /></a>

Once the deployment happens to staging, approval is needed for the manual intervention:

<a href="https://msdnshared.blob.core.windows.net/media/2017/02/manual-intervention-prompt.jpg"><img width="300" height="258" class="alignnone size-medium wp-image-275" alt="manual-intervention-prompt" src="https://msdnshared.blob.core.windows.net/media/2017/02/manual-intervention-prompt-300x258.jpg" /></a>

Then the slot is switched and the app is now running in production:

<a href="https://msdnshared.blob.core.windows.net/media/2017/02/app-running-in-prod-slot.jpg"><img width="1024" height="569" class="alignnone size-large wp-image-265" alt="app-running-in-prod-slot" src="https://msdnshared.blob.core.windows.net/media/2017/02/app-running-in-prod-slot-1024x569.jpg" /></a>

We can also verify that the web.config correctly points to the production database in Kudu:

<a href="https://msdnshared.blob.core.windows.net/media/2017/02/web-config-in-production-env.jpg"><img width="1024" height="394" class="alignnone size-large wp-image-255" alt="web-config-in-production-env" src="https://msdnshared.blob.core.windows.net/media/2017/02/web-config-in-production-env-1024x394.jpg" /></a>

&nbsp;

There you have it. Now on to another post soon.]]></content:encoded>
    </item>
    <item>
      <title>Using web.config transformations and Release Manager</title>
      <link>https://docs.microsoft.com/archive/blogs/alming/using-web-config-transformations-and-release-manager</link>
      <pubDate>Mon, 19 Jan 2015 11:16:00 GMT</pubDate>
      <dc:creator><![CDATA[Marcelo E Silva]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/alming/2015/01/19/using-web-config-transformations-and-release-manager/</guid>
      <description><![CDATA[UPDATE: Look for a newer version of this post that uses the new TFS 2017/Visual Studio Team Services...]]></description>
      <content:encoded><![CDATA[UPDATE: Look for a <a href="https://blogs.msdn.microsoft.com/alming/2017/02/09/using-web-config-transforms-and-release-manager-tfs-2017team-services-edition/">newer version </a>of this post that uses the new TFS 2017/Visual Studio Team Services new architecture.

&nbsp;

First: yes, it's been a long time since I published anything. It's been a busy year and finding time to blog was really tough. For the commenters on my previous posts: apologies for not being prompt on replies.

Anyway, one of my 2015 resolutions is to do better at blogging. :-)

The idea behind this post is to show what I've done on 2 of my clients where we implemented build automation and Release Manager, getting a proof-of-concept application to successfully deploy to environments and to properly manage web.config transformations leveraging Release Manager.
<h4>Scenario</h4>
I'm going to use a dummy MVC Web Application that's basically the Visual Studio 2013 template plus a small modification to the web.config so that we can demo the workflow.

The example I have is to show a message on the home page from a setting in the web.config. This setting then varies based on the environment (dev, prod, etc) the application is running on, and this will be the variable that will be changed by web.config transformations and Release Manager.

Although I'm using an AppSettings key, you can use it for other settings and connection strings as well. The same rules apply.

I made the following modifications:

Index.cshtml

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/6521.Indexfile.JPG"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/6521.Indexfile.JPG" border="0" /></a>

HomeController.cs

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/7380.homecontroller.JPG"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/7380.homecontroller.JPG" border="0" /></a>

Web.config

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/2844.webconfig.JPG"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/2844.webconfig.JPG" border="0" /></a>

The application should show  the msg from the web.config settings as per below (running from Visual Studio);

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/2021.apprunninginvs.JPG"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/2021.apprunninginvs.JPG" border="0" /></a>
<h4> Setting up web.config transforms</h4>
I'll not go into too much detail on how to <a href="https://msdn.microsoft.com/en-us/library/vstudio/dd394698(v=vs.100).aspx#webconfig_transformation" title="https://msdn.microsoft.com/en-us/library/vstudio/dd394698(v=vs.100).aspx#webconfig_transformation">setup web.config transforms</a> and what the <a href="https://msdn.microsoft.com/en-us/library/vstudio/dd394698(v=vs.100).aspx#webconfig_transformation" title="https://msdn.microsoft.com/en-us/library/vstudio/dd394698(v=vs.100).aspx#webconfig_transformation">transformation syntax </a>is for them, as they've been very well explained on MSDN.

The strategy that I used here was to structure my transformations so that:
<ol>
 	<li>The original web.config file has the settings needed for the developer to run in debug mode in Visual Studio</li>
 	<li>I added a new configuration (Release) that will have the proper web.config transformations to put tokens in the key/values that I need to be changed later by Release Management:</li>
</ol>
<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/8715.webconfig_release.JPG"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/8715.webconfig_release.JPG" border="0" /></a>

The same transformed config using Release configuration will be used by Release Management (RM) to deploy to all the environments in the release path.RM will then substitute the "__EnvLabel__" token with the appropriate value for each target deployment environment.
<h4>TFS Build</h4>
You can use any template for the build, including the RM template to trigger a release directly from the build.

The trick here is to force the web config transformation to happen during build, so you end up with a web.config that has the tokens RM is expecting. By default, web config transformations only happen during deployment.

In order for you to add this behaviour, you can add the following arguments to MSBuild:
<pre class="scroll"><code class="csharp">/p:UseWPP_CopyWebApplication=true /p:PipelineDependsOnBuild=false</code></pre>
<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/1651.builds_arguments.JPG"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/1651.builds_arguments.JPG" border="0" /></a>

Also, make sure that you're building the correct configuration that has the transforms to add the token (in our example is Any CPU and Release):

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/6607.build_configs.JPG"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/6607.build_configs.JPG" border="0" /></a>

Once the build finishes, the output should look like this (noticed the web.config transformed to include the token):

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/3531.drop_folder.JPG"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/3531.drop_folder.JPG" border="0" /></a>

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/1108.tranformed%20web%20config.JPG"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/1108.tranformed%20web%20config.JPG" border="0" /></a>

&nbsp;
<h4>Release Path setup</h4>
Now, we have to take that config and replace the tokens with the proper values according to the target environment. In this example, I'm going to use an Agent-based setup. I'll update this later to also include an Agent-less deployment using PowerShell Desired State Configuration (DSC).

First we configure Release Manager Server, Release Management Client and a deployment agent on the target server. You can find more detailed information on setting up those parts here: <a href="https://msdn.microsoft.com/en-us/library/dn593704.aspx" title="https://msdn.microsoft.com/en-us/library/dn593704.aspx">Install Release Management Server and Client</a>, <a href="https://msdn.microsoft.com/en-us/library/dn593701.aspx" title="https://msdn.microsoft.com/en-us/library/dn593701.aspx">Install Deployment Agents</a>..

I used the same target server to simulate both DEV and PROD IIS environments, by using two different ports:

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/5277.iis%20on%20server.JPG"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/5277.iis%20on%20server.JPG" border="0" /></a>

Then I configured a server in RM to point to that box:

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/1680.rm_server.JPG"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/1680.rm_server.JPG" border="0" /></a>

Next I configured the two environments, DEV and PROD:

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/3630.rm_dev_env.JPG"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/3630.rm_dev_env.JPG" border="0" /></a>

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/8105.rm_prod_env.JPG"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/8105.rm_prod_env.JPG" border="0" /></a>

Next step is to configure a release path where we have a DEV -&gt; PROD deployment flow:

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/5483.rm_release_path.JPG"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/5483.rm_release_path.JPG" border="0" /></a>

The setup above is, of course, overly simplistic for demo purposes. What you should have in mind is that you can configure who can approve (individuals or groups), who can validate and whether those steps are automated or not. In my example, I don't need approvals for DEV, but need one for PROD. When the deployment workflow is initiated, DEV will be deployed automatically while PROD will wait for an approval before proceeding.

Next step is to configure the components to be deployed, in this case our web application:

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/8863.rm_component1.JPG"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/8863.rm_component1.JPG" border="0" /></a>

I chose to use the "builds with application" option, since I'm going to use the build definition that will be defined in the release path.

Next, I'll setup the deployment tool. In my case, XCopy, but you can use MS Deploy or other tool as appropriate:

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/3632.rm_component2.JPG"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/3632.rm_component2.JPG" border="0" /></a>

The secret of the web.config token replacement happens here on the Configuration Variables. We specify that the replacement happens "Before Installation", so that the config file is updated before being copied to the target server. We also specify the wildcard to tell RM what files we want RM to look for tokens: in this case *.config.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/4101.rm_component3.JPG"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/4101.rm_component3.JPG" border="0" /></a>

Next we define the release template. In this example:
<ul>
 	<li>You can see the DEV -&gt; PROD workflow</li>
 	<li>Servers in the deployment (I only have one in this example, but you might have multiple most likely)</li>
 	<li>Components: the application being deployed (you might have to manually add it by right-clicking Components</li>
 	<li>I included optional steps to backup current site, and to rollback in case deployment fails (more of a best practice, but they're not necessary)</li>
</ul>
&nbsp;

Notice that the "EnvLabel" token we specified before gets a value here, depending on the environment, along with the other variables like target and backup folders:

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/7853.rm_template_dev.JPG"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/7853.rm_template_dev.JPG" border="0" /></a>

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/3463.rm_template_prod.JPG"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/3463.rm_template_prod.JPG" border="0" /></a>
<h4>Deploying</h4>
Let's get some action going!

We initiate the release manually, choosing the template we configured previously, PROD as the last stage and selecting the last build as the one to deploy:

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/6874.rm_release_start.JPG"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/6874.rm_release_start.JPG" border="0" /></a>

After a while we should see the following results:

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/6131.rm_deploy_dev_completed.JPG"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/6131.rm_deploy_dev_completed.JPG" border="0" /></a>

Notice that the deployment to DEV was completed, but deployment to PROD is waiting for approval.

DEV has been successfully deployed:

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/4628.dev_deployed.JPG"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/4628.dev_deployed.JPG" border="0" /></a>

While PROD has not yet:

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/7043.prod_not_yet_deployed.JPG"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/7043.prod_not_yet_deployed.JPG" border="0" /></a>

The reason is that we're waiting for approval. Let's go ahead and open the approval window using the RM web client:

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/7725.rm_approval.JPG"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/7725.rm_approval.JPG" border="0" /></a>

Clicking on the "Approve" for the selected release, we get the following dialog:

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/4265.rm_approve_dialog.JPG"><img width="364" height="266" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/4265.rm_approve_dialog.JPG" border="0" /></a>

If we want to approve, but delay the deployment for later (off-hours deployment), we can click on the "Deferred Deployment" and select a day/time for when the deployment will execute:

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/7633.rm_deferred_deployment.JPG"><img width="186" height="239" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/7633.rm_deferred_deployment.JPG" border="0" /></a>

After approval is given, the workflow resumes and finishes deploying to PROD:

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/8272.rm_prod_deployed.JPG"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/8272.rm_prod_deployed.JPG" border="0" /></a>

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/2185.prod_site_deployed.JPG"><img alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/2185.prod_site_deployed.JPG" border="0" /></a>

There you have it!

&nbsp;

&nbsp;]]></content:encoded>
    </item>
    <item>
      <title>Finding Event Subscriptions in TFS 2012 Using PowerShell</title>
      <link>https://docs.microsoft.com/archive/blogs/alming/finding-event-subscriptions-in-tfs-2012-using-powershell</link>
      <pubDate>Sun, 05 May 2013 19:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Marcelo E Silva]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/alming/2013/05/05/finding-event-subscriptions-in-tfs-2012-using-powershell/</guid>
      <description><![CDATA[Update: Changed script to use System.Collections.ArrayList for increased performance
Update: You...]]></description>
      <content:encoded><![CDATA[<p><strong>Update: Changed script to use System.Collections.ArrayList for increased performance</strong></p>
<p><strong>Update: You can use the ArrayList but a better approach is to not use it and just pipeline each object out, so I updated the script to reflect that</strong></p>
<p>Well, I'm going thru some PowerShell training at the moment and thought I could continue to apply that into my ALM needs. In this case, I came across a client that had several warning messages about the notification event failing for some email deliveries. This was detected on the Best Practices Analyzer tool found on <a title="https://visualstudiogallery.msdn.microsoft.com/b1ef7eb2-e084-4cb8-9bc7-06c3bad9148f" href="https://blogs.msdn.com/controlpanel/blogs/posteditor.aspx/Team Foundation Power Tools for 2012" target="_blank">Team Foundation Power Tools for 2012</a>.</p>
<p>Their TFS setup is fairly large and contains several team projects with around 250 users, with some degree of turnover. I needed some way to list all subscriptions in the system in a format they could then query.</p>
<p>The script below will create a function that will connect to a TFS collection and then list all existing subscriptions. The subscriptions will be listed in an array of PSObjects, that can be piped into a Where-Object for additional filtering. The created object is a "flatter" version of the original object and it's easier to query. In addition to that, I&nbsp;added some code to resolve the identity of the subscriber.&nbsp;</p>
<p>I also added code that, instead of using a custom PSObject, it uses the original .Net and I add the subscriber identity as an extended property. Either way works, so you can pick which one you like best.</p>
<p>Once you find the subscriptions that are invalid, you can delete them using the <a href="https://msdn.microsoft.com/en-us/magazine/cc507647.aspx">BISSUBSCRIBE.EXE tool</a>&nbsp;and passing the subscription id.</p>
<p>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/8524.Bissubscribe.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-58-11/8524.Bissubscribe.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/8524.Bissubscribe.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-58-11/8524.Bissubscribe.png" alt="" border="0" /></a></p>
<p>The PowerShell script will create the following output (this example uses the collectionurl parameter, but if you don't specify it a dialog will pop up for you to select the collection):</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/0184.output.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-58-11/0184.output.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/0184.output.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-58-11/0184.output.png" alt="" border="0" /></a></p>
<p>&nbsp;</p>
<p>Here's the script:</p>
<div class="WordSection1">
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; color: darkgreen;">#TFS Powershell function to list all event subscriptions in TFS&nbsp; </span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; color: darkgreen;">#for all team projects (or a specific team project) in a given collection</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; color: darkgreen;" lang="PT-BR">#</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; color: darkgreen;" lang="PT-BR">#Author: Marcelo Silva (marcelo.silva@microsoft.com)</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; color: darkgreen;">#</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; color: darkgreen;">#Copyright 2013</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; color: darkgreen;">#</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; color: darkblue;">function</span><span style="font-size: 9.0pt; font-family: 'Lucida Console';"> <span style="color: blueviolet;">Get-TFSEventSubscriptions</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">{</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp; <span style="color: darkblue;">Param</span>(<span style="color: darkgray;">[</span><span style="color: teal;">string</span><span style="color: darkgray;">]</span> <span style="color: orangered;">$CollectionUrlParam</span><span style="color: darkgray;">,</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: darkgray;">[</span><span style="color: teal;">string</span><span style="color: darkgray;">[]]</span> <span style="color: orangered;">$Projects</span>)</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp; <span style="color: darkgreen;"># load the required dlls</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp; <span style="color: darkgreen;"># Below is correct syntax for v3</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp; <span style="color: blue;">Add-Type</span> <span style="color: navy;">-AssemblyName</span> <span style="color: darkred;">"Microsoft.TeamFoundation.Client, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp; <span style="color: darkgreen;">#This syntax is deprecated, however it loads whatever version you have of Team Explorer, :-)</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp; <span style="color: darkgreen;">#[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Client")</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp; <span style="color: orangered;">$tfs</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp; <span style="color: darkblue;">if</span> (<span style="color: orangered;">$CollectionUrlParam</span>)</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp; {</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: darkgreen;">#if collection is passed then get tfs collection obj</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: orangered;">$tfs</span> <span style="color: darkgray;">=</span> <span style="color: darkgray;">[</span><span style="color: teal;">Microsoft.TeamFoundation.Client.TfsTeamProjectCollectionFactory</span><span style="color: darkgray;">]::</span>GetTeamProjectCollection(<span style="color: orangered;">$CollectionUrlParam</span>)&nbsp;&nbsp; </span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp; }</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp; <span style="color: darkblue;">else</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp; {</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: darkgreen;">#if no collection specified, open project picker to select it via gui</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: orangered;">$picker</span> <span style="color: darkgray;">=</span> <span style="color: blue;">New-Object</span> <span style="color: blueviolet;">Microsoft.TeamFoundation.Client.TeamProjectPicker</span>(<span style="color: darkgray;">[</span><span style="color: teal;">Microsoft.TeamFoundation.Client.TeamProjectPickerMode</span><span style="color: darkgray;">]::</span>NoProject<span style="color: darkgray;">,</span> <span style="color: orangered;">$false</span>)</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: orangered;">$dialogResult</span> <span style="color: darkgray;">=</span> <span style="color: orangered;">$picker</span><span style="color: darkgray;">.</span>ShowDialog()</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: darkblue;">if</span> (<span style="color: orangered;">$dialogResult</span> <span style="color: darkgray;">-ne</span> <span style="color: darkred;">"OK"</span>)</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: darkblue;">exit</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: orangered;">$tfs</span> <span style="color: darkgray;">=</span> <span style="color: orangered;">$picker</span><span style="color: darkgray;">.</span>SelectedTeamProjectCollection</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp; }</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp; <span style="color: darkgreen;"># Authenticate current user</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp; <span style="color: darkblue;">try</span> </span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp; {</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: orangered;">$tfs</span><span style="color: darkgray;">.</span>EnsureAuthenticated()</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp; }</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp; <span style="color: darkblue;">catch</span> </span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp; {</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue;">Write-Error</span> <span style="color: darkred;">"Error occurred trying to connect to project collection: </span><span style="color: orangered;">$_</span><span style="color: darkred;"> "</span> </span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: darkblue;">exit</span> <span style="color: purple;">1</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp; }</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp; <span style="color: darkgreen;">#TFS Services to be used</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp; <span style="color: orangered;">$eventService</span> <span style="color: darkgray;">=</span> <span style="color: orangered;">$tfs</span><span style="color: darkgray;">.</span>GetService(<span style="color: darkred;">"Microsoft.TeamFoundation.Framework.Client.IEventService"</span>)</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp; <span style="color: orangered;">$identityService</span> <span style="color: darkgray;">=</span> <span style="color: orangered;">$tfs</span><span style="color: darkgray;">.</span>GetService(<span style="color: darkred;">"Microsoft.TeamFoundation.Framework.Client.IIdentityManagementService"</span>)</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp; <span style="color: darkblue;">foreach</span> (<span style="color: orangered;">$sub</span> <span style="color: darkblue;">in</span> <span style="color: orangered;">$eventService</span><span style="color: darkgray;">.</span>GetAllEventSubscriptions())</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp; {</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: darkgreen;">#First resolve the subscriber ID</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: orangered;">$tfsId</span> <span style="color: darkgray;">=</span> <span style="color: orangered;">$identityService</span><span style="color: darkgray;">.</span>ReadIdentity(<span style="color: darkgray;">[</span><span style="color: teal;">Microsoft.TeamFoundation.Framework.Common.IdentitySearchFactor</span><span style="color: darkgray;">]::</span>Identifier<span style="color: darkgray;">,</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: orangered;">$sub</span><span style="color: darkgray;">.</span>Subscriber<span style="color: darkgray;">,</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: darkgray;">[</span><span style="color: teal;">Microsoft.TeamFoundation.Framework.Common.MembershipQuery</span><span style="color: darkgray;">]::</span>None<span style="color: darkgray;">,</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: darkgray;">[</span><span style="color: teal;">Microsoft.TeamFoundation.Framework.Common.ReadIdentityOptions</span><span style="color: darkgray;">]::</span>None )</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: darkblue;">if</span> (<span style="color: orangered;">$tfsId</span><span style="color: darkgray;">.</span>UniqueName)</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: orangered;">$subscriberId</span> <span style="color: darkgray;">=</span> <span style="color: orangered;">$tfsId</span><span style="color: darkgray;">.</span>UniqueName</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: darkblue;">else</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: orangered;">$subscriberId</span> <span style="color: darkgray;">=</span> <span style="color: orangered;">$tfsId</span><span style="color: darkgray;">.</span>DisplayName</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: darkgreen;">#then create custom PSObject</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: orangered;">$subPSObj</span> <span style="color: darkgray;">=</span> <span style="color: blue;">New-Object</span> <span style="color: blueviolet;">PSObject</span> <span style="color: navy;">-Property</span> @{</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: darkgray;">=</span> <span style="color: orangered;">$sub</span><span style="color: darkgray;">.</span>ID</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Device&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: darkgray;">=</span> <span style="color: orangered;">$sub</span><span style="color: darkgray;">.</span>Device</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Condition&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: darkgray;">=</span> <span style="color: orangered;">$sub</span><span style="color: darkgray;">.</span>ConditionString</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EventType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: darkgray;">=</span> <span style="color: orangered;">$sub</span><span style="color: darkgray;">.</span>EventType</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Address&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: darkgray;">=</span> <span style="color: orangered;">$sub</span><span style="color: darkgray;">.</span>DeliveryPreference<span style="color: darkgray;">.</span>Address</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Schedule&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: darkgray;">=</span> <span style="color: orangered;">$sub</span><span style="color: darkgray;">.</span>DeliveryPreference<span style="color: darkgray;">.</span>Schedule</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DeliveryType&nbsp;&nbsp; <span style="color: darkgray;">=</span> <span style="color: orangered;">$sub</span><span style="color: darkgray;">.</span>DeliveryPreference<span style="color: darkgray;">.</span>Type</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SubscriberName <span style="color: darkgray;">=</span> <span style="color: orangered;">$subscriberId</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Tag&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: darkgray;">=</span> <span style="color: orangered;">$sub</span><span style="color: darkgray;">.</span>Tag</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: darkgreen;">#Send object to the pipeline. You could store it on an Arraylist, but that just</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: darkgreen;">#consumes more memory</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: orangered;">$subPSObj</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: darkgreen;">##This is another variation where we just add a property to the existing Subscription object</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: darkgreen;">##this might be desirable since it will keep the other members</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: darkgreen;">#Add-Member -InputObject $sub -NotePropertyName SubscriberName -NotePropertyValue $subscriberId</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">&nbsp;&nbsp;&nbsp; } </span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console';">} </span></p>
<p class="MsoNormal">&nbsp;</p>
</div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>Using PowerShell and TFS API to list users in TFS 2010 (and 2012)</title>
      <link>https://docs.microsoft.com/archive/blogs/alming/using-powershell-and-tfs-api-to-list-users-in-tfs-2010-and-2012</link>
      <pubDate>Thu, 07 Mar 2013 13:54:00 GMT</pubDate>
      <dc:creator><![CDATA[Marcelo E Silva]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/alming/2013/03/07/using-powershell-and-tfs-api-to-list-users-in-tfs-2010-and-2012/</guid>
      <description><![CDATA[Update: Just wanted to let everyone know that this PowerShell script also runs under PowerShell 3.0...]]></description>
      <content:encoded><![CDATA[<p><span style="color: #ff0000;"><strong>Update</strong></span>: <strong>Just wanted to let everyone know that this PowerShell script also runs under PowerShell 3.0 and it also works with TFS 2012 Team Explorer</strong>.</p>
<p><span style="color: #ff0000;"><strong>Update 2</strong></span>: <strong>After some training in Powershell, I updated the script below to also be in the form of an advanced function, taking optional parameters and also using TeamProjectPicker in case no parameters are passed. Enjoy!</strong></p>
<p>First and foremost: this is my first post! :-)</p>
<p>Now, let's get down to business. I've been studying PowerShell for a short time and wanted to practice it and I have recently had a lot of requests from clients where they ask me the easiest way to get a "dump" of all the users on all projects in TFS.</p>
<p>When, why not use this as a good example to learn PowerShell and solve this problem?</p>
<p>Let's begin.</p>
<p>You can get a list of all users by using <span style="font-family: courier new,courier;">tfssecurity </span>utility. For example: running</p>
<p><span style="font-family: courier new,courier;">tfssecurity /imx "Project Collection Valid Users" /collection:<em>&lt;collectionUrl&gt;</em> </span>will get you something like this:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/7103.tfssecurity%20for%20collection%20valid%20users.JPG" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-58-11/7103.tfssecurity-for-collection-valid-users.JPG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/7103.tfssecurity%20for%20collection%20valid%20users.JPG" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-58-11/7103.tfssecurity-for-collection-valid-users.JPG" alt="" border="0" /></a></p>
<p>Which is helpful somewhat, but not quite, since it doesn't group users by group membership.</p>
<p>Brian Harry posted in his <a href="https://blogs.msdn.com/b/bharry/archive/2010/10/01/dumping-the-contents-of-all-of-your-tfs-groups.aspx">blog</a> a good solution to this problem using C#. The output of that code is something similar like this:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/8473.Brian%20harrys%20dump%20group%20solution.JPG" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-58-11/8473.Brian-harrys-dump-group-solution.JPG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/58/11/8473.Brian%20harrys%20dump%20group%20solution.JPG" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-58-11/8473.Brian-harrys-dump-group-solution.JPG" alt="" border="0" /></a></p>
<p>&nbsp;</p>
<p>This is close to what we want, but the listing is not organized in a hierarchical fashion. Yes, you could fix the code to do it, but we're talking about using PowerShell here. :-)</p>
<p>Anyway, the script in this blog post will not require IT admins to have Visual Studio to compile code or rely on a developer to do it for them. It only requires PowerShell 2.0 (also works with 3.0) and <a href="https://www.microsoft.com/en-us/download/details.aspx?id=30656">Team Explorer 2012</a> (also works with 2010 SP1)</p>
<p>The script source code is:</p>
<div class="WordSection1">
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console'; color: darkgreen;">#TFS <span class="SpellE">Powershell</span> script to dump users by groups </span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console'; color: darkgreen;">#for all team projects (or a specific team project) in a given collection</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console'; color: darkgreen; mso-ansi-language: PT-BR;" lang="PT-BR">#</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console'; color: darkgreen; mso-ansi-language: PT-BR;" lang="PT-BR">#Author: Marcelo Silva (marcelo.silva@microsoft.com)</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console'; color: darkgreen;">#</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console'; color: darkgreen;">#Copyright 2013</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console'; color: darkgreen;">#</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span class="GramE"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console'; color: darkblue;">function</span></span><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"> <span style="color: blueviolet;">Get-<span class="SpellE">TFSGroupMembership</span></span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';">{</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="SpellE"><span class="GramE"><span style="color: darkblue;">Param</span></span></span><span class="GramE">(</span><span style="color: darkgray;">[</span><span style="color: teal;">string</span><span style="color: darkgray;">]</span> <span style="color: orangered;">$<span class="SpellE">CollectionUrlParam</span></span><span style="color: darkgray;">,</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: darkgray;">[</span><span class="GramE"><span style="color: teal;">string</span><span style="color: darkgray;">[</span></span><span style="color: darkgray;">]]</span> <span style="color: orangered;">$Projects</span><span style="color: darkgray;">,</span> </span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: darkgray;">[</span><span class="GramE"><span style="color: teal;">switch</span></span><span style="color: darkgray;">]</span> <span style="color: orangered;">$<span class="SpellE">ShowEmptyGroups</span></span>)</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="color: orangered;">$<span class="SpellE">identation</span></span> <span style="color: darkgray;">=</span> <span style="color: purple;">0</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="color: orangered;">$<span class="SpellE">max_call_depth</span></span> <span style="color: darkgray;">=</span> <span style="color: purple;">30</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: darkblue;">function</span></span> <span style="color: blueviolet;">write-<span class="SpellE">idented</span></span>(<span style="color: darkgray;">[</span><span style="color: teal;">string</span><span style="color: darkgray;">]</span><span style="color: orangered;">$text</span>)</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">Write-Output</span> <span style="color: orangered;">$<span class="SpellE"><span class="GramE">text<span style="color: darkgray;">.</span><span style="color: windowtext;">PadLeft</span></span></span></span><span class="GramE">(</span><span style="color: orangered;">$<span class="SpellE">text<span style="color: darkgray;">.</span><span style="color: windowtext;">Length</span></span></span> <span style="color: darkgray;">+</span> (<span style="color: purple;">6</span> <span style="color: darkgray;">*</span> <span style="color: orangered;">$<span class="SpellE">identation</span></span>)) </span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: darkblue;">function</span></span> <span class="SpellE"><span style="color: blueviolet;">list_identities</span></span> (<span style="color: orangered;">$<span class="SpellE">queryOption</span></span><span style="color: darkgray;">,</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: orangered;">$<span class="SpellE">tfsIdentity</span></span><span style="color: darkgray;">,</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: orangered;">$<span class="SpellE">readIdentityOptions</span></span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>)</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: orangered;">$identities</span> <span style="color: darkgray;">=</span> <span style="color: orangered;">$<span class="SpellE"><span class="GramE">idService<span style="color: darkgray;">.</span><span style="color: windowtext;">ReadIdentities</span></span></span></span><span class="GramE">(</span><span style="color: orangered;">$<span class="SpellE">tfsIdentity</span></span><span style="color: darkgray;">,</span> <span style="color: orangered;">$<span class="SpellE">queryOption</span></span><span style="color: darkgray;">,</span> <span style="color: orangered;">$<span class="SpellE">readIdentityOptions</span></span>)</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: orangered;">$<span class="SpellE">identation</span></span><span style="color: darkgray;">++</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="SpellE"><span class="GramE"><span style="color: darkblue;">foreach</span></span></span><span class="GramE">(</span><span style="color: orangered;">$id</span> <span style="color: darkblue;">in</span> <span style="color: orangered;">$identities</span>)</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: darkblue;">if</span></span> (<span style="color: orangered;">$<span class="SpellE">id<span style="color: darkgray;">.</span><span style="color: windowtext;">IsContainer</span></span></span>)</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: darkblue;">if</span></span> (<span style="color: orangered;">$<span class="SpellE">id<span style="color: darkgray;">.</span><span style="color: windowtext;">Members</span><span style="color: darkgray;">.</span><span style="color: windowtext;">Count</span></span></span> <span style="color: darkgray;">-<span class="SpellE">gt</span></span> <span style="color: purple;">0</span>) </span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: darkblue;">if</span></span> (<span style="color: orangered;">$<span class="SpellE">identation</span></span> <span style="color: darkgray;">-<span class="SpellE">lt</span></span> <span style="color: orangered;">$<span class="SpellE">max_call_depth</span></span>) <span style="color: darkgreen;">#Safe number for max call depth</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{ </span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: blue;">write-<span class="SpellE">idented</span></span></span> <span style="color: darkred;">"Group: "</span><span style="color: darkgray;">,</span> <span style="color: orangered;">$<span class="SpellE">id<span style="color: darkgray;">.</span><span style="color: windowtext;">DisplayName</span></span></span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="SpellE"><span style="color: blue;">list_identities</span></span> <span style="color: orangered;">$<span class="SpellE">queryOption</span></span> <span style="color: orangered;">$<span class="SpellE">id<span style="color: darkgray;">.</span><span style="color: windowtext;">Members</span></span></span> <span style="color: orangered;">$<span class="SpellE">readIdentityOptions</span></span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: darkblue;">else</span></span> </span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">Write-Output</span> <span style="color: darkred;">"Maximum call depth reached. Moving on to next group or project..."</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: darkblue;">else</span></span> </span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;</span><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: darkblue;">if</span></span> (<span style="color: orangered;">$<span class="SpellE">ShowEmptyGroups</span></span>)</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: blue;">write-<span class="SpellE">idented</span></span></span> <span style="color: darkred;">"Group: "</span><span style="color: darkgray;">,</span> <span style="color: orangered;">$<span class="SpellE">id<span style="color: darkgray;">.</span><span style="color: windowtext;">DisplayName</span></span></span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: orangered;">$<span class="SpellE">identation</span></span><span style="color: darkgray;">++</span>;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: blue;">write-<span class="SpellE">idented</span></span></span> <span style="color: darkred;">"-- No users --"</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: orangered;">$<span class="SpellE">identation</span></span><span style="color: darkgray;">--</span>;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: darkblue;">else</span></span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: darkblue;">if</span></span> (<span style="color: orangered;">$<span class="SpellE">id<span style="color: darkgray;">.</span><span style="color: windowtext;">UniqueName</span></span></span>)<span style="mso-spacerun: yes;">&nbsp; </span>{</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: blue;">write-<span class="SpellE">idented</span></span></span> <span style="color: darkred;">"Member user: "</span><span style="color: darkgray;">,</span> <span style="color: orangered;">$<span class="SpellE">id<span style="color: darkgray;">.</span><span style="color: windowtext;">UniqueName</span></span></span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: darkblue;">else</span></span> {</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: blue;">write-<span class="SpellE">idented</span></span></span> <span style="color: darkred;">"Member user: "</span><span style="color: darkgray;">,</span> <span style="color: orangered;">$<span class="SpellE">id<span style="color: darkgray;">.</span><span style="color: windowtext;">DisplayName</span></span></span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<span style="mso-spacerun: yes;">&nbsp; </span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: orangered;">$<span class="SpellE">identation</span></span><span style="color: darkgray;">--</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="color: darkgreen;"># load the required <span class="SpellE">dlls</span></span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">Add-Type</span> <span style="color: navy;">-<span class="SpellE">AssemblyName</span></span> <span style="color: darkred;">"<span class="SpellE">Microsoft.TeamFoundation.Client</span>, Version=11.0.0.0, Culture=neutral, <span class="SpellE">PublicKeyToken</span>=b03f5f7f11d50a3a"</span><span style="color: darkgray;">,</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: darkred;">"<span class="SpellE">Microsoft.TeamFoundation.Common</span>, Version=11.0.0.0, Culture=neutral, <span class="SpellE">PublicKeyToken</span>=b03f5f7f11d50a3a"</span><span style="color: darkgray;">,</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: darkred;">"<span class="SpellE">Microsoft.TeamFoundation</span>, Version=11.0.0.0, Culture=neutral, <span class="SpellE">PublicKeyToken</span>=b03f5f7f11d50a3a"</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: darkgreen;">#[</span></span><span style="color: darkgreen;">void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Client")</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: darkgreen;">#[</span></span><span style="color: darkgreen;">void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Common")</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: darkgreen;">#[</span></span><span style="color: darkgreen;">void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation")</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="color: orangered;">$<span class="SpellE">tfs</span></span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="color: orangered;">$<span class="SpellE">projectList</span></span> <span style="color: darkgray;">=</span> <span class="GramE">@()</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: darkblue;">if</span></span> (<span style="color: orangered;">$<span class="SpellE">CollectionUrlParam</span></span>)</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: darkgreen;">#if collection is passed then use it and select all projects</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: orangered;">$<span class="SpellE">tfs</span></span> <span style="color: darkgray;">=</span> <span style="color: darkgray;">[</span><span style="color: teal;">Microsoft.TeamFoundation.Client.TfsTeamProjectCollectionFactory</span><span style="color: darkgray;">]:<span class="GramE">:<span style="color: windowtext;">GetTeamProjectCollection</span></span></span>(<span style="color: orangered;">$CollectionUrlParam</span>)</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: orangered;">$<span class="SpellE">cssService</span></span> <span style="color: darkgray;">=</span> <span style="color: orangered;">$<span class="GramE">tfs<span style="color: darkgray;">.</span><span style="color: windowtext;">GetService(</span></span></span><span style="color: darkred;">"Microsoft.TeamFoundation.Server.ICommonStructureService3"</span>)<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: darkblue;">if</span></span> (<span style="color: orangered;">$Projects</span>)</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp; </span><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: darkgreen;">#validate project names</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="SpellE"><span class="GramE"><span style="color: darkblue;">foreach</span></span></span> (<span style="color: orangered;">$p</span> <span style="color: darkblue;">in</span> <span style="color: orangered;">$Projects</span>)</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: darkblue;">try</span></span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: orangered;">$<span class="SpellE">projectList</span></span> <span style="color: darkgray;">+=</span> <span style="color: orangered;">$<span class="SpellE"><span class="GramE">cssService<span style="color: darkgray;">.</span><span style="color: windowtext;">GetProjectFromName</span></span></span></span><span class="GramE">(</span><span style="color: orangered;">$p</span>)</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: darkblue;">catch</span></span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: blue;">Write-Error</span> <span style="color: darkred;">"Invalid project name: </span><span style="color: orangered;">$p</span><span style="color: darkred;">"</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: darkblue;">exit</span></span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: darkblue;">else</span></span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: orangered;">$<span class="SpellE">projectList</span></span> <span style="color: darkgray;">=</span> <span style="color: orangered;">$<span class="SpellE"><span class="GramE">cssService<span style="color: darkgray;">.</span><span style="color: windowtext;">ListAllProjects</span></span></span></span><span class="GramE">()</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: darkblue;">else</span></span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: darkgreen;">#if no collection specified, open project picker to select it via <span class="SpellE"><span class="GramE">gui</span></span></span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: orangered;">$picker</span> <span style="color: darkgray;">=</span> <span style="color: blue;">New-Object</span> <span class="GramE"><span style="color: blueviolet;">Microsoft.TeamFoundation.Client.TeamProjectPicker</span>(</span><span style="color: darkgray;">[</span><span style="color: teal;">Microsoft.TeamFoundation.Client.TeamProjectPickerMode</span><span style="color: darkgray;">]::</span>MultiProject<span style="color: darkgray;">,</span> <span style="color: orangered;">$false</span>)</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: orangered;">$<span class="SpellE">dialogResult</span></span> <span style="color: darkgray;">=</span> <span style="color: orangered;">$<span class="SpellE"><span class="GramE">picker<span style="color: darkgray;">.</span><span style="color: windowtext;">ShowDialog</span></span></span></span><span class="GramE">()</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: darkblue;">if</span></span> (<span style="color: orangered;">$<span class="SpellE">dialogResult</span></span> <span style="color: darkgray;">-ne</span> <span style="color: darkred;">"OK"</span>)</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: darkblue;">exit</span></span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: orangered;">$<span class="SpellE">tfs</span></span> <span style="color: darkgray;">=</span> <span style="color: orangered;">$<span class="SpellE">picker<span style="color: darkgray;">.</span><span style="color: windowtext;">SelectedTeamProjectCollection</span></span></span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: orangered;">$<span class="SpellE">projectList</span></span> <span style="color: darkgray;">=</span> <span style="color: orangered;">$<span class="SpellE">picker<span style="color: darkgray;">.</span><span style="color: windowtext;">SelectedProjects</span></span></span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: darkblue;">try</span></span> </span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: orangered;">$<span class="SpellE"><span class="GramE">tfs<span style="color: darkgray;">.</span><span style="color: windowtext;">EnsureAuthenticated</span></span></span></span><span class="GramE">()</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: darkblue;">catch</span></span> </span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">Write-Error</span> <span style="color: darkred;">"Error occurred trying to connect to project collection: </span><span style="color: orangered;">$<span class="GramE">_<span style="color: darkred;"> "</span></span></span> </span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: darkblue;">exit</span></span> <span style="color: purple;">1</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="color: orangered;">$<span class="SpellE">idService</span></span> <span style="color: darkgray;">=</span> <span style="color: orangered;">$<span class="GramE">tfs<span style="color: darkgray;">.</span><span style="color: windowtext;">GetService(</span></span></span><span style="color: darkred;">"Microsoft.TeamFoundation.Framework.Client.IIdentityManagementService"</span>)</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">Write-Output</span> <span style="color: darkred;">""</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">Write-Output</span> <span style="color: darkred;">"Team project collection: "</span> <span style="color: orangered;">$<span class="SpellE">CollectionUrlParam</span></span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">Write-Output</span> <span style="color: darkred;">""</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">Write-Output</span> <span style="color: darkred;">"Membership information<span class="GramE">: "</span></span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="color: orangered;">$<span class="SpellE">identation</span></span><span style="color: darkgray;">++</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="SpellE"><span class="GramE"><span style="color: darkblue;">foreach</span></span></span><span class="GramE">(</span><span style="color: orangered;">$<span class="SpellE">teamProject</span></span> <span style="color: darkblue;">in</span> <span style="color: orangered;">$<span class="SpellE">projectList</span></span>)</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>{<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">Write-Output</span> <span style="color: darkred;">""</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: blue;">write-<span class="SpellE">idented</span></span></span> <span style="color: darkred;">"Team project: "</span><span style="color: darkgray;">,</span><span style="color: orangered;">$<span class="SpellE">teamProject<span style="color: darkgray;">.</span><span style="color: windowtext;">Name</span></span></span> </span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="SpellE"><span class="GramE"><span style="color: darkblue;">foreach</span></span></span><span class="GramE">(</span><span style="color: orangered;">$group</span> <span style="color: darkblue;">in</span> <span style="color: orangered;">$<span class="SpellE">idService<span style="color: darkgray;">.</span><span style="color: windowtext;">ListApplicationGroups</span></span></span>(<span style="color: orangered;">$<span class="SpellE">teamProject<span style="color: darkgray;">.</span><span style="color: windowtext;">Name</span></span></span><span style="color: darkgray;">,</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: darkgray;">[</span><span style="color: teal;">Microsoft.TeamFoundation.Framework.Common.ReadIdentityOptions</span><span style="color: darkgray;">]:<span class="GramE">:<span style="color: windowtext;">TrueSid</span></span></span>))</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="SpellE"><span style="color: blue;">list_<span class="GramE">identities</span></span></span><span class="GramE"><span style="mso-spacerun: yes;">&nbsp; </span>(</span><span style="color: darkgray;">[</span><span style="color: teal;">Microsoft.TeamFoundation.Framework.Common.MembershipQuery</span><span style="color: darkgray;">]::</span>Direct) <span style="color: orangered;">$<span class="SpellE">group<span style="color: darkgray;">.</span><span style="color: windowtext;">Descriptor</span></span></span> (<span style="color: darkgray;">[</span><span style="color: teal;">Microsoft.TeamFoundation.Framework.Common.ReadIdentityOptions</span><span style="color: darkgray;">]::</span>TrueSid)</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>} </span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="color: orangered;">$<span class="SpellE">identation</span></span> <span style="color: darkgray;">=</span> <span style="color: purple;">1</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">Write-Output</span> <span style="color: darkred;">""</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">Write-Output</span> <span style="color: darkred;">"Users that have access to this collection but do not belong to any group:"</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">Write-Output</span> <span style="color: darkred;">""</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="color: orangered;">$<span class="SpellE">validUsersGroup</span></span> <span class="GramE"><span style="color: darkgray;">=</span><span style="mso-spacerun: yes;">&nbsp; </span><span style="color: orangered;">$</span></span><span style="color: orangered;">idService</span><span style="color: darkgray;">.</span>ReadIdentities(<span style="color: darkgray;">[</span><span style="color: teal;">Microsoft.TeamFoundation.Framework.Common.IdentitySearchFactor</span><span style="color: darkgray;">]::</span>AccountName<span style="color: darkgray;">,</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: darkred;">"Project Collection Valid Users"</span><span style="color: darkgray;">,</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: darkgray;">[</span><span style="color: teal;">Microsoft.TeamFoundation.Framework.Common.MembershipQuery</span><span style="color: darkgray;">]:<span class="GramE">:<span style="color: windowtext;">Expanded</span></span>,</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: darkgray;">[</span><span style="color: teal;">Microsoft.TeamFoundation.Framework.Common.ReadIdentityOptions</span><span style="color: darkgray;">]:<span class="GramE">:<span style="color: windowtext;">TrueSid</span></span></span>)</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="SpellE"><span class="GramE"><span style="color: darkblue;">foreach</span></span></span><span class="GramE">(</span><span style="color: orangered;">$member</span> <span style="color: darkblue;">in</span> <span style="color: orangered;">$<span class="SpellE">validUsersGroup</span></span><span style="color: darkgray;">[</span><span style="color: purple;">0</span><span style="color: darkgray;">][</span><span style="color: purple;">0</span><span style="color: darkgray;">].</span>Members)</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: orangered;">$user</span> <span style="color: darkgray;">=</span> <span style="color: orangered;">$<span class="SpellE"><span class="GramE">idService<span style="color: darkgray;">.</span><span style="color: windowtext;">ReadIdentity</span></span></span></span><span class="GramE">(</span><span style="color: orangered;">$member</span><span style="color: darkgray;">,</span> </span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: darkgray;">[</span><span style="color: teal;">Microsoft.TeamFoundation.Framework.Common.MembershipQuery</span><span style="color: darkgray;">]:<span class="GramE">:<span style="color: windowtext;">Expanded</span></span>,</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: darkgray;">[</span><span style="color: teal;">Microsoft.TeamFoundation.Framework.Common.ReadIdentityOptions</span><span style="color: darkgray;">]:<span class="GramE">:<span style="color: windowtext;">TrueSid</span></span></span>)</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';">&nbsp;</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: darkblue;">if</span></span> (<span style="color: orangered;">$<span class="SpellE">user<span style="color: darkgray;">.</span><span style="color: windowtext;">MemberOf</span><span style="color: darkgray;">.</span><span style="color: windowtext;">Count</span></span></span> <span style="color: darkgray;">-<span class="SpellE">eq</span></span> <span style="color: purple;">1</span> <span style="color: darkgray;">-and</span> <span style="color: darkgray;">-not</span> <span style="color: orangered;">$<span class="SpellE">user<span style="color: darkgray;">.</span><span style="color: windowtext;">IsContainer</span></span></span>)</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: darkblue;">if</span></span> (<span style="color: orangered;">$<span class="SpellE">user<span style="color: darkgray;">.</span><span style="color: windowtext;">UniqueName</span></span></span>)<span style="mso-spacerun: yes;">&nbsp; </span>{</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: blue;">write-<span class="SpellE">idented</span></span></span> <span style="color: darkred;">"User: "</span><span style="color: darkgray;">,</span> <span style="color: orangered;">$<span class="SpellE">user<span style="color: darkgray;">.</span><span style="color: windowtext;">UniqueName</span></span></span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: darkblue;">else</span><span style="mso-spacerun: yes;">&nbsp; </span>{</span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="GramE"><span style="color: blue;">write-<span class="SpellE">idented</span></span></span> <span style="color: darkred;">"User: "</span><span style="color: darkgray;">,</span> <span style="color: orangered;">$<span class="SpellE">user<span style="color: darkgray;">.</span><span style="color: windowtext;">DisplayName</span></span></span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; mso-layout-grid-align: none; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console';">} </span></p>
<p class="MsoNormal">&nbsp;</p>
</div>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;">&nbsp;</p>
<p class="MsoNormal" style="margin-bottom: .0001pt; line-height: normal; background: white; text-autospace: none;">&nbsp;</p>
<p class="MsoNormal">&nbsp;There are a couple of points to note about this script:</p>
<ul>
<li>
<div class="MsoNormal">The script uses recursion to navigate a tree of group memberships. In my tests, I found that I had to specify a max # of recursions in order to avoid a call depth error in PowerShell.</div>
</li>
<li>
<div class="MsoNormal">The&nbsp;<strong>ShowEmptyGroups </strong>option can be used to list all groups, even ones that are empty</div>
</li>
<li>
<div class="MsoNormal">You can pass an array of team project names if you want, otherwise it will list all team projects in the given collection</div>
</li>
<li>
<div class="MsoNormal">If you don't pass a team collection URL, it will pop up a dialog so you can select the team project collection and the team projects you want the report for.</div>
</li>
<li>
<div class="MsoNormal">There is a "bonus" piece of code at the end that lists anyone that have permissions set at individual level&nbsp;without belonging to any groups.</div>
</li>
</ul>
<p class="MsoNormal">You should get an output similar to the one below:</p>
<p>&nbsp;</p>
<p><span style="font-family: courier new,courier;">PS C:\Users\marcelos\Documents\TFS PowerShell&gt; . .\TFS-Dump-Group-Membership.ps1</span></p>
<p>&nbsp;</p>
<p><span style="font-family: courier new,courier;">PS C:\Users\marcelos\Documents\TFS PowerShell&gt; Get-TFSGroupMembership&nbsp;</span><span style="font-family: courier new,courier;"><a href="https://192.168.1.72:8080/tfs/defaultcollection">https://192.168.1.72:8080/tfs/defaultcollection</a> -ShowEmptyGroups</span></p>
<p><span style="font-family: courier new,courier;">Team project collection:</span></p>
<p><span style="font-family: courier new,courier;">https://192.168.1.72:8080/tfs/defaultcollection</span></p>
<p><span style="font-family: courier new,courier;">Membership information:</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Team project:&nbsp; JobsSite</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Group:&nbsp; [JobsSite]\Project Administrators</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Member user:&nbsp; TFS10RTM\TFSSETUP</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Group:&nbsp; [JobsSite]\Contributors</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Member user:&nbsp; TFS10RTM\Darren</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Member user:&nbsp; TFS10RTM\Nicole</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Group:&nbsp; [JobsSite]\Readers</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Member user:&nbsp; TFS10RTM\Larry</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Group:&nbsp; [JobsSite]\Builders</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- No users --</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Team project:&nbsp; TailspinToys</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Group:&nbsp; [TailspinToys]\Builders</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- No users --</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Group:&nbsp; [TailspinToys]\Readers</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- No users --</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Group:&nbsp; [TailspinToys]\Project Administrators</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Member user:&nbsp; TFS10RTM\Andrew</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Member user:&nbsp; TFS10RTM\TFSSETUP</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Group:&nbsp; [TailspinToys]\Contributors</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Member user:&nbsp; TFS10RTM\Darren</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Member user:&nbsp; TFS10RTM\Larry</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Team project:&nbsp; MyApplication</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Group:&nbsp; [MyApplication]\Project Administrators</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Member user:&nbsp; TFS10RTM\TFSSETUP</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Group:&nbsp; [MyApplication]\Contributors</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Group:&nbsp; [MyApplication]\DatabaseDevelopers</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Member user:&nbsp; TFS10RTM\Andrew</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Member user:&nbsp; TFS10RTM\Darren</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Group:&nbsp; [MyApplication]\Readers</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- No users --</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Group:&nbsp; [MyApplication]\Builders</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- No users --</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Group:&nbsp; [MyApplication]\DatabaseDevelopers</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Member user:&nbsp; TFS10RTM\Andrew</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Member user:&nbsp; TFS10RTM\Darren</span></p>
<p><span style="font-family: courier new,courier;">Users that have access to this collection but do not belong to any group:</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; User:&nbsp; TFS10RTM\Renee</span></p>
<p><span style="font-family: courier new,courier;">PS C:\Users\marcelos\Documents\TFS PowerShell&gt;&nbsp;</span></p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">There you have it!</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
  </channel>
</rss>