Wednesday, October 30, 2013

SCCM 2012 Client Troubleshooting

In an earlier post I put up a script to re-install the SCCM client and rebuild the repository.  Sometimes the problem is a little bit deeper.  Here is a sticky dump of all the problems / solutions that I have come across.

NOTE: I can't guarentee these will work in your environment, or even break stuff.  But from my experience this has all been successful for me.

If the SCCM 2012 client won't install

Client.MSI.log Error 8004100E stating "Setup was unable to compile the file discoverystatus.mof <someFile> <someError> 8004100E"

Repair the Microsoft Policy Platform as follows.  REF: Technet Forums, though I modified it.

1) Open an elevated command prompt.
    NOTE: I'm usually doing this in a remote command line which works fine.
2) cd "c:\Program Files\Microsoft Policy Platform"
3) net stop winmgmt /y
4) for %i in (*.dll) do regsvr32 /s %i
5) net start winmgmt
5) for %i in (*.mof) do mofcomp %i
    NOTE: there will be some errors, the most important success is ExtendedStatus.mof
6) for %i in (*.mfl) do mofcomp %i
    NOTE: there are typically no mfl files to comp
7) Re-run ccmsetup.exe

CCMSetup.log Error 80070643 preceeded by "The current version of Microsoft Policy Platform is already installed.  Setup will now exit"

Manually uninstall Microsoft Policy Platform

1) Open an elevated command prompt.
     NOTE: I'm usually doing this in a remote command line which works fine.
2) cd "c:\Program Files\Microsoft Policy Platform"
3) msiexec.exe /x MicrosoftPolicyPlatformSetup.msi /qn /l* mpp.log
4) Re-run ccmsetup.exe

Setup log hangs for more than 20 minutes.  Technically it's the ccmsetup service that hangs.  This is probably unique to our environment but if you use McAfee products:

1) Log onto the machine (remote is fine)
2) Right click McAfee in the taskbar and select Update Secuirty
3) Bounce the box and re-run ccmsetup.
 
If the client is installed but not working


Check the locationservices.log
1) Does it know who it's MP is?  If not troubleshoot MP issues

Site Boundary Issues
1) Check the IP of the machine against the boundaries.  Adjust boundaries if you missed a scope.

Grabbing an old site code? Noticed this after 2007 to 2012 upgrade.
1) Open an elevated command prompt
2) cd c:\windows\system32\GroupPolicy\Machine
3) delete the .pol file
4) gpupdate /force

ForgotThe.log Error 80041002 stating '(WBEM_E_NOT_FOUND)
1) see Microsoft KB

Check Impersonation Rights
1) Open local policy
2) Windows --> Security Settings --> Local Policies --> User Rights Assignment
3) "Impersonate a client after authentication" should include SERVICE
     NOTE: Be nice to your IA guy, validate this with them agains their standards


Updates don't work

Is the update you're not compliant with deployed? (duh, I know.  But I've done it)
1) Look in the built-in report 5. Compliance for a specific system
or
2) In the console open Software Updates --> all Software Updates
3) search for the KB, and check the Downloaded and Deployed columns
 
Is it getting the policy?
1) Get the UpdateID from the SCCM Console
2) Use PolicySpy to see if it's listed
     NOTE: using PolicySpy is outside the scope of this post.  Google it unless I write about it later.

WindowsUpdate.log Error 800736b3 (Assembly Not Installed)
NOTE: I'm not going to lie, this is almost always a fatal error.  Rebuilding the box should be considered.  But you can try any or all of the following:

1) Uninstall parent software, i.e. if it's a Office patch, reinstall Office.  I've seen this work for .Net as well.
2) Run the System Update Readiness Tool from Microsoft
3) Run SFC.exe /scannow (takes 15 minutes~ish)
4) Rebuild the Software Distribution folder
  a. Stop Windows Update
  b. Rename the c:\windows\softwaredistribution folder
  c. Start WUA back up, it'll rebuild softwaredistribution
