Automating the Collection of Configuration Manager Client Logs

Hello everyone! Seth Price here to talk with you today about automating the collection of Configuration Manager client logs. Configuration Manager client logs are useful in troubleshooting many types of client issues including client installation, client health, software update installation, hardware inventory, and client policy. In many cases the administrator assisting with troubleshooting client issues does not have direct access to the systems with the required logs. This increases the time required to troubleshoot client issues, especially when multiple clients are involved or when clients are across multiple time zones. The following is a way for the Config Manager administrator to automate the collection of the client logs.

The Configuration Manager client logs are stored in several folders, one for client logs, and one for client installation logs. The client installation log folder is located on the system drive under Windows\ccmsetup\logs. The client logs folder is normally located on the system drive under Windows\ccm\logs, however this location may be different in some situations. You can get the location of the client logs by running the following powershell command:
Get-itemproperty “hklm:\software\Microsoft\ccm\logging\@global” | select –expandproperty Logdirectory

In order to automate the collection of the client logs we need to create a shared folder to copy the logs to, and a ConfigMgr package to deploy to clients. In a small environment creating a single share location may be fine, however, in larger multi-site environments we would want to reduce WAN traffic as much as possible when copying client log files. One possibility is creating the shared folder on the ConfigMgr management point assigned to the client. Each client would then copy log files to its associated management point instead of a single location across a WAN link. We can get the clients management point by running the following powershell command:
(get-ciminstance –namespace root\ccm\locationservices –class sms_mpinformation).MP[0]

Now that we have the location of the client logs and a location to create the shared folders, we can begin to automate log collection. Client logs will be collected by deploying a package that runs a powershell script on the client. The required shared folders can be created by using compliance settings in ConfigMgr. By using compliance settings we can ensure that any new management point installed will automatically have the required share created.

Creating the required shared folders using compliance settings

  1. Create the Configuration Item and Configuration Baseline

    a. Create a new configuration item named CM-ClientLogShare

b. Select all versions of Windows

c. On the Specify settings for this operating system click New…

d. Provide a Name for the setting

Setting type: Script
Data type: Integer

e. Add the discovery and remediation scripts then click OK

 

Discovery script (Script Language: Windows Powershell)





[cmdletbinding()]
#### Script Variables  ####
$SharePath = "\\$env:COMPUTERNAME\Clientlogs"
$ScriptName = "CCM Log Discovery"

#### Error Variables ####
$EventID = 0
$EntryType = 'Information'
$LogName = 'ConfigMgr'
$Trace = @()

#### Begin Script ####

try{
    #### Create EventLog ####
    $Trace += "Compliance Discovery"
    $Action = "Create EventLog $($LogName)"
    $Trace += "Begin $Action"

    New-EventLog -LogName $LogName -Source $ScriptName -ErrorAction Stop

}catch{
    If ($_.Exception.Message -like "* source is already registered*"){
        #Do nothing expected error for existing log
    }else{
        $Trace += "$Action Failed with Error: $($_.Exception.Message)"
        $EventID = 1
        $EntryType = "Error"
        Write-EventLog -LogName $LogName -Source $ScriptName -EntryType $EntryType -EventID $EventID -Message "$ScriptName Failed with Error: $($_.Exception.Message)... 'r'n$($Trace|Out-String)"
        return 0
    }
}

Try{
    #### Test Share Path ####
    $Trace += "$Action Complete"
    $Action = "Test Share Path"
    $Trace += "Begin $Action"

    [int]$ShareExists = Test-Path $SharePath
    if ($ShareExists -eq 1) {
        $Trace += "$Action Complete, $($env:COMPUTERNAME) is compliant"
        Write-EventLog -LogName $LogName -Source $ScriptName -EntryType $EntryType -EventID $EventID -Message "$ScriptName Failed with Error: $($_.Exception.Message)... 'r'n$($Trace|Out-String)"
        return $ShareExists
    }Else{
        $Trace += "$Action Complete, $($env:COMPUTERNAME) is non-compliant"
        Write-EventLog -LogName $LogName -Source $ScriptName -EntryType $EntryType -EventID $EventID -Message "$ScriptName Failed with Error: $($_.Exception.Message)... 'r'n$($Trace|Out-String)"
        return $ShareExists
    }

}catch{
    $Trace += "$Action Failed with Error: $($_.Exception.Message)"
    $EventID = 1
    $EntryType = "Error"
    Write-EventLog -LogName $LogName -Source $ScriptName -EntryType $EntryType -EventID $EventID -Message "$ScriptName Failed with Error: $($_.Exception.Message)... 'r'n$($Trace|Out-String)"
    return 0
} 

