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 }