从PowerShell中删除Windows凭据管理器

mm5n2pyu  于 2023-11-18  发布在  Shell
关注(0)|答案(7)|浏览(226)

我正在Windows Server 2008 R2上使用PowerShell 2.0(由于SP2010而需要)。我需要从Windows凭据管理器中检索进程的凭据。我似乎无法使其工作。
我得到了这段代码:

[Windows.Security.Credentials.PasswordVault,Windows.Security.Credentials,ContentType=WindowsRuntime]
(new-object Windows.Security.Credentials.PasswordVault).RetrieveAll() | % { $_.RetrievePassword(); $_ }

字符串
两行代码抛出错误

Windows.Security.Credentials.PasswordVault,Windows.Security.Credentials,ContentType=WindowsRuntime : Unable to find type [Windows.Security.Credentials.PasswordVault,Windows.Security.Credentials,ContentType=WindowsRuntime]: make sure that the assembly containing this type is loaded.


(new-object Windows.Security.Credentials.PasswordVault).RetrieveAll() | % {$_.RetrievePassword(); $_ }


我一直在尝试以某种方式导入PasswordVault类。到目前为止,Google已经失败了,我甚至无法找到它驻留在哪个程序集中。我错过了什么?

nwnhqdif

nwnhqdif1#

在powershell5中键入:

Install-Module CredentialManager -force

字符串
然后

New-StoredCredential -Target $url -Username $ENV:Username -Pass ....


和后来

Get-StoredCredential -Target ....


该模块的源代码为https://github.com/davotronic5000/PowerShell_Credential_Manager
==编辑2023 ==
原始版本已存档,请安装更新的fork:

Install-Module -Name TUN.CredentialManager


查看Github repository了解更多详情。

hof1towb

hof1towb2#

您需要访问Win32 API才能与凭据管理器交互。
CredMan.ps1 from the Technet scripting gallery很好地证明了这一点。
对于更简单的使用模式,如仅列出主体或添加新凭据,您还可以使用cmdkey,这是一个用于凭据管理的内置Windows命令行实用程序
为了在PowerShell中重用存储的凭据,这家伙似乎找到了一种方法,使用类似于CredMan.ps1的技术,从凭据存储中的通用凭据句柄构建PSCredentialGet-StoredCredential

nue99wik

nue99wik3#

如果任何人只是想要一个代码片段,这样他们就可以分发脚本,而不必指示最终用户安装模块或包含DLL文件,这应该可以做到。

$code = @"
using System.Text;
using System;
using System.Runtime.InteropServices;

namespace CredManager {
  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
  public struct CredentialMem
  {
    public int flags;
    public int type;
    public string targetName;
    public string comment;
    public System.Runtime.InteropServices.ComTypes.FILETIME lastWritten;
    public int credentialBlobSize;
    public IntPtr credentialBlob;
    public int persist;
    public int attributeCount;
    public IntPtr credAttribute;
    public string targetAlias;
    public string userName;
  }

  public class Credential {
    public string target;
    public string username;
    public string password;
    public Credential(string target, string username, string password) {
      this.target = target;
      this.username = username;
      this.password = password;
    }
  }

