poniedziałek, 19 lutego 2018

Checking the Full Folder Path of Collection Objects in SCCM

    Following up the recent post about identifying full folder path in SCCM for certain drivers, that can be found over here:

    I decided to post another, modified SQL query which hopefully will help you in this situation:

 Delete Collection Error - References to Other Collections Block the Delete Collection Action

    We know, that the references to the collection we want to remove in other collections are blocking the possibility to remove our collection. A task to find those collections might not be trivial if you don't know where in SCCM folder structure do they reside. Query below will recursively find the full folder path to those collections based on the regular expressions.

Usage:
    Replace the _CollectionRegexp_ string with the regular expression matching your needs depending on the collections you are looking for.
    Obviously the query should be run via SQL Management Studio or any other similar tool letting you execute T-SQL queries.

Code:
SELECT ROW_NUMBER() OVER (ORDER BY v_Collection.Name,vSMS_Folders.ContainerNodeID) AS [Row], v_Collection.Name, vSMS_Folders.ContainerNodeID,v_Collection.Name AS Folder  INTO #Temp
FROM v_Collection
JOIN vFolderMembers on v_Collection.CollectionID = vFolderMembers.InstanceKey
JOIN vSMS_Folders ON vFolderMembers.ContainerNodeID = vSMS_Folders.ContainerNodeID
WHERE v_Collection.Name LIKE '_CollectionRegexp_'
AND vFolderMembers.ObjectTypeName = 'SMS_Collection_Device'
ORDER BY v_Collection.Name

DECLARE @It INT=1

