none
SCCM Compliance state always 'Compliant' when remediation script runs

    Question

  • We're trying to use SCCM 2012 R2 to run some checks on clients and fix problems when needed. For this we use the PowerShell 'Script' option. This is the first time I'm working with SCCM, so please bare with me.

    Problem description:

    When a 'Discovery script' reports ‘Non-Compliant’ the ‘Remediation script’ is launched. Regardless of the output of the ‘Remediation script’, the result in the report on the client in ‘Configuration Manager > Configurations’ is always ‘Compliant’ even when the ‘Remediation script’ failed to fix the issue and as a result has different output then defined in the ‘Rules for compliance conditions’.

    It seems that from the moment a ‘Remediation script’ is selected, the output of the SCCM Compliance State is always ‘Compliant’.

    Example:

    - Situation:

    When there are files or folders in the folder ‘C:\Users\me\Downloads\Input_Test’ the ‘Discovery script’ reports ‘Not compliant to anything’ and kicks of the ‘Remediation script’. The remediation script takes action and can’t fix the problem so it reports back something else then ‘Compliant’, like ‘Non-Compliant’. The SCCM Compliance State should say after execution of the ‘Remediation script’: ‘Non-Compliant’ (which is not the case).

    - PowerShell Discovery script:

    $Paths = Get-ChildItem -Path 'C:\Users\me\Downloads\Input_Test' | Select -ExpandProperty FullName
    New-EventLog -LogName Application -Source SCCMCompliance
    if ($Paths) {
        $Compliance = 'Non-Compliant'
        Write-EventLog -LogName Application -Source SCCMCompliance -EntryType Warning -EventID 1 -Message Discovery script: Non-Compliant
    }
    else {
        $Compliance = 'Compliant'
        Write-EventLog -LogName Application -Source SCCMCompliance -EntryType Information -EventID 0 -Message Discovery script: Compliant
    }
    $Compliance 

    - PowerShell Remediation script:

    Write-Output 'Non-Compliant'
    Write-EventLog -LogName Application -Source SCCMCompliance -EntryType Warning -EventID 1 -Message Remediation script: Non-Compliant $Paths 

    - SCCM Rules for compliance conditions:enter image description here enter image description here

    - SCCM Compliance State in the Configuration Manager:enter image description here

    In the Windows event viewer all steps can be tracked easily. Am I missing something super obvious here?

    Wednesday, March 16, 2016 11:09 AM

Answers

  • Yes. This is correct. The detection script is *not* run again after the compliance script is run and the success of the remediation script is assumed. Thus, if your remediation script has any errors or does not actually remediate the issue, there's no way to know until the baseline is evaluated again.

    I'm not exactly sure why they designed it this way, but I could imagine scenarios where endless loops could ensue if this wasn't the case.

    Feel free to add a suggestion on UserVoice or file a DCR on Connect though.


    Jason | http://blog.configmgrftw.com | @jasonsandys

    • Marked as answer by DarkLite1 Tuesday, March 22, 2016 9:08 AM
    Wednesday, March 16, 2016 12:52 PM

All replies

  • There is a table similar to this https://technet.microsoft.com/en-us/library/gg682159.aspx?f=255&MSPPError=-2147217396#BKMK_Step4 available for compliance settings, but I cannot find it. I can't remember exact details, but it I think that ConfigMgr assumes that remediation worked fine if the compliance script returned 0.


    Torsten Meringer | http://www.mssccmfaq.de

    Wednesday, March 16, 2016 12:10 PM
  • Thanks for the reply Torsten. I also found someone else mentioning this on a forum, and I already tested it. But in reality it doesn't matter if there is output from the 'Remediation script' or not. It's always saying 'Compliant' after it ran, regardless of its output. Really annoying... 
    Wednesday, March 16, 2016 12:20 PM
  • Yes. This is correct. The detection script is *not* run again after the compliance script is run and the success of the remediation script is assumed. Thus, if your remediation script has any errors or does not actually remediate the issue, there's no way to know until the baseline is evaluated again.

    I'm not exactly sure why they designed it this way, but I could imagine scenarios where endless loops could ensue if this wasn't the case.

    Feel free to add a suggestion on UserVoice or file a DCR on Connect though.


    Jason | http://blog.configmgrftw.com | @jasonsandys

    • Marked as answer by DarkLite1 Tuesday, March 22, 2016 9:08 AM
    Wednesday, March 16, 2016 12:52 PM
  • Thank you for the confirmation Jason. So once a 'Remediation script' is attached there's no way of knowing if the problem is indeed fixed or not. And every time the Baseline is triggered, in case it wasn't correctly fixed before, it will try to run the 'Remediation script' again and report this as 'Compliant' while it's not.

    The only workaround for this that I can see is to create a second Baseline with only one Configuration Item in it without a 'Remediation script' but only a 'Discovery script' (the same one as in the other CI), and this will then run and say 'Compliant' or 'NonCompliant'. Seems a bit of double work... Are we sure this is the only way of using the tool?


    • Edited by DarkLite1 Wednesday, March 16, 2016 1:03 PM
    Wednesday, March 16, 2016 1:02 PM
  • I guess that's one technically valid path. 

    Yes, as noted, this is by design.

    Note that I was wrong about one thing above though: if your remediation script fails with an actual runtime error, you will get an error back from the baseline eval.


    Jason | http://blog.configmgrftw.com | @jasonsandys

    Wednesday, March 16, 2016 1:17 PM
  • Note that I was wrong about one thing above though: if your remediation script fails with an actual runtime error, you will get an error back from the baseline eval.



    Exactly: and this has nothing to do with "it doesn't matter if there is output from the 'Remediationscript' or not". You have to return an non-zero exitcode.

    Torsten Meringer | http://www.mssccmfaq.de

    Wednesday, March 16, 2016 1:20 PM
  • Thanks for the feedback guys. I'm surrounded by pro's here, which is nice! Would it be possible to make some type of code example for me? So I know what you mean with a 'Runtime error'... Is it as simple as using 'Write-Error' when it's not ok for example in the PowerShell 'Remediation script'?
    Wednesday, March 16, 2016 1:23 PM
  • No, a runtime error is a failure in the code or exactly as Torsten pointed out, returning a non-zero exit value.

    in Powershell, that's something like: exit 1


    Jason | http://blog.configmgrftw.com | @jasonsandys

    Wednesday, March 16, 2016 1:31 PM
  • So after testing it seems indeed that 'Exit 1' gives a 'Compliance Status' of 'Error' with a description of the error. Getting to 'Non-Compliant' seems not be possible then...
    • Edited by DarkLite1 Wednesday, March 16, 2016 1:57 PM
    Wednesday, March 16, 2016 1:50 PM