Check this PowerShell script from this case, which should do what you are looking for. It parses the project file to get the included code files. Then it compares that list to the actual files on disk. The remaining files are your unused/obsolete files.
The script can either delete the unused files from disk or pend them as deletes in TFS.
<#
.SYNOPSIS
Find and process files in a project folder that are not included in the project.
.DESCRIPTION
Find and process files in a project folder that are not included in the project.
Options to delete the files or to add them as pending deletes for TFS. Use TF.exe to pend the deletes and start the check-in process for the files.
This is necessary when trying to delete files that are not currently included in a Visual Studio project.
.PARAMETER Project
The path/name for the project file.
.PARAMETER VsVersion
The Visual Studio version (10, 11, 12). Used to locate the tf.exe file.
.PARAMETER DeleteFromDisk
Just delete the files from disk. No interaction with any source control.
.PARAMETER TfsCheckin
After pending the deletes, open the check-in dialog.
#>
[CmdletBinding()]
param(
[Parameter(Position=0, Mandatory=$true)]
[string]$Project,
[Parameter(Mandatory=$false)]
[ValidateRange(10,12)]
[int] $VsVersion = 12,
[switch]$DeleteFromDisk,
[switch]$TfsCheckin
)
$ErrorActionPreference = "Stop"
$tfPath = "${env:ProgramFiles(X86)}\Microsoft Visual Studio $VsVersion.0\Common7\IDE\TF.exe"
$projectPath = Split-Path $project
if($Project.EndsWith("csproj"))
{
$fileType = "*.cs"
}
else
{
$fileType = "*.vb"
}
$fileType
$projectFiles = Select-String -Path $project -Pattern '<compile' | % { $_.Line -split '\t' } | `
% {$_ -replace "(<Compile Include=|\s|/>|["">])", ""} | % { "{0}\{1}" -f $projectPath, $_ }
Write-Host "Project files:" $projectFiles.Count
$diskFiles = gci -Path $path -Recurse -Filter $fileType | % { $_.FullName}
Write-Host "Disk files:" $diskFiles.Count
$diff = (compare-object $diskFiles $projectFiles -PassThru)
Write-Host "Excluded Files:" $diff.Count
#create a text file for log purposes
$diffFilePath = Join-Path $projectPath "DiffFileList.txt"
$diff | Out-File $diffFilePath -Encoding UTF8
notepad $diffFilePath
#just remove the files from disk
if($DeleteFileOnly)
{
$diff | % { Remove-Item -Path $_ -Force -Verbose}
}
else #TFS options
{
#this will add the files as pending deletes in TFS (awaiting check-in)
$diff | % {
[Array]$arguments = @("delete", "`"$_`"")
& "$tfPath" $arguments
}
if($Checkin)
{
#start the check-in process for the pending deletes
[Array]$arguments = "checkin", "/recursive", "$projectPath"
& $tfPath $arguments
}
}
Also, other community members expend this script and share the scripts at:
@Marc Climent: I used this script to create a more detailed one that includes other types of files and does not use TFS: https://gist.github.com/mcliment/d9008a9288cea9d088af
@mikesigs: I too used this file as well as @MarcCliment's to create yet another PowerShell script that takes a .sln file instead of a single proj file. It deletes all files excluded from all projects in the provided solution: https://gist.github.com/mikesigs/3512dbccc1767d447977#file-deleteexcludedfiles-ps1