Gartner’s Magic Quadrant for PC Configuration Life Cycle Management Tools, 2011

Gartner has just published the latest Magic Quadrant for PC Configuration Life Cycle Management Tools. According to Gartner, the market for PC Configuration Life Cycle Management Tools is mature but the rating for Completeness of Vision decreased from past years because vendors have been slow to address the five major market trends:

  1. Alternative Device Management
  2. Desktop Virtualization Management
  3. Integration With Service Desk and Asset Management
  4. Security and Operations Convergence
  5. Alternative Delivery Models
Posted in System Center, System Center Configuraton Manager | Leave a comment

Microsoft is catching up in the IT Event Correlation and Analysis market

Gartner released the latest version of their Magic Quadrant for IT Event Correlation and Analysis. Microsoft is catching up with the “Big Four” in Systems Management – IBM, HP, BMC and CA – and has been placed in the Leaders Quadrant for the first time (see the 2009 version of this document for comparison).

Posted in System Center, System Center Operations Manager | Leave a comment

Creating update lists in Configuration Manager 2007 automatically

System Center Configuration Manager 2007 provides update lists to manage various aspects of the software update management process. An update list is as the name implies just a list of software updates and provides the following benefits:

  • The deployment of software updates can be delegated to administrators in child sites. The update list created on the parent site will be replicated down the hierarchy to child sites. Administrators in child sites can then deploy the updates in that list to a collection of clients.
  • Software update lists can be used for multiple deployments of the same set of updates.
  • Software update lists allow to track the compliance status of update deployments against a defined set of software updates.

Even though software update lists are not absolutely required they are strongly recommended because they simplify the process of deploying software updates.

One aspect I do not particularly like about software update lists is that you need to search and select every single software update you want to add to the update list. If your baseline is, for instance, still Windows XP Service Pack 2, you need to manually select more than 100 software updates. Although you can use appropriate search folders, it is still a too complicated and painful process to initially set up the software update management infrastructure.

Therefore I have written a PowerShell script to make this process easier. The idea is to have a reference client which represents the baseline for a particular client or server type. This reference client needs to have the Configuration Manager client installed and must have successfully completed a software update scan. The script then creates an update list with all software updates reported as missing for this particular client.

The Configuration Manager 2007 Software Development Kit (SDK) describes how to programmatically create an update list by creating an instance of the class SMS_AuthorizationList. The script then queries the class SMS_UpdateComplianceStatus to determine the missing software updates for the client.


param(
   $ReferenceClient,
   $UpdateListName,
   $SiteServer,
   [switch] $force,
   [switch] $verbose
)

$AppName = "Create-UpdateList"

$manpage = @'
NAME
    Create-UpdateList

SYNOPSIS
    Creates a Configuration Manager update list.

SYNTAX
    Create-UpdateList -ReferenceClient  -UpdateListName  [-SiteServer ] [-Force] [-Verbose]

DETAILED DESCRIPTION
    This script creates an update list based on the inventory data of a reference client. The
    reference client should represent the baseline for a specific operating system used within
    your organization. This client needs to be present in the Configuration Manager database
    with valid inventory data. This script then creates an update list which includes all the
    software updates reported as missing from the reference client.

PARAMETERS
    -ReferenceClient
        Specifies the name of the reference client.

    -UpdateListName
        Specifies the name of the update list to be created.

    -SiteServer
        Optional: Specifies the Configuration Manager site server. If not specified, the
        local computer is assumed to be the site server.

    -Force
        Optional: Creates an update list even if an update list with the same display name
        already exists.

    -Verbose
        Optional: Generates detailed information about the script's operations.

'@

if (!$ReferenceClient -or !$UpdateListName) {
   Write-Host $manpage
   exit
}

if ($args.count -eq 1) {
   $siteserver = $args[0]
}
elseif ($args.count -gt 1) {
   Write-Host $manpage
   exit
}

if (!$siteserver) { $siteserver = $env:computername }
$namespace = "root\sms"

