CategorySCCM

Last Logged On User (PowerShell)

So, one of the things I’ve been working on is using SCCM and the Desired Configuration Management (DCM) functionality to test ‘compliance’ on desired configuration items (CIs) at one of the client sites I’m assigned.  As you can likely guess based on several of my other postings, most of these configuration settings are related to Outlook 2010.  If you’ve ever worked with SCCM DCM CIs that use PowerShell to check the contents of registry keys that exist in HKEY_CURRENT_USER, you’ve likely dealt with a few interesting issues:

  •  SCCM runs PowerShell deployed through the DCM interface via the SYSTEM account, therefore HKEY_CURRENT_USER is useless — you must instead loop through HKEY_USERS.  Your SYSTEM account does not have a users registry hive, and even if it did, I’m pretty sure that’s not the registry you want to be checking! 🙂
  • HKEY_USERS is fine, so long as you strip out unimportant profiles for your script — e.g., existing profiles that are part of the imaging process, local administrator profiles, etc.
  • HKEY_USERS is fine, even if a machine has more than one user — so long as it can be reasonably assumed that the last logged in user is the person whose compliance you are interested in.
  • HKEY_USERS is not accessible to normal users programmatically via PowerShell, so to test your scripts you must invoke PowerShell as the SYSTEM account, interactively.  I use PsExec for this, but I’m sure there’s other ways of doing such.

This creates a few interesting issues that require some thought in order to ensure that the code runs perfectly against all, say, 1,600 client computers — AND returns legitimate compliance results.

Thankfully, someone (Brian Wilhite) has done the legwork of putting together a solid PowerShell cmdlet that determines the last logged in user and whether that user is still logged in.  If you need something like this, take a look at Script – Get-LastLogon

I’ve now incorporated that into several of my CI scripts in order to do checks against data in the HKEY_USERS key while confirming that the user account whose registry I’m targeting corresponds to the user that has most recently logged in to the machine, and it’s done wonders to help sanitize the compliance results.

I always like uncovering someone else’s hard work, especially when it is precisely something I was thinking of writing myself.  I get the feeling Brian’s script is better than what I would have come up with!

Anyway, hope this helps anyone else who has found themselves in a similar situation.  I had such good results using this script I couldn’t help but post about how useful it had become for me.

Outlook – Cached Mode & Public Folder Favorites?

So, in my series of things I’m doing with Configuration Items / Configuration Baselines / etc. in SCCM, I’ve been tasked with creating a script that will check whether any profile on the target machine has been configured for Cached Mode w/ Public Folder Favorites caching enabled.

Typical to Outlook 2010 settings, this is stored in a binary encoded registry key deep in the Profiles location under HKCU.  Anyone who has worked with compliance settings in SCCM using Powershell will know that SCCM runs the Powershell script as the SYSTEM account, and not as the locally logged in user — as such, HKCU is a bust.  You must instead loop through HKEY_USERS in order to get the data.

This script does a recursive search through HKU, pulls the location of Outlook profiles where the 00036601 value is found (the specific value that contains the binary encoded representation of the configuration objects we are trying to report on), then checks the specific bytes to validate against the known value for Cached Mode and then the known value for Cached Mode w/ Public Folder Favorite Caching enabled.

If you just want to determine whether someone is in cached mode, you can remove the second bit check from the script — the first bit stays the same when Cached Mode is enabled regardless.

Here’s a quick reference to the bytes and their respective definition:

Byte 0 = 128 
  Cached Mode is Enabled
Byte 0 = 0 
  Cached Mode is not Enabled

Byte 1 = 29
  Public Folder Favorites are being Cached
Byte 1 = 25
  Public Folder Favorites are not Cached

To wrap, here’s the code snippet — note that this is a work in progress and while I’ve tested locally, it’s still pending further testing before I classify it as being 100%.  Use at your own risk, YMMV, etc.

I will update the post once I’ve done deeper testing to ensure it gets the right value across the board.

#Check client Outlook configuration settings for public folders cached mode

