排查内容分发问题

本文讨论如何排查常见的内容分发问题。

原始产品版本:Configuration Manager Current Branch、Microsoft System Center 2012 Configuration Manager、Microsoft System Center 2012 R2 Configuration Manager

示例问题

对于此示例,假设你已将包分发到分发点,但 DP 的包处于 “失败” 或“ 正在进行” 状态。

  1. 首先 ,查看 DP 所在的站点 (主/辅助) 上的DistMgr.log。

    1. 在日志中查找 ~处理包 条目,并标识有关包 ID 的包处理线程。 筛选DistMgr.log标识的线程 ID。 查看 将包分发到标准 DP 中的步骤 4 以查看日志摘录。
    2. 查看筛选的日志,检查是否为有问题的 DP 创建了 DP 线程。 筛选 线程 ID DistMgr.log ,以简化此操作。
    3. 查看筛选的日志,检查是否已创建 PkgXferMgr 作业。
  2. 查看站点上的 PkgXferMgr.log , (DP 所在的主/辅助) 。

    1. 在日志中查找 包含 ID 条目的“找到”发送请求 ,并识别受影响的 DP/包组合的发送线程。 筛选 PkgXferMgr.log 标识的线程 ID。 查看 将包分发到标准 DP 中的步骤 6 以查看日志摘录。
    2. 查看筛选的日志,查看内容是否已成功传输到 DP,或者是否存在错误。
  3. 对于标准 DP,PkgXferMgr 将内容文件 () 复制到 DP,它指示 DP WMI 提供程序通过调用 WMI 方法将文件添加到内容库。 查看 DP 上的 SMSDPProv.log ,确保内容已添加到内容库。 查看 将包分发到标准 DP 中的步骤 7 以查看日志摘录。

    对于拉取 DP,PkgXferMgr 会通知拉取 DP 启动内容下载。 查看 分发包以拉取 DP 中的步骤 8-16,了解流并查看 PullDP.logDataTransferService.log 以确保成功下载内容。

  4. 对于标准 DP,PkgXferMgr 将状态消息发送到 DistMgr。 查看 DistMgr.log ,验证状态消息是否已成功处理。 查看 将包分发到标准 DP 中的步骤 8 以查看日志摘录。

    对于拉取 DP,拉取 DP 会发送一条状态消息来指示成功。 查看 分发包以拉取 DP 中的步骤 16-22,了解流并查看相关日志,以确保成功处理状态消息。

  5. 如果涉及多个站点,请确保数据库复制正常工作,并且相关站点之间的数据库链接处于活动状态。

