26

Windows Server 2008 R2 で PowerShell 2.0 (SP2010 のために必要) を使用しています。Windows Credential Manager からプロセスの資格情報を取得する必要があります。私はそれを機能させることができないようです。

このコードが与えられました:

[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 は私を失望させてきました。Google がどのアセンブリに存在するかを見つけることさえできませんでした。何が欠けているのでしょうか?

4

6 に答える 6

45

powershell5 で次のように入力します。

   Install-Module CredentialManager -force

それで

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

以降

   Get-StoredCredential -Target .... 

モジュールのソース コードはhttps://github.com/davotronic5000/PowerShell_Credential_Managerです。

于 2016-03-30T11:43:52.327 に答える
9

Credential Manager とやり取りするには、Win32 API にアクセスする必要があります。

Technet スクリプト ギャラリーの CredMan.ps1 は、これをうまく示しています。

プリンシパルの一覧表示や新しい資格情報の追加など、より単純な使用パターンの場合はcmdkey、資格情報管理用の組み込みの Windows コマンドライン ユーティリティである を使用することもできます。

PowerShell で保存された資格情報を再利用するために、この男PSCredentialは CredMan.ps1 と同様の手法を使用して、資格情報ストアの汎用資格情報ハンドルから を構築する方法を見つけたようです: Get-StoredCredential

于 2015-03-17T15:56:26.210 に答える
3

エンド ユーザーにモジュールのインストールや 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 フレームワークの最新バージョンが必要になる場合があります。

編集: @alazyworkaholic が指摘したように、不足しているセミコロンをコード スニペットに追加しました

于 2021-06-11T22:25:38.957 に答える
3

ドキュメントによると、PasswordVault クラスは Windows Server 2008 R2 ではサポートされていません。

サポートされる最小サーバーWindows Server 2012

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

于 2015-03-17T15:40:57.403 に答える
2

本当に良い投稿を見つけました。このコードは、すべてのユーザー名、リソース、およびパスワードを出力します

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

トッドの投稿へのクレジット

于 2020-06-21T05:20:41.500 に答える