  public class Util
  {
    [DllImport("advapi32.dll", EntryPoint = "CredReadW", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern bool CredRead(string target, int type, int reservedFlag, out IntPtr credentialPtr);

    public static Credential GetUserCredential(string target)
    {
      CredentialMem credMem;
      IntPtr credPtr;

      if (CredRead(target, 1, 0, out credPtr))
      {
        credMem = Marshal.PtrToStructure<CredentialMem>(credPtr);
        byte[] passwordBytes = new byte[credMem.credentialBlobSize];
        Marshal.Copy(credMem.credentialBlob, passwordBytes, 0, credMem.credentialBlobSize);
        Credential cred = new Credential(credMem.targetName, credMem.userName, Encoding.Unicode.GetString(passwordBytes));
        return cred;
      } else {
        throw new Exception("Failed to retrieve credentials");
      }
    }

    [DllImport("Advapi32.dll", SetLastError = true, EntryPoint = "CredWriteW", CharSet = CharSet.Unicode)]
    private static extern bool CredWrite([In] ref CredentialMem userCredential, [In] int flags);

    public static void SetUserCredential(string target, string userName, string password)
    {
      CredentialMem userCredential = new CredentialMem();

      userCredential.targetName = target;
      userCredential.type = 1;
      userCredential.userName = userName;
      userCredential.attributeCount = 0;
      userCredential.persist = 3;
      byte[] bpassword = Encoding.Unicode.GetBytes(password);
      userCredential.credentialBlobSize = (int)bpassword.Length;
      userCredential.credentialBlob = Marshal.StringToCoTaskMemUni(password);
      if (!CredWrite(ref userCredential, 0))
      {
        throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
      }
    }
  }
}
"@
Add-Type -TypeDefinition $code -Language CSharp
# How to store credentials
[CredManager.Util]::SetUserCredential("Application Name", "Username", "Password")
# How to retrieve credentials
[CredManager.Util]::GetUserCredential("Application Name")
# How to just get the password
[CredManager.Util]::GetUserCredential("Application Name").password

字符串
上面的代码已经在PowerShell 7和PowerShell 5上进行了测试,但是如果你使用后者,你可能需要一个最新版本的.Net框架。

pb3s4cty

pb3s4cty4#

微软的SecretManagement and SecretStore似乎是官方的解决方案。他们是officially released on March 25, 2021。秘密可以是一个凭据。

Install-Module Microsoft.PowerShell.SecretManagement
Install-Module SecretManagement.JustinGrote.CredMan  # windows credential manager
Register-SecretVault SecretManagement.JustinGrote.CredMan
Set-Secret -Name TestSecret -Secret "TestSecret"
Get-Secret -Name TestSecret -AsPlainText

个字符

hzbexzde

hzbexzde5#

根据文档,Windows Server 2008 R2不支持PasswordVault类。

最低支持服务器Windows Server 2012

https://msdn.microsoft.com/library/windows/apps/windows.security.credentials.passwordvault.aspx

ni65a41a

ni65a41a6#

我发现了一个非常好的职位,这段代码将打印所有的用户名,资源和密码

[Windows.Security.Credentials.PasswordVault,Windows.Security.Credentials,ContentType=WindowsRuntime]
$vault = New-Object Windows.Security.Credentials.PasswordVault
$vault.RetrieveAll() | % { $_.RetrievePassword();$_ }

字符串
来源:Todd's post

tjvv9vkg

tjvv9vkg7#

适用于 Windows PowerShell v5.1(以及 * 可能 * 更早版本)以及PowerShell (Core) 7+的解决方案:
BetterCredentials模块available in the PowerShell Gallery提供对CredMan(Windows凭据管理器)的编程访问。
您可以安装,例如,与:

Install-Module BetterCredentials -AllowClobber

字符串
-AllowClobber是必要的,因为模块的Get-Credential命令是用来覆盖built-in one的:它与内置的语法兼容,同时通过额外的参数提供额外的功能。
值得注意的是,-Store开关可用于将返回的凭据存储在CredMan中。
要对如何存储条目进行更多控制,请使用Set-Credential
Get-Credential自动返回已存储的凭据(如果可用),并且如果最初仅指定了用户名,则也足以进行检索。
以下命令与CredMan保险库显式交互,需要完整的条目 * 目标名称 *,如Find-Credential返回的装饰[pscredential]示例的.Target属性值所示。

  • 例如,对于使用Get-Credential -Store -UserName Foo存储的凭据,.Target属性值为LegacyGeneric:target=MicrosoftPowerShell:user=foo

Find-Credential默认列出所有存储的凭据;虽然它确实有一个-Filter参数,但它受到严重限制,并且根据我的经验并不可靠(从模块版本4.5开始)-最好使用Where-Objectpost-filtering,如this answer所示。
要删除存储的凭据,请使用Remove-Credential
要测试CredMan保管库中是否已存在具有给定目标名称的凭据,请使用Test-Credential
[1]您不太可能需要这样做,但是您仍然可以调用重写的小程序,即通过Microsoft.PowerShell.Security\Get-Credential

相关问题