5) Repair WMI
  a. (Best)Run WMIRepair.exe /cmd (packaged in R Zanders SCCM Client Center)
  or
  b. the light version:

  Set WMI service to disabled, and stop
      cd /d %windir%\system32\wbem
      for %i in (*.dll) do RegSvr32 -s %i
      for %i in (*.exe) do %i /RegSvr32
      cd /d %windir%\syswow64\wbem
      for %i in (*.dll) do RegSvr32 -s %i
       for %i in (*.exe) do %i /RegSvr32
   Set WMI to Auto and start
       cd /d %windir%\system32\wbem
       for %i in (*.mof) do mofcomp %i
       for %i in (*.mfl) do mofcomp %i
       cd /d %windir%\sysWoW64\wbem
       for %i in (*.mof) do mofcomp %i
       for %i in (*.mfl) do mofcomp %i

6) Repair MSIExec
    a. CD %windir%\system32
    b. attrib -r -s -h dllcache
    c. ren msi.dll msi.old
    d. ren msiexec.exe msiexec.old
    e. msihnd.dll msihnd.old
    f. Reboot
    g. Net stop msiserver
    h. Msiexec /unregister
    i. Msiexec /regserver
    j. Regsvr32.exe /s %windir%\system32\msi.dll
    k. Net start msiserver
7) If you got this far, rebuild the box.

ForgotThe.log 800F081F
NOTE: I haven't seen this but reading blogs it looks pretty popular right now
1) Microsoft

WUAHandler.log and/or UpdatesDeployment.log and/or UpdatesHander.log Error 800F0902
1) Uninstall impacted application (Office, .Net, etc) from Control Panel
    a. If that fails use the MS Fix It
2) Reset the Windows Update components. NOTE: Long process, I put it at the bottom.
3) Run the System Update Readiness Tool from Microsoft
4) Re-run Windows Update NOTE: you can use WMIC commands from My Blog, use 108 and watch the UpdatesStore.log
5) If it's still not working, hit it with a SFC.exe /scannow (15 minutes or so run time)
6) If you got this far, rebuild the box

ForgotThe.log 80040154 stating that the Class is not Registered
1) Make sure the Trusted Installer Service is set to Auto and Started

CBS.log Error 8004A029
1) Open regedt32 NOTE: Standard disclaimer on Reg Edits, back up your stuff, you might lose it
2) GoTo HKLM\System\CurrentControlSet\Control\Network\MaxNumFilters
3) change the value to 14, or just delete it (the max max filters is hard coded by Win7 to 14)

WUAHander.log 800B0109  REF: Tom Popov
1) Modify GPO (under Windows Update) to "Allow signed updates from an internet Microsoft Update Service Location"

UpdatesDepoyment.og 87D00622 stating "Failed to trigger installation of Software updates"
NOTE: might be related to UpdatesHander.log error 80041033 'RequestTaskStart Failed"
1) Do the full client and WMI rebuild from My Blog

ForgotThe.log Error 87D0070C stating Software Execution Timeout
1) Re-run from Software Center

ForgotThe.log Error 1719 stating The Windows Installer Service Could Not Be Accessed, the Windows Installer Is Not Correctly Installed
1) Open regedt32 NOTE: Standard disclaimer on Reg Edits, back up your stuff, you might lose it
2) GoTo HKLM\System\CurrentControlSet\Services\MSIserver\WOW64 (if you're on 64-bit)
3) Right Click WOW64, then modify set value data to 0 (hex)
4) Bounce the box

ForgotThe.log Error Forgot stating "The Windows Installer Service could not be accessed"
1) Try the 1719 fix above first, I think they are related
2) Microsoft reference


MSIExec Crashes
Noted in the Application Event Log:

Faulting application name: msiexec.exe, version: 5.0.7000.0, time stamp: 0x49432105
Faulting module name: ntdll.dll, version: 6.1.7000.0, time stamp: 0x49434898
Exception code: 0xc0000005
Fault offset: 0x00000000000ebbaa
Faulting process id: -----
Faulting application start time: 0x01c979451ba01943
Faulting application path: C:\Windows\System32\msiexec.exe
Faulting module path: C:\Windows\SYSTEM32\ntdll.dll

 
1) Open regedt32 NOTE: Standard disclaimer on Reg Edits, back up your stuff, you might lose it
2) GoTo HKLM\Software\Microsoft\SQMClient\Windows\DisabledSessions
3) Rename MachineThrottleing to _MachineThrottling
or
3) Delete the DisabledSesssions key NOTE: make sure it's backed up....


