Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

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

Posted on 2014-10-21
26
Medium Priority
?
278 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 12
  • 11
  • 2
  • +1
26 Comments
 
LVL 41

Expert Comment

by:footech
ID: 40396008
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 41

Expert Comment

by:footech
ID: 40396016
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 35

Expert Comment

by:sarabande
ID: 40396828
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
Not sure which OpenStack Certification to get?

So you’ve realized you might want to get certified in OpenStack, but you’re not sure what the benefits might be or even which one you should take. You know there are several certification courses you can choose from, but how do you know which one is right for you?

 

Author Comment

by:scsyeg
ID: 40397169
@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
ID: 40397219
@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 41

Expert Comment

by:footech
ID: 40397450
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
ID: 40397495
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 41

Expert Comment

by:footech
ID: 40397658
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
ID: 40397690
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 41

Expert Comment

by:footech
ID: 40397842
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
ID: 40397907
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 41

Expert Comment

by:footech
ID: 40398026
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
ID: 40399611
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
 
LVL 41

Expert Comment

by:footech
ID: 40399955
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
ID: 40408694
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 41

Expert Comment

by:footech
ID: 40409167
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
ID: 40409224
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 41

Expert Comment

by:footech
ID: 40409251
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
ID: 40413998
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 41

Expert Comment

by:footech
ID: 40414559
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
ID: 40424820
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
ID: 40424855
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 41

Accepted Solution

by:
footech earned 2000 total points
ID: 40424978
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 71

Expert Comment

by:Qlemo
ID: 40460758
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
ID: 40487512
The answer to my question is spread across several posts. This user was amazing at helping.
0
 
LVL 71

Expert Comment

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

Featured Post

Introducing the WatchGuard 420 Access Point

WatchGuard's newest access point includes an 802.11ac Wave 2 chipset, providing the fastest speeds for VoIP, video and music streaming, and large data file transfers. Additionally, enjoy the benefits of strong security as the 3rd radio delivers dedicated WIPS protection!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A recent project that involved parsing Tableau Desktop and Server log files to extract reusable user queries for use in other systems. I chose to use PowerShell to gather the data, and SharePoint to present it...
In previous parts of this Nano Server deployment series, we learned how to create, deploy and configure Nano Server as a Hyper-V host. In this part, we will look for a clustering option. We will create a Hyper-V cluster of 3 Nano Server host nodes w…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

722 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