Solved

Startup Cleanup - Remove Registry values that that do not match a list

Posted on 2014-10-21
26
237 Views
Last Modified: 2014-12-08
Hi Experts,

I am writing a script that removes unwanted startup entries.

I thought that I would start with the keys in
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run

If there is anywhere else you think I should look, please tell me (ie: the startup folder is next in line)

Anyways, I thought I would use powershell (I wrote a VBScript for this, but apparently, we don't want to use VBScript [if there is any argument for against vbscript vs powershell, please share]).

I think the best/easiest way is to have a x.FilterPhrases file (just a text file with line breaks and maybe headers that organize the types) and for powershell to remove all keys that do not have values in this file in the value name.

So far I have as follows:

$excluded = "string1"
Get-Item "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" |Where {$excluded -contains $_.Property} | Remove-Item -WhatIf

Open in new window


This returns:
What if: Performing operation "Remove Key" on Target "Item: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run

This removes the entire Run, which I do not want and I cannot get Remove-ItemProperty to work properly.

Is there a better way of doing this? any warnings? (we backup the registry beforehand just incase). My previous approach was to export everything, filter through the export, keeping what I wanted, remove everything, restore the filtered export, but this lead to some keys not wanting to be imported and some errors.

An example of the filterPhrases file I have compiled so far:

:File Header - Do not Edit
Windows Registry Editor
HKEY_LOCAL_MACHINE
HKEY_CURRENT_USER

:AntiVirusCompaniesAndTerms
ESET
Symantec
McAfee
Trend Micro
TrendMicro
Sophos
Kaspersky
avast!
Webroot
BitDefender
F-Secure
AhnLab
Norton
Panda
VIPRE
AVG
Windows Defender
ZoneAlarm

:GeneralTerms
Security
Firewall
Fortinet
Spybot
BlackICE
fax
printer
GoogleDriveSync
StikyNot
Skype
Viber
VMWare

:Manufacturers
Lenovo
Dell
Hewlett Packard
ASUS
nVidia
AMD

:Misc
Classic Start Menu
Cisco

Open in new window

0
Comment
Question by:scsyeg
  • 12
  • 11
  • 2
  • +1
26 Comments
 
LVL 39

Expert Comment

by:footech
Comment Utility
I don't know what a filterphrases file is - maybe a VBScript concept?  You would have to specially parse the example file to do anything with it.
When working with the registry in PowerShell, an item is a key, and an item property is a value and its data.  So what you're trying to do is find (or exclude) properties where the name changes, and so you've got a moving target which makes it more difficult to hit.  There are also properties added to the returned objects by PowerShell which complicate it further.
Here's an example of deleting registry values (itemproperty) that don't have the name "string1".
$exclude = "string1","PSPath","PSParentPath","PSChildName","PSDrive","PSProvider"
$key = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
$toDelete = Get-ItemProperty $key | Get-Member -MemberType NoteProperty | ? { $exclude -notcontains $_.Name } | % {$_.Name}
Remove-ItemProperty -Path $key -Name $toDelete -WhatIf

Open in new window

0
 
LVL 39

Expert Comment

by:footech
Comment Utility
By the way, I don't typically advocate rewriting VBScript code to PowerShell.  If you've got something that works, stick with it.  If you want to rewrite it more as a learning exercise (or perhaps because of some mandate you have no control over), then all I can say is that it's generally poor practice to try to "translate" VBScript directly to PS.  You'll likely end up with a lot of convoluted and unnecessary code that way.  Instead it's best to learn "the PowerShell way", and then take those concepts and apply them to solving the problem the problem at hand.
0
 
LVL 32

Expert Comment

by:sarabande
Comment Utility
it is probably easier to export run key to a .reg file, edit the .reg file and import it back by regedit (double-click on the .reg file). if you know the valid entries below run, you even could spare the export and edit step and simply import a file which you exported from another machine where the entries are fine.

Windows Registry Editor Version 5.00

[HKEY_USERS\S-1-5-21-251489984-1497240538-811669034-43870\Software\Microsoft\Windows\CurrentVersion\Run]
"OfficeSyncProcess"="\"C:\\Program Files (x86)\\Microsoft Office\\Office14\\MSOSYNC.EXE\""

Open in new window


Sara
0
 

Author Comment

by:scsyeg
Comment Utility
@footech: I will test your code. filterPhrases is a made up extension for a text file that has the information I posted in it. I'm used to doing that in linux. A Get-Content should work I think? Do I always have to exclude: "PSPath","PSParentPath","PSChildName","PSDrive","PSProvider"?

The vb script I have at the moment does more along the lines of what sarabande suggests, that is it exports, edits export, deletes all, imports edited export, but that throws errors for some values when trying to import them back, so I want to only remove what is needed instead.

@sarabande thanks for the advice, my vbscript is similar (see the lines directly above). But that won't do exactly.
0
 

Author Comment

by:scsyeg
Comment Utility
@footech: the code is throwing an error. says that a property with the name it found does not exist at the path. i tried adding \`" around it, same thing.

PS C:\Users\Armen\Desktop> C:\Users\Armen\Desktop\test.ps1
What if: Performing operation "Remove Property" on Target "Item: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run Property: Adobe ARM".
Remove-ItemProperty : Property Adobe ARM does not exist at path HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run.
At C:\Users\Armen\Desktop\test.ps1:4 char:20
+ Remove-ItemProperty <<<<  -Path $key -Name $toDelete -WhatIf
    + CategoryInfo          : InvalidArgument: (Adobe ARM:String) [Remove-ItemProperty], PSArgumentException
    + FullyQualifiedErrorId : System.Management.Automation.PSArgumentException,Microsoft.PowerShell.Commands.RemoveItemPropertyCommand
 
What if: Performing operation "Remove Property" on Target "Item: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run Property: SunJavaUpdateSched".
Remove-ItemProperty : Property SunJavaUpdateSched does not exist at path HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run.
At C:\Users\Armen\Desktop\test.ps1:4 char:20
+ Remove-ItemProperty <<<<  -Path $key -Name $toDelete -WhatIf
    + CategoryInfo          : InvalidArgument: (SunJavaUpdateSched:String) [Remove-ItemProperty], PSArgumentException
    + FullyQualifiedErrorId : System.Management.Automation.PSArgumentException,Microsoft.PowerShell.Commands.RemoveItemPropertyCommand
 
What if: Performing operation "Remove Property" on Target "Item: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run Property: VMware User Process".
Remove-ItemProperty : Property VMware User Process does not exist at path HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run.
At C:\Users\Armen\Desktop\test.ps1:4 char:20
+ Remove-ItemProperty <<<<  -Path $key -Name $toDelete -WhatIf
    + CategoryInfo          : InvalidArgument: (VMware User Process:String) [Remove-ItemProperty], PSArgumentException
    + FullyQualifiedErrorId : System.Management.Automation.PSArgumentException,Microsoft.PowerShell.Commands.RemoveItemPropertyCommand

Open in new window


Seems like it's grabbing the correct values, but that Remove-ItemProperty is having issues.

Edit: these are not real errors, are they. the -WhatIf is the cause? It deletes when I take it out...Sorry I'm a newbie.
0
 
LVL 39

Expert Comment

by:footech
Comment Utility
Get-Content should work for reading the file, but if you have blank lines or header/section lines you'll need to exclude those to avoid errors.  And yes, you'll always have to exclude "PSPath","PSParentPath","PSChildName","PSDrive","PSProvider" - those are properties that are added by PowerShell.  If you run the following you will see.
Get-ItemProperty $key | Get-Member

Open in new window

You could hard code those values into the script if you like and then just add the contents of the file.

I've seen a couple times where using -whatif with different cmdlets gives an error that doesn't reflect reality. Usually it's good, but when it's not I just fall back on doing the actual operation (no -whatif parameter) with some test value to make sure things work as expected.
0
 

Author Comment

by:scsyeg
Comment Utility
Great; thanks. A couple final things:

How do I remove blank lines?
How do I use what's in the filterPhrases file as keywords, and not literals? ie: -notLike "*[filterPhrasesLine]*"

Tried some things and so far this is what I have; I am sure I could clean up the code a bit but I'm not sure how at the moment. Can you help?

$exclude = Get-Content .\Startup.FilterPhrases.txt
$exclude = $exclude -notlike "::*"
$exclude = $exclude |?{$_}
$key = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
$toDelete = Get-ItemProperty $key | Get-Member -MemberType NoteProperty | ? { $exclude -notcontains $_.Name } | % {$_.Name}
foreach ($exclusionItem in $exclude)
{
  $toDelete = $toDelete -notlike $("*"+$exclusionItem+"*")
}
Remove-ItemProperty -Path $key -name $toDelete -WhatIf

Open in new window


Where Startup.FilterPhrases.txt:
::Default Properties - Do not Edit
PSPath
PSParentPath
PSChildName
PSDrive
PSProvider

::AntiVirusCompaniesAndTerms
ESET
Symantec
McAfee
Trend Micro
TrendMicro
Sophos
Kaspersky
avast!
Webroot
BitDefender
F-Secure
AhnLab
Norton
Panda
VIPRE
AVG
Windows Defender
ZoneAlarm

::GeneralTerms
Security
Firewall
Fortinet
Spybot
BlackICE
fax
printer
GoogleDriveSync
StikyNot
Skype
Viber
VMWare

::Manufacturers
Lenovo
Dell
Hewlett Packard
ASUS
nVidia
AMD

::Misc
Classic Start Menu
Cisco

Open in new window

0
 
LVL 39

Expert Comment

by:footech
Comment Utility
I would replace lines 1-3 with:
$exclude = Get-Content .\Startup.FilterPhrases.txt | ? {$_ -notlike "::*" -and $_}

Open in new window


Not sure how you could each line so it isn't literal.  I've thought about it a bit and I'm not coming up with anything obvious.  Instead of doing the simple Where-Object filtering with -notcontains, you'd likely have to loop through every property and compare it to each element in $exclude individually.
0
 

Author Comment

by:scsyeg
Comment Utility
Thanks again. The one question I have left is that line 37, the "? { $exclusionTerms -notcontains $_.Name }" doesnt really need to be there since I iterate through the list and filter without it, but breaks if I remove it.  Could you explain this?

Almost final product (set default parameters for demonstration):

#parameters passed in by user or set as default
Param(
  $filterFile = "Startup.FilterPhrases.txt",
  $filterPath = ".",
  $keyPath = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
)

#check if entered filterPath ends with "\". If not, add "\".
if (!($filterPath.EndsWith("\"))){
  $filterPath = $filterPath + "\"
}

#check that the keyPath is correctly formatted as a powershell path
$hives = @{
  "^HKEY_CLASSES_ROOT\\" = "HKCR:\"; 
  "^HKEY_CURRENT_USER\\" = "HKCU:\"; 
  "^HKEY_LOCAL_MACHINE\\" = "HKLM:\"; 
  "^HKEY_USERS\\" = "HKU:\"; 
  "^HKEY_CURRENT_CONFIG\\" = "HKCC:\";
  "^HKCR\\" = "HKCR:\"; 
  "^HKCU\\" = "HKCU:\"; 
  "^HKLM\\" = "HKLM:\"; 
  "^HKU\\" = "HKU:\"; 
  "^HKCC\\" = "HKCC:\"
}

foreach ($hive in $hives.keys){
  if ($keyPath -match $hive) {
    $keyPath = $keyPath -replace $hive, $hives.$hive
  }
}

#open file, store as array and filter out comment lines that start with "::" and blank lines
$exclusionTerms = Get-Content $filterPath$filterFile | ? {$_ -notlike "::*" -and $_}

#return properties from path
$propertiesToDelete = Get-ItemProperty $keyPath | Get-Member -MemberType NoteProperty | ? { $exclusionTerms -notcontains $_.Name } | % {$_.Name}

#filter properties from path excluding any that contain terms in exclusionTerms
foreach ($term in $exclusionTerms)
{
  $propertiesToDelete = $propertiesToDelete -notlike $("*"+$term+"*")
}

#$propertiesToDelete returns True if it does not have anything left after the exclusion process. 
#If nothing, return that it does not have anything to remove. Otherwise, remove and return properties removed
If ($propertiesToDelete -eq $True){
  $output = 'No keys to delete from "' + $keyPath + '" with exclusion terms in ' + $filterPath + $filterFile
}
Else{
  $output = "Removed: " + ($propertiesToDelete -join ", ") + " from " + $keyPath
  Remove-ItemProperty -Path $keyPath -name $propertiesToDelete
}
Write-Host $output

Open in new window

0
 
LVL 39

Expert Comment

by:footech
Comment Utility
Here's something I came up with for treating each line as a keyword.
$key = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
$keyProperties = Get-ItemProperty $key | Get-Member -MemberType NoteProperty | % {$_.Name}
$perKeyExclude = $keyProperties | % `
{
    $prop = $_
    $exclude | % {
        If ( $prop -match $_ )
        { $prop }
    }
}
$toDelete = $keyProperties | ? { $perKeyExclude -notcontains $_ }
Remove-ItemProperty -Path $key -Name $toDelete -WhatIf -ErrorAction SilentlyContinue

Open in new window


I don't think it's any better than what you have already, just a slightly different approach.  Yours gets an initial list of properties to delete, and then trims down that list.  Mine gets an initial list of all properties, and then adds on to the exclusion list, then trims down the properties to delete using that built-up exclusion list.

I don't see anything that would cause your script to break by changing line 17.  In my testing it appears to function fine.

BTW, on line 22, instead of $("*"+$term+"*") you could use "*$term*"
It's probably more a preference, but I tend to avoid concatentation when I can as it usually involves more typing.
0
 

Author Comment

by:scsyeg
Comment Utility
Thank you for your input. To my un-powershell-trained eyes, my code is easier to follow, so I am tempted to leave it as is. Same with the "*$term*" since my way leaves variables red and strings brown vs your way makes it all brown and may be mistaken for a regex (?).

This works:
$propertiesToDelete = Get-ItemProperty $keyPath | Get-Member -MemberType NoteProperty | ? { $exclusionTerms -notcontains $_.Name } | % {$_.Name}

Open in new window


This throws an error:
$propertiesToDelete = Get-ItemProperty $keyPath | Get-Member -MemberType NoteProperty | % {$_.Name}

Remove-ItemProperty : Cannot bind argument to parameter 'Name' because it is an empty array.
At C:\Users\Armen\Desktop\removeRegistryProperties.ps1:52 char:43
+   Remove-ItemProperty -Path $keyPath -name <<<<  $propertiesToDelete
    + CategoryInfo          : InvalidData: (:) [Remove-ItemProperty], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyArrayNotAllowed,Microsoft.PowerShell.Commands.RemoveItemPropertyCommand

Open in new window

0
 
LVL 39

Expert Comment

by:footech
Comment Utility
I'm using PS 3.0 ISE, and the variable is still red, while the rest of the string is brown.
No big deal, as I said it's probably more a preference.

Check the contents of $propertiesToDelete.  There's probably an empty element.
$propertiesToDelete | % {"'$_'"}

Open in new window

When I run your code, changing line 37, and using -whatif for Remove-ItemProperty, I get no error.  But if I manually add an element with an empty string or $null, then running the Remove-ItemProperty produces the error you posted.
0
 

Author Comment

by:scsyeg
Comment Utility
From an efficiency standpoint though, concatenation is an extra, seemingly unnecessary process. So technically, I think you're way is more correct.

Got it. It's odd though. Sometimes it seems like when it's an empty array, it returns "True" and sometimes nothing.

What's the logic behind that?
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 39

Expert Comment

by:footech
Comment Utility
Are you sure it's an array?
$propertiesToDelete.GetType()

It's probably from the -notlike comparison.
When the input to an operator is a scalar value, comparison operators
return a Boolean value. When the input is a collection of values, the
comparison operators return any matching values. If there are no matches
in a collection, comparison operators do not return anything.
If $propertiesToDelete is a string, then the -notlike comparion could end up being a boolean.
Try this mod to line 37 which will force it to always be an array.
$propertiesToDelete = @(Get-ItemProperty $keyPath | Get-Member -MemberType NoteProperty | % {$_.Name})

Open in new window

0
 

Author Comment

by:scsyeg
Comment Utility
This is the whole code as it stands. In response to forcing it to be an array, do you forsee at all if what I have changed it to (line 37 and 47) will have issues?

I have added some flexibility to entered values and polished it up a bit. If you think this is complete, I will go ahead and mark your next comment as the answer referring to this one for all of your wonderful help. Thanks very much.

#parameters passed in by user or set as default
Param(
  $filterFile,
  $filterPath = ".",
  $keyPath
)

#check if entered filterPath ends with "\". If not, add "\".
if (!($filterPath.EndsWith("\"))){
  $filterPath = $filterPath + "\"
}

#check that the keyPath is correctly formatted as a powershell path
$hives = @{
  "^HKEY_CLASSES_ROOT\\" = "HKCR:\"; 
  "^HKEY_CURRENT_USER\\" = "HKCU:\"; 
  "^HKEY_LOCAL_MACHINE\\" = "HKLM:\"; 
  "^HKEY_USERS\\" = "HKU:\"; 
  "^HKEY_CURRENT_CONFIG\\" = "HKCC:\";
  "^HKCR\\" = "HKCR:\"; 
  "^HKCU\\" = "HKCU:\"; 
  "^HKLM\\" = "HKLM:\"; 
  "^HKU\\" = "HKU:\"; 
  "^HKCC\\" = "HKCC:\"
}

foreach ($hive in $hives.keys){
  if ($keyPath -match $hive) {
    $keyPath = $keyPath -replace $hive, $hives.$hive
  }
}

#open file, store as array and filter out comment lines that start with "::" and blank lines
$exclusionTerms = Get-Content $filterPath$filterFile | ? {$_ -notlike "::*" -and $_}

#return properties from path
$propertiesToDelete = Get-ItemProperty $keyPath | Get-Member -MemberType NoteProperty | % {$_.Name}

#filter properties from path excluding any that contain terms in exclusionTerms
foreach ($term in $exclusionTerms)
{
  $propertiesToDelete = $propertiesToDelete -notlike $("*"+$term+"*")
}

#$propertiesToDelete returns True if it does not have anything left after the exclusion process. 
#If nothing, return that it does not have anything to remove. Otherwise, remove and return properties removed
If ($propertiesToDelete.count -eq 0){
  $output = 'No keys to delete from "' + $keyPath + '" with exclusion terms in ' + $filterPath + $filterFile
}
Else{
  $output = "Removed: " + ($propertiesToDelete -join ", ") + " from " + $keyPath
  Remove-ItemProperty -Path $keyPath -name $propertiesToDelete
}
Write-Host $output

Open in new window

0
 
LVL 39

Expert Comment

by:footech
Comment Utility
Line 47 should work if you make the change to line 37.  What you just posted doesn't show the change I suggested above.
0
 

Author Comment

by:scsyeg
Comment Utility
I know. It seems to work without it. It only returned True when the "? { $exclusionTerms -notcontains $_.Name }" was part of line 37.

That's what was breaking line 47 when I had it check for "True". Now that it's not there, checking the count works.

I will include the change you mentioned if you think it's necessary.
0
 
LVL 39

Expert Comment

by:footech
Comment Utility
I think it would break if the query only returned one key, so yes I would say the change is necessary.  It's possible the systems you query always have more than one key in the registry location, in which case you wouldn't see an error, but why take the chance?
0
 

Author Comment

by:scsyeg
Comment Utility
Sounds good. The one thing that I'm considering adding is a check that the file itself is not blank. As it stands, if it's completely blank, it does nothing - not even throws the error for the "PSPath, PSParentPath, PSChildName, PSDrive, PSProvider" it only says that there was nothing to remove based on the file input - and does not remove anything - which is a good thing, but unintended.

Here is the final code.

#parameters passed in by user or set as default
Param(
  $filterFile,
  $filterPath = ".",
  $keyPath
)

#check if entered filterPath ends with "\". If not, add "\".
if (!($filterPath.EndsWith("\"))){
  $filterPath = $filterPath + "\"
}

#check that the keyPath is correctly formatted as a powershell path
$hives = @{
  "^HKEY_CLASSES_ROOT\\" = "HKCR:\"; 
  "^HKEY_CURRENT_USER\\" = "HKCU:\"; 
  "^HKEY_LOCAL_MACHINE\\" = "HKLM:\"; 
  "^HKEY_USERS\\" = "HKU:\"; 
  "^HKEY_CURRENT_CONFIG\\" = "HKCC:\";
  "^HKCR\\" = "HKCR:\"; 
  "^HKCU\\" = "HKCU:\"; 
  "^HKLM\\" = "HKLM:\"; 
  "^HKU\\" = "HKU:\"; 
  "^HKCC\\" = "HKCC:\"
}

foreach ($hive in $hives.keys){
  if ($keyPath -match $hive) {
    $keyPath = $keyPath -replace $hive, $hives.$hive
  }
}

#open file, store as array and filter out comment lines that start with "::" and blank lines
$exclusionTerms = Get-Content $filterPath$filterFile | ? {$_ -notlike "::*" -and $_}

#return properties from path
$propertiesToDelete = @(Get-ItemProperty $keyPath | Get-Member -MemberType NoteProperty | % {$_.Name})

#filter properties from path excluding any that contain terms in exclusionTerms
foreach ($term in $exclusionTerms)
{
  $propertiesToDelete = $propertiesToDelete -notlike $("*"+$term+"*")
}

#$propertiesToDelete returns True if it does not have anything left after the exclusion process. 
#If nothing, return that it does not have anything to remove. Otherwise, remove and return properties removed
If ($propertiesToDelete.count -eq 0){
  $output = 'No keys to delete from "' + $keyPath + '" with exclusion terms in ' + $filterPath + $filterFile
}
Else{
  $output = "Removed: " + ($propertiesToDelete -join ", ") + " from " + $keyPath
  Remove-ItemProperty -Path $keyPath -name $propertiesToDelete
}
Write-Host $output

Open in new window

0
 
LVL 39

Expert Comment

by:footech
Comment Utility
Substitute the following for line 34.
try {
    $exclusionTerms = Get-Content $filterPath$filterFile -errorAction Stop | ? {$_ -notlike "::*" -and $_}
} catch {
    Write-Host "Input file not found.`nExiting..." -foregroundColor Red
}

Open in new window

0
 

Author Comment

by:scsyeg
Comment Utility
I will look at the previous post ASAP. More significantly, if there is no keys in the location (HKLM:\...) it throws an error. How can I deal with this smoothly? Another Try/Catch?
0
 

Author Comment

by:scsyeg
Comment Utility
most importantly, I just realized that I need to remove the entries from all HKCU's. Anyway to do that? adding the HKCU path only removes it from the current user by definition. I need to be able to filter all HKCU:\...\Run items
0
 
LVL 39

Accepted Solution

by:
footech earned 500 total points
Comment Utility
I can't keep adding on to this.  Feel free to start a new question.
Error handling can easily double the amount of code in a script.
Here's a mod for line 37.
$propertiesToDelete = @(Get-ItemProperty $keyPath -ErrorAction SilentlyContinue | Get-Member -MemberType NoteProperty -ErrorAction SilentlyContinue | % {$_.Name})

Open in new window


To load entries for all users, you would have to load each user's ntuser.dat file and then query it.  I don't have code for that right now.
0
 
LVL 68

Expert Comment

by:Qlemo
Comment Utility
Using HKU to go thru all profiles requires to mount each user's hive temporarily in registry. There is no in-built way to do that, so all I could find was to use reg load, but that doesn't work well and has a lot of issues in PowerShell.
So best way IMHO is to use a logon script, which checks if it has been run for that user already (e.g. by maintaining a file with users).

Regarding the exclusion list, I would build a regex from the lines (resulting e.g. in 'keyword1|keyword2'), and apply the -nomatch operator instead of looping thru the exclusion list.
0
 

Author Closing Comment

by:scsyeg
Comment Utility
The answer to my question is spread across several posts. This user was amazing at helping.
0
 
LVL 68

Expert Comment

by:Qlemo
Comment Utility
http:#a40460758 was not helpful at all? Though I discussed how you could implement applying to all users?
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Microsoft Windows Server Update Service (WSUS) is free for everyone, but it lacks of some desirable features like send an e-mail to the administrator with the status of all computers on the WSUS server. This article is based on my PowerShell script …
I thought I'd write this up for anyone who has a request to create an anonymous whistle-blower-type submission form created using SharePoint 2010 (this would probably work the same for 2013). It's not 100% fool-proof but it's as close as you can get…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now