HOW TO Reset Windows Update Components
NOTE: Linewraps on steps 8 & 9
1 ) open an elevated command prompt
2 ) net stop bits
3 ) net stop wuauserv
4 ) Del "%ALLUSERSPROFILE%\Application Data\Microsoft\Network\Downloader\qmgr*.dat"
5 ) Ren %systemroot%\SoftwareDistribution\DataStore *.bak
6 ) Ren %systemroot%\SoftwareDistribution\Download *.bak
7 ) Ren %systemroot%\system32\catroot2 *.bak
8 ) sc.exe sdset bits D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;AU)(A;;CCLCSWRPWPDTLOCRRC;;;PU)
9 ) sc.exe sdset wuauserv D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;AU)(A;;CCLCSWRPWPDTLOCRRC;;;PU)
10) cd /d %windir%\system32
11) for %i in (*.dll) do RegSvr32.exe –s %i
12) netsh winsock reset
13) netsh winhttp reset proxy
14) net start bits
15) net start wuauserv

Other References
Hotfixes for WMI:
http://ccmexec.com/2011/08/suggested-hotfixes-for-wmi-related-issue-on-windows-platforms/

Misc Client Troubleshooting
http://technet.microsoft.com/en-us/library/bb693982.aspx


Tuesday, October 15, 2013

Batch file for the client re-install powershell from yesterday

Here is the batch file I use for the earlier powershell script to re-install the SCCM client.

NOTES:
  PSExec and CMTrace must be in the folder you launch this from 'MyScripts' in this case.
  The powershell referenced above plus WMIRepair.exe and UnlockPowerShell.vbs must be in the
    'push' subdirectory.  I talked about UnlockPowerShell.vbs HERE.  I also have ccmclean in there
    but I don't use it anymore...
 

xcopy C:\MyScripts\push \\%1\c$\temp\push /E /I /F
psexec \\%1 -s cscript c:\temp\push\UnlockPowerShell.vbs
start "" .\cmtrace \\%1\c$\temp\sccm.log
psexec \\%1 -s powershell c:\temp\push\clifixes.ps1
psexec \\%1 -s cmd /C rmdir /s /q c:\temp\push

The command line would look like
          scriptname.bat computername

%1 in the batch files is replaced with 'computername' from the command line.

Monday, October 14, 2013

SCCM Client Repair / Reinstall Powershell script

This is the most effective way I've found of clearing up client side issues. If my use it's about 95%. If this doesn't get it something is seriously broke on the system and I generally PXE boot and apply a new image at that point.

I'll put my batch file that I use to kick this off in another post, but the way this works is that I copy it over to a local system's temp folder, then I kick it off with PSExec.  This ensures it runs local and eliminates a lot of issues caused by remoting.  For example, if you were trying to run remotely with RM or WMI calls, maybe PSEXEC, and you shut down the WMI repository then you gotta go remote into the machine and start it back up before you can move on.  Running this locally lets it mess with WMI and disregard if you're remote or not.

This script will
1) Cleanly uninstall the SCCM client
2) Rebuild the repository (yes I know not a best practice, but it beats rebuilding the machine)
3) Run WMIRepair (you'll have to get this from Robert Zander's tools, it's not mine to distrubute)
4) Reinstall the SCCM client

****NOTE****: Windows 7 safe.  In my environment XP still has issues.  But only about 2% of our systems are still on XP so I've never worked through those bugs, nor have I added in checking for those systems.

**** NOTE.0 ****: Search for "***" w/o the quotes.  Those items are unique per environment and have to be configured locally.  There are 3 of them.

#---------------------------------------------------------------------------#
#                           SCCM 2012 Client Repair                         #
# AUTH: David Bennett                                                       #
#                                                                           #
# THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY    #
# KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE       #
# IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR     #
# PURPOSE.                                                                  #
#                                                                           #
# Use : powershell clifixes.ps1                                             #
#       The intent is to be ran from Push.bat to be kicked off remotely     #
#       If it's not kicked off by Push.bat, support files may not be there  #
# Desc: Uninstalls SCCM, Rebuilds the Repository, Runs WMIRepair, and       #
#       Re-installs the client                                              #
# Out : Logs to c:\temp\sccm.log on the remote machine.  Minimal logging in #
#       the local command prompt                                            #
# Ass : The script assumes support files are in c:\ps\push change this      #
#       below to a location of your choice.  Support files are the script   #
#       itself, UnlockPowerShell.vbs, and wmirepair.exe                     #
#---------------------------------------------------------------------------#
 