#### Script End #### 

 

Remediation script (Script Language: Windows Powershell)





[cmdletbinding()]
#### Script Variables ####
$ScriptName = "CCM Share Repository"
$Hostname = $env:COMPUTERNAME
$Domain = get-wmiobject win32_computersystem | select -expandproperty domain
$Sharepath = 'E:\ClientLogs'
$ChangeAccess = 'Domain Computers'
$FullAccess = 'administrators'
$Shares = [WMICLASS]"Win32_Share"
$ShareName = 'ClientLogs'

#### Error Variables
$EventID = 0
$EntryType = 'Information'
$LogName = 'ConfigMgr'
$Trace = @()

#### Begin Script ####

try{
    #### Create EventLog ####
    $Trace += "Compliance Remeditation"
    $Action = "Create EventLog $($LogName)"
    $Trace += "Begin $Action"

    New-EventLog -LogName $LogName -Source $ScriptName -ErrorAction Stop

}catch{
    If ($_.Exception.Message -like "* source is already registered*"){
        #Do nothing expected error for existing log
    }else{
        $Trace += "$Action Failed with Error: $($_.Exception.Message)"
        $EventID = 1
        $EntryType = "Error"
        Write-EventLog -LogName $LogName -Source $ScriptName -EntryType $EntryType -EventID $EventID -Message "$ScriptName Failed with Error: $($_.Exception.Message)... 'r'n$($Trace|Out-String)"
        return 0
    }
}

try{
    #### Create SMB Directory and Share ####
    $Trace += "$Action Complete"
    $Action = "Test Share Directory Path"
    $Trace += "Begin $Action"

    If (!(Test-Path $Sharepath)) {
    $Trace += "$Action Complete and $($SharePath) does not exist."
    $Action = " Create directory $SharePath"
    $Trace += "Begin $Action"
    New-Item $Sharepath -type Directory
  }

  $Trace += "$Action Complete"
  $Action = "Create SMB Share ClientLogs"
  $Trace += "Begin $Action"

  #### Test for shared folder, if not there then create it ####
  If(!(Get-WMIObject Win32_Share -filter "name='$($ShareName)'")) {
    New-SmbShare -Name "$ShareName" -Path "$Sharepath" -FullAccess "$FullAccess" -ChangeAccess "$Domain\$ChangeAccess"
  }

  $Trace += "$Action Complete"
  Write-EventLog -LogName $LogName -Source $ScriptName -EntryType $EntryType -EventID $EventID -Message "$ScriptName Remediation completed and successfully created SMB share $($ShareName)"
}catch{
    $Trace += "$Action Failed with Error: $($_.Exception.Message)"
    $EventID = 1
    $EntryType = "Error"
    Write-EventLog -LogName $LogName -Source $ScriptName -EntryType $EntryType -EventID $EventID -Message "$ScriptName Failed with Error: $($_.Exception.Message)...'r'n$($Trace|Out-String)"
}

#### Script End #### 

 

Note1: The log share created in the remediation script is created on the E:\ of the management point server. To change this location modify variable $Sharepath in the remediation script above.

Note2: The discovery and remediation scripts will create an Event Log "ConfigMgr" on the management point servers as shown below: This can be used to troubleshoot discovery and remediation script execution.

