What are Lazy Properties?
So if you’re a script writer, and you also use System Center Configuration Manager 2007 (ConfigMgr), you may have run into a concept called Lazy Properties. Lazy properties are certain (not all) properties on certain (not all) WMI classes, within the ConfigMgr provider namespace, that are marked with a WMI qualifier denoting the property as “lazy.” That was quite a mouthful! What exactly does this mean? Why are certain properties LAZY? Well, during the development of ConfigMgr, Microsoft realized that the enumeration of some information from the ConfigMgr provider could result in a high load on the server where the provider is installed. They introduced lazy properties as a method of providing only (what they deemed) “essential information” unless the script/software developer specifically requested more information.
How do I identify Lazy Properties?
Now that you know what lazy properties are, you are probably wondering how you’re supposed to know whether or not you have to design your code around lazy properties. This actually isn’t too hard. There are a couple different ways you’ll know that you’re dealing with a lazy property:
- You’re not getting data back that you’d expect to when querying a ConfigMgr WMI class
- You find a property marked with the lazy WMI qualifier using a WMI browsing tool (eg. wbemtest, SAPIEN WMI Explorer, CIM Studio, etc.)
- Run a PowerShell script against the ConfigMgr namespace and look for property definitions with the lazy qualifier — read the last section of this article
Here is a screenshot of WbemTest (WMI utility built into Windows), browsing the class definition of rootsmssite_xyz:SMS_AuthorizationList. Instances of the SMS_AuthorizationList class represent Update List objects in ConfigMgr Software Updates. We can see that the property named “Updates” on this class is marked as lazy. This is just one example, and there are many more properties just like this one.
Ok, so how do I get values from Lazy Properties?
Getting values from lazy properties takes just a couple extra steps than normally working with WMI objects. The key thing to remember with lazy properties is that you have to get a reference to each WMI instance (aka. object) explicitly. You’re still ok to enumerate WMI instances using the SwbemServices.ExecQuery() COM interface in VBscript & PowerShell, or Get-WmiObject in PowerShell, but when you’re iterating over each instance, you must get a second, explicit reference to the WMI instance you’re wanting to work with. Let’s look at an example.
PowerShell Code – Retrieving a Lazy Property
Here is a sample script that retrieves all instances of the SMS_AuthorizationList class, that we examined above. Take note that as we iterate over each instance of SMS_AuthorizationList, we are redefining the $UpdateList variable by retrieving a direct reference to the instance. If we hadn’t done this, the Updates property that we looked at in WbemTest would appear to be empty!
[cc lang=”powershell”]
# Retrieve an array of all Update List objects
$UpdateLists = Get-WmiObject -Namespace root\sms\site_lab -Class SMS_AuthorizationList;
# Iterate over each Update List object in results
foreach ($UpdateList in $UpdateLists)
{
# Using the __PATH property, obtain a direct reference to the instance
$UpdateList = [wmi]”$($UpdateList.__PATH)”;
# Iterate over each update CI_ID in the Updates array
foreach ($Update in $UpdateList.Updates)
{
# Get a reference to the update we’re working with, based on its CI_ID
$Update = Get-WmiObject -Namespace root\sms\site_lab -Query “select * from SMS_SoftwareUpdate where CI_ID = ‘$Update'”;
Write-Host -Object “Update List ($($UpdateList.LocalizedDisplayName)) contains update: “,$Update.LocalizedDisplayName;
}
}[/cc]
Code Results
Here is a screenshot of Quest’s free PowerGUI Script Editor running the script above, and retrieving a ConfigMgr lazy property (SMS_AuthorizationList.Updates). It’s actually doing a bit more than simply retrieving a WMI instance with its lazy properties — the lazy property (Updates) itself contains only an array of the UpdateIDs (aka. it’s CI_ID) associated to the Update List (SMS_AuthorizationList) object. We’re going one step further and cross-reference the UpdateID with the SMS_SoftwareUpdate class, so we can retrieve more information about the individual updates. This enables us to print out the friendly name of the update, as seen below in the lower-right PowerShell Console window.
What happens if I don’t retrieve lazy properties in my script?
So you’re thinking you can get off easy by just not retrieving lazy properties, right? Well, you can, but you’ll likely run into trouble. The thing is, if you make any changes to your WMI objects, and write them back to the ConfigMgr provider using the Put() method, you’ll effectively erase the values of any lazy properties on that object! It goes without saying that you need to be very careful when making any changes to your ConfigMgr objects via the provider (which is the only way you should be doing it in the first place, programatically).
If you’re simply reading information from the provider, and do not require the information contained within any lazy properties, then you are safe to read the information without performing the additional steps above.
Mega-Bonus Round: Listing All ConfigMgr Lazy Properties
Here’s a very simple PowerShell script we can use to spit out a list of all the lazy properties in the ConfigMgr namespace! Keep in mind that this could change with service pack or “R” revisions to ConfigMgr. I also would surmise that ConfigMgr vNext will introduce more changes to this list, and who knows, maybe they’ll eliminate lazy properties altogether! Just a theory, don’t quote me 🙂
PowerShell Code – Listing All ConfigMgr Lazy Properties
If you copy/paste/execute this code, after changing “lab” to your ConfigMgr site code, you should be able to get similar output to what I’ve included below for a reference. If you’re running the script from a remote management workstation, rather than on your server with the ConfigMgr provider, simply tack on the -ComputerName parameter to the Get-WmiObject cmdlet.
[cc lang=”powershell”]$WmiClassList = Get-WmiObject -List -Namespace root\sms\site_lab
$LazyList = @()
# Iterate over each WMI class in the namespace
foreach ($WmiClass in $WmiClassList)
{
# Iterate over properties for current WMI class
foreach ($WmiProperty in $WmiClass.Properties)
{
# Iterate over WMI qualifiers for current WMI property
foreach ($WmiQualifier in $WmiProperty.Qualifiers)
{
# If qualifier is named “lazy”, and the value is “true”, then it’s a lazy property
if ($WmiQualifier.Name -eq ‘lazy’)
{
# Add class name, property name, and qualifier name to array for processing
$LazyList += New-Object PSCustomObject -Property @{ “Class” = $WmiClass.__CLASS; “Property” = $WmiProperty.Name; “Qualifier” = $WmiQualifier.Name }
}
}
}
}
# Sort array of lazy properties by WMI class name, property name
$LazyList = $LazyList | Sort-Object -Property Class,Property
# Write array of lazy properties to console
Format-Table -InputObject $LazyList -Property Class,Property,Qualifier | Out-File “All ConfigMgr Lazy Properties.txt”[/cc]
ConfigMgr Lazy Property Reference
This is a reference of all ConfigMgr lazy properties, based on an installation of ConfigMgr 2007 SP2 with R3 Release Candidate installed. It’s possible that this list could change, but if you simply run the script above (change your site code from “lab“), you can get a current list once again.
Class Property Qualifier
----- -------- ---------
SMS_Advertisement AssignedSchedule lazy
SMS_Advertisement AssignedScheduleEnabled lazy
SMS_Advertisement AssignedScheduleIsGMT lazy
SMS_Advertisement ExpirationTimeEnabled lazy
SMS_Advertisement ExpirationTimeIsGMT lazy
SMS_Advertisement ISVData lazy
SMS_Advertisement ISVDataSize lazy
SMS_Advertisement PresentTimeEnabled lazy
SMS_Advertisement PresentTimeIsGMT lazy
SMS_AuthorizationList LocalizedInformation lazy
SMS_AuthorizationList Updates lazy
SMS_BootImagePackage BackgroundBitmapPath lazy
SMS_BootImagePackage ContextID lazy
SMS_BootImagePackage EnableLabShell lazy
SMS_BootImagePackage ImageDiskLayout lazy
SMS_BootImagePackage ImageIndex lazy
SMS_BootImagePackage ImageProperty lazy
SMS_BootImagePackage ReferencedDrivers lazy
SMS_CategoryInstanceBase LocalizedInformation lazy
SMS_CertificateInfo Certificate lazy
SMS_CertificateInfo PublicKey lazy
SMS_CertificateInfo Thumbprint Lazy
SMS_CI_CurrentComplianceStatus ComplianceStatusDetails lazy
SMS_Collection CollectionRules lazy
SMS_Collection RefreshSchedule lazy
SMS_Collection RefreshType lazy
SMS_Collection ReplicateToSubSites lazy
SMS_CollectionSettings CollectionVariables lazy
SMS_CollectionSettings PowerConfigs lazy
SMS_CollectionSettings ServiceWindows lazy
SMS_ConfigurationItem LocalizedEulas lazy
SMS_ConfigurationItem LocalizedInformation lazy
SMS_ConfigurationItemBaseClass IsDigest lazy
SMS_ConfigurationItemBaseClass SDMPackageLocalizedData lazy
SMS_ConfigurationItemBaseClass SDMPackageXML lazy
SMS_DeviceSettingItem PropList lazy
SMS_DeviceSettingPackage DeviceSettingItemUniqueIDs lazy
SMS_DistributionPoint ISVData lazy
SMS_DistributionPoint ISVDataSize lazy
SMS_Driver LocalizedEulas lazy
SMS_Driver LocalizedInformation lazy
SMS_EULAContent EULAText lazy
SMS_G_System_CollectedFile FileData lazy
SMS_ImagePackage ImageDiskLayout lazy
SMS_ImagePackage ImageProperty lazy
SMS_MachineSettings MachineVariables lazy
SMS_ObjectContainerNode SearchString lazy
SMS_OperatingSystemInstallPackage ImageProperty lazy
SMS_PackageBaseclass AlternateContentProviders lazy
SMS_PackageBaseclass ExtendedData lazy
SMS_PackageBaseclass ExtendedDataSize lazy
SMS_PackageBaseclass IconSize lazy
SMS_PackageBaseclass ISVData lazy
SMS_PackageBaseclass ISVDataSize lazy
SMS_PackageBaseclass RefreshPkgSourceFlag lazy
SMS_PackageBaseclass RefreshSchedule lazy
SMS_PDF_Package Icon lazy
SMS_PDF_Package IconSize lazy
SMS_PDF_Package RequiredIconNames lazy
SMS_PDF_Package Status lazy
SMS_PDF_Program Icon lazy
SMS_PDF_Program IconSize lazy
SMS_PendingRegistrationRecord Certificate lazy
SMS_PendingRegistrationRecord PublicKey lazy
SMS_PendingRegistrationRecord Thumbprint Lazy
SMS_Program ExtendedData lazy
SMS_Program ExtendedDataSize lazy
SMS_Program IconSize lazy
SMS_Program ISVData lazy
SMS_Program ISVDataSize lazy
SMS_Program SupportedOperatingSystems lazy
SMS_Report DrillThroughReportPath lazy
SMS_Report ReportParams lazy
SMS_Report SQLQuery lazy
SMS_SiteControlFile BuildNumber lazy
SMS_SiteControlFile FormatVersion lazy
SMS_SiteControlFile SCFData lazy
SMS_SiteInstallMap BuildNumber lazy
SMS_SiteInstallMap FormatVersion lazy
SMS_SiteInstallMap IMapData lazy
SMS_SoftwareUpdate LocalizedEulas lazy
SMS_SoftwareUpdate LocalizedInformation lazy
SMS_SoftwareUpdateSource PublicKeys Lazy
SMS_StateMigration UserNames lazy
SMS_TaskSequencePackage BootImageID lazy
SMS_TaskSequencePackage Category lazy
SMS_TaskSequencePackage CustomProgressMsg lazy
SMS_TaskSequencePackage DependentProgram lazy
SMS_TaskSequencePackage References lazy
SMS_TaskSequencePackage Reserved lazy
SMS_TaskSequencePackage Sequence lazy
SMS_TaskSequencePackage SupportedOperatingSystems lazy
SMS_TaskSequencePackage TaskSequenceFlags lazy
SMS_TaskSequencePackage Type lazy
SMS_Template Data lazy
SMS_UpdatesAssignment LegacyCollectInventory lazy
SMS_UpdatesAssignment LegacyDeploymentSchedule lazy
SMS_UpdatesAssignment LegacyDPLocality lazy
SMS_UpdatesAssignment LegacyForceReboot lazy
SMS_UpdatesAssignment LegacyInstallAllOnDeadline lazy
SMS_UpdatesAssignment LegacyInstallAllowedWindow lazy
SMS_UpdatesAssignment LegacyPostponeInstall lazy
SMS_UpdatesAssignment LegacySilentInstall lazy
SMS_VirtualApp IconSize lazy