Remove an entry from credential manager for all users on Windows
Asked Answered
S

4

12

I am currently implementing a "remove settings" for all users in a Windows uninstaller and came over an issue I am not even sure is possible to solve.

The application stores credential entries for the current user using the CredentialManager (keymgr.dll). Let's call the target of the credential "X". On uninstall all credentials with stored with target "X" should be removed on all users. The uninstaller of course requires administrator privileges but still I find it very difficult to accomplish this.

For the current user that command is generally solved via cmdkey /delete=:X from a command prompt. As far as I know cmdkey.exe /list only helps to list entries for the current user and can't remove local entries from another user.

I have learned that the credentials are stored as OS files under the C:\Users\_user_\AppData\Local\Microsoft\Credentials folder, but I can't know which files are the entries I want to delete and removing all would be dangerous for other applications. Also I assume removing OS files will be dangerous and could have limitations (extra UAC prompt?) as well.

Runas command is the closest shot I got but because it requires the password of the user it becomes very difficult and not something I would want in the uninstaller. I also would need a way to get the username and domain for each user and iterate them.

I would prefer to use either cmd or powershell for this.

Schriever answered 13/9, 2016 at 19:54 Comment(1)
Hi, after having done a bit of research about this myself, I think what you want to achieve is not possible if you are not running as the user owning the credentials. At most you will be able to remove all stored credentials...Bookmobile
S
23

Don't want to necro an old post but I needed to do this myself so I figured I'd add this in case anyone else needs it:

cmdkey /list | ForEach-Object{if($_ -like "*Target:*" -and $_ -like "*microsoft*"){cmdkey /del:($_ -replace " ","" -replace "Target:","")}} 

Powershell one liner that will remove any credentials with Microsoft in the string.

Reference: https://gist.github.com/janikvonrotz/7819990

I ran this and it purged it locally without needing to run as admin (but I am a local admin)

Strenuous answered 3/8, 2017 at 17:36 Comment(0)
H
2

The cmdkey.exe utility when run from a batch file or a PowerShell command may encounter two issues related to special characters. 1. If run from a batch file, if the credential has "(" or ")" without the double quotes, that is left and right paren, that credential will not be removed. 2. If the credential name aka targetname, has a hyphen surronded by spaces the cmdkey will not remove or create a a credential with that string " - ".

There are a few powershell modules written to try and do this, but the only one i found that handles this exceptions was on Github https://github.com/bamcisnetworks/BAMCIS.CredentialManager

BAMCIS.CredentialManager

Using this i was able to create credentials to set up a test environment with parens or hyphens, but more importantly to remove them by gathering the users list of cached credentials using the modules command and then passing the information in the command to the remove command to remove ALL cached credentials.

One caveat. After removing the command, after some period of time two cached credentials dynamically reappear.

So to address frequent user lock out issues i am going to try and deploy this using SCCM under user context at logoff. Otherwise a system restart after removing the credentials may be needed. Here is a prototype script that imports the module and then uses it to remove all cached credentials, As always, test, test, test and use at your own risk!

Clear-host
import-Module "$PSScriptRoot\BAMCIS.CredentialManager\BAMCIS.CredentialManager.psd1"
$L = Get-CredManCredentialList -ErrorAction SilentlyContinue 

If($L -eq $null)
{

  Write-host "No Cached Credentials found to remove, no action taken"
  $LASTEXITCODE = 0
  Write-host "The last exit code is $LASTEXITCODE"


}
Else
{

  ForEach($cred in $L)
  {

    Write-host "`tProcessing...`n"
    Write-host "$($cred.TargetName.ToString())`n"
    Write-host "$($cred.Type.ToString())`n`n"

    $R = Remove-CredManCredential -TargetName  $($cred.TargetName.ToString()) -Type $($cred.Type.ToString()) -Force

  }
  $L = Get-CredManCredentialList -ErrorAction SilentlyContinue -ErrorVariable $Cred_Error

  If($L -eq $null)
  {

    Write-host "All Cached Credentials removed, program Complete"
    $LASTEXITCODE = 0
    Write-host "The last exit code is $LASTEXITCODE"

  }
  Else
  {

    Write-host "WARNING: One or more Cached Credentials were not removed, program Complete"
    $LASTEXITCODE = 1


  }
}
Hemp answered 30/8, 2018 at 14:19 Comment(0)
J
0

Batch, elevated cmd prompt:

To find the main ones, lists any with MS.O, Micro and teams:

for /f "tokens=1-4 Delims=:=" %A in ('cmdkey /list  ^| findstr Target: ^| findstr /i "MS.O Micro Teams"') do @echo %D

This deletes all the entries for teams:

for /f "tokens=1-4 Delims=:=" %A in ('cmdkey /list ^| findstr /i teams') do @cmdkey /delete:%D

If you want to include this as a script the syntax will be slightly different. Double the %%A %%D vars

Johnathon answered 27/6, 2019 at 20:45 Comment(0)
I
0

Ran into similar issue, clearing old credentials for non domain joined devices. Created logon task to clear credentials. In my case was looking for particular file server, so not to clear all creds by accident. Because of syntax issue when piping string expressions into task, was easier to create reference .ps1 then reference in task. Pushed this script through Intune....

# Full path of the file
$file = 'C:\script\clearcreds.ps1'
    
#If the file does not exist, create it.
if (-not(Test-Path -Path $file -PathType Leaf)) {
try {
$null = New-Item -Path "C:\ProgramData\CentraStage\Packages" -Name 
"clearcreds.ps1" -ItemType "file" -Value 'cmdkey /list | ForEach-Object{if($_ - 
         like "*Target:*" -and $_ -like "*fileserver*"){cmdkey /del:($_ -replace " ","" -replace "Target:","")}}'
Write-Host "The file [$file] has been created."
             }
         catch {
             throw $_.Exception.Message
         }
     }
#######################################
#Create ScheduledTask to Run at log on.
#######################################
$schtaskName = "Clear Cached Creds "
$schtaskDescription = "Clears Cached Creds for each user at logon."
$trigger = New-ScheduledTaskTrigger -AtLogOn
$class = cimclass MSFT_TaskEventTrigger root/Microsoft/Windows/TaskScheduler
#Execute task in users context
$principal = New-ScheduledTaskPrincipal -GroupId "S-1-5-32-545" -Id "Author"
$action3 = New-ScheduledTaskAction -Execute 'Powershell.exe' "-File C:\script\clearcreds.ps1"
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries
$null=Register-ScheduledTask -TaskName $schtaskName -Trigger $trigger -Action   $action3  -Principal $principal -Settings $settings -Description 
$schtaskDescription -Force
Start-ScheduledTask -TaskName $schtaskName
Ichthyology answered 27/1, 2022 at 18:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.