#Running Function
# Input the process you want to monitor, returns when the process is finished
Function Running($proc)
{
    $Now = "Exists"
    While ($Now -eq "Exists")
    {
        If(Get-Process $proc -ErrorAction silentlycontinue)
        {
            $Now = "Exists"
            "INFO   : $proc is running, waiting 15 seconds" >> $LogFile
            Sleep -Seconds 15
        }
        Else
        {
            $Now = "Nope"
            "INFO   : $proc has finished running" >> $LogFile
        }
    }
}
 
$Error.Clear()
$exe = "C:\Windows\ccmsetup\ccmsetup.exe"
$Uarg = "/uninstall"
$Iarg = "smssitecode=***"
$wmiC = "C:\temp\push\wmirepair.exe"  #*** Change this to where you run from, I use push.bat (later post)
$wmiA = "/CMD"
$strComputer = Get-Content env:computername
 
"Working on $strComputer"
 
If(Test-Path c:\temp\SCCM.log -ErrorAction SilentlyContinue)
{
    Remove-Item c:\temp\sccm.log
    IF (! $?) {"ERROR: Unable to delete old sccm.log"}
    ELSE {"SUCCESS: Removed old sccm.log"}
}
 
$LogFile = "C:\temp\sccm.log"
 
"Working on $strComputer" >> $LogFile
IF (! $?) {"ERROR: Unable to Create sccm.log"}
ELSE {"SUCCESS: Created sccm.log, logging continues there"
      "SUCCESS: Created sccm.log on $strComputer">> $LogFile}
 
If(Test-Path C:\Windows\ccmsetup\ccmsetup.exe -ErrorAction SilentlyContinue)
{
    "SUCCESS: Found existing CCMSetup.exe" >> $LogFile
 
    #Uninstall the Client
    "INFO   : Running $exe $Uarg on system $strComputer" >> $LogFile
    &$exe $Uarg
    Running CCMSetup
    If (! $?) {"ERROR: The ccmsetup /uninstall did not exit cleanly" >> $LogFile
               "    I'm going to continue, the next steps may fix it" >> $LogFile
               $Error.clear}
    Else {"SUCCESS: Completed CCMSETUP.EXE /Uninstall" >> $LogFile }
}
 
#StopWinmgmt
Set-Service Winmgmt -StartupType Disabled -ErrorAction SilentlyContinue
If (! $?) {"ERROR: Could not disable Winmgmt" >> $LogFile
               $Error.clear}
Else {"SUCCESS: Disabled Winmgmt" >> $LogFile }
Stop-Service Winmgmt -Force -ErrorAction SilentlyContinue
If (! $?) {"ERROR: Could not Stop Winmgmt" >> $LogFile
               $Error.clear}
Else {"SUCCESS: Stopped Winmgmt" >> $LogFile }
 
#Sleep 10 for WMI Startup
"INFO   : Sleeping 10 Seconds for WMI Shutdown" >> $LogFile
Sleep -Seconds 10
 
#Rename The Repository
#NO, THIS IS NOT A BEST PRACTICE.  But I have yet to break anything with it so it's how I do
#If I start breaking stuff, I'll fix it then
# Step 1, check to see if there is an old backup repository.  Remove it.
If(Test-Path C:\Windows\System32\wbem\repository.old -ErrorAction SilentlyContinue)
    {
        Remove-Item -Path C:\Windows\System32\wbem\repository.old -Recurse -Force -ErrorAction SilentlyContinue
        If (! $?) {"ERROR: Could not delete the old repository backup, check permissions" >> $LogFile
               $Error.clear}
        Else {"SUCCESS: Removed the old repository back." >> $LogFile
              "    NOTE: You've done this before, there may be deeper system issues" >> $LogFile}
    }
 
