内容分发疑难解答

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

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

示例问题

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

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

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

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

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

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

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

  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.
    

    当内容从一个站点传输到另一个站点时,通常会暂时发生这种情况。 查看发送方/Despooler 日志,确保站点通信没有问题。 如果在站点到站点通信期间看到错误(计划程序 ->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 文件由主 DistMgr 线程处理,因此在这些情况下,通过查找 SMS_EXECUTIVE启动SMS_DISTRIBUTION_MANAGER 日志条目来标识主 DistMgr 线程 ID 会很有帮助,然后筛选 标识的线程 ID DistMgr.log

    在大多数情况下,当主 DistMgr 线程对远程 DP 进行 WMI 调用但 DP 上的 WMI 未响应时,会出现此问题,导致 DistMgr 无限期等待。 筛选主 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:00AM 到 10:00AM 期间才配置为 允许高优先级 。 因此,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 内容 ID ContentID 创建了 SignatureDownload DTS 作业 {JOBID}。 JobState = NotStarted
    为 C010000D.28 收到的 DTS 错误消息,内容作业 {JOBID},0x80070002: BITS 错误:“HTTP 状态 404:服务器上不存在请求的 URL。

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

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

    • 重新分发包(重新分发包不需要下载签名,因为下载完整内容)。
    • 将拉取 DP 配置为使用未在站点服务器上并置的源 DP。
  • 尝试从源 DP 下载内容时,DataTransferService.log显示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 类中的数千个 DTS 作业,以及处于“失败”状态的ROOT\ccm\DataTransferService:CCM_DTS_JobEx大约 50 个(或更多)位作业。 在此方案中,从拉取 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 响应时,会发生这种情况。 查看分发包中的 步骤 16-22 以拉取 DP 以了解流,并查看相关日志以调查状态消息未得到处理的原因。 此问题的最有可能原因是管理点上的 \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
    

    常见错误代码:0x80070002,0x80070003

    对于文件/路径找不到错误,问题可能是因为站点服务器上的内容库缺少包的内容文件。 因此,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.
    

    常见错误代码:2、3、5364

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

    1. 是否可以使用 FQDN/NetBIOS/IP 地址 ping 受影响的 SERVERNAME?
    2. 是否可以使用站点服务器的 SYSTEM 帐户通过 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 ,而不是实际的内容库位置。

    这是因为内容库传输工具中存在已知问题。