The HKCU Registry Bridge On the River PowerShell.

Last Updated on September 28, 2022 by rudyooms

This blog will show you the options you have when you need to deploy Hkey_Current_User (HKCU) Registry changes when you are blocking PowerShell!

I will divide this blog into multiple parts

  1. Introduction
  2. Using Reg.exe
  3. ProActive Remediations
  4. PowerShell Script
  5. Conclusion

1. Introduction

When you are blocking PowerShell in the user context with Applocker, deploying HKCU registry changes could be difficult! Why? Because when running a PowerShell script or a Proactive Remediation as the logged-in user, it will be blocked!

As shown below, you will notice the error 0x8004005 in your agentexecutor.log mentioning that the program is blocked by group policy.

So how are we going to solve this issue because sometimes you really want to push a simple HKEY_Current_User (HKCU) setting that isn’t available in the Intune Settings Catalog or Administrative templates.

As an example: When you are using OneDrive and you configured the settings to Automount team sites and you want to speed things up a little bit

Normally that is not a problem when you are NOT blocking PowerShell.The only thing you need to do is to configure the “Run this script using the logged on credentials” option to “yes”

But in my opinion.. not blocking PowerShell for the non-admins is a no-go. It’s just my opinion but if you want to read more about this…

If you have read the blog above you will know why I prefer to block PowerShell. It’s because malware/cryptoware/privilege escalation uses most of the time Powershell. And a normal user.. does not need access to PowerShell (except for loading user scripts.…)

So how can you make sure a user always gets the registry keys necessary? We also need to beware of the fact, the TimerAutoMount key will be reset, when OneDrive has successfully mounted the Sharepoint sites. So we need to have a solution that changes this key for each logon or each hour

I will show you the options we have got:

2. Using Reg.exe

I know deploying a PowerShell script in Intune is very simple to do… this is a little bit different. This is the PowerShell script that needs to be run in the system context instead of the user context, which you normally do when you want to deploy an HKCU key.

PowerShell Script:

$content = @'
 Windows Registry Editor Version 5.00
 [HKEY_CURRENT_USER\Software\Microsoft\OneDrive]
 "Test"=dword:00000001
 '@

$path = $(Join-Path $env:ProgramData CustomScripts)
 if (!(Test-Path $path))
 {
 New-Item -Path $path -ItemType Directory -Force -Confirm:$false
 }
 Out-File -FilePath $(Join-Path $env:ProgramData CustomScripts\onedrive.reg) -Encoding unicode -Force -InputObject $content -Confirm:$false

$WshShell = New-Object -comObject WScript.Shell
 $Shortcut = $WshShell.CreateShortcut("$env:ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\config.lnk")
 $Shortcut.TargetPath = '"c:\windows\System32\reg.exe"'
 $Shortcut.Arguments = "import c:\programdata\CustomScripts\onedrive.reg"
 $Shortcut.WorkingDirectory = '"c:\programdata\CustomScripts\"'
 $Shortcut.Save()

As shown above, you can see I just make use of reg.exe to import the .reg file and create a shortcut to the all user’s startup folder to make sure this reg file is imported on startup.

You can also create an intunewin installer to make sure this is done when the device is deployed to Azure ad for the first time.

Please note: You can’t change/add/remove a registry key in the HKEY_CURRENT_USER\Software\Policies path. It will not work, because it would be very weird if you could change the policies that have been applied as a regular user!

3. ProActive Remediations

A way better option than the reg.exe option would be to use Proactive remediations. So let’s do some magic with the use of ProActive remediations. If you want to see my other ideas with ProActive Remediations…

https://call4cloud.nl/category/proactive-remediations/

But how are we going to make sure we can read the TimerAutoMount key in the HKEY_Current_User registry section when running the remediations in a system context?

Because when we don’t know which user to look for… how are we going to change that setting? Here is how!

Detection Script:

New-PSDrive HKU Registry HKEY_USERS | out-null
$user = get-wmiobject -Class Win32_Computersystem | select Username;
$sid = (New-Object System.Security.Principal.NTAccount($user.UserName)).Translate([System.Security.Principal.SecurityIdentifier]).value;
$key = "HKU:\$sid\Software\Microsoft\OneDrive\Accounts\Business1"
$val = (Get-Item "HKU:\$sid\Software\Microsoft\OneDrive\Accounts\Business1");
$Timer = $val.GetValue("TimerAutoMount");

##################################
#Launch Timer Detection         #
##################################

if($Timer -ne 1)
{
    Write-Host "TimerAutoMount Needs to be changed!"
    Exit 1
}
else
{
    Write-Host "TimerAutoMount doesn't need to be changed"
    Exit 0
}

Remediation Script