WHILE (@It <= (SELECT COUNT(*) FROM #Temp))
BEGIN
      DECLARE @ContainerID INT=(SELECT ContainerNodeID FROM #Temp WHERE Row=@It)
      DECLARE @ContainerIDBeg INT=(SELECT ContainerNodeID FROM #Temp WHERE Row=@It)
      DECLARE @ContainerFullName VARCHAR(MAX)
      DECLARE @ContainerName VARCHAR(MAX)
      WHILE (SELECT ParentContainerNodeID FROM vSMS_Folders WHERE ContainerNodeID=@ContainerID) != 0
      BEGIN
            SET @ContainerName = (SELECT Name FROM vSMS_Folders WHERE ContainerNodeID=@ContainerID)
            IF (@ContainerID=(SELECT TOP 1 ContainerNodeID FROM #Temp))
                  SET @ContainerFullName = @ContainerName
            ELSE
                  SET @ContainerFullName = @ContainerName + '\' + @ContainerFullName
            SET @ContainerID = (SELECT ParentContainerNodeID FROM vSMS_Folders WHERE ContainerNodeID=@ContainerID)
      END
SET @ContainerFullName = (SELECT Name FROM vSMS_Folders WHERE ContainerNodeID=@ContainerID) + '\' + @ContainerFullName
UPDATE #Temp
SET Folder = @ContainerFullName
WHERE Row = @It
SET @It += 1
SET @ContainerFullName = ''
END

SELECT Name,Folder FROM #Temp
DROP TABLE #Temp

środa, 14 lutego 2018

SCOM Monitor Checking Updates Availability in Software Center

    Recently I came across an interesting request, that I considered having a huge added value to the infrastructure thanks to SCCM-SCOM synergy. Namely the task was to configure a way to receive SCOM alerts whenever there are updates available on the servers in Software Center. After some research over few possible ways of implementing this via Script Rule I finally decided to complete the task with the usage of WMI Performance Counter monitor. Here is how to configure the whole solution

Configuration:
1. Go to the Authoring pane in SCOM console, right-click on monitors and select Create a Monitor -> Unit Monitor... option
     
Starting Monitor Creation Wizard Window

2. In the Monitor Type tab of the wizard go to WMI Performance Counters -> Static Thresholds -> Single Threshold -> Simple Threshold and select a Management Pack of your choice to store the monitor. Keep in mind, that if you plan to later on enable a monitor only for certain group of computers, this group will have to be kept in the same Management Pack in order for the override to be created
Monitor Type Settings Tab of the Wizard

3. In the General tab of the wizard provide the name of the monitor and select a parent monitor for it. I choose a Configuration one, which I think fits best the nature of the monitor, but it's an open choice. For the name you can copy the following one:

Manual Intervention Required for Software Updates Installation on the System

    I recommend, as a best practice, to always create a monitor as disabled and only enable it for a specific group of computers in order to avoid serious problems in case of a mistake during configuration process.

 General Settings Tab of the Wizard

4. In the WMI Configuration tab of the wizard put the following settings in the WMI Namespace and Query windows:

root\ccm\ClientSDK
SELECT * FROM CCM_SoftwareUpdate WHERE ComplianceState='0'

    I chose to configure the interval to 21600 seconds, as I believe one check every 6 hours is enough. Here you can see the configuration used for initial testing purposes

 WMI Configuration Settings Tab of the Wizard

5. In the Performance Mapper tab of the wizard put the following settings in the Object, Counter, Instance and Value fields:

Pending Updates
Pending Updates
$Data/Property[@Name='Name']$
$Data/Property[@Name='PercentComplete']$

 Performance Mapper Settings Tab of the Wizard

6. In the Threshold Value tab of the wizard set the threshold to 1.00
Threshold Value Settings Tab of the Wizard

7. In the Configure Health tab of the wizard set the Over Threshold condition to Healthy and Under Threshold one to Warning

Configure Health Settings Tab of the Wizard

8. In the Configure Alerts tab of the wizard tick both boxes - to generate and automatically resolve alerts. Set the monitor to generate an alert when the monitor is in a warning health state and put the following text in Alert Name and Alert Description fields:

Manual Intervention Required for Software Updates Installation on the System

The server has updates pending manual intervention. Please review the Software Center in order to verify whether there are no available updates or updates pending restart, and take necessary actions to resolve the SCOM alert
    Further troubleshooting:
1. Open wbemtest program on the problematic server
2. Connect to the root\ccm\ClientSDK namespace
3. Run the following query:
    SELECT * FROM CCM_SoftwareUpdate WHERE ComplianceState='0'
4. Verify whether there are any objects returned that would have an EvaluationState property set to either '0' (update available) or '8' (restart pending)


   Priority and Severity of the alerts is a personal choice, but I set it to Medium and Warning.

Configure Alerts Settings Tab of the Wizard


Additional Notes:
    1. Do not use the WMI Events branch in the wizard. The reason for this is, that we are using "normal" WMI query here rather than WMI Event query, which cannot be parsed by WMI Event Monitor/Rule. It will produce an alert in SCOM and a windows event 10357 from Health Service Modules source with the following error:

Module was unable to execute the notification query
Error: 0x80041059
Details: Class is not an event class

    2. Unfortunately WQL does not provide COUNT method similar to SQL. Therefore it is not possible to write a WQL query which would return the number of pending software updates and return an alert when it's greater than '0'. The workaround solution applied in this case is to catch the value of PercentComplete property of the collected WMI objects and throw an alert when it's lower than 1% (if the update is pending restart or available this value will be always set to 0%). If there is no value returned at all (meaning there are no pending update -related actions) there will be no instance found and the monitor will remain Healthy.

    3. After some testing it turned out, that despite all settings properly set in SCOM the alerts do not auto-close because the monitor do not change the status back to Healthy. They have to be manually reset after applying the updates to the servers. I believe a reason for this is, that the WMI objects queried simply disappear after the installation of patches and SCOM has no possibility to check for the values of the properties of those objects anymore. The developed solution is a simple PowerShell script, which can be run after the updates have been applied in order to reset the status of this monitor for a particular group of computers:

$monitor = Get-SCOMMonitor | ?{$_.DisplayName -like "*Manual Intervention*"}
$(Get-SCOMGroup | ?{$_.DisplayName -like "*Computer_Group_
Name*"}) | Get-SCOMClassInstance | ?{$_.HealthState -ne "Success"} | foreach {Write-Host -Foreground Green Resetting Manual Updates Intervention Monitor for server $_.Name;$_.ResetMonitoringState($monitor)}


    The script has to be saved as a .ps1 file and run from either Operations Manager Shell or normal PowerShell window after importing Operations Manager module. You have to replace the Computer_Group_Name string with the name of your computer group.


    4. Below is a quick command to double check the existence of patches from the command line (which I find more trustful than the Software Center itself):

wmic /namespace:\\root\ccm\ClientSDK path CCM_SoftwareUpdate WHERE ComplianceState=0 GET ArticleID,EvaluationState /format:list