Quite simply, I’m trying to get a list of workspaces by calling the QueryWorkspaces method of the VersionControlServer class in powershell. I’m passing null across to the parameters and according to the documentation it should give me a list of workspaces.
If I name the workspace it works fine and returns a single workspace but the documentation says a null name should give all the workspaces.
function Get-Workspace
{
param
(
[Parameter(Mandatory=$true)]
[string]$TeamProjectCollection,
[string]$Owner,
[string]$Computer,
[parameter(ValueFromPipeline=$true)]
[string]$Name
)
begin
{
[Microsoft.TeamFoundation.Client.TfsTeamProjectCollection]$tfsTeamProjectCollection = [Microsoft.TeamFoundation.Client.TfsTeamProjectCollectionFactory]::GetTeamProjectCollection($TeamProjectCollection)
[Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer]$versionControlServer = $tfsTeamProjectCollection.GetService([Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer])
}
process
{
Write-Output $versionControlServer.QueryWorkspaces($Name, $Owner, $Computer)
}
}
I am running with Project Collection Administrator rights.
The problem appears to be PowerShell does not pass null as null when the .net class is expecting string. Somewhere in the PowerShell layer the null was translated to an empty string. This prevented the code path which returns all the workspaces from executing. Instead it was trying to match a workspace called “”.
The details of the issue are on a Microsoft Connect article which reports the issue to be fixed in PowerShell 3.0.
Knowing what the problem and with hints on how to fix it I started down the Reflection route. However this got more complicated because the QueryWorkspaces method is overloaded so a simple call to GetType threw an exception. Attempts to pass the array of types into the GetType call failed because PowerShell passed it as an array of Object instead of an array of Type. Thus it had to be done long hand …