KMaks.WindowsUpdate.psm1

Function Get-WindowsUpdateCABFile {
    Invoke-WebRequest -Uri "https://catalog.s.download.windowsupdate.com/microsoftupdate/v6/wsusscan/wsusscn2.cab" -OutFile "wsusscn2.cab"
}
Function Get-WindowsUpdateService {
    $ServiceManager = New-Object -ComObject Microsoft.Update.ServiceManager

    return $ServiceManager.Services
}
Function Remove-WindowsUpdateService {
    param (
        [Parameter()]
        [string]
        $ServiceID
    )
    $ServiceManager = New-Object -ComObject Microsoft.Update.ServiceManager
    $ServiceManager.RemoveService($ServiceID)
}
Function New-WindowsUpdateService {
    param (
        [Parameter(Mandatory)]
        [string]
        $Name,

        [Parameter(Mandatory)]
        [ValidateScript({
            if( -Not ($_ | Test-Path) ){
                throw "File or folder does not exist."
            }
            if(-Not ($_ | Test-Path -PathType Leaf) ){
                throw "The Path argument must be a file. Folder paths are not allowed."
            }
            if($_ -notmatch "(\.cab)"){
                throw "The file specified in the path argument must be a cab file."
            }
            return $true
        })]
        [System.IO.FileInfo]
        $CABPath
    )

    [Flags()]
    enum UpdateServiceOption {
        usoNonVolatileService = 0x1
    }
    $UpdateServiceManager = New-Object -ComObject Microsoft.Update.ServiceManager
    $UpdateService = $UpdateServiceManager.AddScanPackageService($Name, $CABPath.FullName, $UpdateServiceOption.usoNonVolatileService)
    
    Return $UpdateService
}
Function Get-WindowsUpdate {
    param (
        [Parameter()]
        [switch]
        $IsHidden,

        [Parameter()]
        [switch]
        $IsInstalled,

        # System.__ComObject#{1518b460-6518-4172-940f-c75883b24ceb}
        [Parameter()]
        [System.__ComObject]
        $UpdateServiceID
    )

    $UpdateSession = New-Object -ComObject Microsoft.Update.Session
    $UpdateSearcher = $UpdateSession.CreateUpdateSearcher()

    if ($UpdateServiceID) {
        # Source: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-uamg/07e2bfa4-6795-4189-b007-cc50b476181a
        [Flags()]
        enum tagServerSelection
        {
            ssDefault = 0
            ssManagedServer = 1
            ssWindowsUpdate = 2
            ssOthers = 3
        }
        $UpdateSearcher.ServerSelection =  $tagServerSelection.ssOthers
        $UpdateSearcher.ServiceID = $UpdateServiceID.ServiceID
    }

    $searchFilter = New-Object -TypeName "System.Collections.ArrayList"
    if ($IsHidden) { [void]$searchFilter.Add(("IsHidden={0}" -f [int][bool]$IsHidden)) }
    if ($IsInstalled) { [void]$searchFilter.Add(("IsInstalled={0}" -f [int][bool]$IsInstalled)) }
    $searchFilter = $searchFilter -join " and "

    $Updates = $UpdateSearcher.Search($searchFilter).Updates

    return $Updates
}