Monday, December 21, 2015

Using Powershell to Manipulate TFS Get Latest, Check In, and Merge

In our environment, changes made in the Test branch have to travel through the Main branch and into the Release branch to be deployed into production. Sometimes changes need to move through quickly without regard to other changes, especially in an environment where there may be a single coder. Note: the following code will merge all checked in code regardless of who checked it in. Be careful in multi-coder environments.

While PowerShell is being used to write this process, many of the commands below are actual command line directives. These older, mature commands have more features than the native PowerShell TFS commands and are documented more extensively.

The first line in the PowerShell script should be the Set-Location command. This will set the scripts working location to the location of the TFS workspace. In my instance it is “C:\Development”.

set-location c:\development

Next, the comment that I want attached to the “Check in” of the changed files to each branch.

$Comment = """123456"""

In order to keep from typing the full path of the TF.exe on each Merge and Checkin, a variable is used to hold the file location.

$CommandLocation = "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\TF.exe "

Since there are multiple branches that need to be merged and checked out, I’m hard coding the GET command for each branch. Basically, it gets the latest version of each file (not including your changes) from each branch. This is done to keep merge confilcts to a minimum.

$GetDevCommand = " get $/<TeamProjectName>/<DevBranch>/<Directory> /recursive /force "
$GetMainCommand = " get $/<TeamProjectName>/<MainBranch>/<Directory> /recursive /force "
$GetReleaseCommand = " get $/<TeamProjectName>/<ReleaseBranch>/<Directory> /recursive /force "

<TeamProjectName> is the name of the Team Project you are working in under the Team Collection.

<xBranch> is either Dev, Main, or Release in this instance.

<Directory> is the name of a directory (and possible subdirectories) below the branch. This can be as granular as needed in that <directory/subdirectory/subdirectory> can be specified. The /recursive flag recurses through all subdirectories under the <Directory> and /force causes them to be overwritten.

The same hard coding occurs in the Merge and Checkin commands below

$MergeToMain = " merge $/<TeamProjectName>/<DevBranch>/<Directory> $/<TeamProjectName>/<MainBranch>/<Directory>/recursive  /version:T"
$CheckinToMain = " checkin /comment:$comment /recursive /noprompt ""c:\development\<TeamProjectName>/<MainBranch>/<Directory>"""

$MergeToRelease = " merge $/<TeamProjectName>/<MainBranch>/<Directory> $/<TeamProjectName>/<ReleaseBranch>/<Directory> /recursive  /version:T"
$CheckinToRelease = " checkin /comment:$comment /recursive /noprompt ""c:\development\<TeamProjectName>/<ReleaseBranch>/<Directory>"""

Once you enter the TeamProjectName, Branch, and Directory, the work of moving files in TFS can begin. This is accomplished with the Start-Process command.

By using the –wait and –RedirectStandardOutput flags, each command executes sequentially and redirects the output from each command to its own txt file for troubleshooting later.

#Get Lastest Files From Sources Control
Start-Process "$CommandLocation" "$GetDevCommand" -wait -RedirectStandardOutput c:\temp\Get-TFS.txt
Start-Process "$CommandLocation" "$GetMainCommand" -wait -RedirectStandardOutput c:\temp\Get-TFS.txt
Start-Process "$CommandLocation" "$GetReleaseCommand" -wait -RedirectStandardOutput c:\temp\Get-TFS.txt

#Merge and Checkin to Main
Start-Process "$CommandLocation" "$MergeToMain" -nonewwindow -wait -RedirectStandardOutput c:\temp\MergePreProd-TFS.txt
Start-Process "$CommandLocation" "$CheckinToMain" -nonewwindow -wait -RedirectStandardOutput c:\temp\CheckinPreProd-TFS.txt

#Merge and Checkin to Release
Start-Process "$CommandLocation" "$MergeToRelease" -nonewwindow -wait -RedirectStandardOutput c:\temp\MergeProd-TFS.txt
Start-Process "$CommandLocation" "$CheckinToRelease" -nonewwindow -wait -RedirectStandardOutput c:\temp\CheckinProd-TFS.txt

In this instance the output for each command is directed to a file the in the C:\Temp directory for viewing later.



Thursday, December 17, 2015

SQL Reporting Services 2014 Save, Refresh, and Print Buttons on Separate Lines in IE

In SSRS 2014 there is a bug in rendering pages in Internet Explorer where the Save, Refresh, and Print buttons will all show on different lines in IE.

Below is a screenshot of an report rendering on an unpatched server.

By moving to build 12.00.4422 (CU2 for SQL Server 2014 Service Pack 1) the problem is corrected.


Thursday, December 3, 2015

Quickly Flip Database to Mirroring Partner

While Database Mirroring is certainly not a new technology, I’ve only started using it for HA on some of our older SQL instances. In doing so, I’ve found the need to quickly (and manually) flip the databases using mirroring to the mirrored instance. While you can accomplish this slowly using the GUI, if you have more than 1 or 2 databases to flip it can get old very quickly.

With that in mind, I’ve created a script where the output of the script can be used to quickly flip the databases that meet certain criteria. In this case, any databases that are currently SYNCHRONIZED and are the PRINCIPAL in the mirroring session will be selected.

   1: SELECT 'ALTER DATABASE [' + DB_NAME(database_mirroring.database_id) + '] SET PARTNER FAILOVER' AS 'Script'
   2:        ,DB_NAME(database_mirroring.database_id) as 'DB Name'
   3:        ,database_mirroring.mirroring_partner_name AS 'Mirroring Failover Partner'
   4: FROM    sys.database_mirroring
   5:  WHERE database_mirroring.mirroring_state_desc = 'SYNCHRONIZED'
   6:    AND database_mirroring.mirroring_role_desc = 'PRINCIPAL'

The meat of the script is in column 1. By running the commands generated in column 1 in another window with the same connection, you can quickly flip the databases to the mirrored servers. Columns 2 and 3 are there for extra information, namely the name of the database to be flipped and the name of the mirrored server that will serve primary instance of the database.