Searching and deleting registry entries using wildcards - powershell

Is it possible to search for a wildcard - example *WAAgent* or *WAHost* and delete every registry key that references that wildcard statement above?

You may try something like:
Get-ChildItem -Path HKLM:\ -Recurse -Include *WAAgent* -ErrorAction SilentlyContinue | Remove-Item
Get-ChildItem -Path HKLM:\ -Recurse -Include *WAHost* -ErrorAction SilentlyContinue | Remove-Item
You have to specify in -Path if they are location in HKLM(local machine) or HKCU(current user), as they are two different drives. This has to be run as admin, and will give lots of errors(that's why I used -ErrorAction SilentlyContinue to hide them).
CAUTION: Personally I don't think it's smart to be using wildcards in registry though since it may delete something you didn't know about that could crash the system. My recommendation would be to compile a list of paths to the keys you want to remove and loop through it with foreach to delete one by one. Again, wildcards are DANGEROUS in registry.

If you are searching for a property value instead of a key value (and delete the relative key) you can use something like this:
gci HKLM: -rec -ea SilentlyContinue | % { if((get-itemproperty -Path $_.PsPath)
-match "WAAGent") { $_.PsPath} } | Remove-Item
Like for the #Graimer's answer, BE CAREFULL!!!

As all have already suggested, use this with extremely caution!! The following will go through all registry hives. Keep in mind that a matching key found can have a deep structure underneath it and you're deleting it all. Remove the WhatIf switch to actually delete the keys.
Get-ChildItem Microsoft.PowerShell.Core\Registry:: -Include *WAAgent*,*WAHost* -Recurse |
Remove-Item -Recurse -Force -WhatIf

I had the problem that there was a Session ID in the path of the registry.
To solve this is got the first part of the registry, stored it in a variable and used this for my foreach loop where the keys for drive mappings were stored.
The above was too rigorous in my case.
The below shows an example to remove (local) drive mappings in a session (the problem i had).
Start-Sleep -Seconds 20
# This stores the Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\SessionInfo\<SESSIONID>"
$SessionInfo = Get-Item "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\SessionInfo\*"
cd "HKCU:\"
Start-Sleep -Seconds 1
$Items = Get-ChildItem "$SessionInfo\MyComputer\Namespace"
foreach($Item in $Items){
Remove-Item $Item -Force -Recurse -Verbose
}

Related

How do I remove-items in a folder without the confirm box popping up? [duplicate]

This question already has an answer here:
How do I automatically answer “yes” in Powershell?
(1 answer)
Closed 4 months ago.
I want to deleted all the files in the temp folder... any .zip files , .txt files and any folder files including whatever is inside each of those folders (everything). I thought this would be simple but so far my script keeps getting the confirmation pop-up asking if I want to delete all these child items. I tried using -confirm:$false but that doesn't seem to work. I appreciate any suggestions. Thank you.
$list = Get-ChildItem -directory "C:\temp\*" -Include * -Name
get-childitem c:\temp -Include #(get-content $list) | Remove-Item -Force -whatif
I tried using the -confirm:$false argument as well as the -force with no luck.
You want -path vs -directory.
#Looking for Temp under Windows:
$list = (Get-ChildItem -path "C:\*\Temp*\*.*").FullName | Remove-Item -Force
#Looking for Temp under Root:
$list = (Get-ChildItem -path "C:\Temp*\*.*").FullName | Remove-Item -Force
If your Temp dirs have subs you could also add the -recurse switch.
To avoid confirmation requests add the parameter -confirm:$false. If you want to include everything don't specify the parameter -include * - the default is to return everything, no need to slow down due to unecessary filters.
just do:
get-childitem -path C:\temp -directory | remove-item -force -confirm:$false -recurse
btw. u did specify the parameter -directory, currently only directories are returned by get-childitem, so files directly stored in C:\temp would remain.

Recursive Wildcards in PowerShell

I'm trying to delete files in a specific set of folders with PowerShell. My code currently looks like this:
$tempfolders = #(
"C:\Windows\Temp\*"
"C:\Documents and Settings\*\Local Settings\temp\*"
"C:\Users\*\Appdata\Local\Temp\*"
)
Remove-Item $tempfolders -Recurse -Force -ErrorAction SilentlyContinue
I want to add a new folder to that list, with the following formula:
"C:\users\*\AppData\Local\Program\**\Subfolder"
where ** could be multiple subfolders of unknown length. For example, it could be settings\subsettings or it could be folder\settings\subsettings. Is there a way to do this?
You can feed the full path of each file to a regex; this will return only the files that match your format, which you can then pipe to Remove-Item:
ls "C:\Users" -Recurse -Hidden | Where-Object { $_.FullName -imatch '^C:\\users\\([^\\]+)\\AppData\\Local\\Program\\(.*)\\Subfolder' }
Because regexes are considered write-only, a bit of explanation:
backslashes count as escape characters inside a regex and need to be doubled.
([^\\]+) means one or more of any character except a backslash
.* means zero or more of any character
You can use Get-ChildItem -Directory -Recurse,
This will do exactly what you are asking for. Pipe it from the array to a Remove-Item
#("C:\Windows\Temp\*", "C:\Documents and Settings\*\Local Settings\temp\*", "C:\Users\*\Appdata\Local\Temp\*") |
Get-ChildItem -Directory -Recurse -Force -ErrorAction SilentlyContinue |
Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
Just for a heads up in Powershell Piping | is key. PowerShell we love to chain commands.