New-PSDrive HKU Registry HKEY_USERS | out-null
$user = get-wmiobject -Class Win32_Computersystem | select Username;
$sid = (New-Object System.Security.Principal.NTAccount($user.UserName)).Translate([System.Security.Principal.SecurityIdentifier]).value;
$key = "HKU:\$sid\Software\Microsoft\OneDrive\Accounts\Business1"
$val = (Get-Item "HKU:\$sid\Software\Microsoft\OneDrive\Accounts\Business1") | out-null
$reg = Get-Itemproperty -Path $key -Name TimerAutoMount -erroraction 'silentlycontinue'

##################################
#Launch timer  detection       #
##################################

if(-not($reg))
	{
		Write-Host "Registry key didn't exist, creating it now"
                New-Itemproperty -path $Key -name "TimerAutoMount" -value "1"  -PropertyType "qword" | out-null
		exit 1
	} 
else
	{
 		Write-Host "Registry key changed to 1"
		Set-ItemProperty  -path $key -name "TimerAutomount" -value "1" | out-null
		Exit 0  
	}
 

Go open the ProActive Remediations and take a look at the outcome!

And yes, of course, it has been remediated!

Isn’t this cool? With this solution, you could change the user registry key each hour (when it’s not configured to 1).

Do you know what else is great? When you don’t want a policy to be targeted at the device (HKLM:\software\policies) maybe you could even change HKCU:\software\policies settings with this idea?

4. PowerShell Script

Another option to get the current logged-in Azure Ad user would be to query the User who is running Explorer.exe and convert that username to the well-known SID to change the registry values! To be sure I am getting the only correct username I am using a word boundary -match “\b$CurrentUser\b” to perform a search for “whole words only”

$currentUser = (Get-Process -IncludeUserName -Name explorer | Select-Object -First 1 | Select-Object -ExpandProperty UserName).Split("\")[1] 

$Data = $currentUser
$Keys = GCI "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\" -Recurse
Foreach($Key in $Keys){
    IF(($key.GetValueNames() | %{$key.GetValue($_)}) -match "\b$CurrentUser\b" ){$sid = $key}
}

$sid = $sid.pschildname

New-PSDrive HKU Registry HKEY_USERS | out-null
$key = "HKU:\$sid\Software\Microsoft\OneDrive\Accounts\Business1"
set-Itemproperty -path $Key -name "TimerAutoMount" -value "1" | out-null

Conclusion:

Blocking Powershell is very important but it can put you in a difficult situation when you need to change some HKCU setting… Because it could be hard to apply the settings to the logged in user and not to the system account!

Deploy 1 of these ideas and watch it pouring down to the devices!

Funny Animated The Simpsons Gifs

Of course, you will know I prefer the pro-active remediations…. they are great!

10 thoughts on “The HKCU Registry Bridge On the River PowerShell.

  1. Pingback: Once upon a time in the automount of OneDrive team sites - Call4Cloud
  2. Hi
    I have tried to implement this using intunewin and System install behavior, but it fails to run.
    I have tested running the script on my Windows 10 lab PC and it does work.
    I am using the following command in the Win32 App config to run the ps1 file:
    powershell.exe -executionpolicy bypass -Windowstyle Hidden -file “.\Test.ps1.ps1”
    Can you please assist?

    1. Hi

      I have created an install.cmd inside the folder where the powershell script is located.

      install.cmd content:
      powershell.exe -executionpolicy bypass -command “& ‘.\Windows10_Onedrive.ps1′”

      The install.cmd is called upon in the install command inside intune

  3. I’m thinking about a better way to get the remediation reporting success.

    If we change both exits to 0, or just removed them, and then added another check like

    $Timer = $val.GetValue(“TimerAutoMount”)

    if($Timer -ne 1)
    {
    Write-Host “TimerAutoMount hasn’t been changed”
    Exit 1
    }
    else
    {
    Write-Host “TimerAutoMount has been changed”
    Exit 0
    }

    Do you think that would work to show actual success or failure?

  4. Re: 4. The Powershell Script

    I believe this is still missing New-PSDrive at the start to set up the HKU reference, it isn’t available by default in a Powershell sessions.

    And for getting the SID, the current -Match statement returns only the last hit, while it can give multiple hits in a row (partial matches), so it cannot guarantee to get the right SID if a machine has a bunch of userprofiles on it with similar names.
    %{$Profile.GetValue($_)}) -match “\b$CurrentUser\b” makes it only return an exact match instead.

    1. Hi,

      True.. the New-psdrive needed to be added. I guess I didn’t closed my previous powershell session … But you are totally right about the $currenuser part is better to use word boundaries like your example -match “\b$CurrentUser\b”

      Updated the blog

  5. Hi,
    I’ve just found this, really like it. One thing that kind of bothers me though is that further executions of the script will generate an error as the drive ‘HKU’ will already exist – is there merit to checking for existence of the drive with an exit return so that there’s no errors at all?

Leave a Reply

Your email address will not be published.

74  +    =  83