Delete Multiple Office Profiles in Registry Keys Under HKEY_Users

Hello Everyone! I need some help with deleting the Outlook profile from all users on a PC. I know I can use the action below to remove from the currently logged-on user but not for all users.

dos reg delete “HKEY_USERS{component string of sid of security account (name of logged on user)}\Software\Microsoft\Office\16.0\Outlook\Profiles” /f

I came up with the action script below to delete for all users but need to append it somehow for PCs that are shared and the relevance returns multiple strings.

dos reg delete “{keys whose (name of it as string contains “Profiles”) of keys “Software\Microsoft\Office\16.0\Outlook” of keys of key “HKEY_USERS” of native registry}” /f

I thought about saving the results of the relevance statement to a text file and then using the results to delete but that sounds more complicated. I know of an append option but not very familiar with it and I have never used it before. Thank you!

The principal difficulty is that you are shooting at a moving target - the Current User hives are loaded dynamically for each user, and if the user isn’t logged on, there is no entry under HKEY_USERS to process.

Furthermore, even once you have run this action, when a different user logs on, their unaffected user hive is loaded.

One way you can approach it is to capture all the keys that exists as a parameter then pipe that to a reg delete command. I’ve used this approach to add/modify values for all user keys but not to delete so my syntax for the reg delete command is unverified.

Your detection logic would be something like.

(windows of operating system) and (exists keys "Software\Microsoft\Office\16.0\Outlook\Profiles" of keys of keys "HKU" of registry)

Your Actionscript would be
parameter "Keys2Delete" = "{"%22" & (concatenation "%22,%22" of (pathnames of keys "Software\Microsoft\Office\16.0\Outlook\Profiles" of keys of key "HKU" of registry)) & "%22"}"
waithidden cmd.exe /c "for %a in ({parameter "Keys2Delete"}) do (reg delete %a /f)"

1 Like

After more digging, it seems like we can do this with PowerShell. The ntuser.dat files need to be loaded into the HKUSERS hive if users are not logged in as @trn mentioned. I found an article explaining this very issue and it provides a script to load and unload the individual users. I modified the section to delete the “Profiles” key from all users. I get some errors for the path stating “it does not exist” but for users who have never used Outlook which is expected. The next step is to delete the Outlook folder in all users AppData\Local which should be easier.

# Regex pattern for SIDs
$PatternSID = 'S-1-5-21-\d+-\d+\-\d+\-\d+$'
 
# Get Username, SID, and location of ntuser.dat for all users
$ProfileList = gp 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\*' | Where-Object {$_.PSChildName -match $PatternSID} | 
    Select  @{name="SID";expression={$_.PSChildName}}, 
            @{name="UserHive";expression={"$($_.ProfileImagePath)\ntuser.dat"}}, 
            @{name="Username";expression={$_.ProfileImagePath -replace '^(.*[\\\/])', ''}}
 
# Get all user SIDs found in HKEY_USERS (ntuser.dat files that are loaded)
$LoadedHives = gci Registry::HKEY_USERS | ? {$_.PSChildname -match $PatternSID} | Select @{name="SID";expression={$_.PSChildName}}
 
# Get all users that are not currently logged
$UnloadedHives = Compare-Object $ProfileList.SID $LoadedHives.SID | Select @{name="SID";expression={$_.InputObject}}, UserHive, Username
 
# Loop through each profile on the machine
Foreach ($item in $ProfileList) {
    # Load User ntuser.dat if it's not already loaded
    IF ($item.SID -in $UnloadedHives.SID) {
        reg load HKU\$($Item.SID) $($Item.UserHive) | Out-Null
    }
 
    #####################################################################
    # This is where you can read/modify a users portion of the registry 
 
    # This example deletes the Profiles key under Software\Microsoft\Office\16.0\Outlook for each user registry hive
        Get-ChildItem registry::HKEY_USERS\$($Item.SID)\Software\Microsoft\Office\16.0\Outlook -Recurse | ForEach-Object {if ($_ -match "Profiles"){Remove-Item -Path "Registry::$_" -recurse -force -confirm:$false}}
    
    #####################################################################
 
    # Unload ntuser.dat        
    IF ($item.SID -in $UnloadedHives.SID) {
        ### Garbage collection and closing of ntuser.dat ###
        [gc]::Collect()
        reg unload HKU\$($Item.SID) | Out-Null
    }
}

Congrats on finding an effective solution that works for you!

In general I’d try to avoid manually loading user hives, as it can get us into trouble with Roaming Profiles.

In a case where we need to apply a policy to users, I’d look to LocalGPO to apply user-based policy to machines.

In this case, I expect you need to run this deletion once, and only once, for each user account, so a LocalGPO is probably out of the question - you don’t want it to reapply every time they log on.

I think this might be a case where ActiveSetup can help. You supply a script or command line and it runs one time for each user, the next time they log on. I describe it a bit at Action That Runs Once per User and have a link to an example from BigFix.me there.

1 Like

I’ve used a similar approach by placing a custom reg file on each user profile and a bat file in C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup that runs the reg file and then deletes the reg file out of the user profile of who’s logged in.

You can also use a loop for removing files or folders from profiles such as
for /f "delims=|" %%f in ('dir /B /A:D-H-R c:\users') do (rmdir "C:\Users\%%f\AppData\Ect\Ect" /s/q)

2 Likes