Using Powershell to remind users of checked out files from TFS

With any source control system it is possible to leave files checked out. This is especially true if your IDE does the checking out behind the scenes. This is made worse still by the fact you can have a number of workspaces on the same PC in TFS. It is too easy to forget.

It is therefore a good idea to check from time to time that the files you have checked out are the ones you think you have. There is nothing worse than trying to work on a project to find a key file is checked out or locked to another user or PC.

To this end I have written the following Powershell script to check for the files checked out by a team of developers. In this version you have to list the users by name, but I am sure it could be extended to pickup users for an AD or TFS Group

# To run this script without signing need to first run
#     Set-ExecutionPolicy  Unrestricted
# If you want run it from a timer you will need to sign it
# Then run it using
#    .TFstatus.ps1

function CheckOutTFSFileForUser(
    [string]$user,
    [string]$domain,
    [string]$server,
    [string]$from     )
{

get the open file list,

    # we put a newline at the start of the line,
    # used an ASCii code as 'n did not seem to work
    [char]10 + "Checking checked out file for " + $user
    $filelist = &"C:Program FilesMicrosoft Visual Studio 9.0Common7IDEtf.exe" status /user:$user /s:https://vsts.domain.com:8443

    # we have the results as an array of rows
    # so insert some line feeds    foreach ($s in $filelist) { $emailbody = $emailbody + [char]10 + $s }
    # note the strange concatenation for the email to field, not a + as I suspected being new to Powershell
    $title = "Files currently have checked out to " + $user + " in TFS"
    if ($user -eq "*" )
    {
        # if they have asked for all user email send to the admin/from account
        $to = $from
    } else
    {
        $to = $user + $domain
    }
    SendEmail $to  $from $server  $title  $emailbody
}

function SendEmail(
    [string]$to,
    [string]$from,
    [string]$server,
    [string]$title,
    [string]$body    )
{

    # send the email
    $SmtpClient = new-object system.net.mail.smtpClient
    $SmtpClient.host = $server
    $SMTPClient.Send($from,$to,$title,$body)
    "Email sent to " + $to
}

# the main body
$domain = "@domain.com"
$emailServer = "mail.domain.com"
$from = "admin@domain.com "

# the list of users to check, the * means all
$users = ("*","anne","bill","chris")
# loop through the list of users
foreach ($u in $users) { CheckOutTFSFileForUser $u $domain $emailServer $from }