[DllImport("Advapi32.dll", SetLastError=true, EntryPoint="CredWriteW", CharSet=CharSet.Unicode)]
static extern bool CredWrite([In] Credential userCredential, [In] UInt32 flags);
Declare Function CredWrite Lib "advapi32.dll" (TODO) As TODO
enum CRED_TYPE : uint
{
CRED_TYPE_GENERIC = 1,
CRED_TYPE_DOMAIN_PASSWORD = 2,
CRED_TYPE_DOMAIN_CERTIFICATE = 3,
CRED_TYPE_DOMAIN_VISIBLE_PASSWORD = 4
}
enum CRED_PERSIST : uint
{
CRED_PERSIST_SESSION = 1,
CRED_PERSIST_LOCAL_MACHINE = 2,
CRED_PERSIST_ENTERPRISE = 3
}
[StructLayout(LayoutKind.Sequential)]
private struct Credential
{
public UInt32 flags;
public UInt32 type;
public string targetName;
public string comment;
//public System.Runtime.InteropServices.FILETIME lastWritten; // .NET 1.1
public System.Runtime.InteropServices.ComTypes.FILETIME lastWritten; // .NET 2.0
public UInt32 credentialBlobSize;
public IntPtr credentialBlob;
public UInt32 persist;
public UInt32 attributeCount;
public IntPtr credAttribute;
public string targetAlias;
public string userName;
}
If it's legal for PInvoke.net to swipe Microsoft's own code, the stuff here is even better:
http://blogs.msdn.com/peerchan/pages/487834.aspx
The stuff on this page about needing custom marshaling are just wrong.
Needs extensive custom marshaling code. See CredRead to for an example on the custom marshaling code.
internal static void AddDomainUserCredential(string target, string userName, string password)
{
Credential userCredential = new Credential();
userCredential.targetName = target;
userCredential.type = (UInt32)CRED_TYPE.CRED_TYPE_DOMAIN_PASSWORD;
userCredential.userName = userName;
userCredential.attributeCount = 0;
userCredential.persist = (UInt32)CRED_PERSIST.CRED_PERSIST_ENTERPRISE;
byte[] bpassword = Encoding.Unicode.GetBytes(password);
userCredential.credentialBlobSize = (UInt32)bpassword.Length;
userCredential.credentialBlob = Marshal.StringToCoTaskMemUni(password);
if (!Unmanaged.CredWrite(ref userCredential, 0))
{
throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
}
}
$sig = @"
[DllImport("Advapi32.dll", SetLastError=true, EntryPoint="CredWriteW", CharSet=CharSet.Ansi)]
public static extern bool CredWrite([In] Credential userCredential, [In] UInt32 flags);
[StructLayout(LayoutKind.Sequential)]
public struct Credential
{
public UInt32 flags;
public UInt32 type;
public string targetName;
public string comment;
public System.Runtime.InteropServices.ComTypes.FILETIME lastWritten;
public UInt32 credentialBlobSize;
public IntPtr credentialBlob;
public UInt32 persist;
public UInt32 attributeCount;
public IntPtr Attributes;
public string targetAlias;
public string userName;
}
"@
$type = Add-Type -MemberDefinition $sig -Namespace "ADVAPI32" -Name 'Util' -PassThru
$cred = New-Object ADVAPI32.Util+Credential
$cred.targetName = 'server1'
$cred.type = 2
$cred.userName = 'home\user'
$cred.attributeCount = 0
$cred.persist = 2
$password = "password"
$cred.credentialBlobSize = [System.Text.Encoding]::Unicode.GetBytes($password).length
$cred.credentialBlob = [System.Runtime.InteropServices.Marshal]::StringToCoTaskMemUni($password)
[ADVAPI32.Util]::CredWrite($cred,0)
Do you know one? Please contribute it!