sobota, 24 listopada 2018

Life Hacks - Patching a computer without Software Center GUI


    Sometimes you might find yourself in a rare situation when you have an urgent need to immediately patch the computer with an SCCM agent on it, but Software Center refuses to cooperate - it throws errors and does nt open despite several troubleshooting attempts including re-installation of the agent. In this case the following commands might come in handy:

Usage:

    The following cmd command will help you to "see" the actionable patches list as displayed in the Software Center. The exemplary output of the comment is below:

ArticleID=4055532
EvaluationState=6
Name=2018-01 Security and Quality Rollup for .NET Framework 3.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1 on Windows 7 and Server 2008 R2 for x64 (KB4055532)

ArticleID=890830
EvaluationState=6
Name=Windows Malicious Software Removal Tool x64 - February 2018 (KB890830)

ArticleID=4076492
EvaluationState=8
Name=2018-02 Security and Quality Rollup for .NET Framework 3.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1 on Windows 7 and Server 2008 R2 for x64 (KB4076492)

ArticleID=4055269
EvaluationState=6
Name=2018-01 Security Only Update for .NET Framework 3.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1 on Windows 7 and Server 2008 R2 for x64 (KB4055269)


    Below you can find a reference for available Evalutaion state (source: CCM_SoftwareUpdate Client WMI Class)

Value    State

0    ciJobStateNone
1    ciJobStateAvailable
2    ciJobStateSubmitted
3    ciJobStateDetecting
4    ciJobStatePreDownload
5    ciJobStateDownloading
6    ciJobStateWaitInstall
7    ciJobStateInstalling
8    ciJobStatePendingSoftReboot
9    ciJobStatePendingHardReboot
10    ciJobStateWaitReboot
11    ciJobStateVerifying
12    ciJobStateInstallComplete
13    ciJobStateError
14    ciJobStateWaitServiceWindow
15    ciJobStateWaitUserLogon
16    ciJobStateWaitUserLogoff
17    ciJobStateWaitJobUserLogon
18    ciJobStateWaitUserReconnect
19    ciJobStatePendingUserLogoff
20    ciJobStatePendingUpdate
21    ciJobStateWaitingRetry
22    ciJobStateWaitPresModeOff
23    ciJobStateWaitForOrchestration

Code:

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

Usage:

    The following cmdlets will force the installation of all actionable updates

Code:

$MissingUpdates = Get-WmiObject -Class CCM_SoftwareUpdate -Filter ComplianceState=0 -Namespace root\CCM\ClientSDK
$MissingUpdatesReformatted = @($MissingUpdates | ForEach-Object {IF($_.ComplianceState -eq 0){[WMI]$_.__PATH}})
$InstallReturn = Invoke-WmiMethod -Class CCM_SoftwareUpdatesManager -Name InstallUpdates -ArgumentList (,$MissingUpdatesReformatted) -Namespace root\ccm\ClientSDK

piątek, 7 września 2018

Troubleshooting - Disappering configuration.mof File

Symptoms:

   Recently we noticed an unexpected behavior of Hardware Inventory settings applied in the configuration.mof file on one of our SCCM instances. None of the WMI classes introduced into the file were collected and upon re-checking the file it turned out, that any newly added section were being removed and the file was reverted to it's original form. Interestingly enough, the section added did not contain any errors, as this was happening even in case of adding additional spaces or new lines to the file - they would disappear as well.

Resolution:

    My first suspicion was to verify the extension added by the custom HP inventory module solution, which was only applied on this particular instance and added the following section at the end of the configuration.mof file:



Extension added to configuration.mof file by a custom HP plugin

    Removing this section however didn't take an effect either - the file was restored and the section re-appeared. An action was reflected in the dataldr.log file with the following entries:

MofCompiler failed:
parsing error
Failed to confert MOF class/poperties to policy; a retry will be attemted in 30 seconds...


Errors in the dataldr.log file

    Despite no apparent syntax problems the file refused to get parsed. Even voiding each section one by one didn't fix the problem - an empty file would get removed and restored from backup too. What helped to pinpoint the problem was running file comparison tool FC.exe - against another configuration.mof file from the properly working environment. This revealed the following phenomenon:



