Showing posts with label Configuration Baseline. Show all posts
Showing posts with label Configuration Baseline. Show all posts

Thursday, June 30, 2016

Basic Maintenance Confguration Baseline

I like to create a configuration baseline, containing several configuration items, to check some basic client health items.  This is not only beneficial at the console but also benefits technicians/administrators at the endpoint when they are trying to troubleshoot issues.

  • Configuration Items:
    • ConfigMgr Client Health - Reboot Pending
      • Checks CCMClientSDK in WMI
        • (Invoke-WmiMethod -Class CCM_ClientUtilities -Name DetermineIfRebootPending -Namespace ROOT\ccm\ClientSDK -Computer $env:COMPUTERNAME).RebootPending equals False 
      • Checks Component Based Servicing in registry
        • HKLM\Software\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending must not exist
      • Checks Pending File Rename Operations in registry
        • HKLM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations string array must be empty
      • Checks Windows Update Reboot Required in registry
        • SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired must not exist
      • Checks if last reboot time is greater than 90 day
        • (New-TimeSpan -Start ((Get-CimInstance -ClassName win32_operatingsystem | select csname, lastbootuptime).lastbootuptime) -End (get-date)).Days less than or equal to 45
    • ConfigMgr Client Health - Windows Update Service (wuauserv)
      • (get-service -Name wuauserv).StartType not equal Disabled
    • ConfigMgr Client Health - Windows Installer Service (msiserver)
      • (get-service -Name msiserver).StartType not equal Disabled

  • Configuration Baseline:
    • ConfigMgr Client Health
      • ConfigMgr Client Health - Reboot Pending
      • ConfigMgr Client Health - Windows Update Service (wuauserv)
      • ConfigMgr Client Health - Windows Installer Service (msiserver)

You can find client health collections here if interested: http://randoltech.blogspot.com/2016/06/client-health-collections.html

Tuesday, March 8, 2016

Use SCCM to Centrally Manage Java Configuration

Managing java settings, from site exceptions lists to trusted certs to which TLS versions to use, has been a major pain in the butt for techs and administrators for a long time.  Using SCCM's Compliance Settings (formerly Desired Configuration Management) we can make fairly quick work of this.

I am going to give you is two scripts.  The first one checks the four files against your central store to be sure that what is on the client machine matches the central store (discovery script).  The second script copies the files from your central store to the client machine (remediation script).  The contents of the four Java settings/configuration files are up to you.

