get-tfs.ps1 - example of adding properties to make interactive life easier
One of the things I noticed while working inside PowerShell was wanting to make a quick TFS object model (OM) call (for instance, to VersionControlServer) and slice/data/inspect the results. The OM calls to get an instance of TeamFoundationServer aren't bad (first load the assembly, then just call the ctor or use the factory class), and getting the VersionControlServer from there isn't bad (load the assembly, then GetService the type), but they weren't "very" scripting-friendly, so here's a simple wrapper for them.
Currently it just adds 4 properties to the TeamFoundationServer instance, for a little easier access to the particular interfaces I find myself using the most. Of course, you can add/remove entries from these (or just not add them at all, of course). For each of them, it generates the script block to execute for that property, then uses add-member to attach it. Of course, we're not really changing the TeamFoundationServer type on the fly, but the PsObject mechanics make it look like that, which is really slick and useful :)
With this script, I can fetch an instance with " $tfs = get-tfs https://tkbgitvstfat01:8080" (substitute your server name or URL, of course) and then make OM calls easily. Since we're in PowerShell, I can take the output of these calls and do lots of fun filtering and inspection. Here are a few simple examples - hopefully it's clear that this is far easier than having to call tf.exe and do the cut/awk/sed/grep/findstr kinds of work you normally would deal with in a cmd/bash/whatever world.
Note that the actual useful functionality (Version Control, Work Item Tracking, etc.) was always there, of course, the only real thing this script does it make it a little easier to get at it. Also, there are far more useful services offered by TeamFoundationServer than just these 4, but I wanted to keep the example simple, but still useful.
Use VersionControlServer (VCS) to find the top-level folder with the longest name
C:\> $tfs.vcs.GetItems('$/*').Items | sort -desc { $_.serveritem.length } | select -first 1 | fl serveritem,checkindate,changesetid
ServerItem : $/Developer Division Product Scope
CheckinDate : 5/30/2006 1:08:36 PM
ChangesetId : 74756
Use CommonStructureService (CSS) to show all the team projects that have 'VSTS' in the name
C:\> $tfs.css.listallprojects() | ?{ $_.Name -match 'VSTS' } | fl
Uri : vstfs:///Classification/TeamProject/180e1e5d-bbe8-418a-b9a4-152026964fb4
Name : VSTS V2 Plans
Status : WellFormed
Uri : vstfs:///Classification/TeamProject/365f4f53-9e05-4ded-9c21-52e9d9de978a
Name : VSTS Architecture Group
Status : Deleting
Uri : vstfs:///Classification/TeamProject/7c0d0a50-e31a-4bed-8e48-a99bc95def95
Name : VSTS Dogfood
Status : WellFormed
Uri : vstfs:///Classification/TeamProject/76a10abd-b3be-4803-9efc-d2a9d219885a
Name : VSTS Community
Status : WellFormed
Use WIT to check out the links from a work item and who created it when
C:\> $tfs.wit.getworkitem(99000) | fl links,CreatedBy,CreatedDate
Links : {100701, 99473, 95514}
CreatedBy : Doug Mortensen
CreatedDate : 5/22/2006 7:26:09 PM
Use GSS to look up my display name and email address
C:\> $tfs.gss.ReadIdentity('accountname', 'NORTHAMERICA\jmanning', 'none') | fl displayname,mailaddress
DisplayName : James Manning
MailAddress : james.manning@microsoft.com
Use GSS to count the number of direct members in a security group
C:\> $tfs.gss.ReadIdentity('accountname', 'REDMOND\burtonall', 'direct').members.count
6
param(
[string] $serverName = $(throw 'serverName is required')
)
begin
{
# load the required dll
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Client")
$propertiesToAdd = (
('VCS', 'Microsoft.TeamFoundation.VersionControl.Client', 'Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer'),
('WIT', 'Microsoft.TeamFoundation.WorkItemTracking.Client', 'Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemStore'),
('CSS', 'Microsoft.TeamFoundation', 'Microsoft.TeamFoundation.Server.ICommonStructureService'),
('GSS', 'Microsoft.TeamFoundation', 'Microsoft.TeamFoundation.Server.IGroupSecurityService')
)
}
process
{
# fetch the TFS instance, but add some useful properties to make life easier
# Make sure to "promote" it to a psobject now to make later modification easier
[psobject] $tfs = [Microsoft.TeamFoundation.Client.TeamFoundationServerFactory]::GetServer($serverName)
foreach ($entry in $propertiesToAdd) {
$scriptBlock = '
[System.Reflection.Assembly]::LoadWithPartialName("{0}") > $null
$this.GetService([{1}])
' -f $entry[1],$entry[2]
$tfs | add-member scriptproperty $entry[0] $ExecutionContext.InvokeCommand.NewScriptBlock($scriptBlock)
}
return $tfs
}
Comments
Anonymous
September 28, 2006
Great stuff James!
Very useful.Anonymous
September 29, 2006
Along with easier TeamFoundationServer access, one of the things I found myself wanting was easier access...Anonymous
November 17, 2006
Did a little script this week that updates one work item (the "feature") based on summing values in otherAnonymous
January 30, 2007
I was trying to modify a work item today and put in, apparently, too much text into a field I reallyAnonymous
February 13, 2007
[note: all my scripts are now zip'd up together on this page ] This particular script probably isn'tAnonymous
February 21, 2007
One thing that's missing from PowerShell is the ability to import foreign namespaces into the currentAnonymous
March 30, 2009
PingBack from http://get-powershell.com/2008/11/14/powershell-and-tfs-work-items/Anonymous
April 10, 2009
Fun with PowerShell and TFS Work ItemsAnonymous
May 29, 2009
PingBack from http://paidsurveyshub.info/story.php?title=james-manning-s-blog-get-tfs-ps1-example-of-adding-properties-to