Compare-Packages.psm1

function GetName($item){
    $val = $item.Attributes["id"].Value
    if($null -ne $val){ return $val    }
    return $item.Attributes["Include"].Value
}
function GetVersion($item){
    $val = $item.Attributes["allowedVersions"].Value
    if($null -ne $val) { return $val }
    $val = $item.Attributes["version"].Value
    if($null -ne $val) { return $val }
    return $item.Attributes["Version"].Value 
}
function FindItem($elements, $name, $version) {
    foreach($e in $elements){
        $n = GetName $e
        $v = GetVersion $e
        if(
            ($n -eq $name) -and
            ($v -eq $version)
        ) {
            return $false
        }
    }
    return $true;
}
<#
.Synopsis
   Automatic Publish Tool (APT)
.DESCRIPTION
   Compare packages for project
.EXAMPLE
   Compare-Packages D:\Projects\src
.NOTES
   Author: Imrich Szolik
#>

function Compare-Packages
{
    [CmdletBinding()]
    [Alias()]
    Param(
        # Solution directory
        [string]
        [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$false, HelpMessage="Project src file.")]
        $Solution
    )
    Begin{
    }
    Process{
        $projects = Get-ChildItem -Recurse -Path $Solution -Filter *.csproj
        foreach($project in $projects){
            $name = $project.Name
            $prj = $project.FullName
            $nuget = $prj -replace "csproj", "nuspec"
            $package = Join-Path $project.Directory 'packages.config'
            
            $referenceItems = $null
            if( Test-Path -Path $nuget -PathType Leaf) {
                $type = $false
                #net48
                if(Test-Path -Path $package -PathType Leaf ){
                    $referenceItems = Select-Xml -Path $package -XPath //packages/package | ForEach-Object { $_.Node }
                    $type = $false
                }
                #net core
                else{
                    $type=$true
                    $content = (Get-Content $prj) -as [Xml]
                    $referenceItems = Select-Xml -Xml $content -XPath //Project/ItemGroup/PackageReference | ForEach-Object { $_.Node }
                }

                #nuget items
                $nugetReference = Select-Xml -Path $nuget -XPath //package/metadata/dependencies/group/dependency | ForEach-Object { $_.Node }

                #print
                $print = $true

                #processing
                foreach($pr in $referenceItems){
                    $n = GetName $pr
                    $v = GetVersion $pr

                    if (FindItem $nugetReference $n $v){
                        if($print){
                            Write-Warning "===== $name (update dependencies/group/) ======"
                            $print = $false
                        }
                        Write-Warning "<dependency id=""$n"" version=""$v"" exclude=""Build,Analyzers"" />"
                    }
                }

                foreach($pr in $nugetReference){
                    $n = GetName $pr
                    $v = GetVersion $pr

                    if (FindItem $referenceItems $n $v){
                        if($print){
                            Write-Verbose "===== $name (update dependencies/group/ or packages) ======"
                            $print = $false
                        }

                        if($type){
                            Write-Verbose "<PackageReference Include=""$n"" Version=""$v"" />"
                        }
                        else{
                            Write-Verbose "<package id=""$n"" version=""$v"" targetFramework=""net48"" />"
                        }
                    }
                }
            }
        }
    }
    End{
    }
}
Export-ModuleMember -Function Compare-Packages
# SIG # Begin signature block
# MIIIEwYJKoZIhvcNAQcCoIIIBDCCCAACAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBVAu/SrlnOwGSt
# MdbpPhwpRmHBvymY8MNKwvcLfQS5JaCCBQ8wggULMIIC86ADAgECAgIApTANBgkq
# 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
# AgELMQ4wDAYKKwYBBAGCNwIBFjAvBgkqhkiG9w0BCQQxIgQgVFxJDL22hu3yQ3vV
# PX4pl8fivPutU90z5fVNNDbzzGMwDQYJKoZIhvcNAQEBBQAEggEAofg046ypepBz
# 20o0N+qcB6UoLOQ2VQlws+MiIFagt2xXnMeIf1xWaQFt3W3MHSx0dxOrK2lGyBWD
# wQ7eUEnwUz1cFqPnztNIB9hnbS+f8t1RHRvrup2kscLDe9RYbTY/qcyEM5ZO37MB
# Wg0xw87cN/V7TGBZje3apMSb0AXNQHZoKwm0eAFlq7c3VlpHCMCh9EYfHoF1iTMj
# euJG1hSdHmQyTxs1Qi01kvsAICk8ESemq5GT95MRGPYCRSSxzbgpGiRWI0WF+RPV
# ZUAcyDIL7uGxCPZPnllPtjEfwErtQ2slauZ4C0MmUdo6LHIUpukt1XrK4KTV5l6t
# SpVXOquCBg==
# SIG # End signature block