Errors in the dataldr.log file

    Apparently the beginning of the file was taken by some special character invisible either notepad or any other editing tool that was available. The problem was fixed by replacing the file with a properly working one and transplanting custom sections from the old faulty one. Looking at the history of the changes it seems that the latest accepted change to the file was accepted after adding the custom HP SCCM plugin

wtorek, 10 lipca 2018

Troubleshooting - Where to Look for SCCM Console's Default Connection Settings

Symptoms:

   Imagine SCCM Console is pushed as an SCCM application and you make a typo in the  properties providing a value of a DefaultSiteServerName parameter (a thing that happened to us recently). Normally it's not a big deal - a single user can correct this by introducing a proper server name on the first screen. Now imagine that apart from other computers the console was installed as well on the RemoteApp server. Every single user starting an application will face the same situation which can result in a significant amount of complaints

Resolution:

    The connection settings for each individual user are stored in the below registry key - HKU\{User_GUID}\Software\Microsoft\ConfigMgr10\AdminUI\MRU\1:



Location of individual SCCM Console connection settings in the registry

    This key is modified automatically once the user introduces a new value at the console startup. However every new user starting a console from the before-mentioned RemoteApp server will initially face the same. We also discovered another interesting phenomenon - upgrading a console on the server resets the above-shown keys to the general value set up during the first installation of the console. So - where is the main value stored? It turned out it is also written in the registry and can be found in the below key - HKLM\SOFTWARE\Microsoft\SMS\Identification:


Location of the main SCCM Console connection settings in the registry

    Changing a value of this key fixes a problem for all the future users. If you want to fix it for all the users already facing a problem, you have to modify their respective keys in the hive mentioned on the first screen-shot.

czwartek, 10 maja 2018

Update - Script Installing Java and Removing any Obsolete Versions v2

    Following up the recent post about removing confidential data from the log files,
that can be found over here:


    It turned out after more in-depth analysis of several scenarios where Java was deployed on the servers rather than workstations, that WMIC CALL UNINSTALL command might sometimes enforce a system restart (a thing that we have never observed on workstations with a first version of the script) and it turns out, that there is no built-in way to avoid this with WMIC. Due to this in the effort to exclude this possibility I wrote a second version of the script, which is based on msiexec /X command, some REG QUERY and -REPLACE manipulations which are extracting GUIDs from the registry and forming msiexec uninstall strings. By doing this we can explicitly add the /norestart parameter which does what we need.

Usage:

    Similarly to the previous version place the script file in the same folder as the Java binaries. Script in the below version is installing Java 8.0.121 and removing any Java version installed on the computer.
    When the SCCM Application is ready, be sure to set up properly detection methods depending on the Java versions that you expect to see on the computer after the installation process completes. I recommend using registry keys for this purpose as in the example below:
Detection method set for Java 8 U 121

Additional Notes:
    In contrary to the first version of the script here there unfortunately is no way to choose which versions of Java we would like to keep on the computer, like with the NOT Version LIKE '8.0.121'" module in the previous script. Therefore filtering has to be performed on the collection rules level. When creating collections for staged deployment include only computers containing Java version you would like to uninstall or which don't contain any Java if you want to push the software to them.
    After setting this up properly I still recommend to divide your environment in several parts, increasing in size and to deploy the script to those collections one by one.

Code:

setLocal EnableDelayedExpansion

REM Stop IE
if EXIST "%WINDIR%\system32\taskkill.exe" (
   taskkill /F /IM iexplore.exe 2> NUL
)

REG QUERY HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall /s /f "Java*Update" | findstr "HKEY_LOCAL_MACHINE" >> tmpFile.bat
REG QUERY HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall /s /f "Java*Update" | findstr "HKEY_LOCAL_MACHINE" >> tmpFile.bat

