Private/Get-OSBuild.ps1

<#
.SYNOPSIS
Gets details about all Operating Systems in OSBuilds
 
.DESCRIPTION
Gets details about all Operating Systems in OSBuilds
 
.PARAMETER FullDetails
Displays Microsoft Update information for Adobe, SSU, and LCU. LCU requires Sessions.xml
 
.LINK
https://www.osdeploy.com/osbuilder/osmedia/Get-OSBuild
#>

function Get-OSBuild {
    [CmdletBinding()]
    PARAM (
        [switch]$FullDetails
    )

    BEGIN {
        #Write-Host '========================================================================================' -ForegroundColor DarkGray
        #Write-Host "$($MyInvocation.MyCommand.Name) BEGIN" -ForegroundColor Green

        #===================================================================================================
        Write-Verbose '19.1.1 Initialize OSBuilder'
        #===================================================================================================
        Get-OSBuilder -CreatePaths -HideDetails

        #===================================================================================================
        Write-Verbose '19.1.1 Gather All Updates'
        #===================================================================================================
        $CatalogsXmls = @()
        $ImportCatalog = @()
        $AllUpdates = @()

        $CatalogsXmls = Get-ChildItem "$OSBuilderContent\Updates" Cat*.xml -Recurse
        foreach ($CatalogsXml in $CatalogsXmls) {
            $ImportCatalog = Import-Clixml -Path "$($CatalogsXml.FullName)"
            $AllUpdates += $ImportCatalog
        }
        $AllUpdates = $AllUpdates | Select-Object -Property *

        #===================================================================================================
        Write-Verbose '19.1.1 Gather All OSBuilds'
        #===================================================================================================
        $AllOSBuilds = @()
        $AllOSBuilds = Get-ChildItem -Path "$OSBuilderOSBuilds" -Directory | Select-Object -Property * | Where-Object {Test-Path $(Join-Path $_.FullName "info\xml\Get-WindowsImage.xml")}

        $null = $OSBuilds
    }

    PROCESS {
        #Write-Host '========================================================================================' -ForegroundColor DarkGray
        #Write-Host "$($MyInvocation.MyCommand.Name) PROCESS" -ForegroundColor Green

        $OSBuilds = foreach ($Item in $AllOSBuilds) {
            #===================================================================================================
            Write-Verbose '19.1.1 Get Windows Image Information'
            #===================================================================================================
            Write-Verbose "OSMedia Full Path: $($Item.FullName)"
            
            $OSMWindowsImage = @()
            $OSMWindowsImage = Import-Clixml -Path "$($Item.FullName)\info\xml\Get-WindowsImage.xml"
            
            $OSMVersion = $($OSMWindowsImage.Version)
            Write-Verbose "Version: $OSMVersion"

            $OSMImageName = $($OSMWindowsImage.ImageName)
            Write-Verbose "ImageName: $OSMImageName"
            
            $OSMArch = $OSMWindowsImage.Architecture
            if ($OSMArch -eq '0') {$OSMArch = 'x86'}
            if ($OSMArch -eq '6') {$OSMArch = 'ia64'}
            if ($OSMArch -eq '9') {$OSMArch = 'x64'}
            if ($OSMArch -eq '12') {$OSMArch = 'x64 ARM'}
            Write-Verbose "Arch: $OSMArch"

            $OSMEditionId = $($OSMWindowsImage.EditionId)
            Write-Verbose "EditionId: $OSMEditionId"

            $OSMInstallationType = $($OSMWindowsImage.InstallationType)
            Write-Verbose "InstallationType: $OSMInstallationType"

            $OSMMajorVersion = $($OSMWindowsImage.MajorVersion)
            Write-Verbose "MajorVersion: $OSMMajorVersion"

            $OSMMinorVersion = $($OSMWindowsImage.MinorVersion)
            Write-Verbose "MinorVersion: $OSMMinorVersion"

            $OSMBuild = $($OSMWindowsImage.Build)
            Write-Verbose "Build: $OSMBuild"

            $OSMLanguages = $($OSMWindowsImage.Languages)
            Write-Verbose "Languages: $OSMLanguages"

            $OperatingSystem = ''
            if ($OSMMajorVersion -eq 6 -and $OSMInstallationType -eq 'Client') {$OperatingSystem = 'Windows 7'}
            if ($OSMMajorVersion -eq 10 -and $OSMInstallationType -eq 'Client') {$OperatingSystem = 'Windows 10'}
            if ($OSMMajorVersion -eq 10 -and $OSMInstallationType -eq 'Server' -and $OSMImageName -like "*2016*") {$OperatingSystem = 'Server 2016'}
            if ($OSMMajorVersion -eq 10 -and $OSMInstallationType -eq 'Server' -and $OSMImageName -like "*2019*") {$OperatingSystem = 'Server 2019'}

            $OSMUBR = $($OSMWindowsImage.UBR)
            Write-Verbose "UBR: $OSMUBR"

            #===================================================================================================
            Write-Verbose '19.1.1 Gather Registry Information'
            #===================================================================================================
            $OSMRegistry = @()
            if (Test-Path "$($Item.FullName)\info\xml\CurrentVersion.xml") {
                Write-Verbose "Registry: $($Item.FullName)\info\xml\CurrentVersion.xml"
                $OSMRegistry = Import-Clixml -Path "$($Item.FullName)\info\xml\CurrentVersion.xml"
            } else {
                Write-Verbose "Registry: $($Item.FullName)\info\xml\CurrentVersion.xml (Not Found)"
            }
            [string]$OSMReleaseId = $($OSMRegistry.ReleaseId)

            if ($OSMBuild -eq 7600) {$OSMReleaseId = 7600}
            if ($OSMBuild -eq 7601) {$OSMReleaseId = 7601}
            if ($OSMBuild -eq 10240) {$OSMReleaseId = 1507}
            if ($OSMBuild -eq 14393) {$OSMReleaseId = 1607}
            if ($OSMBuild -eq 15063) {$OSMReleaseId = 1703}
            if ($OSMBuild -eq 16299) {$OSMReleaseId = 1709}
            if ($OSMBuild -eq 17134) {$OSMReleaseId = 1803}
            if ($OSMBuild -eq 17763) {$OSMReleaseId = 1809}

            Write-Verbose "ReleaseId: $OSMReleaseId"

            if ($FullDetails.IsPresent) {

                #===================================================================================================
                Write-Verbose '19.1.1 Gather Package Information'
                #===================================================================================================
                $OSMPackage = @()
                if (Test-Path "$($Item.FullName)\info\xml\Get-WindowsPackage.xml") {
                    Write-Verbose "Packages: $($Item.FullName)\info\xml\Get-WindowsPackage.xml"
                    $OSMPackage = Import-Clixml -Path "$($Item.FullName)\info\xml\Get-WindowsPackage.xml"
                } else {
                    Write-Verbose "Packages: $($Item.FullName)\info\xml\Get-WindowsPackage.xml (Not Found)"
                }

                #===================================================================================================
                Write-Verbose '19.1.1 Gather Sessions Information'
                #===================================================================================================
                $OSMSessions = @()
                $OSMSessionsXml = @()
                
                if (Test-Path "$($Item.FullName)\Sessions.xml") {
                    Write-Verbose "Sessions: $($Item.FullName)\Sessions.xml"
                    [xml]$OSMSessionsXml = Get-Content -Path "$($Item.FullName)\Sessions.xml"
                    $OSMSessions = $OSMSessionsXml.Sessions.Session.Tasks.Phase.package | Where-Object {$_.id -like "*RollupFix*" -and $_.targetState -eq 'Installed'} | Sort-Object id
                } else {
                    Write-Verbose "Sessions: $($Item.FullName)\Sessions.xml (Not Found)"
                }

                #===================================================================================================
                Write-Verbose '19.1.1 Get Latest Adobe Security Update'
                #===================================================================================================
                $LatestAdobe = @()
                $LatestAdobe = $AllUpdates | Sort-Object -Property DatePosted -Descending
                $LatestAdobe = $LatestAdobe | Where-Object {$_.Category -eq 'Adobe'}
                $LatestAdobe = $LatestAdobe | Where-Object {$_.KBTitle -like "*$OSMReleaseId*"}
                $LatestAdobe = $LatestAdobe | Where-Object {$_.KBTitle -like "*$($Arch)*"}
                $LatestAdobe = $LatestAdobe | Where-Object {$_.KBTitle -like "*$OperatingSystem*"}
                $LatestAdobe = $LatestAdobe | Select-Object -First 1

                $InstalledAdobe = $OSMPackage | Where-Object {$_.PackageName -like "*$($LatestAdobe.KBNumber)*"}
                if ($null -eq $InstalledAdobe) {
                    Write-Verbose "LatestAdobe: $($LatestAdobe.KBTitle) (Not Installed)"
                    #$LatestAdobe = "KB$($LatestAdobe.KBNumber)"
                    $LatestAdobe = ''
                } else {
                    Write-Verbose "LatestAdobe: $($LatestAdobe.KBTitle) (Installed)"
                    $LatestAdobe = 'Latest'
                }

                if ($OSMMajorVersion -eq 6) {$LatestAdobe = 'None'}
                #===================================================================================================
                Write-Verbose '19.1.1 Get Latest Servicing Stack Update'
                #===================================================================================================
                $LatestSSU = @()
                $LatestSSU = $AllUpdates | Sort-Object -Property DatePosted -Descending
                $LatestSSU = $LatestSSU | Where-Object {$_.Category -eq 'Servicing'}
                $LatestSSU = $LatestSSU | Where-Object {$_.KBTitle -like "*$OSMReleaseId*"}
                $LatestSSU = $LatestSSU | Where-Object {$_.KBTitle -like "*$($Arch)*"}
                $LatestSSU = $LatestSSU | Where-Object {$_.KBTitle -like "*$OperatingSystem*"}
                $LatestSSU = $LatestSSU | Select-Object -First 1

                $InstalledSSU = $OSMPackage | Where-Object {$_.PackageName -like "*$($LatestSSU.KBNumber)*"}
                if ($null -eq $InstalledSSU) {
                    Write-Verbose "LatestSSU: $($LatestSSU.KBTitle) (Not Installed)"
                # $LatestSSU = "KB$($LatestSSU.KBNumber)"
                    $LatestSSU = ''
                } else {
                    Write-Verbose "LatestSSU: $($LatestSSU.KBTitle) (Installed)"
                    $LatestSSU = 'Latest'
                }

                #===================================================================================================
                Write-Verbose '19.1.1 Get Latest Cumulative Update'
                #===================================================================================================
                $LatestLCU = @()
                $LatestLCU = $AllUpdates | Sort-Object -Property DatePosted -Descending
                $LatestLCU = $LatestLCU | Where-Object {$_.Category -eq 'Cumulative'}
                $LatestLCU = $LatestLCU | Where-Object {$_.KBTitle -like "*$OSMReleaseId*"}
                $LatestLCU = $LatestLCU | Where-Object {$_.KBTitle -like "*$($Arch)*"}
                $LatestLCU = $LatestLCU | Where-Object {$_.KBTitle -like "*$OperatingSystem*"}
                $LatestLCU = $LatestLCU | Select-Object -First 1

                $InstalledLCU = $OSMSessions | Where-Object {$_.name -like "*$($LatestLCU.KBNumber)*"}

                if (!(Test-Path "$($Item.FullName)\Sessions.xml")) {
                    Write-Verbose "LatestLCU: Sessions.xml required for validation"
                    $LatestLCU = 'Unknown'
                } elseif ($null -eq $InstalledLCU) {
                    Write-Verbose "LatestLCU: $($LatestLCU.KBTitle) (Not Installed)"
                    $LatestLCU = ''
                } else {
                    Write-Verbose "LatestLCU: $($LatestLCU.KBTitle) (Installed)"
                    $LatestLCU = 'Latest'
                }

                #===================================================================================================
                Write-Verbose '19.1.1 Object Properties'
                #===================================================================================================
                $ObjectProperties = @{
                    MediaType           = $Item.Parent
                    Name                = $Item.Name
                    ImageName           = $OSMImageName
                    EditionId           = $OSMEditionId
                    Arch                = $OSMArch
                    MajorVersion        = $OSMMajorVersion
                    ReleaseId           = $OSMReleaseId
                    Build               = [string]$OSMBuild
                    UBR                 = $OSMUBR
                    Servicing           = $LatestSSU
                    Cumulative          = $LatestLCU
                    Adobe               = $LatestAdobe
                    FullName            = $Item.FullName
                    ModifiedTime        = [datetime]$OSMWindowsImage.ModifiedTime
                }
                New-Object -TypeName PSObject -Property $ObjectProperties
                Write-Verbose ""

            } else {

                $ObjectProperties = @{
                    MediaType           = $Item.Parent
                    Name                = $Item.Name
                    ImageName           = $OSMImageName
                    EditionId           = $OSMEditionId
                    Arch                = $OSMArch
                    MajorVersion        = $OSMMajorVersion
                    ReleaseId           = $OSMReleaseId
                    Build               = [string]$OSMBuild
                    UBR                 = $OSMUBR
                    FullName            = $Item.FullName
                    ModifiedTime        = [datetime]$OSMWindowsImage.ModifiedTime
                }
                New-Object -TypeName PSObject -Property $ObjectProperties
                Write-Verbose ""
            
            }
        }

        #===================================================================================================
        Write-Verbose '19.1.1 Output'
        #===================================================================================================
        if ($FullDetails.IsPresent) {
            $OSBuilds | Select-Object MediaType,Name,ImageName,EditionId,Arch,MajorVersion,ReleaseId,Build,UBR,Servicing,Cumulative,Adobe,FullName,ModifiedTime
        } else {
            $OSBuilds | Select-Object MediaType,Name,ImageName,EditionId,Arch,MajorVersion,ReleaseId,Build,UBR,FullName,ModifiedTime
        }
    }

    END {
        #Write-Host '========================================================================================' -ForegroundColor DarkGray
        #Write-Host "$($MyInvocation.MyCommand.Name) END" -ForegroundColor Green
    }
}