Find Orphaned Solution Files

Each day, I am becoming more and more OCD. Tonight I wrote a script that will analyze a Visual Studio csproj file and compare it to the files in the directory. The main goal being an easy way to find orphaned files that might still be in version control. It probably only works on very vanilla projects, but I figured I would share anyways.

# find-orphanedFiles.ps1
#
# Compare files in a Visual Studio project file to the actual files in the directory
#
# Usage:
# .\find-orphanedFiles.ps1 Project\FooBar.csproj
# .\find-orphanedFiles.ps1 Project\FooBar.csproj -exclude "*.csproj","*.csproj.user","svn.ignore"

param
(
    $csProjFile,
    $exclude = ("*.csproj*")
)

function custom-gci($path=(get-location)){
    gci $path -exclude $exclude | 
    %{
        if($_.PSIsContainer -and ($_.name -ne "bin" -and $_.name -ne "obj")){
            custom-gci $_
        }elseif(!($_.PSIsContainer)){
            $_
        }
    } 
}

if(!(test-path $csProjFile)){
    throw "File $csprojFile does not exist"
}

$dir = split-path $csProjFile
$csProjfile = split-path $csProjFile -leaf

push-location $dir

$x = [xml] (gc $csProjFile)

$filesInProject = $x.Project.ItemGroup | 
    foreach {
        if($_.Compile) { 
            $_.Compile
        }elseif($_.None){
            $_.None
        }elseif($_.Content){
            $_.Content
        }elseif($_.EmbeddedResource){
            $_.EmbeddedResource
        }
    } | 
    select -expand include | 
    resolve-path | 
    gi | 
    select -expand fullname

$filesInDir = custom-gci |
    select -expand fullname

compare-object $filesInProject $filesInDir

pop-location