f. Select the Compliance Rules tab, click New…

     i. Provide a name for the compliance condition

     ii. Under Selected setting: Choose the setting created in the last step

     iii. Rule type: Value

     iv. Under setting must comply with the following rule:

             The value returned by the specified script: Equals 1

     v. Select check boxes for:

            Run the specified remediation script when the setting is noncompliant

            Report noncompliance if this setting instance is not found

g. Complete the Create Configuration Item Wizard

h. Create a configuration baseline for deployment

     i. Provide a name for the configuration baseline

     ii. Under Configuration Data, add the configuration item created in the last step


 

2. Create a collection to deploy the configuration baseline

This collection will contain all the Configuration Manager servers with the Management Point role installed

To create the collection use the following query criteria:

Verify the newly created collection contains the expected management point servers

2a. Deploy the configuration baseline to the management point collection created in step 2

In the ConfigMgr console under Assets and Compliance > Compliance Settings > Configuration Baselines, right click the CCM Client Log Share baseline and click deploy
Verify the baseline is selected

Select Remediate noncompliant rules when supported

Select Allow remediation outside the maintenance window

Under Select the collection for this configuration baseline deployment, choose the collection created in step 2

Configure a schedule for how often the compliance rule should run

Click OK

 

2b. Verify the shared folder is created on the management point servers after the compliance rule has run

Folder Name: Clientlogs

Share Name: Clientlogs

Share permissions:

Domain Computers (Change, Read)

Administrators (Full Control)

NTFS permissions:

Creator Owner (Special)

System (Full Control)

Administrators (Full Control)

Users (Read and Execute)

Create and deploy the package to copy client log files

When deployed to a device collection this package will execute a script that completes the following:

  1. Creates a zip file containing the client log directories
  2. Copies the zip file to the shared drive on the clients associated management point
  3. Removes the zip file on the client

Follow these steps to create the package:

  1. Create a powershell script named ArchiveCCMLogs.ps1 with the following content:
      
      
      
      #Set Variables
      $Hostname = get-content env:computername
      $date = Get-Date -Format yyyy-MM-dd
      $Foldername = "$Hostname-CCMLogs-$Date"
      $CcmclientLogsdir = get-itemproperty "hklm:\software\Microsoft\ccm\logging\@global" | select -expandproperty Logdirectory
      $MP = (get-ciminstance –namespace root\ccm\locationservices –class sms_mpinformation).MP[0]
      
      #Create local directories
      New-Item -itemType Directory -Path C:\Temp -Name $Foldername
      New-Item -itemType Directory -Path C:\Temp\$foldername -name CCMSetupLogs
      New-Item -itemType Directory -Path C:\Temp\$foldername -name CCMClientLogs
      
      #Copy log folders to temp directory
      copy-item $ccmclientlogsdir\*.log c:\temp\$Foldername\ccmclientlogs
      copy-item c:\windows\ccmsetup\logs\*.log c:\temp\$foldername\ccmsetuplogs
      
      #Compress folder and send to MP share
      #Note: Compress-Archive requires Powershell 5
      Compress-Archive -path C:\Temp\$Foldername -DestinationPath C:\Temp\"$foldername.zip"
      copy-item c:\temp\"$foldername.zip" \\$MP\ClientLogs
      
      #Remove Local folder and zip file
      Remove-Item c:\temp\$foldername -Recurse
      Remove-Item c:\temp\$foldername.zip -Recurse 
      
       #### Script End #### 
      
      

  2. Create a new package with source files, ArchiveCCMLogs.ps1 will be in the source file location for the package
  3. Create a program for the new package:

Command line: %WINDIR%\Sysnative\WindowsPowerShell\v1.0\powershell.exe -executionpolicy bypass -file ArchiveCCMLogs.ps1

Configure to run with administrative rights (Whether or not a user is logged on)

Accept all other defaults by clicking OK

4. Distribute the package to your distribution points

5. Create a new deployment collection with no members, deploy this package to the collection as either required, or available

6. Add clients to the deployment collection to collect client logs

Note: Once the client updates policy and executes the script, the client logs will be on the share associated with the system's management point