if ($verbose) {
   Write-Host "`nReferenceClient: $ReferenceClient"
   Write-Host "UpdateListName : $UpdateListName"
   Write-Host "SiteServer     : $SiteServer`n"
}

$smsContext = New-Object System.Management.ManagementNamedValueCollection
$smsContext.Add("ApplicationName", $AppName)
$smsContext.Add("MachineName", $env:computername)
$smsContext.Add("LocaleID", 1033)

$connOptions = New-Object System.Management.ConnectionOptions
$connOptions.Context = $smsContext

$path = New-Object System.Management.ManagementPath
$path.NamespacePath = "\\$siteserver\" + $namespace

$scope = New-Object System.Management.ManagementScope($path, $connOptions)

$ErrorActionPreference = “silentlycontinue”
$scope.Connect()
if (!$?) {
   $ErrorActionPreference = “continue”
   $cred = Get-Credential
   if (!$cred) {
      Write-Host "No credentials supplied." -foregroundcolor Red -backgroundcolor Black
      exit
   }

   # Property "SecurePassword" requires .NET Framework 2.0 SP1 or higher!
   $connOptions.Username = $cred.Username
   $connOptions.SecurePassword = $cred.Password
   $scope.Options = $connOptions

   $ErrorActionPreference = “silentlycontinue”
   $scope.Connect()
   if (!$?) {
      Write-Host "Could not connect to site server $siteserver." -foregroundcolor Red -backgroundcolor Black
      Write-Host $error[0] -foregroundcolor Red -backgroundcolor Black
      exit
   }
}
elseif ($verbose) {
   Write-Host "Successfully connected to \\$siteserver\$namespace."
}

$ErrorActionPreference = “continue”

$wqlquery = "SELECT * FROM SMS_ProviderLocation"
$query = New-Object System.Management.ObjectQuery($wqlquery)
$searcher = New-Object System.Management.ManagementObjectSearcher($scope, $query)
$providerLoc = $searcher.Get()

if (!$providerLoc) {
   Write-Host "Could not get instances from the SMS_ProviderLocation class." -foregroundcolor Red -backgroundcolor Black
   exit
}
foreach ($providerInst in $providerLoc) {
   if (!$providerInst.ProviderForLocalSite) {
      Write-Host "SMS Provider $providerInst.SiteCode not set as local site server." -foregroundcolor Red -backgroundcolor Black
      exit
   }
   else {
      $sitecode = $providerInst.SiteCode
   }
}

$namespace = "root\sms\site_$sitecode"

$ErrorActionPreference = “silentlycontinue”
$scope.Path = "\\$siteserver\$namespace"
$scope.Connect()
if (!$?) {
   Write-Host "Could not connect to site server $siteserver." -foregroundcolor Red -backgroundcolor Black
   exit
}
elseif ($verbose) {
   Write-Host "Successfully connected to \\$siteserver\$namespace."
}

$ErrorActionPreference = “continue”

# Check if the specified reference client already exists within the ConfigMgr database
$wqlquery = 'SELECT ResourceID FROM SMS_R_System WHERE Name = ' + '"' + "$ReferenceClient" + '"' + ' AND Active = 1'
if ($verbose) {
   Write-Host "Verifying if the reference client $ReferenceClient actually exists in the ConfigMgr database."
   Write-Host "Running WQL query: $wqlquery."
}

$query = New-Object System.Management.ObjectQuery($wqlquery)
$searcher = New-Object System.Management.ManagementObjectSearcher($scope, $query)
$searcher.Get() | Foreach-Object { $rscID = $_.ResourceID }
if (!$rscID) {
   Write-Host "Could not find the reference client $ReferenceClient in the Configuration Manager database." -foregroundcolor Red -backgroundcolor Black
   exit
}
if ($verbose) {
   Write-Host "Found $ReferenceClient in the database with Resource ID $rscID."
}

