PS; Get-ContentFromSCUPCatalog; Скачиваем MSI-файлы Adobe Flash Player и прочее из SCUP-Catalog

«Сначала прикололся, потом загнался»

Набор функций для скачивания файлов полученных из метаданных SCUP-Каталога.

  • Что такое SCUP
  • Что такое SCUP-Catalog
  • Скрипт
  • Как использовать

Что такое SCUP

Что такое SCUP, зачем он нужен, как его разворачивать и использовать — Антон уже давно написал:

Что такое SCUP-Catalog

SCUP-Catalog — это файл .xml, который упакован в .cab. XML-файл содержит метаданные обновлений, например, имя пакета, размер пакета, путь откуда скачать пакет, коды возврата (Exit Code) удачной установки, параметры установки. А также правила проверки о необходимости установки на конечном клиенте, правила проверки на успешность установки и т.д.

SCUP-Catalog предоставляется вендором в формате .cab файла. Из коробки доступны каталоги Adobe, HP (теперь без доступа к контенту), Dell, Fujitsu. До версии SCCM CB Microsoft так же предоставлял обновления клиентской и серверной части SCCM в виде обновлений для SCUP.

Скрипт

Function Extract-Cab
{   # Orig finction: https://technet.microsoft.com/en-us/library/2009.04.heyscriptingguy.aspx?f=255&MSPPError=-2147217396
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [ValidateScript({Test-Path $_})]
        [string]$Path,

        [string]$Destination = (Get-Location).Path
    )
    Begin {
        if($Debug) { $debugPreference = "Continue" }
        if($Verbose) { $VerbosePreference = "Continue" }
    }
    Process {
        $comObject = "Shell.Application"
        Write-Verbose "Creating $comObject"
        $shell = New-Object -Comobject $comObject
        if(!$?) { $(Throw "unable to create $comObject object")}
        Write-Verbose "Creating source cab object for $Path"
        $sourceCab = $shell.Namespace($Path).Items()
        Write-Verbose "Creating Destination folder object for $Destination"
        $DestinationFolder = $shell.Namespace($Destination)
        Write-Verbose "Expanding $Path to $Destination"
        $a = $DestinationFolder.CopyHere($sourceCab, 16) # 16 - "Yes to All"
        if(!$?) { $(Throw "Shit happens: CopyHere($sourceCab)")}
    }
    End {
        return $sourceCab
    }
}

function Get-InfoFromSCUPCatalog
{
    [CmdletBinding()]
    [Alias()]
    [OutputType([PSObject])]
    Param
    (
        [ValidateNotNullOrEmpty()]
        [string]$URICatalog = "http://fpdownload.adobe.com/get/flashplayer/distribution/win/AdobeFlashPlayerCatalog_SCUP.cab"
    )
    Begin
    {
        if($Debug) { $debugPreference = "Continue" }
        if($Verbose) { $VerbosePreference = "Continue" }

        #$TmpXMLFile =  Join-Path ([System.IO.Path]::GetTempPath()) ([System.IO.Path]::GetRandomFileName())
        #    Write-Verbose "TmpXMLFile = $TmpXMLFile"
        $TmpFolder = (Join-Path ([System.IO.Path]::GetTempPath()) (Split-Path $URICatalog -Leaf ))
        $TmpCabFile = (Join-Path $TmpFolder (Split-Path $URICatalog -Leaf ))
            Write-Verbose "TmpCabFile = $TmpCabFile"

        if((Test-Path $TmpFolder -PathType Container) -eq $false) {
            New-Item $TmpFolder -ItemType Directory -ErrorAction Stop | Out-Null
        }

    }
    Process
    {
        Invoke-WebRequest -Uri $URICatalog -OutFile $TmpCabFile -ErrorAction Stop
        $FilesInCab = Extract-Cab -Path $TmpCabFile -Destination $TmpFolder
        $UnpackedFiles = @($FilesInCab.Path) | ForEach-Object {
            Write-Verbose "Files in cab path: $_"
            $_.Replace($TmpCabFile, $TmpFolder)
        }

        $xml = [xml](Get-Content -Path $UnpackedFiles -Include "*.xml" -ErrorAction Stop)

        foreach ($Pack in $xml.DocumentElement.SoftwareDistributionPackage) {
            New-Object psobject -Property @{
                Title = $Pack.LocalizedProperties.Title
                ProductName = $Pack.Properties.ProductName
                PublicationState = $Pack.Properties.PublicationState
                CreationDate = $Pack.Properties.CreationDate
                UpdateType = $Pack.Properties.UpdateType
                OriginUri = $Pack.InstallableItem.OriginFile.OriginUri
                FileName = $Pack.InstallableItem.OriginFile.FileName
                Version = Split-Path (Split-Path $Pack.InstallableItem.OriginFile.OriginUri) -Leaf # Правильнее использовать IsInstalled - но много логики :)
            }
        }

    }
    End
    {
        # Remove Temp Directory
        Write-Verbose "Remove TmpFolder = $($TmpFolder)"
        Remove-Item -Path $TmpFolder -Force -Recurse -ErrorAction 0
    }
}

function Get-FilesFromSCUPCatalogInfo
{
    [CmdletBinding()]
    [Alias()]
    [OutputType([PSObject])]
    Param
    (
        # Param1 URI
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=0)]
        [ValidateNotNullOrEmpty()]
        [Alias("URI","URL")]
        [string] $OriginUri,

        # Param2 File name
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=0)]
        [ValidateNotNullOrEmpty()]
        [Alias("Name","TargetName")]
        [string] $FileName,

        # Param3 Upload Folder
        [Alias("UploadFolder","DownloadFolder")]
        [string] $Folder = (Get-Location).Path
    )

    Begin
    {
        if($Debug) { $debugPreference = "Continue" }
        if($Verbose) { $VerbosePreference = "Continue" }

        if((Test-Path $Folder -PathType Container -ErrorAction 0) -ne $true) {
            Write-Verbose "Folder does not exists, create folder: $($Folder)"
            New-Item $Folder -ItemType Directory -ErrorAction Stop
        }
    }
    Process
    {
        Write-Verbose "Download URI = $($OriginUri) `n`tto Folder = $($Folder)"
        Invoke-WebRequest -Uri $OriginUri -OutFile (Join-Path $Folder $FileName)
    }
    End
    {
    }
}

Как использовать

Например, мы хотим получить MSI-файлы Adobe Flash Player. Достаточно вызвать функции без параметров, поскольку это была основная задача скрипта:


$updates = Get-InfoFromSCUPCatalog -Verbose

$Published = $updates | Where-Object PublicationState -ne "Expired"
$Published | Format-Table Title,Version,Filename

$Published | Get-FilesFromSCUPCatalogInfo -Verbose

Так как мы не задавали параметры в виде URICatalog (ссылку на SCUP-каталог) и Folder (куда скачивать), файлы будут скачены в текущий каталог.

image

Реклама
Запись опубликована в рубрике PowerShell, Updates. Добавьте в закладки постоянную ссылку.

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход /  Изменить )

Google photo

Для комментария используется ваша учётная запись Google. Выход /  Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход /  Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход /  Изменить )

Connecting to %s