从 Windows 上的所有用户的凭据管理器中删除一个条目

Remove an entry from credential manager for all users on Windows

我目前正在 Windows 卸载程序中为所有用户实施 "remove settings" 并遇到了一个我什至不确定是否可以解决的问题。

应用程序使用 CredentialManager (keymgr.dll) 为当前用户存储凭据条目。让我们调用凭证的目标 "X"。卸载时,应删除所有用户上存储有目标 "X" 的所有凭据。卸载程序当然需要管理员权限,但我仍然觉得很难做到这一点。

对于当前用户,该命令通常通过命令提示符 cmdkey /delete=:X 解决。据我所知,cmdkey.exe /list 仅有助于列出当前用户的条目,不能从其他用户删除本地条目。

我了解到凭证以 OS 文件的形式存储在 C:\Users\_user_\AppData\Local\Microsoft\Credentials 文件夹下,但我不知道哪些文件是我要删除的条目,如果全部删除会很危险用于其他应用。此外,我假设删除 OS 文件将是危险的,并且可能会有限制(额外的 UAC 提示?)。

Runas 命令是我得到的最接近的镜头,但因为它需要用户的密码,所以变得非常困难,而不是我想要的卸载程序。我还需要一种方法来获取每个用户的用户名和域并迭代它们。

我更愿意为此使用 cmdpowershell

不想破坏旧的 post 但我需要自己做所以我想我会添加它以防其他人需要它:

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

Powershell 一个衬里,将删除字符串中任何带有 Microsoft 的凭据。

参考: https://gist.github.com/janikvonrotz/7819990

我运行这个并且它在本地清除它而不需要运行作为管理员(但我是本地管理员)

当从批处理文件或 PowerShell 命令中 运行 时,cmdkey.exe 实用程序可能会遇到两个与特殊字符相关的问题。 1. 如果来自批处理文件的 运行,如果凭据包含不带双引号的“(”或“)”,即左右括号,则不会删除该凭据。 2. 如果凭证名称 aka targetname 有一个由空格包围的连字符,cmdkey 将不会删除或创建带有该字符串“-”的凭证。

已经编写了一些 powershell 模块来尝试执行此操作,但我发现唯一一个处理此异常的模块是 Github https://github.com/bamcisnetworks/BAMCIS.CredentialManager

BAMCIS.CredentialManager

使用它我能够创建凭据来设置带有括号或连字符的测试环境,但更重要的是通过使用模块命令收集缓存凭据的用户列表然后在命令中传递信息来删除它们到删除命令以删除所有缓存的凭据。

一个警告。删除命令后,一段时间后,两个缓存的凭据会动态重新出现。

因此,为了解决频繁的用户锁定问题,我将尝试在注销时在用户上下文中使用 SCCM 进行部署。否则,可能需要在删除凭据后重新启动系统。 这是一个导入模块然后使用它来删除所有缓存凭据的原型脚本,一如既往地测试,测试,测试和使用,风险自负!

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


  }
}

批处理,提升 cmd 提示符:

要找到主要的,请列出 MS.O、微型和团队

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

删除 teams 的所有条目:

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

如果您想将其作为脚本包含在内,语法会略有不同。将 %%A %%D 变量加倍

运行 进入类似问题,清除未加入域的设备的旧凭据。创建登录任务以清除凭据。在我的例子中正在寻找特定的文件服务器,所以不要意外清除所有信用。由于将字符串表达式输送到任务中时存在语法问题,创建引用 .ps1 比在任务中引用更容易。通过 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