다음을 통해 공유


콘텐츠 배포 문제 해결

이 문서에서는 일반적인 콘텐츠 배포 문제를 해결하는 방법을 설명합니다.

원래 제품 버전: Configuration Manager 현재 분기, Microsoft System Center 2012 Configuration Manager, Microsoft System Center 2012 R2 Configuration Manager

샘플 문제

이 예제에서는 패키지를 배포 지점에 배포했지만 패키지가 DP에 대해 실패 또는 진행 중 상태라고 가정해 보겠습니다.

  1. 먼저 DP가 있는 사이트(기본/보조)에서 DistMgr.log 검토합니다.

    1. 로그에서 ~Processing 패키지 항목을 찾고 해당 패키지 ID에 대한 패키지 처리 스레드를 식별합니다. 식별한 스레드 ID에 대한 DistMgr.log 필터링합니다. 표준 DP에 패키지 배포의 4단계를 검토하여 로그 발췌 내용을 확인합니다.
    2. 필터링된 로그를 검토하고 해당 DP에 대해 DP 스레드가 만들어졌는지 검사. 스레드 ID에 대한 DistMgr.log 필터링하여 이 작업을 더 쉽게 수행합니다.
    3. 필터링된 로그를 검토하고 PkgXferMgr 작업이 만들어졌는지 검사.
  2. DP가 있는 사이트(기본/보조)에서 PkgXferMgr.log 검토합니다.

    1. 로그에 ID 항목이 있는 검색된 보내기 요청을 찾고 영향을 받는 DP/패키지 조합에 대한 전송 스레드를 식별합니다. 식별된 스레드 ID에 대한 PkgXferMgr.log 필터링합니다. 표준 DP에 패키지 배포의 6단계를 검토하여 로그 발췌 내용을 확인합니다.
    2. 필터링된 로그를 검토하여 콘텐츠가 DP로 성공적으로 전송되었는지 또는 오류가 있는지 확인합니다.
  3. 표준 DP의 경우 PkgXferMgr은 콘텐츠 파일을 DP에 복사하고, WMI 메서드를 호출하여 DP WMI 공급자에게 콘텐츠 라이브러리에 파일을 추가하도록 지시합니다. DP에서 SMSDPProv.log 검토하여 콘텐츠 라이브러리에 콘텐츠가 추가되었는지 확인합니다. 표준 DP에 패키지 배포의 7단계를 검토하여 로그 발췌 내용을 확인합니다.

    끌어오기 DP의 경우 PkgXferMgr은 끌어오기 DP에 콘텐츠 다운로드를 시작하도록 알릴 수 있습니다. DP를 끌어오기 위해 패키지 배포의 8-16단계를 검토하여 흐름을 이해하고 PullDP.log 검토하고 DataTransferService.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.
    

    일반적으로 콘텐츠가 한 사이트에서 다른 사이트로 전송되는 동안 일시적으로 발생합니다. 보낸 사람/데스풀러 로그를 검토하여 사이트 통신에 문제가 없는지 확인합니다. 사이트 간 통신 중에 오류가 표시되는 경우(Scheduler ->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:00~오전 10:00 동안만 높은 우선 순위 허용 에 대해 구성되었습니다. 그 결과 PkgXferMgr은 오전 8시에 콘텐츠 전송을 중지하고 패키지/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 Explorer 사용하여 클래스의 instance 개수를 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, 콘텐츠 작업 {JOBID}, 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에 콘텐츠가 성공적으로 설치되면 의 값을 ContentDPMap업데이트 URL/URLSubPath 하는 데 필요한 데이터가 포함된 상태 메시지를 보냅니다. 이는 끌어오기 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
    

    일반적인 오류 코드: 0x80070002, 0x80070003.

    파일/경로를 찾을 수 없는 오류의 경우 사이트 서버의 콘텐츠 라이브러리에 패키지에 대한 콘텐츠 파일이 누락되어 문제가 발생할 수 있습니다. 따라서 PkgXferMgr은 파일을 DP로 보낼 수 없습니다.

    이러한 경우 로그에서 콘텐츠 ID를 식별하고 에서 로의 콘텐츠를 PkgLibFileLib 추적하여 파일이 있는지 확인할 수 있습니다. 콘텐츠 라이브러리 Explorer 사용하여 콘텐츠 라이브러리에서 패키지 콘텐츠 파일을 사용할 수 있는지 검사 수 있지만 콘텐츠 라이브러리 Explorer 로드하는 데 다소 시간이 걸릴 수 있으며 에서 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, 53, 64.

    네트워크 관련 오류의 경우 로그를 검토하고 오류가 발생할 때 통신하려는 서버를 식별합니다. 식별되면 다음을 테스트합니다.

    1. FQDN/NetBIOS/IP 주소를 사용하여 영향을 받는 SERVERNAME을 ping할 수 있나요?
    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 경로인 경우 영향을 받는 SERVERNAME을 ping할 수 있나요?
    2. 사이트 서버 컴퓨터 계정에 경로에 액세스할 수 있는 권한이 있나요?
    3. 사이트 서버에서 SYSTEM 계정을 사용할 때 FQDN/NetBIOS/IP 주소를 사용하여 영향을 받는 경로에 액세스할 수 있나요?
    4. 사이트 서버에서 로그인한 사용자 계정을 사용할 때 FQDN/NetBIOS/IP 주소를 사용하여 영향을 받는 경로에 액세스할 수 있나요?
    5. 사이트 서버와 영향을 받는 서버 사이에 방화벽이 있나요? 관련 포트(RPC/SMB)가 열려 있나요?

    위의 테스트가 성공하면 검토 오류를 재현하는 동안 사이트 서버에서 프로세스 모니터 추적을 캡처합니다.

  • DistMgr/PkgXferMgr은 실제 콘텐츠 라이브러리 위치 대신 디렉터리에서 \bin\x64\FileLib 콘텐츠를 찾습니다.

    이는 콘텐츠 라이브러리 전송 도구의 알려진 문제 때문입니다.