none
PowerShell - Loading, Unloading, and reading HKU RRS feed

  • Question

  • Hi,

    I need to load NTUSER.DAT for each user profile on a computer and inspect for a given path. If the path exists, I need to delete it, unload the hive and load the next user profile's NTUSER.DAT.

    I found an article that talks about using PSDrive to map HKU since PowerShell doesn't see this key by default. I can load the hive and detect whether the path exists. The problem I am having is that I cannot unload the hive so I can then load the next one. I keep getting access is denied. Here is my snippet:

    $regHKUPath = "HKU:\UserHive\SOFTWARE\Policies\Microsoft\Office\16.0\Outlook\Resiliency"
    $element = "C:\Users\Default"
    
    $hideMe = New-PSDrive -PSProvider Registry -Name HKU -Root HKEY_USERS
    $hideMe = reg load HKU\UserHive "$element\NTUSER.DAT"
    
    if (Test-Path $regHKUPath) {
        Write-Host "Path was found"
    } else {
        Write-Host "Path was not found"
    }
    
    $hideMe = reg unload HKU\UserHive
    $hideMe = Remove-PSDrive -Name HKU

      What do I need to do so that HKU can be unloaded and ready for the next iteration? This check runs in a loop so the timing of adding and removing PSDrive likely needs consideration.

    Thank you!

    Rob


    • Edited by robwm1 Monday, March 27, 2017 11:31 PM
    Monday, March 27, 2017 11:30 PM

Answers

  • Here is the solution that is working in this scenario:

    $regHKUPath = "HKU:\UserHive\SOFTWARE\Policies\Microsoft\Office\16.0\Outlook\Resiliency"
    $profiles = @("C:\Users\Default","C:\Users\jackied")
    
    $null = New-PSDrive -PSProvider Registry -Name HKU -Root HKEY_USERS
    
    
    foreach ($profile in $profiles) {
    
    $username = Split-Path $profile -leaf
    
    $null = reg load HKU\UserHive "$profile\NTUSER.DAT"
    
    if (Test-Path $regHKUPath) {
        Write-Host "$username - Path was found"
    } else {
        Write-Host "$username - Path was not found"
    }
    
    [gc]::collect()
    
    $null = reg unload HKU\UserHive
    
    }
    
    $null = Remove-PSDrive -Name HKU

    I can't say for sure this is the best approach but it definitely works.

    • Marked as answer by robwm1 Wednesday, March 29, 2017 3:43 PM
    Wednesday, March 29, 2017 3:43 PM

All replies

  • What problem are you solving?

    -- Bill Stewart [Bill_Stewart]

    Tuesday, March 28, 2017 12:39 PM
    Moderator
  • Bill,

    Here is the scenario I am working on. We have an Outlook add-in deployed/installed on all of our client computers. After this was deployed, we discovered that Outlook kept disabling the add-in due to performance requirements. We deployed a registry setting that blocks Outlook from disabling the add-in which was also added to Default so new users received the keys as well.

    A decision was recently made to completely remove this software from our environment. Uninstalling the add-in will not address the additional registry keys that were deployed so they will need to be dealt with independently from the software removal. In addition, we have a number of computers that have several active user profiles on them. The registry hive must be processed for every user profile. It isn't possible or practical to go to each computer and login as every user to address this directly (I saw that mentioned somewhere).

    I have the entire solution working except for the inspection of NTUSER.DAT loaded into HKU. This last puzzle involves retrieving each user profile, load NTUSER.DAT into HKU, delete the registry key if it exists, validate it's gone, and then unload the hive. This means there will be a foreach loop to step through each profile so I'm not sure how this will work with PSDrive.

    If the snippet I posted can be made to work, I can easily port it into my full solution. In the meantime, I'm still researching. The main problem is that after I load and inspect an NTUSER.DAT, I cannot seem to unload it which then becomes a problem when I need to load the next one.

    -Rob

    Tuesday, March 28, 2017 3:37 PM
  • For some reason, adding the lines with LS allow the hive to be unloaded. Doesn't seem like the proper way to do this but it does seem to work.

    $null = ls env:
    $null = ls variable:
    
    $null = Remove-PSDrive -Name HKU
    $null = reg unload HKU\UserHive

    I found this at: http://itknowledgeexchange.techtarget.com/powershell/registry-oddity/

    Tuesday, March 28, 2017 3:53 PM
  • Invoking garbage collection also seems to work:

    [gc]::collect()
    
    $null = Remove-PSDrive -Name HKU
    $null = reg unload HKU\UserHive

    https://jrich523.wordpress.com/2012/03/06/powershell-loading-and-unloading-registry-hives/

    This is probably the best solution unless someone knows a better way to get around this access denied issue.



    • Edited by robwm1 Tuesday, March 28, 2017 4:04 PM
    Tuesday, March 28, 2017 4:01 PM
  • Why not just use group policy preferences rather than trying to script it?

    -- Bill Stewart [Bill_Stewart]

    Tuesday, March 28, 2017 4:58 PM
    Moderator
  • You could use ActiveSetup to clean up the user registry. It's actually made for installing software but it can be used to uninstall or clean up installations.

    Grüße - Best regards

    PS:> (79,108,97,102|%{[char]$_})-join''

    Tuesday, March 28, 2017 7:10 PM
  • Here is the solution that is working in this scenario:

    $regHKUPath = "HKU:\UserHive\SOFTWARE\Policies\Microsoft\Office\16.0\Outlook\Resiliency"
    $profiles = @("C:\Users\Default","C:\Users\jackied")
    
    $null = New-PSDrive -PSProvider Registry -Name HKU -Root HKEY_USERS
    
    
    foreach ($profile in $profiles) {
    
    $username = Split-Path $profile -leaf
    
    $null = reg load HKU\UserHive "$profile\NTUSER.DAT"
    
    if (Test-Path $regHKUPath) {
        Write-Host "$username - Path was found"
    } else {
        Write-Host "$username - Path was not found"
    }
    
    [gc]::collect()
    
    $null = reg unload HKU\UserHive
    
    }
    
    $null = Remove-PSDrive -Name HKU

    I can't say for sure this is the best approach but it definitely works.

    • Marked as answer by robwm1 Wednesday, March 29, 2017 3:43 PM
    Wednesday, March 29, 2017 3:43 PM
  • I can say for sure that it's not the best approach.

    You can use group policy preferences to make changes in HKCU, and you do not need a script.


    -- Bill Stewart [Bill_Stewart]

    Wednesday, March 29, 2017 4:29 PM
    Moderator
  • Bill,

    I do appreciate your input but I had a task to script this solution this time around. I already had to script the rest of the work so it just made sense to add this to the task. Today was my deadline and I beat it by a day.

    If I would have went the group policy route, I would have missed my deadline because I don't have access to group policy and getting things done through other departments is often very time consuming here. A one or two-day turnaround on a request like this wouldn't happen in my experience.

    If a request comes up like this again, hopefully I will be afforded the time to do it your way (the best/right way). I definitely don't disagree with your approach.

    -Rob

    Wednesday, March 29, 2017 5:07 PM