Get-VersionInfo.psm1

# Get AssemblyInfo.cs VersionInfo
function Get-Csharp-Project-AssemblyInfo([string] $projectFile){
    try{
        #vars
        $majorVersion = "1"
        $minorVersion = "0"
        $buildNumber = "0"
        
        #validate assemblyFileName
        $dir = Split-Path $projectFile -Parent
        $assemblyFileName =  Join-Path -Path $dir  -ChildPath "Properties" | Join-Path -ChildPath "Assemblyinfo.cs" 
        #
        if( !(Test-Path $assemblyFileName -PathType Leaf ) ) {
            $msg = "Assembly info is missing [$assemblyFileName]."
            
            Write-Warning $msg
            throw $msg
        }
        # find version info
        $versionPattern='^\[assembly: AssemblyVersion\(\s*"(?<major>[1-9]+[0-9]*)\.(?<minor>[0-9]+)\.(?<build>[0-9]+)(\.[0-9]+)?"\s*\)\]'
        (Get-Content $assemblyFileName) | Foreach-Object { if($_ -match $versionPattern) { $majorVersion=$matches["major"]; $minorVersion=$matches["minor"]; $buildNumber=$matches["build"] } }
        return "$majorVersion.$minorVersion.$buildNumber"
    }
    catch{
        Write-Warning "Cann't set assembly info [$projectFile]."
        return $null
    }
}
# Get c# project VersionInfo
function Get-Csharp-Project-VersionInfo([string] $projectFile, $version){
    try{
        #vars
        $majorVersion = "1"
        $minorVersion = "0"
        $buildNumber = "0"
        
        # find version info
        $versionPattern='<Version>((?<major>[1-9]+[0-9]*)\.(?<minor>[0-9]+)\.(?<build>[0-9]+)(\.[0-9]+)?)</Version>'
        (Get-Content $projectFile) | Foreach-Object { if($_ -match $versionPattern) { $majorVersion=$matches["major"]; $minorVersion=$matches["minor"]; $buildNumber=$matches["build"] } }
        return "$majorVersion.$minorVersion.$buildNumber"
    }
    catch{
        Write-Warning "Cann't set version info [$projectFile]."
        return $null
    }
}
# Process c# proj
function Get-Csharp-Project([string] $projectFile){
    #
    $textVersion = $null
    #
    try{
        [xml] $project = Get-Content $projectFile
        if ($project.Project.Sdk.Length -eq 0){
            Write-Verbose "Using AssemblyInfo.cs [$(Split-Path $projectFile -Leaf)]"
            $textVersion = Get-Csharp-Project-AssemblyInfo $projectFile 
        }
        else{
            $textVersion = Get-Csharp-Project-VersionInfo $projectFile
        }
        if ( $null -ne $textVersion){
            return @{ Project=[System.IO.Path]::GetFileNameWithoutExtension($projectFile); Version = $textVersion }
        }
    }
    catch{
        Write-Warning "Not valid project file [$projectFile]."
        return $null
    }
}
# Process sln file
function Get-VisualStudio-Solution([string] $slnFile){
    try{
        # get all projects
        $projects = Get-Content $slnFile |
                     Where-Object { $_ -match "^Project" } | 
                     ForEach-Object { $_ -match ".*=(.*)$" | out-null ; $matches[1] } | 
                     ForEach-Object { $_.Split(",")[1].Trim().Trim('"') } |
                     Where-Object { $_ -match ".*\.csproj$" }
        
        #
        $dir = Split-Path $slnFile -Parent

        $version = @{}
        #process
        foreach($p in $projects){
            Write-Verbose "Processing project: $p"
            $prj =  Join-Path -Path $dir -ChildPath $p
            $tmp = Get-Csharp-Project $prj
            if($null -ne $tmp){
                foreach($k in $tmp){
                    if(-not $version.ContainsKey($k.Project)){
                        $version.Add($k.Project, $k.Version)  
                    }
                }
            }
        }
        return $version
    }
    catch{
        throw "Not valid solution file [$slnFile]."
    }
}
<#
.Synopsis
   Automatic Version Tool (AVT)
.DESCRIPTION
  Get VersionInfo
.EXAMPLE
   Get-VersionInfo D:\Projects\project.csproj
.EXAMPLE
   Get-VersionInfo D:\Projects\project.sln
#>

