Posso fare questo con qualche API che sto trascurando o devo calcolare il porting the C# .NET API calls mentioned here in PowerShell per fare in modo che ciò accada in uno script?Ottieni credenziali memorizzate nella cache in PowerShell da Windows 7 Credential Manager
7
A
risposta
7
È possibile utilizzare Add-Type
cmdlet per facilmente porto io credo:
$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
}
Adattato da qui: http://social.technet.microsoft.com/Forums/en-US/ITCG/thread/e91769eb-dbce-4e77-8b61-d3e55690b511/
Sulla base: http://blogs.msdn.com/b/peerchan/archive/2005/11/01/487834.aspx
1
Questo è già stato fatto:
http://gallery.technet.microsoft.com/scriptcenter/PowerShell-Credentials-d44c3cde/view/Discussions
Fornisce un paio di metodi correlati a cred-man ed è già documentato.
Penso che in realtà sono passato abbastanza imbarazzante ma ho pensato che ci fosse un modo più semplice. Sono un po 'insultato, non c'è un modo più semplice per ottenere credenziali sicure per uno script su Windows, ma suppongo che dovrei smettere di essere sorpreso. Aggiornerò questo post quando avrò più tempo per testarlo. Grazie. – songei2f
Grazie per questo tizio. – songei2f