#Silence Errors to ensure sane output regardless of run circumstances
$ErrorActionPreference = 'silentlycontinue' 

#Create PS Drive to HKEY Users registry
$null = New-PSDrive -Name HKU -PSProvider Registry -Root Registry::HKEY_USERS 

#Define the source registry path to begin the search, including wildcard
$REG_LOC = "HKU:\*\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles\"

#Define the value name we are looking for
$ConnectModeValueName="00036601"

#Set the initial state of the output of the script
$Output="Check not run"

#Recursively search through the registry location previously specified and set the variable with the results
$REG_Hits = (get-childitem -recurse $REG_LOC | ?{$_.Property -contains $ConnectModeValueName})

#If the cached mode is found, check the specific binary value to ensure it complies with best practices
If ($REG_Hits) {
 $Profile_Key = $REG_Hits.Name
 $Profile_Key = $Profile_Key -replace "HKEY_USERS", "HKU:"
 $Key_Data_0 = (Get-ItemProperty $Profile_Key -name 00036601)."00036601"[0]
 $Key_Data_1 = (Get-ItemProperty $Profile_Key -name 00036601)."00036601"[1]
 If ($Key_Data_0 -eq 128 -and $Key_Data_1 -eq 29) { $Output = "Enabled" }
}

#Remove PS Drive definition
$null = Remove-PSDrive HKU

#Provide output for SCCM
$Output

Outlook – On Fast Networks / On Slow Networks

So, one of the clients I do business with was looking for a way to use SCCM to generate a compliance baseline including some key Outlook 2010 performance metrics they uncovered in their environment.

One of the settings they wanted to check was whether the “Connect to Microsoft Exchange using HTTP” “On fast networks, connect using HTTP first, then connect using TCP/IP” and “On slow networks, connect using HTTP first, then connect using TCP/IP” checkboxes were enabled.

Anyone who has worked with Outlook and Powershell likely knows that Outlook loves to store data in binary encoded keys, which are not trivial to decipher using standard methods.  Additionally, SCCM CIs run as the SYSTEM account and not as the logged on user’s account, so checking settings directly through HKCU is not an option.

To work through this, I wrote a Powershell script that loops through the USERS key, looks for an Outlook Profile Registry set, then checks the value of that bit and returns back whether the setting is enabled or disabled.  It’s a fairly simplistic script and I’ve commented it fairly well to indicate what each line does.  We’ve run this across about 1,600 machines at this point and the results seem sound, however, with any script you download from the internet, test small first to make sure it does nothing unexpected in your environment.  I take no responsibility if you copy/paste, then run this and it does anything you’d prefer it didn’t.

If you have any suggestions on how to improve the script, let me know in the comments below!

#Check client Outlook configuration settings for connect over HTTP/S and fast/slow link settings

#Silence Errors to ensure sane output regardless of run circumstances
$ErrorActionPreference = 'silentlycontinue' 

#Create PS Drive to HKEY Users registry
$null = New-PSDrive -Name HKU -PSProvider Registry -Root Registry::HKEY_USERS 

#Define the source registry path to begin the search, including wildcard
$REG_LOC = "HKU:\*\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles\"

#Define the value name we are looking for
$ConnectModeValueName="00036623"

#Set the initial state of the output of the script
$Output="Disabled"

#Recursively search through the registry location previously specified and set the variable with the results
$REG_Hits = (get-childitem -recurse $REG_LOC | ?{$_.Property -contains $ConnectModeValueName})

#If the connect mode is found, check the specific binary value to ensure it complies with best practices
If ($REG_Hits) {
 $Profile_Key = $REG_Hits.Name
 $Profile_Key = $Profile_Key -replace "HKEY_USERS", "HKU:"
 $Key_Data = (Get-ItemProperty $Profile_Key -name 00036623)."00036623"[0]
 If ($Key_Data = 43) { $Output = "Enabled" }
}

#Remove PS Drive definition
$null = Remove-PSDrive HKU

#Provide output for SCCM
$Output

© 2018 TJ in IT

Theme by Anders NorénUp ↑