function Get-VersionInfo
{
    [CmdletBinding()]
    [Alias()]
    [OutputType([hashtable])]
    Param
    (
        # Project/Solution file (csproj,sln)
        [string]
        [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$false, HelpMessage="Project file.")]
        $File
    )
    Begin
    {
        if( !(Test-Path $File -PathType Leaf ) ) {
            throw "File is missing [$File]."
        }
    }
    Process
    {
        if ($File -like '*.csproj') {
            $tmp = Get-Csharp-Project $File
            return @{ $tmp.Project=$tmp.Version }
        }
        elseif ($File -like '*.sln') {
            return Get-VisualStudio-Solution $File 
        }
        else{
            throw "Not supported [$File]."
        }
    }
    End
    {
    }
}
Export-ModuleMember -Function Get-VersionInfo
# SIG # Begin signature block
# MIIIEwYJKoZIhvcNAQcCoIIIBDCCCAACAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDJDqZkv1U3HOMx
# dDLkof5Wa8Lc3j48E0SL+X36erJ+VqCCBQ8wggULMIIC86ADAgECAgIApTANBgkq
# hkiG9w0BAQsFADCBoDELMAkGA1UEBhMCU0sxETAPBgNVBAgTCFNsb3Zha2lhMRMw
# EQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpMb210ZWMuY29tMSswKQYDVQQD
# EyJMb210ZWMuY29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MScwJQYJKoZIhvcN
# AQkBFhhJbXJpY2guU3pvbGlrQGxvbXRlYy5jb20wHhcNMTkwMzI2MTUwNDQzWhcN
# MzAwMTAxMDAwMDAwWjCBkzELMAkGA1UEBhMCU0sxETAPBgNVBAgTCFNsb3Zha2lh
# MRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpMb210ZWMuY29tMR4wHAYD
# VQQDExVMb210ZWMuY29tIFBvd2Vyc2hlbGwxJzAlBgkqhkiG9w0BCQEWGEltcmlj
# aC5Tem9saWtAbG9tdGVjLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
# ggEBAL4n4nCHbkdrf09IHNFQ2P/z6I43GKScsFJOQHUMkRD3ALoUFL/URC9sW2fY
# rqG5VkFAKhnM0VxeiICR53cAshNShjFf58PhaS973jtCoJcaugIVBVoFIuQ+gnNY
# Jp2VdBbIPKMW4JjjZOxBEkHpMWmfitXKWGKeU68Qcn3oI6PO+YSztfXLe1NU+1GI
# O3fA7E0vHVPUf/qWZXMYU5ElLQVm9AXbfX79mTgl76A57+OC6j+Aehkd2OPfUl4w
# snox3fOyUAUA8iojeWh97PpXd/s+RkuxWdgsC4YSWDUjhZSzBkml9uerYqo9a+XA
# b39dvkpK9TPl3q5HNBQMkCfp8bkCAwEAAaNaMFgwCQYDVR0TBAIwADALBgNVHQ8E
# BAMCB4AwKwYDVR0lBCQwIgYIKwYBBQUHAwMGCisGAQQBgjcCARUGCisGAQQBgjcC
# ARYwEQYJYIZIAYb4QgEBBAQDAgSwMA0GCSqGSIb3DQEBCwUAA4ICAQAJJapv9skY
# jh5HTsJnqDdtqh7YOOXuA8g+DKBj+5gDEZE5V9VhAFVp8UJ9RoITGGIRTVId0lqc
# LJiVSTHx305VW9aID8vo77kfrTyXvPXNIsTtHnPkkwH47+CoiY3IpPQLjUA/Q6Qd
# qwINvvwom7/Wc+OoIqlPdJH5DbBrIy85dr6M/Lm3Rw2BolcTRwXTB3xAhweth78B
# P6pbcAd32FdymkRopLIihuNs7g7ZR/Q/5803G+OiQIMRGyTvaQ+aQjJgFpkzp7NI
# whzougfCOV47Sc89jEpUqw16i2UFfz2ywOlWUyYtue1S1PjM1ljgJfRo+e0wUnFp
# gFQzXGF1bTYVaQ4e3nJleADfvqeXoH2AYeBTbz9BcogkkfURAC3iiob1bNs5jE1C
# brEDCw6m/03k0oOmm3xQksXyAhBYuUkRwu9jd4y3FwZ/syDGLz3b6cY8o1YyINOO
# A3B2r92shNt0rWhJu3v+qcIVmFQ0aKlhNNRoiVlQgJ7NgO0UV+vU2lgiscpUSxEt
# xKN+450r49su06NA6zsyn3CELUmVkPyjx5fyizwt9KxVuYOUSEb32Y7QCffHJ1qt
# F6SuQrKbgb/24y7cCDW6PDVRvPOySUlKu9sPykICDjvzXBvjYEILM7AmtYCIBGQg
# imBsQvTEoXJXiwAOi1XNz3LxcjQHQ/ZM4zGCAlowggJWAgEBMIGnMIGgMQswCQYD
# VQQGEwJTSzERMA8GA1UECBMIU2xvdmFraWExEzARBgNVBAcTCkJyYXRpc2xhdmEx
# EzARBgNVBAoTCkxvbXRlYy5jb20xKzApBgNVBAMTIkxvbXRlYy5jb20gQ2VydGlm
# aWNhdGlvbiBBdXRob3JpdHkxJzAlBgkqhkiG9w0BCQEWGEltcmljaC5Tem9saWtA
# bG9tdGVjLmNvbQICAKUwDQYJYIZIAWUDBAIBBQCggYQwGAYKKwYBBAGCNwIBDDEK
# MAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3
# AgELMQ4wDAYKKwYBBAGCNwIBFjAvBgkqhkiG9w0BCQQxIgQge622GY8UXIjy29lZ
# xrdup2HwJsJ33NO3Qk5wK0PH93wwDQYJKoZIhvcNAQEBBQAEggEAht+1GyRzDGhp
# 9fiSGNs/ZYDtxWsN0LvIK+QNUl+W7RInLAe3eIueFzMcBJ3D5U3ylXee7+x6uQbg
# Ihoq1ASuC2AO1zbiEm7FZasaw/vIf3xxH+R621lke4t/CTxvaXep/fSMXhZoEhCk
# zfaIFD2KnU/kY8lyx5N6qQWpg9y2HbRu4sMmZkRqC2obLS9TNTpZuFhS7Bq3yUVK
# hV9mW89CnoYU6NFPxb/GWNhNeiPzsXxorBlj3zcjLCVQTA0a6m9B8U9592kx6Zq4
# dmPmDC2Zp33yJyRrwa0vQgpYdUuhKG08wt1TgCXuXiKzSJ+oPl/sjtY6DL/Mtk+J
# tBSaMqjSAA==
# SIG # End signature block