Libraries/Lib.Windows/Lib.Windows.psm1

<#
    .SYNOPSIS
    Get the flavor of the OS
 
.PARAMETER Online
True to specify to fetch information from the running OS
 
.PARAMETER Root
The path to the root of an OS.
 
.EXAMPLE
Get-OSKernelVersion -Online
 
.EXAMPLE
Get-OSKernelVersion -Root F:\
 
#>

function Get-OSKernelVersion {
    [CmdletBinding()][OutputType([String])]Param (
        [switch]$Online,
        [string]$Root
    )
    Begin {
        Write-PwShFwOSEnterFunction
    }

    Process {
        if ($Online) {
            $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion"
        } else {
            $RegPath = Mount-OfflineWindowsRegistry -Path "$Root\Windows" -Hive SOFTWARE
            $RegPath = $RegPath + "\Microsoft\Windows NT\CurrentVersion"
        }

        if ($PSVersionTable.PSVersion.Major -lt 5) {
            return (Get-ItemProperty $RegPath 'CurrentBuildNumber' -ErrorAction:SilentlyContinue).CurrentBuildNumber
        } else {
            return Get-ItemPropertyValue $RegPath -Name CurrentBuildNumber
        }
    }

    End {
        Write-PwShFwOSLeaveFunction
    }
}

<#
.SYNOPSIS
Get the release ID of an OS
 
.DESCRIPTION
The release ID of an OS is often a number identifying OS in time.
It can return 1607 or 1809 on windows 10 or 16.04 or 18.10 on ubuntu.
 
.EXAMPLE
Get-OSReleaseId -Online
 
.NOTES
General notes
#>

function Get-OSReleaseId {
    [CmdletBinding()][OutputType([String])]Param (
        [switch]$Online,
        [string]$Root
    )
    Begin {
        Write-PwShFwOSEnterFunction
    }

    Process {
        if ($Online) {
            $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion"
        } else {
            $RegPath = Mount-OfflineWindowsRegistry -Path "$Root\Windows" -Hive SOFTWARE
            $RegPath = $RegPath + "\Microsoft\Windows NT\CurrentVersion"
        }

        if (Test-RegValueExist -RegPath $RegPath -Name ReleaseId) {
            return Get-ItemPropertyValue $RegPath -Name ReleaseId
        } else {
            return $null
        }
    }

    End {
        Write-PwShFwOSLeaveFunction
    }
}

<#
.SYNOPSIS
Fetch the Installation Type from the registry
 
.DESCRIPTION
The installation type give information wether the OS is a client, server, or something else.
 
.PARAMETER Online
True to specify to fetch information from the running OS
 
.PARAMETER Root
The path to the root of an OS.
 
.EXAMPLE
Get-OSInstallType -Online
 
.EXAMPLE
Get-OSInstallType -Root F:\
 
.NOTES
General notes
#>


function Get-OSInstalltype {
    [CmdletBinding()][OutputType([String])]Param (
        [switch]$Online,
        [string]$Root
    )
    Begin {
        Write-PwShFwOSEnterFunction
    }

    Process {
        if ($Online) {
            $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion"
        } else {
            $RegPath = Mount-OfflineWindowsRegistry -Path "$Root\Windows" -Hive SOFTWARE
            $RegPath = $RegPath + "\Microsoft\Windows NT\CurrentVersion"
        }

        $value = Get-ItemPropertyValue $RegPath -Name InstallationType

        return $value
   }

    End {
        Write-PwShFwOSLeaveFunction
    }
}

<#
.SYNOPSIS
Retrieve the family of an OS
 
.DESCRIPTION
The family of an OS can give informations on how to handle it.
 
.PARAMETER Online
True to specify to fetch information from the running OS
 
.PARAMETER Root
The path to the root of an OS.
 
.EXAMPLE
Get-OSFamily -Online
 
.EXAMPLE
Get-OSFamily -Root F:\
 
.NOTES
General notes
#>


function Get-OSFamily {
    [CmdletBinding()][OutputType([String])]Param (
        [Parameter(ParameterSetName = 'ONLINE')][switch]$Online,
        [Parameter(ParameterSetName = 'ROOT')][string]$Root
    )
    Begin {
        Write-PwShFwOSEnterFunction
    }

    Process {
        # switch ($PSCmdlet.ParameterSetName) {
        # 'ONLINE' {
        # $InstallationType = Get-OSInstalltype -Online
        # break
        # }
        # 'ROOT' {
        # $InstallationType = Get-OSInstalltype -Root $Root
        # break
        # }
        # }
        # switch -Wildcard ($InstallationType) {
        # "WindowsPE" {
        # $family = $InstallationType
        # break
        # }
        # "Server*" {
        # $family = "Windows Server"
        # break
        # }
        # "Client" {
        # $family = "Windows Desktop"
        # break
        # }
        # }

        # return $family
        return "Windows"
    }

    End {
        Write-PwShFwOSLeaveFunction
    }
}