# Check if the specified name for the update list is already in use
$wqlquery = "SELECT * FROM SMS_AuthorizationList WHERE LocalizedDisplayName = " + "'"
$wqlquery += $UpdateListName + "'"
if ($verbose) {
   Write-Host "Check if the specified name for the update list is already in use."
   Write-Host "Running WQL query: $wqlquery."
}

$query = New-Object System.Management.ObjectQuery($wqlquery)
$searcher = New-Object System.Management.ManagementObjectSearcher($scope, $query)
$searcher.Get() | Foreach-Object { $ListID = $_.CI_ID }
if ($ListID) {
   if (!$force) {
      $msg = "`nAn update list with the name $UpdateListName already exists. If you want the update list to be created, "
      $msg += "please specify the -force switch."
      Write-Host $msg -foregroundcolor Yellow -backgroundcolor Black
      exit
   }
}
elseif ($verbose) {
   Write-Host "An update list with the name $UpdateListName does not exist."
}

# Get the missing software updates reported for the reference client
$wqlquery = "SELECT css.CI_ID FROM SMS_UpdateComplianceStatus css "
$wqlquery += "JOIN SMS_SoftwareUpdate ui ON css.CI_ID = ui.CI_ID "
$wqlquery += "WHERE css.MachineID = $rscID AND css.Status = 2"
if ($verbose) {
   Write-Host "Getting required software updates for $ReferenceClient from the ConfigMgr database."
   Write-Host "Running WQL query: $wqlquery."
}

$swupdates = New-Object System.Collections.ArrayList
$query = New-Object System.Management.ObjectQuery($wqlquery)
$searcher = New-Object System.Management.ManagementObjectSearcher($scope, $query)
$searcher.Get() | Foreach-Object { [void] $swupdates.Add($_['CI_ID']) }
if (!$swupdates) {
   Write-Host "Reference Client $ReferenceClient has all required software updates installed." -foregroundcolor Yellow -backgroundcolor Black
   Write-Host "No Update List will be created." -foregroundcolor Yellow -backgroundcolor Black
   exit
}

# Get the LocaleID of the site server installation
$wqlquery = 'SELECT * FROM SMS_Identification'
$query = New-Object System.Management.ObjectQuery($wqlquery)
$searcher = New-Object System.Management.ManagementObjectSearcher($scope, $query)
$searcher.Get() | Foreach-Object { $LocaleID = $_.LocaleID }
if (!$LocaleID) { $LocaleID = 1033 }
if ($verbose) {
   Write-Host "Using LocaleID $LocaleID."
}

$options = New-Object System.Management.ObjectGetOptions
$options.Context = $smsContext
$path = New-Object System.Management.ManagementPath("\\$siteserver\$namespace" + ":SMS_CI_LocalizedProperties")
$smsCiLoc = (New-Object System.Management.ManagementClass($scope, $path, $options)).CreateInstance()

# Workaround a PowerShell V1 issue
[void] $smsCiLoc.psbase.Properties

$smsCiLoc.DisplayName = $UpdateListName
$smsCiLoc.LocaleID = $LocaleID

[System.Management.ManagementObject[]] $newDescriptionInfo += $smsCiLoc

$options = New-Object System.Management.ObjectGetOptions
$options.Context = $smsContext
$path = New-Object System.Management.ManagementPath("\\$siteserver\$namespace" + ":SMS_AuthorizationList")
$newUpdateList = (New-Object System.Management.ManagementClass($scope, $path, $options)).CreateInstance()

# Workaround a PowerShell V1 issue
[void] $newUpdateList.psbase.Properties

$newUpdateList.Updates = $swupdates
$newUpdateList.LocalizedInformation = $newDescriptionInfo

$putOptions = New-Object System.Management.PutOptions($smsContext)
$ErrorActionPreference = “silentlycontinue”
[void] $newUpdateList.Put($putOptions)
if (!$?) {
   Write-Host "Could not create update list $UpdateListName."
   Write-Host $error[0]
}
else {
   Write-Host "Successfully created update list $UpdateListName."
}
SMS_UpdateComplianceStatus
Posted in System Center, System Center Configuraton Manager | Leave a comment