PowerShell (2.0, 32-bit) can’t load TFS 2010 snap-in… except when it can

powershelltfs

I have a PowerShell script which interacts with Team Foundation Server. When I run it in the PowerShell console, it works perfectly. This is nice for testing it, but I want to run it by double-clicking on it, or on a batch file or something. I'd even settle for right-clicking on it and selecting "Run with PowerShell".

But when I do that, I get an error. "Run with PowerShell" closes the window too fast to see what the error is. Somebody was really thinking when they designed that, maybe Ballmer was involved. I can also run it in cmd.exe, like so:

PowerShell -File dostufftocheckouts.ps1

When I do that, I get to see an error message, and I'm guessing it might be the same one:

Get-PSSnapin : No Windows PowerShell snap-ins matching the pattern 
'Microsoft.TeamFoundation.PowerShell' were found. Check the pattern and then 
try the command again.

The following code is included in the script before anything else:

if ((Get-PSSnapin -Name  Microsoft.TeamFoundation.PowerShell -ErrorAction SilentlyContinue) -eq $null )
{
    Add-PsSnapin  Microsoft.TeamFoundation.PowerShell -ErrorAction SilentlyContinue
}

When I start a new instance of the interactive PowerShell shell and run the script in that, everything works perfectly.

UPDATE

I get the same error with either of the following PowerShell executables (since I seem to recall the TFS snapin was 32-bit only):

C:\windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe
C:\windows\System32\WindowsPowerShell\v1.0\powershell.exe

In cmd.exe, the following command produces the following output:

c:\ powershell -Command "get-pssnapin -registered | where { $_.Name -eq 'TfsBPAPowerShellSnapIn' }"

Name        : TfsBPAPowerShellSnapIn
PSVersion   : 2.0
Description : This is a PowerShell snap-in that includes Team Foundation Server cmdlets.

So, I've written a very minimal script, joke.ps1:

Add-PsSnapin TfsBPAPowerShellSnapIn

$server = Get-TfsServer tfsserver/DefaultCollection

And I run it:

c:\ powershell -File .\joke.ps1

The term 'Get-TfsServer' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:\Users\jmcnamara\PowerShell\broken.ps1:3 char:24
+ $server = Get-TfsServer <<<<  gearys/DefaultCollection
    + CategoryInfo          : ObjectNotFound: (Get-TfsServer:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Add-PsSnapin doesn't give me an error. But adding the snap-in doesn't make any of the snap-in's cmdlets visible to the rest of the script.

Allegedly, Add-PsSnapin adds a snap-in to the current session:

The Add-PSSnapin cmdlet adds registered Windows PowerShell snap-ins to
the current session. After the snap-ins are added, you can use the
cmdlets and providers that the snap-ins support in the current
session.

"You" can, eh? "You" who? Yeah, sure you can.

But how?

Best Answer

My question turns out to have been almost a duplicate of Is there no TFS Snapin for PowerShell on x64?, TFS Power Tools 2008 Powershell Snapin won't run in on 64-bit in Windows 2008 R2, and probably others.

I don't understand why different snap-ins were listed as "registered" the 32-bit PowerShell console vs running 32-bit powershell.exe (the WOW64 one is 32-bit) in cmd.exe, but whatever.

The answer appears to be here: The installer doesn't properly add the TFS snap-in to the Registry. The link shows you how to set it up to be usable from 64-bit PowerShell, but it appears that you need to do the same, at a different key, to make it usable from 32-bit PowerShell outside of the PowerShell console. So you paste the following into tfskludge.reg, double click it, and it should make the snap-in available in both PowerShells:

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\PowerShellSnapIns\Microsoft.TeamFoundation.PowerShell]
"PowerShellVersion"="2.0"
"Vendor"="Microsoft Corporation"
"Description"="This is a PowerShell snap-in that includes the Team Foundation Server cmdlets."
"VendorIndirect"="Microsoft.TeamFoundation.PowerShell,Microsoft"
"DescriptionIndirect"="Microsoft.TeamFoundation.PowerShell,This is a PowerShell snap-in that includes the Team Foundation Server cmdlets."
"Version"="10.0.0.0"
"ApplicationBase"="C:\\Program Files (x86)\\Microsoft Team Foundation Server 2010 Power Tools"
"AssemblyName"="Microsoft.TeamFoundation.PowerTools.PowerShell, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
"ModuleName"="C:\\Program Files (x86)\\Microsoft Team Foundation Server 2010 Power Tools\\Microsoft.TeamFoundation.PowerTools.PowerShell.dll"
"CustomPSSnapInType"="Microsoft.TeamFoundation.PowerTools.PowerShell.TFPSSnapIn"

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\PowerShell\1\PowerShellSnapIns\Microsoft.TeamFoundation.PowerShell]
"PowerShellVersion"="2.0"
"Vendor"="Microsoft Corporation"
"Description"="This is a PowerShell snap-in that includes the Team Foundation Server cmdlets."
"VendorIndirect"="Microsoft.TeamFoundation.PowerShell,Microsoft"
"DescriptionIndirect"="Microsoft.TeamFoundation.PowerShell,This is a PowerShell snap-in that includes the Team Foundation Server cmdlets."
"Version"="10.0.0.0"
"ApplicationBase"="C:\\Program Files (x86)\\Microsoft Team Foundation Server 2010 Power Tools"
"AssemblyName"="Microsoft.TeamFoundation.PowerTools.PowerShell, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
"ModuleName"="C:\\Program Files (x86)\\Microsoft Team Foundation Server 2010 Power Tools\\Microsoft.TeamFoundation.PowerTools.PowerShell.dll"
"CustomPSSnapInType"="Microsoft.TeamFoundation.PowerTools.PowerShell.TFPSSnapIn"
Related Topic