Steps to set up your configuration item:
  • Build a configuration item with a compliance rule of type "Script" and data type "String".
  • Copy the scripts into the Discovery Script and Remediation Script areas of your CI.  Both scripts are powershell.
  • Put your Java files in a central place that all of your machine accounts have access to read (users don't need access but the machines do).
  • Modify the Discovery Script and Remediation Script in your CI and change the CentralFileLocation variable to point to the location of your files.
  • Add a compliance rule that evaluates as compliant if the value returned by the script = "True All Java files pass all checks."
  • Check the check-box "Run the specified remediation script when this setting is noncompliant"
  • Add the CI to a baseline and deploy the baseline to a collection.  Be sure that in the deployment you have selected "Remediate noncompliant rules when supported".

Discovery Script:

<#
.Synopsis
   Check the files in %windir%\Sun\Java\Deployment against centrally managed files.
.DESCRIPTION
   This script is meant to be used in conjunction with the Copy_JavaSettings.ps1 script to
   manage Java JRE settings from a central location.  This script checks the files on the
   local workstation.  If the files do not match the central repository then Copy_JavaSettings.ps1
   can be used to write the correct files.
   It is suggested that the two files be used together in an SCCM configuration item for checking
   and automated remediation.
   You will need to set $CentralFileLocation to the location of your centrally managed files.
   That should be the only change that you need to make to the script.  It is suggested that
   you use a location in your sysvol as shown in the example.
   Success condition will return "True All Java files pass all checks."
   Failure conditions will return "False " followed by the reason for failure.
#>

function Check-LocalJavaFolder
{
    [OutputType([Boolean],[String])]
    $Compliant=$false
    $JavaFolderExist=Test-Path $JavaFolder
    #write-host ("Checking Java Folder Existence")
    if ($JavaFolderExist -eq $true)
    {
        $Compliant=$true
        $Problem="Java Folder Exists in $JavaFolder"
    }
    else
    {
        $Compliant=$false
        $Problem='Folder %windir%\Sun\Java\Deployment does not exist.'
    }
    Return $Compliant, $Problem
}

function Check-JavaSettingsFileExist
{
    [OutputType([Boolean],[String])]
    $Compliant=$false
    $DeploymentConfigFileExist=Test-Path $DeploymentConfigFile
    $DeploymentPropertiesFileExist=Test-Path $DeploymentPropertiesFile
    $ExceptionSitesFileExist=Test-Path $ExceptionSitesFile
    $TrustedCertsFileExist=Test-Path $TrustedCertsFile
    if ($DeploymentConfigFileExist -ne $true)
    {
        $Compliant=$false
        $Problem="$DeploymentConfigFile does not exist."
        Return $Compliant, $Problem
    }
    if ($DeploymentPropertiesFileExist -ne $true)
    {
        $Compliant=$false
        $Problem="$DeploymentPropertiesFile does not exist."
        Return $Compliant, $Problem
    }
    if ($ExceptionSitesFileExist -ne $true)
    {
        $Compliant=$false
        $Problem="$ExceptionSitesFile does not exist."
        Return $Compliant, $Problem
    }
    if ($TrustedCertsFileExist -ne $true)
    {
        $Compliant=$false
        $Problem="$TrustedCertsFile does not exist."
        Return $Compliant, $Problem
    }
    $Compliant=$true
    $Problem='All managed files exist.'
    Return $Compliant, $Problem
}

function Check-JavaSettingsFileSizes
{
    [OutputType([Boolean],[String])]
    $Compliant=$false
    $DeploymentConfigFileSize=(Get-Item $CentralDeploymentConfigFile).length
    $DeploymentConfigLocalFileSize=(Get-Item $DeploymentConfigFile).Length
    if ($DeploymentConfigLocalFileSize -ne $DeploymentConfigFileSize)
    {
        $Compliant=$false
        $Problem="$DeploymentConfigFile file size is not correct."
        Return $Compliant, $Problem
    }
    $DeploymentPropertiesFileSize=(Get-Item $CentralDeploymentPropertiesFile).length
    $DeploymentPropertiesLocalFileSize=(Get-Item $DeploymentPropertiesFile).Length
    if ($DeploymentPropertiesLocalFileSize -ne $DeploymentPropertiesFileSize)
    {
        $Compliant=$false
        $Problem="$DeploymentPropertiesFile file size is not correct."
        Return $Compliant, $Problem
    }
    $ExceptionSitesFileSize=(Get-Item $CentralExceptionSitesFile).length
    $ExceptionSitesLocalFileSize=(Get-Item $ExceptionSitesFile).Length
    if ($ExceptionSitesLocalFileSize -ne $ExceptionSitesFileSize)
    {
        $Compliant=$false
        $Problem="$ExceptionSitesFile file size is not correct."
        Return $Compliant, $Problem
    }
    $TrustedCertsFileSize=(Get-Item $CentralTrustedCertsFile).length
    $TrustedCertsLocalFileSize=(Get-Item $TrustedCertsFile).Length
    if ($TrustedCertsLocalFileSize -ne $TrustedCertsFileSize)
    {
        $Compliant=$false
        $Problem="$TrustedCertsFile file size is not correct."
        Return $Compliant, $Problem
    }
    $Compliant=$true
    $Problem='All managed files are correct size.'
    Return $Compliant, $Problem
}

function Check-JavaSettingsFileDates
{
    [OutputType([Boolean],[String])]
    $Compliant=$false
    $DeploymentConfigFileDate=(Get-Item $CentralDeploymentConfigFile).length
    $DeploymentConfigLocalFileDate=(Get-Item $DeploymentConfigFile).Length
    if ($DeploymentConfigLocalFileDate -ne $DeploymentConfigFileDate)
    {
        $Compliant=$false
        $Problem="$DeploymentConfigFile file date is not correct."
        Return $Compliant, $Problem
    }
    $DeploymentPropertiesFileDate=(Get-Item $CentralDeploymentPropertiesFile).length
    $DeploymentPropertiesLocalFileDate=(Get-Item $DeploymentPropertiesFile).Length
    if ($DeploymentPropertiesLocalFileDate -ne $DeploymentPropertiesFileDate)
    {
        $Compliant=$false
        $Problem="$DeploymentPropertiesFile file date is not correct."
        Return $Compliant, $Problem
    }
    $ExceptionSitesFileDate=(Get-Item $CentralExceptionSitesFile).length
    $ExceptionSitesLocalFileDate=(Get-Item $ExceptionSitesFile).Length
    if ($ExceptionSitesLocalFileDate -ne $ExceptionSitesFileDate)
    {
        $Compliant=$false
        $Problem="$ExceptionSitesFile file date is not correct."
        Return $Compliant, $Problem
    }
    $TrustedCertsFileDate=(Get-Item $CentralTrustedCertsFile).length
    $TrustedCertsLocalFileDate=(Get-Item $TrustedCertsFile).Length
    if ($TrustedCertsLocalFileDate -ne $TrustedCertsFileDate)
    {
        $Compliant=$false
        $Problem="$TrustedCertsFile file date is not correct."
        Return $Compliant, $Problem
    }
    $Compliant=$true
    $Problem='All managed files are correct dates.'
    Return $Compliant, $Problem
}


$CentralFileLocation="\\domain.com\sysvol\domain.com\Java"
$WindowsFolder=$env:windir
$JavaFolder="$WindowsFolder\Sun\Java\Deployment"
$DeploymentConfigFile=$JavaFolder+"\deployment.config"
$DeploymentPropertiesFile=$JavaFolder+"\deployment.properties"
$ExceptionSitesFile=$JavaFolder+"\exception.sites"
$TrustedCertsFile=$JavaFolder+"\trusted.certs"
$CentralDeploymentConfigFile=$CentralFileLocation+"\deployment.config"
$CentralDeploymentPropertiesFile=$CentralFileLocation+"\deployment.properties"
$CentralExceptionSitesFile=$CentralFileLocation+"\exception.sites"
$CentralTrustedCertsFile=$CentralFileLocation+"\trusted.certs"
$Compliant=$false
$Problem='Compliant'

clear-host
$Compliance=(Check-LocalJavaFolder)
If ($Compliance -match $true)
    {
        $Compliance=(Check-JavaSettingsFileExist)
    }
If ($Compliance -match $true)
    {
        $Compliance=(Check-JavaSettingsFileSizes)
    }
If ($Compliance -match $true)
    {
        $Compliance=(Check-JavaSettingsFileDates)
    }
If ($Compliance -match $true)
    {
        $Compliance=($true, "All Java files pass all checks.")
        write-host $Compliance
    }
    else
    {
        write-host $Compliance
    }



Remediation Script:


<#
.Synopsis
    Copies files used for centralized management of Java JRE from central location to local workstation.
.DESCRIPTION
   This script will copy the centrally managed Java config files from a
   central repository (definied by $CentralFileLocation) to %windir%\Sun\Java\Deployment
   You will need to set $CentralFileLocation to the location of your centrally managed files.
   That should be the only change that you need to make to the script.  It is suggested that
   you use a location in your sysvol as shown in the example.
#>

$CentralFileLocation="\\domain.com\sysvol\domain.com\Java"
$WindowsFolder=$env:windir
$JavaFolder="$WindowsFolder\Sun\Java\Deployment"
$DeploymentConfigFile=$JavaFolder+"\deployment.config"
$DeploymentPropertiesFile=$JavaFolder+"\deployment.properties"
$ExceptionSitesFile=$JavaFolder+"\exception.sites"
$TrustedCertsFile=$JavaFolder+"\trusted.certs"
$CentralDeploymentConfigFile=$CentralFileLocation+"\deployment.config"
$CentralDeploymentPropertiesFile=$CentralFileLocation+"\deployment.properties"
$CentralExceptionSitesFile=$CentralFileLocation+"\exception.sites"
$CentralTrustedCertsFile=$CentralFileLocation+"\trusted.certs"

#Check first part of path - if it doesn't exist then create it
  $JavaFolder="$WindowsFolder\Sun"
  $JavaFolderExist=Test-Path $JavaFolder
  if ($JavaFolderExist -eq $false) {New-Item $JavaFolder -type directory}
#Check second part of path - if it doesn't exist then create it
  $JavaFolder="$WindowsFolder\Sun\Java"
  $JavaFolderExist=Test-Path $JavaFolder
  if ($JavaFolderExist -eq $false) {New-Item $JavaFolder -type directory}
#Check last part of path - if it doesn't exist then create it
  $JavaFolder="$WindowsFolder\Sun\Java\Deployment"
  $JavaFolderExist=Test-Path $JavaFolder
  if ($JavaFolderExist -eq $false)     {New-Item $JavaFolder -type directory}

Clear-Host

#clear any contents that might already be there
Get-ChildItem -Path $JavaFolder -Include *.* -File -Recurse | foreach { $_.Delete()}

#Drop in our configuration files
Copy-Item -path $CentralDeploymentConfigFile -destination $DeploymentConfigFile
Copy-Item -path $CentralDeploymentPropertiesFile -destination $DeploymentPropertiesFile
Copy-Item -path $CentralExceptionSitesFile -destination $ExceptionSitesFile
Copy-Item -path $CentralTrustedCertsFile -destination $TrustedCertsFile

Friday, September 11, 2015

Configuration Baselines - let the government do the work!

A few years ago I was contracted to a government agency and I was tasked with ensuring that all computers in that agency were compliant with USGCB (US Government Configuration Baseline).  At the time USGCB was new, they had been previously using FDCC (Federal Desktop Core Configuration).  Unfortunately they didn't really know if they were even compliant with FDCC.  They knew that the machines were compliant when they were built and originally deployed but they didn't know if any configuration drift had occurred in the meantime.

So... the problem was determining whether or not the computers were currently compliant and if they were not compliant then remediating them.

My tool of choice, of course, was SCCM (2007 at the time) and specifically Desired Configuration Managment (now known as Compliance Settings... I liked DCM better).

At first the task seemed daunting, overwhelming, a five year effort for this one little SCCM engineer.  They had pointed me to the NIST website (https://web.nvd.nist.gov/view/ncp/repository) for a list of what the compliance should look like.  Unfortunately none of the files available from NIST were something that SCCM could import.

I reached out to one of the Microsoft engineers that I've met over the years and he pointed me to a tool.  In my humble opinion one of the best tools ever... Security Compliance Manager (SCM).  It is an absolutely free solution accelerator from Microsoft.  See the big list of solution accelerators here: https://technet.microsoft.com/en-us/library/cc936627.aspx

SCM is able to import GPO templates and spit out SCCM configuration items.  So, now armed with SCM I imported all of the GPO templates from the NIST site and turned them into CIs.  What had originally looked like a five year job turned into about two weeks.  Two days of importing and two weeks of testing, then roll-out.

So... let NIST do all that work for.  Download the GPO templates from NIST and use SCM to turn them into CIs.

In my years since that first job I've had to set up compliancy CIs for many other regulatory agencies (HIPAA, SOX, FISMA, PCI, etc) . The most beautiful part of this is that most of these compliancy agencies have a lot of duplication on their requirements.  If you are compliant with just one of them you are over 95% compliant with all of them.  So... you re-use the exact same CI in multiple baselines to create your baselines for all of them and NIST did all that work for you.

Give me a +1, or a comment, or a link back if this helps you out.


Tuesday, September 8, 2015

Reboot Pending configuration item and baseline

For anyone that wants a CI and/or baseline to keep track of computers that are in a pending reboot state, import this file into Configuration Baselines and it will create the following:

  • A baseline Named "Basic Maintenance"
  • A configuration item named "Basic Maintenance - Reboot Pending"
The CI has 4 settings that it checks

The 3 registry values are extremely straightforward as they are using SCCM's built-in functionality for checking the registry.  The script is a one liner that checks WMI and returns a value from there ("True", "False" or "NULL")
Link to download CAB File to create these CIs and the baseline:
Basic Maintenance.cab
Please open each item and look at it before you assign the baseline to any collections.
Never blindly enable stuff that you found on the internet.