2011-08-23 11 views

Odpowiedz

7

Można użyć Add-Type komandletu łatwo portu niego wierzę:

$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 
} 

Adaptacja tutaj: http://social.technet.microsoft.com/Forums/en-US/ITCG/thread/e91769eb-dbce-4e77-8b61-d3e55690b511/

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

+0

Myślę, że faktycznie przeszedłem przez to zawstydzająco, ale myślałem, że musi być łatwiejszy sposób. Jestem obrażony, że nie jest łatwiejszy sposób na wyciągnięcie bezpiecznych referencji dla skryptu w Windows Land, ale myślę, że powinienem przestać być zaskoczony. Zaktualizuję ten post, gdy będę mieć więcej czasu na przetestowanie go. Dzięki. – songei2f

+0

Dzięki za ten koleś. – songei2f