<#
.SYNOPSIS
Retrieve the distrib of an OS
 
.DESCRIPTION
The distrib of an OS can give informations on how to handle it.
 
.PARAMETER Online
True to specify to fetch information from the running OS
 
.PARAMETER Root
The path to the root of an OS.
 
.EXAMPLE
Get-OSDistrib -Online
 
.EXAMPLE
Get-OSDistrib -Root F:\
 
.NOTES
General notes
#>


function Get-OSDistrib {
    [CmdletBinding()][OutputType([String])]Param (
        [Parameter(ParameterSetName = 'ONLINE')][switch]$Online,
        [Parameter(ParameterSetName = 'ROOT')][string]$Root
    )
    Begin {
        Write-PwShFwOSEnterFunction
    }

    Process {
        $InstallationType = Get-OSInstalltype @PSBoundParameters
        $CurrentMajorVersionNumber = Get-OSCurrentMajorVersionNumber @PSBoundParameters
        $CurrentBuildNumber = Get-OSKernelVersion @PSBoundParameters
        # default distrib
        $distrib = "Windows"

        switch -Wildcard ($InstallationType) {
            "WindowsPE" {
                $distrib = $InstallationType
                break
            }
            "Server*" {
                $distrib = "Windows $InstallationType"
                break
            }
            "Client" {
                # We can no longer rely on CurrentVersion since Windows 8
                # We can no longer rely on ReleaseId since Windows 10 2009
                # We can no longer rely on CurrentMajorVersionNumber since Windows 11
                # So let's use build number

                # Starting with windows 2000
                if ($CurrentBuildNumber -gt 2195) {
                    $distrib = "Windows"

                }
                # First build of Windows 10
                if ($CurrentBuildNumber -gt 10240) {
                    $distrib = "Windows 10"

                }
                # First build of Windows 11
                if ($CurrentBuildNumber -gt 22000) {
                    $distrib = "Windows 11"

                }
                break
            }
        }

        return $distrib
    }

    End {
        Write-PwShFwOSLeaveFunction
    }
}

<#
    .SYNOPSIS
    Get the distribution of the OS
 
.PARAMETER Online
True to specify to fetch information from the running OS
 
.PARAMETER Root
The path to the root of an OS.
 
.EXAMPLE
Get-OSVersion -Online
 
.EXAMPLE
Get-OSVersion -Root F:\
 
#>

function Get-OSVersion {
    [CmdletBinding()][OutputType([String])]Param (
        [Parameter(ParameterSetName = 'ONLINE')][switch]$Online,
        [Parameter(ParameterSetName = 'ROOT')][string]$Root
    )
    Begin {
        Write-PwShFwOSEnterFunction
    }

    Process {
        if ($Online) {
            $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion"
        } else {
            $RegPath = Mount-OfflineWindowsRegistry -Path "$Root\Windows" -Hive SOFTWARE
            $RegPath = $RegPath + "\Microsoft\Windows NT\CurrentVersion"
        }

        if ($PSVersionTable.PSVersion.Major -lt 5) {
            return [system.version](Get-ItemProperty $RegPath 'CurrentVersion' -ErrorAction:SilentlyContinue).CurrentVersion
        } else {
            return [system.version](Get-ItemPropertyValue $RegPath -Name CurrentVersion)
        }
   }

    End {
        Write-PwShFwOSLeaveFunction
    }
}

function Get-OSCurrentMajorVersionNumber {
    [CmdletBinding()][OutputType([String])]Param (
        [Parameter(ParameterSetName = 'ONLINE')][switch]$Online,
        [Parameter(ParameterSetName = 'ROOT')][string]$Root
    )
    Begin {
        Write-PwShFwOSEnterFunction
    }

    Process {
        if ($Online) {
            $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion"
        } else {
            $RegPath = Mount-OfflineWindowsRegistry -Path "$Root\Windows" -Hive SOFTWARE
            $RegPath = $RegPath + "\Microsoft\Windows NT\CurrentVersion"
        }

        if ($PSVersionTable.PSVersion.Major -lt 5) {
            return (Get-ItemProperty $RegPath 'CurrentMajorVersionNumber' -ErrorAction:SilentlyContinue).CurrentMajorVersionNumber
        } else {
            return Get-ItemPropertyValue $RegPath -Name CurrentMajorVersionNumber
        }
   }

    End {
        Write-PwShFwOSLeaveFunction
    }
}