1

I have the script where it captures blank profile paths in the profile list. I am not sure how to call the array and delete the whole key. It is saying path is not found as it is trying to run it from c:\windows\system32

how do i get it to go through the different paths it might have ? Right now I am just testing by blanking out one profile path

$Profiles = get-childitem “HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList”

$ProfileData = @()

foreach($Profile in $Profiles){
$ThisProfileInfo = $null

$ThisProfileInfo = @{Name=$Profile.Name;

                    ProfilePath=$Profile.GetValue("ProfileImagePath")}

   if (!($ThisProfileInfo.ProfilePath)) {
   $ProfileData += $ThisProfileInfo
}

}

$ProfileData

ForEach-Object{Remove-Item -Path ($Object.name)}

the error is ForEach-Object{Remove-Item -Path ($Object.name)}

Name                           Value                                                                                                                                  
----                           -----                                                                                                                                  
Name                           HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\S-1-5-21-115761338-1150813220-1225219381-227283            
ProfilePath                                                                                                                                                           
Remove-Item : Cannot find path 'C:\WINDOWS\system32\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows 
NT\CurrentVersion\ProfileList\S-1-5-21-115761338-1150813220-1225219381-227283' because it does not exist.
At line:24 char:16
+ ForEach-Object{Remove-Item -Path ($Object.name)}
+                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\WINDOWS\syst...25219381-227283:String) [Remove-Item], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand
  • can you share the error code? So, you just want to delete the keys that are added to `$ProfileData` due to null values? – Abraham Zinala Apr 13 '22 at 20:57
  • I wanted both in there to just be a visual check. I would remove it afterwards. I am trying to delete the whole registry if it finds blank. That full path is found in the name. But if you run the remove-item it is not doing that. I have edited the question and added the error. You see it puts the c:\windows\system32 in front. I am not sure why – mattmoore5553 Apr 13 '22 at 21:04

2 Answers2

2

tl;dr

The following removes all registry keys representing user profiles that have no / an empty ProfileImagePath value:

# Note: Run with elevation, otherwise Remove-Item will fail.
Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" |
  Where-Object { -not $_.GetValue('ProfileImagePath') } |
    Remove-Item -WhatIf

Note: The -WhatIf common parameter in the command above previews the operation. Remove -WhatIf once you're sure the operation will do what you want.


Your primary problem is that the .Name property of items representing registry keys is a registry-native key path (e.g. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\S-1-5-18), which PowerShell's Remove-Item doesn't recognize as such[1] and interprets as a relative file-system path.

There's also an incidental syntax problem in your question, as of this writing: your last two statements should be a single pipeline, as follows:
$ProfileData | ForEach-Object{ Remove-Item -Path $_.Name }

Piping the Get-ChildItem output directly to Remove-Item avoids this problem, because it binds the .PSPath property values to Remove-Item's -LiteralPath parameter, and .PSPath contains a provider-qualified path, i.e. it has a prefix that identifies the path as a registry path; e.g. Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\S-1-5-18

For details on where the .PSPath property values come from and how they bind to the
-LiteralPath parameter of PowerShell's provider cmdlets, see this answer.


[1] There is one exception: If the current location (as reflected in $PWD / Get-Location) happens to be the root of the targeted registry hive (which would be unusual, because registry locations are rarely made the current location), the registry-native path is recognized. E.g, if you changed to the root of the HKEY_LOCAL_MACHINE hive with Set-Location HKLM:\,
Get-ChildItem HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList would work (with or without the HKEY_LOCAL_MACHINE\ prefix).

mklement0
  • 382,024
  • 64
  • 607
  • 775
0

It would be best to troubleshoot by running just:

get-childitem “HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList”

When I ran this, I got two fields: Name and Property. The name field only had the name of the key, but when I ran:

get-childitem “HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList” | select Name

I was able to get the full path to the key, which may be why the prior method wasn't working. Might just need to add | select Name.

Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77
  • I wanted both in there to just be a visual check. I would remove it afterwards. I am trying to delete the whole registry if it finds blank. That full path is found in the name. But if you run the remove-item it is not doing that. – mattmoore5553 Apr 13 '22 at 21:03
  • I think you want remove-itemproperty then – jboss19 Apr 13 '22 at 21:06
  • mattmoore5553 is already using `.Name` - i.e. the full registry key path - in his attempt. The core problem is that you cannot pass such a path directly to `Remove-Item`, because it will interpret it as a relative file-system path. As an aside: if you wanted just the `Name` property _value_, you'd need `| select -ExpandProperty Name`. – mklement0 Apr 13 '22 at 21:40