常见的 DistMgr 问题

  • DistMgr.log 显示有问题的包 ID 的以下条目:

    SMS_DISTRIBUTION_MANAGER 2732 (0xaac) ~The contents for the package \<PackageID> hasn't arrived from site CS1 yet, will retry later.
    

    当内容从一个站点传输到另一个网站时,通常会暂时发生此情况。 查看发件人/后台处理程序日志,确保站点通信没有问题。 如果在计划程序 -Sender> ->Despooler) (站点到站点通信过程中看到错误,请在DistMgr.log中排查上述消息之前,重点解决这些错误。 查看 跨站点将包分发到 DP 以了解日志流。

    如果没有错误,可能需要强制父站点将包重新发送到受影响的站点。 有关详细信息 ,请参阅将包的压缩副本重新发送到站点

  • DistMgr.log 可能会显示它正忙于处理其他包,并且正在使用所有可用的线程来处理包。

    SMS_DISTRIBUTION_MANAGER 4824 (0x12d8) ~Currently using 3 out of 3 allowed package processing threads.
    

    如果看到此消息,请查看 DistMgr.log 中的当前包处理线程,以查看它们是否停滞。 还可以查看以下注册表项下的 “包处理队列 ”和“ 正在处理的包 ”注册表值,以查看处理队列中当前有多少个包:

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SMS\Components\SMS_DISTRIBUTION_MANAGER

    如果 “正在处理的包 ”值未更改,并且长时间停滞,则 DistMgr 可能会挂起/停滞。 如果发生这种情况,请捕获 SMSExec.exe 的进程转储 以供审阅。

    如果队列中有许多包,但队列正在移动,则可能需要查看和更改线程配置。

  • DistMgr.log 不处理传入的 PKN 文件,因此不会处理包。 这会导致 DistMgr 收件箱中积压 PKN 文件。

    PKN 文件由 main DistMgr 线程处理,因此在这些情况下,通过查找SMS_DISTRIBUTION_MANAGER日志条目启动SMS_EXECUTIVE,然后筛选已标识的线程 ID DistMgr.log,来标识main DistMgr 线程 ID 会很有帮助。

    在大多数情况下,当main DistMgr 线程对远程 DP 进行 WMI 调用,但 DP 上的 WMI 未响应,导致 DistMgr 无限期等待时,会出现此问题。 筛选 main DistMgr 线程的DistMgr.log可以提供有关它尝试与之通信的 DP 的线索。 标识后,检查 DP 是否响应且 WMI 在 DP 上正常运行。 如有必要,请重新启动 DP,看看是否有帮助。

    如果筛选 的DistMgr.log 未提供任何线索,请在处于问题状态时捕获 SMSExec.exe 的进程转储 以供审阅。

常见的 PkgXferMgr 问题

  • PkgXferMgr.log 在 DP 上将文件添加到内容库时显示错误:

    SMS_PACKAGE_TRANSFER_MANAGER 5744 (0x1670) ~Sending completed  
    [D:\SCCMContentLib\FileLib\B53B\B53B6F96ECC3FB2AF59D02C84A2D31434904BACF2F9C90D80107B6602860BCFD]  
    SMS_PACKAGE_TRANSFER_MANAGER 5744 (0x1670) ~ExecStaticMethod failed (80041001)  
    SMS_DistributionPoint, AddFile  
    SMS_PACKAGE_TRANSFER_MANAGER 5744 (0x1670) CSendFileAction::AddFile failed; 0x80041001  
    SMS_PACKAGE_TRANSFER_MANAGER 5744 (0x1670) ~Deleting remote file  
    \\DPNAME.CONTOSO.COM\SMS_DP$\Content_b034813c-bc60-4a16-b471-7a0dc3d9662b.1-B53B6F96ECC3FB2AF59D02C84A2D31434904BACF2F9C90D80107B6602860BCFD  
    SMS_PACKAGE_TRANSFER_MANAGER 5744 (0x1670) ~ Sending failed. Failure count = 1, Restart time = 12/4/2014 6:14:27 AM Eastern Standard Time
    

    PkgXferMgr 将内容文件复制到 DP 后,它会执行 WMI 方法,以指示远程 DP 将文件添加到内容库。 如果远程 DP 无法将文件添加到内容库,你将在 PkgXferMgr.log 中看到泛型 WMI 错误 (0x80041001 = WBEM_E_FAILED)

    发生这种情况时,必须查看 DP 上的 SMSDPProv.log ,以确定 DP 未能将文件添加到内容库的原因。 如果在 SMSDPProv.log 中看到文件/路径未找到错误,则需要捕获进程监视器跟踪以确定失败的原因。

  • PkgXferMgr.log 显示仅允许一个连接到 DP:

    SMS_PACKAGE_TRANSFER_MANAGER 21216 (0x52e0) ~Address to DPNAME.CONTOSO.COM is currently under bandwidth control, therefore only one connection is allowed, returning send request to the pool.
    

    SMS_PACKAGE_TRANSFER_MANAGER 21216 (0x52e0) ~Address to DPNAME.CONTOSO.COM is currently in pulse mode, therefore only one connection is allowed.
    

    如果 PkgXferMgr.log 显示“只允许一个连接”到 DP,则表示 DP 已针对带宽限制进行了配置。 如果是这种情况,PkgXferMgr 只能对 DP 使用一个线程,因此一次只能向 DP 发送一个包。 有关详细信息 ,请参阅带宽控制和线程

  • PkgXferMgr.log 显示地址已关闭:

    SMS_PACKAGE_TRANSFER_MANAGER 7156 (0x1BF4) Address is closed for priority 2 jobs, stop sending[E:\SCCMContentLib\FileLib\2F08\2F0819F959E788CF843F42E9CA7B44E258B8B4BA37BB63902DB39ACF747BE7DA]  
    SMS_PACKAGE_TRANSFER_MANAGER 7156 (0x1BF4) Deleting remote file \\DPNAME.CONTOSO.COM\SMS_DP$\<PackageID>.6-2F0819F959E788CF843F42E9CA7B44E258B8B4BA37BB63902DB39ACF747BE7DA  
    SMS_PACKAGE_TRANSFER_MANAGER 7156 (0x1BF4) CSendFileAction::SendFiles failed; 0x80004005  
    SMS_PACKAGE_TRANSFER_MANAGER 7156 (0x1BF4) Sending failed. Failure count = 1, Restart time = 3/15/2016 8:30:08 AM Mountain Daylight Time
    

    如果在日志中看到此内容,则表示 DP 处于带宽控制之下,并且内容传输正在进行时 DP 的地址已关闭。 在上面的示例中,DP 计划配置为仅在上午 8:00 到 10:00 期间 允许高优先级 。 因此,PkgXferMgr 在上午 8:00 停止发送内容,并将包/DP 标记为失败状态。

  • PkgXferMgr.log 显示同一作业同时启动的多个线程:

    SMS_PACKAGE_TRANSFER_MANAGER 8360 (0x20a8) Sending thread starting for Job: 12771, package: <PackageID>, Version: 8, Priority: 2, server: DPNAME.CONTOSO.COM, DPPriority: 200  
    SMS_PACKAGE_TRANSFER_MANAGER 10752 (0x2a00) Sending thread starting for Job: 12771, package: <PackageID>, Version: 8, Priority: 2, server: DPNAME.CONTOSO.COM, DPPriority: 200  
    SMS_PACKAGE_TRANSFER_MANAGER 12208 (0x2fb0) Sending thread starting for Job: 12771, package: <PackageID>, Version: 8, Priority: 2, server: DPNAME.CONTOSO.COM, DPPriority: 200  
    SMS_PACKAGE_TRANSFER_MANAGER 4244 (0x1094) Sending thread starting for Job: 12771, package: <PackageID>, Version: 8, Priority: 2, server: DPNAME.CONTOSO.COM, DPPriority: 200  
    SMS_PACKAGE_TRANSFER_MANAGER 8348 (0x209c) Sending thread starting for Job: 12771, package: <PackageID>, Version: 8, Priority: 2, server: DPNAME.CONTOSO.COM, DPPriority: 200
    

    通常,PkgXferMgr 为作业使用一个线程,但如果对同一作业使用多个线程,则内容传输可能会开始失败,因为 错误0x80070020 (ERROR_SHARING_VIOLATION) 。 如果站点服务器和站点数据库服务器位于不同的时区,则会出现这种情况。 此处的解决方案是确保站点服务器和站点数据库服务器具有相同的时区设置。

常见的拉取 DP 问题

  • PkgXferMgr.log 显示拉取 DP 处于容量中,并且不再将作业发送到拉取 DP:

    SMS_PACKAGE_TRANSFER_MANAGER 4712 (0x1268) PullDP ["Display=\\P01PDP1.CONTOSO.COM\"]MSWNET:["SMS_SITE=P01"]\\P01PDP1.CONTOSO.COM\ has reached maximum capacity 50  
    SMS_PACKAGE_TRANSFER_MANAGER 4712 (0x1268) ~ PullDP has no capacity. Restart time = 1/10/2019 1:16:33 PM Eastern Standard Time
    

    PkgXferMgr 运行以下查询来检查拉取 DP 上当前处于未完成状态的作业数。 如果查询返回的作业数超过 50 个,则不会向拉取 DP 发送更多作业。

    SELECT COUNT(*) FROM DistributionJobs job
    JOIN DistributionPoints dp ON dp.DPID=job.DPID AND dp.NALPath='["Display=\\P01PDP1.CONTOSO.COM\"]MSWNET:["SMS_SITE=P01"]\\P01PDP1.CONTOSO.COM\'
    WHERE job.State in (2, 3, 4) AND (job.Action<>5) AND (ISNULL(job.SendAction, '') <> '')
    

    当拉取 DP 发送成功状态消息或状态轮询停止 (基于配置的值) 时,将从表中删除DistributionJobs这些作业。 若要查看拉取 DP 上的作业,可以使用 wbemtest 或 WMI 资源管理器 查看类的 SMS_PullDPNotification 实例计数。 还可以查看拉取 DP 上的 WMI 类实例 ROOT\SCCMDP:SMS_PullDPState ,以识别处于 “失败” 状态的包,查看 PullDP.log 以及 DataTransferService.log 来调查失败。

  • SignatureDownload 请求 DP 上的作业失败并出现 HTTP 404 错误。

    为包 C010000D.28 创建了 Signature 下载 DTS 作业 {JOBID},内容 ID ContentID。 JobState = NotStarted
    收到 C010000D.28 内容作业 {JOBID} 的 DTS 错误消息,0x80070002: BITS 错误:“HTTP 状态 404:服务器上不存在请求的 URL。

    这是一个已知问题,因为站点服务器上并置的源 DP 上不存在签名文件。 仅当分发操作未 重修时,才会发生此问题。

    若要解决此问题,请使用以下某种方法:

    • 重新分发包 (重新分发包不需要下载签名,因为完整内容) 下载。
    • 将请求 DP 配置为使用站点服务器上未并置的源 DP。
  • DataTransferService.log 显示尝试从源 DP 下载内容时的 0x800706D9

    DataTransferService 4864 (0x1300) CDTSJob::HandleErrors: DTS Job '{5285F8B3-C426-4882-85F2-AD5331DD4179}' BITS Job '{D53BA625-24AA-41FA-A357-6EB1B7D7E701}' under user 'S-1-5-18' OldErrorCount 29 NewErrorCount 30 ErrorCode
    

    0x800706D9意味着终结点映射器中不再有可用的终结点。 由于防火墙导致的 RPC 端口分配失败,可能会出现此问题。 禁用 Windows 防火墙 服务时,也可能发生此情况。

    检查站点服务器和受影响的服务器之间是否有防火墙,并找出 RPC 端口 是否已打开。 还可以从拉取 DP 以及源 DP 服务器捕获 网络跟踪 () 同时重现错误以供审阅。

  • 拉取 DP 显示具有大量作业,但作业未得到处理。

    在某些情况下,在安装新的拉取 DP 后,当所有内容都发送到拉取 DP) 时,通常 (,拉取 DP 上的太多作业失败最终会导致作业处理停滞。 尽管这些产品的最新版本 (Configuration Manager 版本 1810) 中修复了其中大多数问题,但某些环境因素可能会导致拉取 DP 不处理作业。 发生这种情况时,你可能会在 WMI 类中看到 ROOT\ccm\DataTransferService:CCM_DTS_JobEx 数千个 DTS 作业,大约 50 个 (或更多) BITS 作业处于 “失败” 状态。 在此方案中,从拉取 DP 上的 WMI 中删除所有特定于作业的项,并以受控方式再次将内容分发到拉取 DP 并调查失败情况可能很有用。

    若要从拉取 DP 上的 WMI 中删除所有特定于作业的项,可以使用以下 PowerShell 脚本 (查看脚本注释以获取帮助) :

    Reset-PullDPState.ps1

    <#
    
    .SYNOPSIS  
    Resets the state of the Pull DP and deletes data from various WMI classes related to Pull DP. You need to run this script as Administrator.
    
    .DESCRIPTION
    This script deletes the data from following WMI classes:
    - CCM_DTS_JobEx
    - CCM_DTS_JobItemEx
    - SMS_PullDPState
    - SMS_PullDPContentState
    - SMS_PullDPNotification (optional)
    
    The script also checks and reports the count of BITS Jobs.
    
    .PARAMETER ComputerName
    (Optional) Name of the Pull DP. You can leave this blank for local machine.
    
    .PARAMETER DeletePullDPNotifications
    (Optional) Use this switch if you want to delete the job notifications from SMS_PullDPNotification class.
    
    .PARAMETER KeepBITSJobs
    (Optional) Use this switch if you don't want the script to delete ALL BITS Jobs. If this switch is not used, ALL BITS jobs are deleted (even the ones that are not created by ConfigMgr)
    
    .PARAMETER NotifyPullDP
    (Optional) Use this switch if you want the script to execute NotifyPullDP method against SMS_DistributionPoint class. This is only useful when there aren't a lot of notifications in WMI and -DeletePullDPNotifications switch was not used.
    
    .PARAMETER WhatIf
    (Optional) Use this switch to see how many instances will be deleted.
    
    .EXAMPLE
    Reset-PullDPState -WhatIf
    This command checks how many Pull PD jobs will get deleted when running the script
    
    .EXAMPLE
    Reset-PullDPState
    This command resets the Pull DP related WMI classes except the Pull DP job Notification XML's
    
    .EXAMPLE
    Reset-PullDPState -DeletePullDPNotifications
    This command resets the Pull DP related WMI classes along with the Pull DP job Notification XML's. If you do this, you would need to distribute/redistribute these packages to the Pull DP again.
    
    .NOTES
    07/28/2016 - Version 1.0 - Initial Version of the script
    01/09/2019 - Version 2.0 - Added batch size for instance removal to prevent WMI Quota issues. Also added removal of BITS jobs (can be disabled by using -KeepBITSJobs switch) and restart of CcmExec service.
    
    #>
    
    [CmdletBinding()]
    Param(
      [Parameter(Mandatory=$false)]
       [string]$ComputerName = $env:COMPUTERNAME,
    
       [Parameter(Mandatory=$false)]
       [switch]$DeletePullDPNotifications,
    
       [Parameter(Mandatory=$false)]
       [switch]$KeepBITSJobs,
    
       [Parameter(Mandatory=$false)]
       [switch]$NotifyPullDP,
    
       [Parameter(Mandatory=$false)]
       [switch]$WhatIf
    )
    
    $LogFile = Join-Path (Split-Path $SCRIPT:MyInvocation.MyCommand.Path -Parent) "Reset-PullDPState.log"
    $ErrorActionPreference = "SilentlyContinue"
    
    Function Write-Log {
        Param(
          [string] $text,
          [switch] $NoWriteHost,
          [switch] $IsErrorMessage,
          [switch] $IsWarning,
          [switch] $WhatIfMode
        )
    
        $timestamp = Get-Date -Format "MM-dd-yyyy HH:mm:ss"
        "$timestamp $text" | Out-File -FilePath $LogFile -Append
    
        if ($WhatIfMode) {
            Write-Host $text -ForegroundColor Yellow
            return
        }
    
        if (-not $NoWriteHost) {
            if ($IsErrorMessage) {
                Write-Host $text -ForegroundColor Red
            }
            elseif ($IsWarning) {
                Write-Host $text -ForegroundColor Yellow
            }
            else {
                Write-Host $text -ForegroundColor Cyan
            }
        }
    }
    
    Function Delete-WmiInstances {
        Param(
            [string] $Namespace,
            [string] $ClassName,
            [string] $Filter = $null,
            [string] $Property1,
            [string] $Property2 = "",
            [string] $Property3 = "",
            [int] $BatchSize = 10000
        )
    
        $success = 0
        $totalfailed = 0
        $counter = 0
        $total = 0
    
        Write-Host ""
        Write-Log "$ClassName - Connecting to WMI Class on $ComputerName"
    
        do {
    
            if ($Filter -eq $null) {
                $Instances = Get-WmiObject -ComputerName $ComputerName -Namespace $Namespace -Class $ClassName -ErrorVariable WmiError -ErrorAction SilentlyContinue | Select -First $BatchSize
            }
            else {
                $Instances = Get-WmiObject -ComputerName $ComputerName -Namespace $Namespace -Class $ClassName -Filter $Filter -ErrorVariable WmiError -ErrorAction SilentlyContinue | Select -First $BatchSize
            }
    
            if ($WmiError.Count -ne 0) {
                Write-Log "    Failed to connect. Error: $($WmiError[0].Exception.Message)" -IsErrorMessage
                $WmiError.Clear()
                return
            }
    
            $currentfailed = 0
            $current = ($Instances | Measure-Object).Count
            if ($current -gt 0) {$script:serviceRestartRequired = $true}
            if ($WhatIf) { break }
    
            if ($current -ne $null -and $current -gt 0) {
                Write-Log "    Found $total total instances (Batch size $BatchSize)"
    
                foreach($instance in $Instances) {
    
                    $instanceText = "$Property1 $($instance.$Property1)"
    
                    if ($Property2 -ne "") {
                        $instanceText += ", $Property2 $($instance.$Property2)"
                    }
    
                    if ($Property3 -ne "") {
                        $instanceText += ", $Property3 $($instance.$Property3)"
                    }
    
                    Write-Log "    Deleting instance for $instanceText" -NoWriteHost
                    $counter += 1
    
                    $percentComplete = "{0:N2}" -f (($counter/$total) * 100)
                    Write-Progress -Activity "Deleting instances from $ClassName" -Status "Deleting instance #$counter/$total - $instanceText" -PercentComplete $percentComplete -CurrentOperation "$($percentComplete)% complete"
    
                    Remove-WmiObject -InputObject $instance -ErrorVariable DeleteError -ErrorAction SilentlyContinue
                    if ($DeleteError.Count -ne 0) {
                        Write-Log "    Failed to delete instance. Error: $($DeleteError[0].Exception.Message)" -NoWriteHost -IsErrorMessage
                        $DeleteError.Clear()
                        $currentfailed += 1
                    }
                    else {
                        $success += 1
                    }
                }
    
                $totalfailed += $currentfailed
    
                if ($currentfailed -eq $current) {
                    # Every instance in current batch failed. Break to avoid infinite while loop
                    break
                }
            }
    
        } while (($Instances | Measure-Object).Count -ne 0)
    
        if ($WhatIf) {
            if ($total -eq $BatchSize) {
                Write-Log "    (What-If Mode) Found more than $BatchSize instances which will be deleted" -WhatIfMode
            }
            else {
                Write-Log "    (What-If Mode) $total instances will be deleted" -WhatIfMode
            }
        }
        else {
            if ($total -gt 0) {
                # $totalfailed is likely not the accurate count here as it could include duplicate failures due to batching
                Write-Log "    Deleted $success instances. Failed to delete $totalfailed instances."
            }
            else {
                Write-Log "    Found 0 instances."
            }
        }
    }
    
    Function Check-BITSJobs {
    
        $DisplayName = "BITS Jobs"
    
        Write-Host ""
        Write-Log "$DisplayName - Gettting jobs on $ComputerName"
        Import-Module BitsTransfer
        $Instances = Get-BitsTransfer -AllUsers -Verbose -ErrorVariable BitsError -ErrorAction SilentlyContinue | Where-Object {$_.DisplayName -eq 'CCMDTS Job'}
    
        if ($BitsError.Count -ne 0) {
            Write-Log "    $DisplayName - Failed to get jobs. Error: $($BitsError[0].Exception.Message)" -IsErrorMessage
            $BitsError.Clear()
        }
        else {
            $total = ($Instances | Measure-Object).Count
            Write-Log "    $DisplayName - Found $total jobs"
    
            if ($KeepBITSJobs) {
                Write-Log "    BITS Jobs will not be removed because KeepBITSJobs is true." -WhatIfMode
            }
            else {
                if ($WhatIf) {
                    Write-Log "    (What-If Mode) ALL BITS jobs will be removed since KeepBITSJobs is NOT specified." -WhatIfMode
                }
                else {
                    if ($total -gt 0) {
                        Write-Log "    Removing ALL jobs since KeepBITSJobs is NOT specified."
                        Remove-BITSJobs
                    }
                    else {
                        Write-Log "    There are no jobs to delete."
                    }
                }
            }
        }
    }
    
    Function Remove-BITSJobs {
    
        try {
            Stop-Service BITS
            Rename-Item "$($env:ALLUSERSPROFILE)\Microsoft\Network\Downloader" -NewName "Downloader.OLD.$([Guid]::NewGuid().Guid.Substring(0,8))"
            Start-Service BITS
            $script:serviceRestartRequired = $true
            Write-Log "    Removed ALL BITS Jobs successfully."
        } catch {
            Write-Log "    Failed to delete the BITS jobs."
            Write-Log "    If necessary, run 'bitsadmin /reset /allusers' command under SYSTEM account (using psexec.exe) to delete the BITS Jobs."
            Write-Log "    Additionally, you can delete these jobs by stopping BITS service, renaming %allusersprofile%\Microsoft\Network\Downloader folder, and starting BITS service."
        }
    }
    
    Function Restart-CcmExec {
    
        $DisplayName = "SMS Agent Host"
    
        Write-Host ""
        Write-Log "$DisplayName - Checking if service restart is required."
        if ($script:serviceRestartRequired) {
    
            if ($WhatIf) {
                Write-Log "    (What-If Mode) Service Restart will be required." -WhatIfMode
                if ($NotifyPullDP) {
                    Write-Log "    (What-If Mode) NotifyPullDP method will be executed." -WhatIfMode
                }
                else {
                    Write-Log "    (What-If Mode) NotifyPullDP method will NOT be executed because -NotifyPullDP switch was NOT used." -WhatIfMode
                }
                return
            }
    
            try {
                Write-Host ""
                Write-Log "### Restarting CCMEXEC service... ###"
                Restart-Service CcmExec
                Write-Log "### Success! ###"
            } catch {
                Write-Log "### ERROR! Restart CcmExec Manually in order to recreate BITS jobs for content transfer! ###"
            }
    
            if (-not $DeletePullDPNotifications -and $NotifyPullDP) {
                # Only do this if notifications were not deleted. If they were deleted, NotifyPullDP will not do anything.
                try {
                    Write-Host ""
                    Write-Log "### Invoking NotifyPullDP WMI method against the SMS_DistributionPoint class in $DPNamespace."
                    Invoke-WmiMethod -Namespace root\SCCMDP -Class SMS_DistributionPoint -Name NotifyPullDP | Out-Null
                    Write-Log "### Success! ###"
                } catch {
                    Write-Log "### ERROR! Failed to invoke NotifyPullDP method! You can use wbemtest or WMI Explorer to invoke the method manually. ###"
                }
            }
            else {
                if (-not $NotifyPullDP) {
                    Write-Log "### Skipped invoking NotifyPullDP WMI method because -NotifyPullDP was NOT specified" -IsWarning
                    Write-Log "### You can use wbemtest or WMI Explorer to invoke the method manually, if necessary. ###"
                }
    
                if ($DeletePullDPNotifications) {
                    Write-Log "### Skipped invoking NotifyPullDP WMI method because -DeletePullDPNotifications was specified" -IsWarning
                    Write-Log "### Executing NotifyPullDP when there are no notifications does not do anything." -IsWarning
                }
    
            }
        }
        else {
            Write-Log "    Service Restart is NOT required. " -WhatIfMode
            if ($NotifyPullDP) {
                Write-Log "    NotifyPullDP method skipped. " -WhatIfMode
            }
        }
    }
    
    Write-Host ""
    Write-Log "### Script Started ###"
    $script:serviceRestartRequired = $false
    
    if ($WhatIf) {
        Write-Host ""
        Write-Log "*** Running in What-If Mode" -WhatIfMode
    }
    
    $DPNamespace = "root\SCCMDP"
    $DTSNamespace = "root\CCM\DataTransferService"
    
    Delete-WmiInstances -Namespace $DTSNamespace -ClassName "CCM_DTS_JobEx" -Filter "NotifyEndpoint like '%PullDP%'" -Property1 "ID"
    Delete-WmiInstances -Namespace $DTSNamespace -ClassName "CCM_DTS_JobItemEx" -Property1 "JobID"
    Delete-WmiInstances -Namespace $DPNamespace -ClassName "SMS_PullDPState" -Property1 "PackageID" -Property2 "PackageVersion" -Property3 "PackageState"
    Delete-WmiInstances -Namespace $DPNamespace -ClassName "SMS_PullDPContentState" -Property1 "PackageKey" -Property2 "ContentId" -Property3 "ContentState"
    
    if ($DeletePullDPNotifications) {
        Delete-WmiInstances -Namespace $DPNamespace -ClassName "SMS_PullDPNotification" -Property1 "PackageID" -Property2 "PackageVersion"
    }
    else {
        Write-Host ""
        Write-Log "SMS_PullDPNotification - Connecting to WMI Class on $ComputerName"
    
        $temp = Get-WmiObject -ComputerName $ComputerName -Namespace $DPNamespace -Class "SMS_PullDPNotification" -ErrorVariable WmiError -ErrorAction SilentlyContinue
    
        if ($WmiError.Count -ne 0) {
            Write-Log "    SMS_PullDPNotification - Failed to connect. Error: $($WmiError[0].Exception.Message)" -IsErrorMessage
            $WmiError.Clear()
        }
        else {
            Write-Log "    Found $(($temp | Measure-Object).Count) instances."
            Write-Log "    Skipped because DeletePullDPNotifications switch was NOT used." -IsWarning
        }
    }
    
    if ($ComputerName -eq $env:COMPUTERNAME) {
        Check-BITSJobs
    }
    else {
        Write-Host ""
        Write-Log "BITS Jobs"
        Write-Log "    Skipped because script is running against a remote computer." -IsWarning
    }
    
    Restart-CcmExec
    
    Write-Host ""
    Write-Log "### Script Ended ###"
    Write-Host "### Check $LogFile for more details. ###" -ForegroundColor Cyan
    #if (-not $WhatIf -and $serviceRestartRequired) {Write-Log "### Please restart the WMI service (which also restarts CcmExec). ###" -IsWarning}
    Write-Host ""
    
  • 内容 显示在拉 取 DP 上安装,但拉取 DP 的 URL 和 URLSubPath 未填充在 中 ContentDPMap,这会导致启用了 SMB 访问的包出现问题。

    当拉取 DP 成功安装内容时,它会发送一条状态消息,其中包含更新 URL/URLSubPathContentDPMap值所需的数据。 处理拉取 DP 响应时会发生这种情况。 查看 分发包以拉取 DP 中的步骤 16-22 以了解流并查看相关日志以调查未处理状态消息的原因。 此问题的最有可能原因是管理点上的 积压状态消息 \MP\outboxes\StateMsg.box ,或者 MPFDM 由于权限问题而无法将文件复制到站点服务器。

内容库中缺少内容文件

有时,你会注意到内容库中缺少内容。 这可能是由于以前的内容分发问题或有人/有人意外从内容库中删除文件而导致的。 若要确认内容库中缺少内容,请标识受影响的包,并将包内容从 PkgLib 跟踪到 FileLib

确认内容库中缺少包的必需内容后,请参阅将 包的压缩副本重新发送到网站 ,了解如何重新填充内容。

一般问题

  • DistMgr 或 PkgXferMgr 日志显示找不到文件/路径错误:

    SMS_PACKAGE_TRANSFER_MANAGER 3776 (0xec0) CContentDefinition::TotalFileSizes failed; 0x80070003
    SMS_PACKAGE_TRANSFER_MANAGER 3776 (0xec0) Sending content 000f8a0a-825c-457b-a15b-57ade145a09b for package \<PackageID>
    SMS_PACKAGE_TRANSFER_MANAGER 3776 (0xec0) CSendFileAction::SendFiles failed; 0x80070003
    SMS_PACKAGE_TRANSFER_MANAGER 3776 (0xec0) CSendFileAction::SendContent failed; 0x80070003
    SMS_PACKAGE_TRANSFER_MANAGER 648 (0x288) Sent status to the distribution manager for pkg <PackageID>, version 14, status 4 and distribution point ["Display=\\DPNAME.CONTOSO.COM\"]MSWNET:["SMS_SITE=S01"]\\DPNAME.CONTOSO.COM\~
    

    SMS_PACKAGE_TRANSFER_MANAGER 11228 (0x2bdc) Sending legacy content P0100053.2 for package <PackageID>  
    SMS_PACKAGE_TRANSFER_MANAGER 11228 (0x2bdc) CContentDefinition::TotalFileSizes failed; 0x80070003  
    SMS_PACKAGE_TRANSFER_MANAGER 11228 (0x2bdc) CSendFileAction::SendFiles failed; 0x80070003
    

    常见错误代码: 0x800700020x80070003

    对于“找不到文件/路径”错误,问题可能是由于站点服务器上的内容库缺少包的内容文件。 因此,PkgXferMgr 无法将文件发送到 DP。

    在这些情况下,可以从日志中标识内容 ID,并从 中跟踪内容PkgLibFileLib,以确保文件存在。 如果包内容文件在内容库中可用,还可以使用内容库资源管理器检查,但是,加载内容库资源管理器可能需要一些时间,并且手动跟踪从 PkgLibFileLib的内容可能更容易。 或者,可以捕获 进程监视器 跟踪,以验证站点服务器上的内容库中是否缺少必要的文件。

    如果内容库中缺少内容的站点是包源站点,则需要更新包以递增包源版本,以便 DistMgr 再次从包源目录中获取内容快照,并重新填充缺少的内容。

    如果内容库中缺少内容的站点与包源站点不同,则可以强制包源站点将包的压缩副本重新发送到受影响的站点。 有关详细信息 ,请参阅将包的压缩副本重新发送到站点

  • DistMgr/PkgXferMgr 日志显示网络错误:

    SMS_DISTRIBUTION_MANAGER 5112 (0x13f8) Failed to make a network connection to \\DPNAME.CONTOSO.COM\ADMIN$ (0x35).~  
    SMS_DISTRIBUTION_MANAGER 5112 (0x13f8) ~Cannot establish connection to ["Display=\\DPNAME.CONTOSO.COM\"]MSWNET:["SMS_SITE=PS1"]\\DPNAME.CONTOSO.COM\. Error = 53
    SMS_DISTRIBUTION_MANAGER 5112 (0x13f8) Error occurred. Performing error cleanup prior to returning.
    

    常见错误代码: 235364

    对于与网络相关的错误,请查看日志,并在收到错误时标识你尝试与之通信的服务器。 识别后,测试以下内容:

    1. 是否可以使用 FQDN/NetBIOS/IP 地址对受影响的 SERVERNAME 执行 ping 操作?
    2. 是否可以使用站点服务器的系统帐户使用 FQDN/NetBIOS/IP 地址访问 \\SERVERNAME\admin$ 共享?
    3. 是否可以使用站点服务器的已登录用户帐户使用 FQDN/NetBIOS/IP 地址访问 \\SERVERNAME\admin$ 共享?
    4. 站点服务器和受影响的服务器之间是否有防火墙? RPC /SMB (相关端口是否) 打开?

    如果上述测试成功,请从站点服务器以及受影响的服务器捕获 网络跟踪 () ,同时重现错误以供审阅。

  • DistMgr/PkgXferMgr 日志显示访问被拒绝错误:

    SMS_DISTRIBUTION_MANAGER    7076 (0x1ba4)    Taking package snapshot for package <PackageID> from source \\PS1SITE\PKGSOURCE\DummyPackage
    SMS_DISTRIBUTION_MANAGER    7076 (0x1ba4)    ~The source directory \\PS1SITE\PKGSOURCE\DummyPackage doesn't exist or the SMS service cannot access it, Win32 last error = 5
    SMS_DISTRIBUTION_MANAGER    7076 (0x1ba4)    ~Failed to take snapshot of package <PackageID>
    

    常见错误代码:5,0x80070005

    对于与权限相关的错误,请查看日志,并确定在收到错误时尝试访问的路径。 识别后,测试以下内容:

    1. 如果路径是 UNC 路径,是否可以 ping 受影响的 SERVERNAME?
    2. 站点服务器计算机帐户是否有权访问路径?
    3. 从站点服务器使用 SYSTEM 帐户时,是否可以使用 FQDN/NetBIOS/IP 地址访问受影响的路径?
    4. 使用站点服务器中登录的用户帐户时,是否可以使用 FQDN/NetBIOS/IP 地址访问受影响的路径?
    5. 站点服务器和受影响的服务器之间是否有防火墙? RPC /SMB (相关端口是否) 打开?

    如果上述测试成功,请从站点服务器捕获 进程监视器 跟踪,同时重现错误以供审阅。

  • DistMgr/PkgXferMgr 查找目录中的内容 \bin\x64\FileLib ,而不是实际的内容库位置。

    这是由于内容库传输工具中的已知问题导致的。