Today I was playing with TFS Power Tools to check in some PowerShell scripts where I ran into a strange error. Obviously I wanted to use the PowerShell Cmdlets for that you can select via the ‘Custom’ option in the ‘Power Tools’ installer … For a quick intro on TFS via PowerShell you can have a look at PowerShell and TFS: The Basics and Beyond.
So after some fiddling when I had my script ready and working from the command line, I noticed that the script would not run as it would not find the the #required PSSnapin ‘Microsoft.TeamFoundation.PowerShell’:
The script 'Update-TfsBuild.ps1' cannot be run because the following 1> snap-ins that are specified by the "#requires" statements of the script are 1> missing: Microsoft.TeamFoundation.PowerShell.
It took me a restart that did not do either and a 30 minutes to realise that ‘Visual Studio 2013’ was a 32bit/x86 process and the TFS PSSnapin was only available as 64bit. So I had to change the way on how I would invoke my PowerShell script in the Post-Build Event to call the 64bit version of PowerShell (which is done via the SysNative link within the Windows directory):
C:\Windows\Sysnative\WindowsPowerShell\v1.0\powershell.exe
-NoLogo -NonInteractive
-Command "&'C:\scripts\Update-TfsBuild.ps1' -ProjectDir '$(ProjectDir)'
-TargetPath '$(TargetPath)' -TargetFileName '$(TargetFileName)'"
From then on my script would be invoked correctly and I was able to upload the file I wanted. In case you are interested here is the quick hack that uploads a file to TFS (Online):
Param (
[Parameter(Mandatory = $false)]
[string] $TFSServer = 'https://www.example.com.visualstudio.com/defaultcollection'
,
[Parameter(Mandatory = $false)]
[string] $Workspace = 'MyWorkspace'
,
[Parameter(Mandatory = $false)]
[string] $Owner = "Edgar Schnittenfittich"
,
[Parameter(Mandatory = $false)]
[PSCredential] $Credential = (Import-CliXml C:\scripts\Credential-tfsfch.xml)
,
[Parameter(Mandatory = $true, Position = 0)]
[string] $ProjectDir
,
[Parameter(Mandatory = $true, Position = 1)]
[string] $TargetPath
,
[Parameter(Mandatory = $true, Position = 2)]
[string] $TargetFileName
)
[string] $fn = $MyInvocation.MyCommand.Name;
Write-Host ("ProjectDir: '{0}'" -f $ProjectDir);
Write-Host ("TargetPath: '{0}'" -f $TargetPath);
Write-Host ("TargetFileName: '{0}'" -f $TargetFileName);
Write-Host ("PROCESSOR_ARCHITECTURE: '{0}'" -f $ENV:PROCESSOR_ARCHITECTURE);
Add-PSSnapin Microsoft.TeamFoundation.PowerShell;
Write-Host ("Login to TFS '{0}' ..." -f $TfsServer);
$tfs = Get-TfsServer $TFSServer -Credential $Credential;
Write-Host ("Getting workspace '{0}' ..." -f $Workspace);
$tfws = Get-TfsWorkspace -Server $tfs -Owner $Owner -Name $Workspace
CD (Join-Path -Path $ProjectDir -ChildPath "someChildDir");
Copy-Item $TargetPath $PWD -Force
Write-Host ("Adding '{0}' ..." -f $TargetFileName);
$tfspc = Add-TfsPendingChange -Edit $TargetFileName
$cs = New-TfsChangeset -Item $tfspc -Comment "POST BUILD: UPDATE comment";
$cs | Out-String
Write-Host ("ChangeSet {0}: Checked in '{1}'." -f $cs.ChangesetId, $TargetFileName)
Write-Host "Finished POST-BUILD"
One strange thing I was not able to solve was the fact that I could not use ‘#Required’ in the script file to load the PSSanpi, but instead I had to load it manually. So anyone who has a hint on that is welcome to give feedback …

1 Comment »