powershell -Command "(gc tmpFile.bat) -replace 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\', 'msiexec /X ' | Out-File -Encoding "Default" tmpFile.bat"
powershell -Command "(gc tmpFile.bat) -replace 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\', 'msiexec /X ' | Out-File -Encoding "Default" tmpFile.bat"
powershell -Command "(gc tmpFile.bat) -replace '\S+$', '$& /quiet /norestart' | Out-File -Encoding "Default" tmpFile.bat"

.\tmpFile.bat
"%~dp0jre-8u121-windows-x64.exe" /s "ADDLOCAL=ALL IEXPLORER=1 MOZILLA=0 JAVAUPDATE=0 REBOOT=Disable"

DEL .\tmpFile.bat

piątek, 20 kwietnia 2018

Script Installing Java and Removing any Obsolete Versions

    Managing centrally Java life-cycle with SCCM might be a little challenging due to the fact, that multiple versions of Java might coexist on one computer. If you add to this, that only some of those versions might be approved to be present in the network (which implies that you might not be allowed to use Java Auto Updater) and that the installer doesn't automatically uninstall old Java version during the installation you find yourself in quite a complex situation. That's when the script below might come in handy. It was written in order to remove all non-approved Java versions, Java Auto Downloader and install the latest approved version of Java

Usage:
    Place the script file in the same folder as the Java binaries. Script in the below version is installing Java 8.0.121 and removing any different version, together with Java Auto Downloader. The NOT Name LIKE '%%DEV%%' exclusion ensures, that Java Development Environment, if exists on the computer, will remain untouched.
    You can add more NOT Version LIKE 'xxx' modules to the wmic command if you have some applications that depend strictly on a particular Java version and you know that it should not be uninstalled.
    When the SCCM Application is ready, be sure to set up properly detection methods depending on the Java versions that you expect to see on the computer after the installation process completes. I recommend using registry keys for this purpose as in the example below:
Detection method set for Java 8 U 121

Additional Notes:
    As in all the scripted deployments you should be very careful. I recommend to verify first which products matching 'Java%%' wildcard do you have in your environment with use Hardware Inventory and either SCCM Reporting or SQL query. 
    When you are sure what you're doing, you can always test several cases on the test computer by calling this part of command only:

wmic product WHERE "Name LIKE 'Java%Update%' AND NOT Name LIKE '%Dev%' AND NOT Version LIKE '8.0.121'"

    By doing this you will verify which programs would be uninstalled when executing your SCCM deployment.
    After checking this I still recommend to go for a staged deployment. Divide your environment in several parts, increasing in size and deploy the script to those collections one by one.

Code:

REM Stop IE

if EXIST "%WINDIR%\system32\taskkill.exe" (
   taskkill /F /IM iexplore.exe 2> NUL
)

wmic product WHERE "Name LIKE 'Java%%Update%%' AND NOT Name LIKE '%%Dev%%' AND NOT Version LIKE '8.0.121'" call uninstall /nointeractive

REM "%~dp0jre-8u121-windows-x64.exe" /s "ADDLOCAL=ALL IEXPLORER=1 MOZILLA=0 JAVAUPDATE=0 REBOOT=Disable"

poniedziałek, 5 marca 2018

How to check which binaries can be removed from SCCM server

    Recently I received an interesting question - can particular folders from the SCCM source share be removed or are they still in use by any application? It can be actually verified with a below SQL query, which helps to identify all folders set as a source for any application or package and matching a certain wildcard chosen by an administrator.


Exemplary output of the folder presence SQL query

Usage:
    Replace the _ServerFQDN_ string with the name of the source server, XXX$ with a name of the share and YYY with a regular expression matching a path to the folders you want to verify. 
    Obviously the query should be run via SQL Management Studio or any other similar tool letting you execute T-SQL queries.

Code:
SELECT Name,PkgSourcePath,ContentSource FROM v_Content
JOIN v_Package ON v_Package.PackageID = v_Content.PkgID
WHERE ContentSource LIKE '\\_ServerFQDN_\XXX$\YYY\%'
OR PkgSourcePath LIKE '\\_ServerFQDN_\XXX$\YYY\%'

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