从Windows 7获取PowerShell中的缓存凭据凭证管理器

问题描述:

我可以使用一些我忽略的API来做到这一点吗?或者我必须考虑将the C# .NET API calls mentioned here移植到PowerShell中,以便在脚本中执行此操作?从Windows 7获取PowerShell中的缓存凭据凭证管理器

您可以使用Add-Type cmdlet可以轻松地将它,我相信:

$sig = @" 

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 
public struct NativeCredential 
{ 
    public UInt32 Flags; 
    public CRED_TYPE Type; 
    public IntPtr TargetName; 
    public IntPtr Comment; 
    public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten; 
    public UInt32 CredentialBlobSize; 
    public IntPtr CredentialBlob; 
    public UInt32 Persist; 
    public UInt32 AttributeCount; 
    public IntPtr Attributes; 
    public IntPtr TargetAlias; 
    public IntPtr UserName; 

    internal static NativeCredential GetNativeCredential(Credential cred) 
    { 
     NativeCredential ncred = new NativeCredential(); 
     ncred.AttributeCount = 0; 
     ncred.Attributes = IntPtr.Zero; 
     ncred.Comment = IntPtr.Zero; 
     ncred.TargetAlias = IntPtr.Zero; 
     ncred.Type = CRED_TYPE.GENERIC; 
     ncred.Persist = (UInt32)1; 
     ncred.CredentialBlobSize = (UInt32)cred.CredentialBlobSize; 
     ncred.TargetName = Marshal.StringToCoTaskMemUni(cred.TargetName); 
     ncred.CredentialBlob = Marshal.StringToCoTaskMemUni(cred.CredentialBlob); 
     ncred.UserName = Marshal.StringToCoTaskMemUni(System.Environment.UserName); 
     return ncred; 
    } 
} 

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 
public struct Credential 
{ 
    public UInt32 Flags; 
    public CRED_TYPE Type; 
    public string TargetName; 
    public string Comment; 
    public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten; 
    public UInt32 CredentialBlobSize; 
    public string CredentialBlob; 
    public UInt32 Persist; 
    public UInt32 AttributeCount; 
    public IntPtr Attributes; 
    public string TargetAlias; 
    public string UserName; 
} 

public enum CRED_TYPE : uint 
    { 
     GENERIC = 1, 
     DOMAIN_PASSWORD = 2, 
     DOMAIN_CERTIFICATE = 3, 
     DOMAIN_VISIBLE_PASSWORD = 4, 
     GENERIC_CERTIFICATE = 5, 
     DOMAIN_EXTENDED = 6, 
     MAXIMUM = 7,  // Maximum supported cred type 
     MAXIMUM_EX = (MAXIMUM + 1000), // Allow new applications to run on old OSes 
    } 

public class CriticalCredentialHandle : Microsoft.Win32.SafeHandles.CriticalHandleZeroOrMinusOneIsInvalid 
{ 
    public CriticalCredentialHandle(IntPtr preexistingHandle) 
    { 
     SetHandle(preexistingHandle); 
    } 

    public Credential GetCredential() 
    { 
     if (!IsInvalid) 
     { 
      NativeCredential ncred = (NativeCredential)Marshal.PtrToStructure(handle, 
        typeof(NativeCredential)); 
      Credential cred = new Credential(); 
      cred.CredentialBlobSize = ncred.CredentialBlobSize; 
      cred.CredentialBlob = Marshal.PtrToStringUni(ncred.CredentialBlob, 
        (int)ncred.CredentialBlobSize/2); 
      cred.UserName = Marshal.PtrToStringUni(ncred.UserName); 
      cred.TargetName = Marshal.PtrToStringUni(ncred.TargetName); 
      cred.TargetAlias = Marshal.PtrToStringUni(ncred.TargetAlias); 
      cred.Type = ncred.Type; 
      cred.Flags = ncred.Flags; 
      cred.Persist = ncred.Persist; 
      return cred; 
     } 
     else 
     { 
      throw new InvalidOperationException("Invalid CriticalHandle!"); 
     } 
    } 

    override protected bool ReleaseHandle() 
    { 
     if (!IsInvalid) 
     { 
      CredFree(handle); 
      SetHandleAsInvalid(); 
      return true; 
     } 
     return false; 
    } 
} 

[DllImport("Advapi32.dll", EntryPoint = "CredReadW", CharSet = CharSet.Unicode, SetLastError = true)] 
public static extern bool CredRead(string target, CRED_TYPE type, int reservedFlag, out IntPtr CredentialPtr); 

[DllImport("Advapi32.dll", EntryPoint = "CredFree", SetLastError = true)] 
public static extern bool CredFree([In] IntPtr cred); 


"@ 
Add-Type -MemberDefinition $sig -Namespace "ADVAPI32" -Name 'Util' 

$targetName = "computer" 
$nCredPtr= New-Object IntPtr 

$success = [ADVAPI32.Util]::CredRead($targetName,1,0,[ref] $nCredPtr) 

if($success){ 
    $critCred = New-Object ADVAPI32.Util+CriticalCredentialHandle $nCredPtr 
    $cred = $critCred.GetCredential() 
    $password = $cred.CredentialBlob; 
    write-host -fore blue $password 
} 

从这里改编:http://social.technet.microsoft.com/Forums/en-US/ITCG/thread/e91769eb-dbce-4e77-8b61-d3e55690b511/

基于:http://blogs.msdn.com/b/peerchan/archive/2005/11/01/487834.aspx

+0

我想我实际上已经过了那种令人尴尬的感觉,但认为必须有一个更简单的方法。我有点侮辱,有没有一种更简单的方法来获取Windows土地上的脚本的安全证书,但我想我应该停止惊讶。当我有更多时间来测试时,我会更新这篇文章。谢谢。 – songei2f

+0

感谢这个家伙。 – songei2f

这已经完成:

http://gallery.technet.microsoft.com/scriptcenter/PowerShell-Credentials-d44c3cde/view/Discussions

它提供了一对夫妇相关的方法,并且它已经被记录。