Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从PowerShell访问Windows凭据管理器_Powershell_Credential Manager - Fatal编程技术网

从PowerShell访问Windows凭据管理器

从PowerShell访问Windows凭据管理器,powershell,credential-manager,Powershell,Credential Manager,我正在Windows Server 2008 R2上使用PowerShell 2.0(因SP2010而必需)。我需要从Windows凭据管理器检索进程的凭据。我似乎无法让它工作 我得到了这段代码: [Windows.Security.Credentials.PasswordVault,Windows.Security.Credentials,ContentType=WindowsRuntime] (new-object Windows.Security.Credentials.PasswordV

我正在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.


分别。我一直在尝试以某种方式导入PasswordVault类。到目前为止,谷歌让我失望了,我甚至还没有找到它所在的程序集。我缺少什么?

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

支持的最低服务器数Windows server 2012


您需要访问Win32 API才能与凭据管理器交互

很好地证明了这一点

对于更简单的使用模式,如仅列出主体或添加新凭据,您还可以使用内置的Windows命令行实用程序进行凭据管理

为了重用PowerShell中存储的凭据,这家伙似乎找到了一种方法,使用与powershell5中的CredMan.ps1:

类似的技术,从凭据存储库中的通用凭据句柄构建
PSCredential

   Install-Module CredentialManager -force
然后

后来

   Get-StoredCredential -Target .... 

模块的源代码是

这些powershell模块刚刚获得完整版本:。秘密可以是凭证

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

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

[Windows.Security.Credentials.PasswordVault,Windows.Security.Credentials,ContentType=WindowsRuntime]
$vault=新对象Windows.Security.Credentials.PasswordVault
$vault.RetrieveAll()|%{$|.RetrievePassword();$|}

如果任何人只需要一段代码片段,这样他们就可以分发脚本,而无需指示最终用户安装模块或包含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; // .NET 2.0
    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
$code=@”
使用系统文本;
使用制度;
使用System.Runtime.InteropServices;
命名空间CredManager{
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]
公共结构证书
{
公共国旗;
公共int类型;
公共字符串targetName;
公共字符串评论;
public System.Runtime.InteropServices.ComTypes.FILETIME LastWrite;//.NET 2.0
公共int-credentialBlobSize;
公共IntPtr证书blob;
公众参与;
公共int属性计数;
公共国际信托财产;
公共字符串targetAlias;
公共字符串用户名;
}
公共类凭证{
公共字符串目标;
公共字符串用户名;
公共字符串密码;
公共凭据(字符串目标、字符串用户名、字符串密码){
this.target=目标;
this.username=用户名;
this.password=密码;
}
}
公共类Util
{
[DllImport(“advapi32.dll”,EntryPoint=“crederaw”,CharSet=CharSet.Unicode,SetLastError=true)]
私有静态外部布尔凭证(字符串目标、int类型、int reservedFlag、out IntPtr凭证tr);
公共静态凭据GetUserCredential(字符串目标)
{
CredentialMem CredentialMem;
IntPtr credPtr;
if(CredRead(目标,1,0,出credPtr))
{
credMem=Marshal.ptr结构(credPtr);
byte[]passwordBytes=新字节[credMem.credentialBlobSize];
Marshal.Copy(credMem.credentialBlob,passwordBytes,0,credMem.credentialBlobSize);
Credential cred=新凭证(credMem.targetName、credMem.userName、Encoding.Unicode.GetString(passwordBytes));
回信;
}否则{
抛出新异常(“检索凭据失败”);
}
}
[DllImport(“Advapi32.dll”,SetLastError=true,EntryPoint=“CredWriteW”,CharSet=CharSet.Unicode)]
私有静态外部bool CredWrite([In]ref-CredentialMem-userCredential,[In]int标志);
公共静态void SetUserCredential(字符串目标、字符串用户名、字符串密码)
{
CredentialMem userCredential=新的CredentialMem();
userCredential.targetName=目标;
userCredential.type=1;
userCredential.userName=用户名;
userCredential.attributeCount=0;
userCredential.persist=3;
byte[]bpassword=Encoding.Unicode.GetBytes(密码);
userCredential.credentialBlobSize=(int)bpassword.Length;
userCredential.credentialBlob=Marshal.StringToCoTaskMemUni(密码);
如果(!CredWrite(ref userCredential,0))
{
抛出新的System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
}
}
}
}
"@
添加Type-TypeDefinition$code-Language CSharp
#如何存储凭据
[CredManager.Util]::SetUserCredential(“应用程序名”、“用户名”、“密码”)
#如何检索凭据
[CredManager.Util]::GetUserCredential(“应用程序名称”)
#如何获取密码
[CredManager.Util]::GetUserCredential(“应用程序名称”).密码

上面的代码是在PowerShell 7和PowerShell 5上测试的,不过如果您使用的是.Net framework,则可能需要.Net framework的最新版本。

好的,重点放在这里。因此,我的问题是,如何在Windows Server 2008上访问凭据管理器?一定有办法。谢谢,只是为了确保,在我花时间研究它之前,它会允许我检索密码,对吗?不,至少
cmdkey
不会。为什么要检索密码?因为我需要使用存储在凭据管理器中的凭据远程调用进程。我认为这一部分是不言而喻的,如果不使用存储在其中的凭据,为什么我需要访问凭据管理器?在没有实施此类解决方案的任何实际经验的情况下,我认为这样做的“正确”方式是通过SSPI或类似方式导出令牌或安全上下文,我使用的是System.Managemens实例,而不是直接在纯文本中修改密码
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
TestSecret
$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; // .NET 2.0
    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