# Step 2, rename existing repository directory.
Rename-Item -Path C:\Windows\System32\wbem\repository -NewName 'Repository.old' -Force -ErrorAction SilentlyContinue
If (! $?) {"ERROR: Could not rename the existing repository, check permissions" >> $LogFile
               $Error.clear}
Else {"SUCCESS: SUCCESS: Renamed Repository" >> $LogFile }
#Start WMI back up
Set-Service Winmgmt -StartupType Automatic -ErrorAction SilentlyContinue
If (! $?) {"ERROR: Could not configure WINMGMT, you're screwed" >> $LogFile
               $Error.clear}
Else {"SUCCESS: SUCCESS: Configured WINMGMT" >> $LogFile }   
Start-Service Winmgmt -ErrorAction SilentlyContinue
If (! $?) {"ERROR: Could not start WINMGMT, you're screwed" >> $LogFile
               $Error.clear}
Else {"SUCCESS: SUCCESS: Started WINMGMT" >> $LogFile }   
 
#Sleep 10 for WMI Startup
"Sleeping 10 Seconds for WMI Startup" >> $LogFile
Sleep -Seconds 10
#Start other services that WMI typically takes down with it
Start-Service iphlpsvc -ErrorAction SilentlyContinue
If (! $?) {"ERROR: Could not start IP Helper, might not be needed in this environment" >> $LogFile
               $Error.clear}
Else {"SUCCESS: SUCCESS: Started IP Helper" >> $LogFile }   
      
Start-Service Winmgmt -ErrorAction SilentlyContinue
If (! $?) {"ERROR: Could not configure Security Center, might not be needed in this environment" >> $LogFile
               $Error.clear}
Else {"SUCCESS: SUCCESS: Started Security Center" >> $LogFile }   
 
#Sleep 1 Minute to allow the WMI Repository to Rebuild
"INFO   : Sleep 1 Minute to allow the WMI Repository to Rebuild" >> $LogFile
Sleep -Seconds 60
 
#Run WMIRepair **Credits for WMI Repair: Robert Zander
#              **This comes with SCCM Client Center and I didn't wand to re-create the wheel
#              **You have to extract the Executable by running Client Center WMI Repair on
#              **  a system and finding the exe in the Windows folder (or system32, I forget)
"INFO   : Running WMI Repair" >> $LogFile
&$wmiC $wmiA
Running WMIRepair
If (! $?) {"ERROR: WMIRepair encountered errors, check output" >> $LogFile
               $Error.clear}
Else {"SUCCESS: WMIRepair Success" >> $LogFile }   
 
#Clear ccmsetup folder
#Just something I do, without deleteing ccmsetup.exe I've seen it pull a client from our old site,
# which is still up for 'Just In Case' reasons, if the client was never upgraded correctly
Remove-Item -Path C:\Windows\ccmsetup\* -Recurse -Exclude "logs" -ErrorAction SilentlyContinue
If (! $?) {"ERROR: Could not clean up CCMSETUP folder" >> $LogFile
               $Error.clear}
Else {"SUCCESS: Cleaned up CCMSETUP folder" >> $LogFile }   
 
 
#Get the current ccmsetup.exe
Copy-Item -Path \\***\SCCM_2012_Client\ccmsetup.exe -Destination C:\Windows\ccmsetup -ErrorAction SilentlyContinue
If (! $?) {"ERROR: Could not copy ccmsetup.exe from the server, check paths" >> $LogFile
               $Error.clear}
Else {"SUCCESS: Copied a fresh ccmsetup.exe from the site server" >> $LogFile }   
 
#Sleep 10 just in case WMI is still trashing from WMIRepair; #SeenItOnce
"INFO   : Sleeping 10 Seconds for system stability" >> $LogFile
Sleep -Seconds 10
#Install the client
"Running $exe $Iarg" >> $LogFile
&$exe $Iarg
Running CCMSetup
If (! $?) {"ERROR: CCMSETUP install encountered errors, check ccmsetup.log" >> $LogFile
               $Error.clear}
Else {"SUCCESS: CCMSETUP install completed successfully" >> $LogFile }     
 
#Report Completion back to the command line
$CCMTime = Get-Item -Path C:\Windows\ccmsetup\ccmsetup.cab | Select-Object -Property CreationTime
"CCM Installed on $CCMTime"