Скрипт для массовго prestage пакетов на серверах SCCM

Часто требуется выполнить prestage пакетов, которые нормальным образом не хотят распространяться на SCCM Distribution Point сервера. Для этого можно использовать связку утилиты PSEXEC и утилиты ExtractContent.exe, которая входит в состав установки SCCM DP сервера и выполняет prestage. Утилиту PSEXEC вы должны скачать и положить в папку Windows\System32 заранее.

Я предлагаю мной написанный скрипт, который делает все это автоматически на множественных серверах. Итак, задача: есть пакет или пакеты, которые застряли или зафейлились при распространении на DP. Необходимо сделать prestage таких пакетов на всех DP, где они застряли.

Исходные данные: на всех DP серверах есть диск M:, на который и поставлен SCCM. Файлы pkgx для prestage мы будет складывать на диске M в папку PrestagePKGX. Центральный сервер SCCM — CEN_server.mycorp, сервера, на которых будут создаваться pkgx — DP1.mycorp и DP2.mycorp (на них пакет уже должен быть распространен). Локальное хранилище пакетов pkgx будет находиться в папке M:\Prestage\ на сервере, где вы запускаете скрипт.

Скрипт работает в двух режимах: или пользователь указывает ID пакета, который необходимо запрестейджить или же он указывает *, тогда выполняется престейдж всех пакетов на указанном им DP сервере.

Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process
#Import SCCM powershell module
Import-Module "$($ENV:SMS_ADMIN_UI_PATH)\..\ConfigurationManager.psd1" # Import the ConfigurationManager.psd1 module
Set-Location "CEN:" # Set the current location to be the site code.
    $date = Get-Date
    $log = "c:\temp\package_prestage_mass.txt"
    "" | Out-File $log -Append
    "==== $date ==== " | Out-File $log -Append
