【问题标题】:Get Cached Credentials in PowerShell from Windows 7 Credential Manager从 Windows 7 凭据管理器获取 PowerShell 中的缓存凭据
【发布时间】:2011-11-02 00:28:08
【问题描述】:

我可以使用一些我忽略的 API 来执行此操作,还是我必须弄清楚将 the C# .NET API calls mentioned here 移植到 PowerShell 以在脚本中实现此操作?

【问题讨论】:

    标签: windows-7 powershell credentials


    【解决方案1】:

    我相信您可以使用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

    【讨论】:

    • 我想我实际上已经够尴尬了,但我认为一定有更简单的方法。我有点侮辱没有更简单的方法来为 Windows 领域的脚本提取安全凭据,但我想我应该停止感到惊讶。当我有更多时间测试它时,我会更新这篇文章。谢谢。
    【解决方案2】:

    这已经完成了:

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

    它提供了一些与 cred-man 相关的方法,并且已经记录在案。

    【讨论】:

    • 这个文件的使用许可是什么?
    猜你喜欢
    • 2020-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-22
    • 2012-03-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多