ps/Modules/Alkami.PowerShell.Choco/Public/Compare-InstalledChocoPackages.ps1

127 lines
4.7 KiB
PowerShell
Raw Normal View History

2023-05-30 22:51:22 -07:00
function Compare-InstalledChocoPackages {
<#
.SYNOPSIS
This function compares installed choco packages between servers
.DESCRIPTION
Invoke Compare-InstalledChocoPackages -SourceServer foo.fh.local -targetServer bar.fh.local
The function exposes these properties describing comparisons:
.fullyMatchedPackages
.missingFromSource
.missingFromTarget
.packageVersionMismatch
.packageVersionMismatchDetails
.EXAMPLE
Compare-InstalledChocoPackages -SourceServer foo.fh.local -targetServer bar.fh.local
Compare the installed choco packages and determines similarities or differences
.INPUTS
-SourceServer foo.fh.local -targetServer bar.fh.local
.OUTPUTS
.fullyMatchedPackages
.missingFromSource
.missingFromTarget
.packageVersionMismatch
.packageVersionMismatchDetails
#>
[CmdletBinding()]
param (
$SourceServer = ([System.Net.Dns]::GetHostByName(($env:computerName))).Hostname,
$TargetServer
)
$logLead = Get-LogLeadName
$providerStopWatch = [System.Diagnostics.StopWatch]::StartNew()
# go get package list
$serversToQuery = @($SourceServer, $TargetServer)
$results = Get-RemoteInstalledChocoPackages -serversToQuery $serversToQuery
# assign first result to source and second to target. order is based on index in $sessions
foreach ($result in $results) {
if ($result.pscomputername -eq $serversToQuery[0]) {
$sourcePackages = ($result[$serversToQuery[0]])
}
if ($result.pscomputername -eq $serversToQuery[1]) {
$targetPackages = ($result[$serversToQuery[1]])
}
}
# select packages that match in both name and version
$fullyMatchedPackages = @()
foreach ($sourcepackage in $sourcePackages) {
if ($targetPackages.contains($sourcepackage)) {
$fullyMatchedPackages += $sourcepackage
}
}
Write-Verbose "$logLead : Packages matching between $SourceServer & $TargetServer"
# remove the versions from packages to make use of .contains method
$targetPackageNames = @()
foreach ($targetPackage in $targetPackages) {
$targetPackageNames += $targetPackage.Split('|')[0]
}
# find packages entirely missing from target
$missingFromTarget = @()
foreach ($sourcepackage in $sourcePackages) {
if (!$targetPackageNames.contains($sourcepackage.Split('|')[0])) {
$missingFromTarget += $sourcepackage
}
}
Write-Verbose "$logLead : Packages not installed on target machine $TargetServer"
# find packages entirely missing from source but exist on target
$sourcePackageNames = @()
foreach ($sourcePackage in $sourcePackages) {
$sourcePackageNames += $sourcePackage.Split('|')[0]
}
$missingFromSource = @()
foreach ($targetPackage in $targetPackages) {
if (!$sourcePackageNames.contains($targetPackage.Split('|')[0])) {
$missingFromSource += $targetPackage
}
}
Write-Verbose "$logLead : Packages not installed on source machine $SourceServer"
# find packages that exist on source and target but may be version mismatched
# recording both package name as well as detailed diff source -> target
$nameMatchedPackages = @()
$packageVersionMismatchDetails = @()
$packageVersionMismatch = @()
foreach ($sourcePackage in $sourcePackages) {
if ($targetPackageNames.contains($sourcepackage.Split('|')[0])) {
$nameMatchedPackages += $sourcePackage
}
}
foreach ($nameMatchedPackage in $nameMatchedPackages) {
if (!$targetPackages.Contains($nameMatchedPackage)) {
$packageVersionMismatch += $nameMatchedPackage.Split('|')[0]
$packageVersionMismatchDetails += ( $nameMatchedPackage + " -> " + ($targetPackages -like ( "$($nameMatchedPackage.Split('|')[0])|*" ) ) )
}
}
$fullyMatchedPackages = Format-ParseChocoPackages $fullyMatchedPackages
$missingFromSource = Format-ParseChocoPackages $missingFromSource
$missingFromTarget = Format-ParseChocoPackages $missingFromTarget
$packageVersionMismatch = Format-ParseChocoPackages $packageVersionMismatch
# organize comparisons done above into dict
$comparedPackageLists = @{ }
$comparedPackageLists += @{ fullyMatchedPackages = $fullyMatchedPackages }
$comparedPackageLists += @{ missingFromSource = $missingFromSource }
$comparedPackageLists += @{ missingFromTarget = $missingFromTarget }
$comparedPackageLists += @{ packageVersionMismatch = $packageVersionMismatch }
$comparedPackageLists += @{ packageVersionMismatchDetails = $packageVersionMismatchDetails }
Write-Verbose "$logLead : [$($providerStopWatch.Elapsed)] : comparisons complete"
$providerStopWatch.Stop()
return $comparedPackageLists
}