#Package ID to prestage
$PkgID = Read-Host "Enter PackageID"
if ($PkgID -ne "*")
{
#get the list of DP servers where this package failed
$query = Get-WmiObject –NameSpace Root\SMS\Site_CEN –Class SMS_DistributionDPStatus -ComputerName CEN_server.mycorp –Filter "PackageID='$PkgID'" | where MessageState -NE '1' | Select Name, ObjectTypeID
#Didn't find any DPs where this package failed.
If ($query -eq $null) {
    Write-Host "No DP found with a package in pending state for this package"
    Exit
}
$FileName = "M:\Prestage\$PkgID.pkgx"
    $DPName = "DP1.mycorp"
    $DPName2 = "DP2.mycorp"
#check if pkgx is already created and located in the storage
    if (-Not (Test-Path "M:\Prestage\$PkgID.pkgx")) {
    "Package $PkgID file not found in the storage. It will be created now."
    $ObjType = $query.ObjectTypeID[0]
    "Package Type is $ObjType"

    if ($ObjType -eq "2") {
        CD "$SitePath"
        try {
            Publish-CMPrestageContent -PackageID $PkgID -FileName $FileName -DistributionPointName $DPName
            "Package $PkgID type $ObjType saved as $FileName" | Out-File $log -Append
            }
        catch {
            Publish-CMPrestageContent -PackageID $PkgID -FileName $FileName -DistributionPointName $DPName2
            "Package $PkgID type $ObjType failed on DP1, trying DP2" | Out-File $log -Append
            }

    }
    if ($ObjType -eq "23") {
        CD "$SitePath"
        try {
            Publish-CMPrestageContent -DriverPackageID $PkgID -FileName $FileName -DistributionPointName $DPName
            "Package $PkgID type $ObjType saved as $FileName" | Out-File $log -Append
            }
        catch {
            Publish-CMPrestageContent -DriverPackageID $PkgID -FileName $FileName -DistributionPointName $DPName2
            "Package $PkgID type $ObjType failed on DP1, trying DP2" | Out-File $log -Append
            }
    }
    if ($ObjType -eq "19") {
        CD "$SitePath"
        try {
            Publish-CMPrestageContent -BootImageId $PkgID -FileName $FileName -DistributionPointName $DPName
            "Package $PkgID type $ObjType saved as $FileName" | Out-File $log -Append
            }
        catch {
            Publish-CMPrestageContent -BootImageId $PkgID -FileName $FileName -DistributionPointName $DPName2
            "Package $PkgID type $ObjType failed on DP1, trying DP2" | Out-File $log -Append
            }
    }
    if ($ObjType -eq "14") {
        CD "$SitePath"
        try {
            Publish-CMPrestageContent -OperatingSystemImageId $PkgID -FileName $FileName -DistributionPointName $DPName
            "Package $PkgID type $ObjType saved as $FileName" | Out-File $log -Append
            }
        catch {
            Publish-CMPrestageContent -OperatingSystemImageId $PkgID -FileName $FileName -DistributionPointName $DPName2
            "Package $PkgID type $ObjType failed on DP1, trying DP2" | Out-File $log -Append
            }
    }
    }
    else {
        "Package $PkgID exists in the storage" | Out-File $log -Append
    }
#Start checking every failed DP server: connection, required folders
Foreach ($DP in $query.name) {
    cd c:\
    "=> Server $DP" | Out-File $log -Append
    "Processing server $DP"
    if ((Test-Connection $DP -Count 2 -Quiet) -eq $false) {"Connection failed. Server $DP not available"}
    else {
     if (-Not (Test-Path "\\$DP\m$\PrestagePKGX")) {New-Item -ItemType directory -Path "\\$DP\m$\PrestagePKGX" -Force}
     if (-Not (Test-Path "\\$DP\m$\PrestagePKGX\GOOD")) {New-Item -ItemType directory -Path "\\$DP\m$\PrestagePKGX\GOOD" -Force}
     if (-Not (Test-Path "\\$DP\m$\PrestagePKGX\Done")) {New-Item -ItemType directory -Path "\\$DP\m$\PrestagePKGX\Done" -Force}
     mi -Path \\$DP\m$\PrestagePKGX\*.pkgx -Destination \\$DP\m$\PrestagePKGX\Done -Force
     if ((Test-Path "\\$DP\m$\PrestagePKGX\$PkgID.pkgx") -and ((Get-Item $FileName).length -ne (Get-Item "\\$DP\m$\PrestagePKGX\$PkgID.pkgx").length) -or (-not (Test-Path "\\$DP\m$\PrestagePKGX\$PkgID.pkgx"))) {
         Copy-Item -Path "Microsoft.PowerShell.Core\FileSystem::$FileName" -Destination "Microsoft.PowerShell.Core\FileSystem::\\$DP\m$\PrestagePKGX" -Force
         "$PkgID.pkgx file copied with exitcode $lastExitCode" | Out-File $log -Append
     }
     else {"File $PkgID.pkgx exists on remote server $DP and has the same size. Will extract it now."}
#Run ExtractContent on every DP
     if (Test-Path "\\$DP\m$\SMS_DP$\sms\Tools\ExtractContent.exe")
         { psexec \\$DP /accepteula cmd /c M:\SMS_DP$\sms\Tools\ExtractContent.exe /P:M:\PrestagePKGX\$PkgID.pkgx /f /i >> $log }
     else
         { psexec -s \\$DP /accepteula cmd /c M:\CM12\Bin\x64\ExtractContent.exe /P:M:\PrestagePKGX\$PkgID.pkgx /f /i >> $log }
     if ($lastExitCode -eq "0") {mi -Path \\$DP\m$\PrestagePKGX\$PkgID.pkgx -Destination \\$DP\m$\PrestagePKGX\GOOD -Force}
     else {mi -Path \\$DP\m$\PrestagePKGX\$PkgID.pkgx -Destination \\$DP\m$\PrestagePKGX\Done -Force}
    }
}
"ExtractContent completed on $DP with exitcode $lastExitCode" | Out-File $log -Append
}
else {
        $DP = Read-Host "Enter DP name"
        if (Test-Path "\\$DP\m$\SMS_DP$\sms\Tools\ExtractContent.exe")
            { psexec \\$DP /accepteula cmd /c M:\SMS_DP$\sms\Tools\ExtractContent.exe /P:M:\PrestagePKGX\ /f /i >> $log }
        else
            { psexec -s \\$DP /accepteula cmd /c M:\CM12\Bin\x64\ExtractContent.exe /P:M:\PrestagePKGX\ /f /i >> $log }
        if ($lastExitCode -eq "0") {mi -Path \\$DP\m$\PrestagePKGX\*.pkgx -Destination \\$DP\m$\PrestagePKGX\GOOD -Force}
        else {mi -Path \\$DP\m$\PrestagePKGX\*.pkgx -Destination \\$DP\m$\PrestagePKGX\Done -Force}
        "ExtractContent completed on $DP with exitcode $lastExitCode" | Out-File $log -Append
    }

Был ли наш пост полезен?

Нажмите на звезду, чтобы оценить мои труды!

Средний рейтинг: 1 / 5. Количество голосов: 1

Пока голосов нет. Проголосуй первым!

Мне жаль, что пост вам не помог 🙁

Позвольте мне исправиться.

Поделитесь, что можно улучшить?

Похожие посты