A class that implements IComparable
and System.IEquatable
. Thanks to Chris Dent for the inspiration (DnsRecordType.ps1) and the StackOverflow community question How to compare multiple object values against each other and using mathematical operators in Powershell Overriding Assignment and Comparison operators (from JFFail gist. Mathematical operators are not included in the example below, but linked here for future reference.
Assuming the current state contain version 1.0.0 and the minimum required version is 1.0.1-preview1.
$currentStateResource = [PSResourceObject] @{
Name = 'MyModule'
Version = '1.0.0'
}
$minimumRequiredResource = [PSResourceObject] @{
Name = 'MyModule'
Version = '1.0.1'
PreRelease = 'preview1'
}
$minimumRequiredResource.CompareTo($currentStateResource)
That would result in 1
meaning the minumim version required is not installed.
1
= minimum version need to be installed0
= minimum version is compliant, the exact minimum version is installed-1
= minimum version is compliant, there is already a higher version installed than the minimum version
Mermaid class diagram (syntax help in the docs):
classDiagram
class PSResourceObject {
+Name: System.String
+Version: System.Version
+PreRelease: System.String
+PSResourceObject()
+PSResourceObject(System.String Name)
+PSResourceObject(System.String Name, System.Version Version)
+PSResourceObject(System.String Name, System.Version Version, System.String PreRelease)
+Equals(System.Object): System.Boolean
+CompareTo(System.Object): System.Int32
+GetHashCode(): System.Int32
+ToString(): System.String
+static GetInstalledResource(System.String)$ PSResourceObject[]
+static GetMinimumInstalledVersion(System.String)$ PSResourceObject
+static GetMinimumInstalledVersion(PSResourceObject[])$ PSResourceObject
+static GetMaximumInstalledVersion(System.String)$ PSResourceObject
+static GetMaximumInstalledVersion(PSResourceObject[])$ PSResourceObject
+static Install(System.Collections.Hashtable)$ void
+IsPreRelease()$ System.Boolean
-static op_Implicit(System.Management.Automation.PSModuleInfo): PSResourceObject
-ToUniqueString(): System.String
}
class IComparable {
<<Interface>>
CompareTo(System.Object) System.Int32
}
class IEquatable {
<<Interface>>
Equals(System.Object) System.Boolean
}
IComparable <|-- PSResourceObject : implements
IEquatable <|-- PSResourceObject : implements
Example output:
using module SqlServerDsc # Just took an existing module that was already using classes to run the code in.
$a = [PSResourceObject] @{ Name = 'MyModule'; Version = '1.0.0' }
$b = [PSResourceObject] @{ Name = 'MyModule'; Version = '1.0.0' }
$c = [PSResourceObject] @{ Name = 'MyModule2'; Version = '1.0.0' }
$d = [PSResourceObject] @{ Name = 'MyModule'; Version = '1.0.1' }
$e = [PSResourceObject] @{ Name = 'MyModule2'; Version = '0.9.0' }
$f = [PSResourceObject] @{ Name = 'MyModule'; Version = '1.0.0'; PreRelease = 'preview3' }
$g = [PSResourceObject] @{ Name = 'MyModule'; Version = '1.0.0'; PreRelease = 'preview2' }
$h = [PSResourceObject] @{ Name = 'MyModule2'; Version = '1.0.0'; PreRelease = 'preview' }
$all = @($a,$b,$c,$d,$e,$f,$g,$h)
$all | Sort-Object
Name Version PreRelease
---- ------- ----------
MyModule 1.0.0 preview2
MyModule 1.0.0 preview3
MyModule 1.0.0
MyModule 1.0.0
MyModule 1.0.1
MyModule2 0.9.0
MyModule2 1.0.0 preview
MyModule2 1.0.0
PS > $all | Sort-Object -Descending
Name Version PreRelease
---- ------- ----------
MyModule2 1.0.0
MyModule2 1.0.0 preview
MyModule2 0.9.0
MyModule 1.0.1
MyModule 1.0.0
MyModule 1.0.0
MyModule 1.0.0 preview3
MyModule 1.0.0 preview2
PS > $all | Sort-Object -Top 1
Name Version PreRelease
---- ------- ----------
MyModule 1.0.0 preview2
PS > $all | Sort-Object -Unique
Name Version PreRelease
---- ------- ----------
MyModule 1.0.0 preview2
MyModule 1.0.0 preview3
MyModule 1.0.0
MyModule 1.0.1
MyModule2 0.9.0
MyModule2 1.0.0 preview
MyModule2 1.0.0
PS > $all | Sort-Object -Property Version -Unique
Name Version PreRelease
---- ------- ----------
MyModule2 0.9.0
MyModule 1.0.0
MyModule 1.0.1
PS > $a -eq $d
False
PS > $a -eq $b
True
PS > [PSResourceObject]::GetInstalledResource('Pester') | Sort-Object
Name Version PreRelease
---- ------- ----------
Pester 3.4.0
Pester 5.4.0 rc1
PS > [PSResourceObject]::GetInstalledResource('Pester') | Sort-Object -Descending
Name Version PreRelease
---- ------- ----------
Pester 5.4.0 rc1
Pester 3.4.0
PS > [PSResourceObject]::GetMinimumInstalledVersion('Pester')
Name Version PreRelease
---- ------- ----------
Pester 3.4.0
PS > [PSResourceObject]::GetMinimumInstalledVersion(([PSResourceObject[]] @(@{Name = 'MyModule'; Version = '1.0.0'},@{Name = 'MyModule'; Version = '1.0.0'; PreRelease = 'preview'})))
Name Version PreRelease
---- ------- ----------
MyModule 1.0.0 preview
PS > [PSResourceObject]::GetMaximumInstalledVersion('Pester')
Name Version PreRelease
---- ------- ----------
Pester 5.4.0 rc1
PS > [PSResourceObject]::GetMaximumInstalledVersion(([PSResourceObject[]] @(@{Name = 'MyModule'; Version = '1.0.0'},@{Name = 'MyModule'; Version = '1.0.0'; PreRelease = 'preview'})))
Name Version PreRelease
---- ------- ----------
MyModule 1.0.0
PS >
PS > $currentStateResource = [PSResourceObject] @{Name = 'MyModule'; Version = '1.0.0'}
PS > $minimumRequiredResource = [PSResourceObject] @{Name = 'MyModule'; Version = '1.0.1'; PreRelease = 'preview1'}
PS > $minimumRequiredResource.CompareTo($currentStateResource)
1
PS >
PS > $currentStateResource = [PSResourceObject] @{Name = 'MyModule'; Version = '1.0.0'}
PS > $minimumRequiredResource = [PSResourceObject] @{Name = 'MyModule'; Version = '1.0.0'; PreRelease = 'preview1'}
PS > $minimumRequiredResource.CompareTo($currentStateResource)
-1
PS >
PS > $currentStateResource = [PSResourceObject] @{Name = 'MyModule'; Version = '1.0.0'}
PS > $minimumRequiredResource = [PSResourceObject] @{Name = 'MyModule'; Version = '1.0.0'}
PS > $minimumRequiredResource.CompareTo($currentStateResource)
0
PS >
PS > $a.IsPrerelease()
False
PS > $f.IsPrerelease()
True
Implicit conversion from PSModuleInfo to PSResourceObject:
PS > $moduleInfo = get-module DscResource.DocGenerator
PS > $moduleInfo
ModuleType Version PreRelease Name ExportedCommands
---------- ------- ---------- ---- ----------------
Script 0.12.0 preview00… DscResource.DocGenerator {Add-NewLine, Edit-CommandDocumentation, Invoke-Git, New-Ds…
PS> [PSResourceObject] $moduleInfo
Name Version PreRelease
---- ------- ----------
DscResource.DocGenerator 0.12.0 preview0004