Define folder depth for the verbose option in Copy-Item cmdlet

I'm using the following command to copy a directory tree from one folder to another.
Copy-Item $SOURCE $DEST -Filter {PSIsContainer} -Recurse -Force -Verbose
The verbose option is correctly showing each folder that is copied. However, I would like to tell the Verbose option to only shows the first level of the subfolders that are copied. Hence the subfolders/subfolders/... etc wouldn't appear.
Is it possible?
Instead of using the -Verbose option, you could use the -PassThru option to process the successfully processed items via the pipeline. In the following example, I am assuming that $DEST is the existing directory in which the newly copied directory will appear. (You cannot call Get-Item on non-existant objects.)
$SOURCE = Get-Item "foo"
$DEST = Get-Item "bar"
Copy-Item $SOURCE $DEST -Filter {PSIsContainer} -Recurse -Force -PassThru | Where-Object {
# Get the parent object. The required member is different between
# files and directories, which makes this a bit more complex than it
# might have been.
if ($_.GetType().Name -eq "DirectoryInfo") {
$directory = $_.Parent
} else {
$directory = $_.Directory
}
# Select objects as required, in this case only allow through
# objects where the second level parent is the pre-existing target
# directory.
$directory.Parent.FullName -eq $DEST.FullName
}
Count the number of backslashes in the path and add logic to select first level only perhaps. Something like this perhaps?
$Dirs=get-childitem $Source -Recurse | ?{$_.PSIsContainer}
Foreach ($Dir in $Dirs){
$Level=([regex]::Match($Dir.FullName,"'b")).count
if ($Level -eq 1){Copy-Item $Dir $DEST -Force -Verbose}
else{Copy-Item $Dir $DEST -Force}}
*Edited to include looping and logic per requirements
I would suggest using robocopy instead of copy-item. Its /LEV:n switch sounds like it's exactly what you're looking for. Example (you'll need to test & tweak to meet your requirements):
robocopy $source $dest /LEV:2
robocopy has approximately 7 gazillion options you can specify to get some very useful and interesting behavior out of it.

How to keep a specific folder and delete rest of the files using powershell

I am trying delete all files within a folder but there is 1 folder called pictures which I would like to keep but don't know how to do that. I am using the following script , it deletes everything in a folder
if ($message -eq 'y')
{
get-childitem "C:\test" -recurse | % {
remove-item $_.FullName -recurse
}
}
One solution is to use something like:
Get-ChildItem -Path "c:\test" -Recurse | Where-Object { $_.FullName -cnotmatch "\\Pictures($|\\)" -and (Get-ChildItem $_.FullName -Include "Pictures" -Recurse).Length -eq 0 } | Remove-Item -Recurse -ErrorAction SilentlyContinue;
I suspect there must be a way more elegant way to do this. Here's what this does: it enumerates all files in the C:\test folder recursively (Get-ChildItem), then it removes all items from the result list using Where-Object where the path contains the directory to be excluded (specified using regex syntax) or when the item in question has child items that contains the file or directory to be excluded. The resulting list is fed to Remove-Item for removal. The -ErrorAction SilentlyContinue switch is applied to prevent errors being logged with recursive removal.
Get-ChildItem $PSScriptRoot -Force| Where-Object {$_.Name -ne "Pictures"} | Remove-Item -Recurse
I just tried this, and it worked for me. If you want to change what is deleted just change the "Pictures". This uses $PSScriptRoot for the path, which is the execution path of the Powershell script. You can rename that to be the path of where you want to delete.

Suppressing confirmation on Remove-Item WITHOUT using -recurse

So I want to delete top level directories based on creation date. I don't want my script to consider ANY dates below that (e.g. my top level folder might be 31 days old, whereas subdirectories may be newer - but I still want the whole top level directory removed along with everything in it - I only care about the top level folder's creation date. Thus I don't want to use -recurse. However, I keep getting prompted with the whole "the folder has subdirectories do you want to continue...blah blah". Can't have that. How can I suppress this without using -recurse? I've tried Remove-Item -Force -confirm:$false as well as Remove-Item -Force -ea 0 to no avail. (PS -ea 0 is short for -ErrorAction SilentlyContinue) Thanks!
Get-ChildItem -Path e:\myfolder -Force | Where-Object { $_.PSIsContainer -and $_.CreationTime -lt (Get-Date).AddDays(-29) } | Remove-Item -Force