using System; using System.Runtime.InteropServices; using System.Security.Principal; using System.Text; class NativeMethods { public const int LOGON32_LOGON_INTERACTIVE = 2; public const int LOGON32_LOGON_NETWORK = 3; public const int LOGON32_LOGON_BATCH = 4; public const int LOGON32_LOGON_SERVICE = 5; public const int LOGON32_LOGON_UNLOCK = 7; public const int LOGON32_LOGON_NETWORK_CLEARTEXT = 8; public const int LOGON32_LOGON_NEW_CREDENTIALS = 9; public enum SID_NAME_USE { SidTypeUser = 1, SidTypeGroup, SidTypeDomain, SidTypeAlias, SidTypeWellKnownGroup, SidTypeDeletedAccount, SidTypeInvalid, SidTypeUnknown, SidTypeComputer, } public struct LOCALGROUP_MEMBERS_INFO_0 { public IntPtr PSID; } [DllImport("kernel32.dll")] public extern static bool CloseHandle(IntPtr hToken); [DllImport("advapi32.DLL", SetLastError = true)] public static extern int LogonUser( string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken); [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern bool LookupAccountName( string lpSystemName, string lpAccountName, [MarshalAs(UnmanagedType.LPArray)] byte[] Sid, ref uint cbSid, StringBuilder ReferencedDomainName, ref uint cchReferencedDomainName, out SID_NAME_USE peUse); [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern bool LookupAccountSid( string lpSystemName, [MarshalAs(UnmanagedType.LPArray)] byte[] lpSid, StringBuilder lpName, ref uint cchName, StringBuilder lpReferencedDomainName, ref uint cchReferencedDomainName, out SID_NAME_USE peUse); [DllImport("netapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern int NetLocalGroupAddMembers( string servername, string groupname, uint level, ref LOCALGROUP_MEMBERS_INFO_0 buf, uint totalentries); } public class AddAdminUserHelper { public static void AddAdminUser(string domain, string username, string password) { // Get built in administrators account name StringBuilder adminGroupName = new StringBuilder(); uint adminGroupNameCapacity = (uint)adminGroupName.Capacity; StringBuilder referencedDomainName = new StringBuilder(); uint referencedDomainNameCapacity = (uint)referencedDomainName.Capacity; NativeMethods.SID_NAME_USE eUse; byte[] adminGroupSid = new byte[] { 1, 2, 0, 0, 0, 0, 0, 5, 32, 0, 0, 0, 32, 2 }; if (!NativeMethods.LookupAccountSid( null, adminGroupSid, adminGroupName, ref adminGroupNameCapacity, referencedDomainName, ref referencedDomainNameCapacity, out eUse)) { Console.WriteLine("LookupAccountSid failed with error " + Marshal.GetLastWin32Error()); return; } // Get a security token needed to be able to afterwards query for the user's SID IntPtr token = IntPtr.Zero; if (NativeMethods.LogonUser( username, domain, password, NativeMethods.LOGON32_LOGON_NEW_CREDENTIALS, 0, out token) == 0) { Console.WriteLine("LogonUser failed with error " + Marshal.GetLastWin32Error()); return; } // Get user's SID byte[] userSid = new byte[1024]; uint userSidLength = (uint)userSid.Length; referencedDomainName = new StringBuilder(); referencedDomainNameCapacity = (uint)referencedDomainName.Capacity; NativeMethods.SID_NAME_USE peUse; using (WindowsImpersonationContext context = WindowsIdentity.Impersonate(token)) { if (!NativeMethods.LookupAccountName( domain, username, userSid, ref userSidLength, referencedDomainName, ref referencedDomainNameCapacity, out peUse)) { Console.WriteLine("LookupAccountName failed with error " + Marshal.GetLastWin32Error()); return; } } NativeMethods.CloseHandle(token); // Add user's SID to local admins group IntPtr userSidNative = Marshal.AllocHGlobal(userSid.Length); Marshal.Copy(userSid, 0, userSidNative, (int)userSid.Length); NativeMethods.LOCALGROUP_MEMBERS_INFO_0 info0; info0.PSID = userSidNative; int r = NativeMethods.NetLocalGroupAddMembers( null, adminGroupName.ToString(), 0, ref info0, 1); Marshal.FreeHGlobal(userSidNative); if (r != 0) { Console.WriteLine("NetLocalGroupAddMembers failed by returning " + r); return; } } }
Tuesday, July 24, 2012
Adding domain user as local admin immediatly after domain join
Here's a way to add a domain user as a local admin immediatly after joining the domain, without rebooting first:
Thursday, July 12, 2012
Join a domain and rename in one reboot using WMI
If you don't take special care in your script, then renaming a machine and then joining it to a Windows domain will join it using the old name. Apparently there's an undocumented flag 0x400 on JoinDomainOrWorkGroup. At least I think it started working when I added that flag... Here's a PowerShell snippet that's working for me now:
$computer = Get-WmiObject Win32_ComputerSystem $cred = Get-Credential $computer.Rename("newmachinename", $NULL, $NULL) $computer.JoinDomainOrWorkGroup( ` "mydomain", ` ($cred.GetNetworkCredential()).Password, ` $cred.UserName, ` $NULL, ` 0x1 + 0x2 + 0x20 + 0x400)
Sunday, July 08, 2012
Windows Shares vs. FTP vs. FTPS vs. SFTP
Conducted this little test between a Windows 7 machine and Windows XP machine on a 100 Mbit switch.
Used FileZilla server for FTP and FTPS server, FileZilla as FTP and FTPS client, Cygwin OpenSSH as SFTP server and WinSCP as SFTP client.
Was surprised to see how much overhead there was on FTPS, but it could also be something specific to FileZilla.
Windows shares | FTP | FTPS | SFTP | |
---|---|---|---|---|
2700 files, 200Mb | 4,17 Mb/sec 48 secs | 4,76 Mb/sec 42 secs | 0,61 Mb/sec 326 secs | 3,03 Mb/sec 66 secs |
1 file, 550Mb | 9,82 Mb/sec 56 secs | 11,22 Mb/sec 49 secs | 11,00 Mb/sec 50 secs | 6,25 Mb/sec 88 secs |
Friday, July 06, 2012
Finding all machines a user owns in Active Directory
Here's a quick and dirty way to find all machines a user owns in Active Directory. Performance is not good though, as the objects are processed client side. I was not able to find any way of doing server side queries dealing with the ntSecurityDescriptor field. Please let me know if you find a way!
Adjust the DN strings as needed.
Adjust the DN strings as needed.
using System; using System.DirectoryServices; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { DateTime startTime = DateTime.Now; DirectoryEntry d = new DirectoryEntry("LDAP://ou=UserAccounts,dc=contoso,dc=com"); DirectorySearcher s = new DirectorySearcher(d, "(&(objectClass=user)(cn=John Smith))", new string[] { "cn", "objectsid" }); string sid = BitConverter.ToString( (byte[])s.FindOne().Properties["objectsid"][0]) .Replace("-", ""); int count = 0; d = new DirectoryEntry("LDAP://ou=Machines,dc=contoso,dc=com"); s = new DirectorySearcher(d, "(&(objectCategory=computer)(objectClass=computer)(cn=*))", new string[] { "cn", "ntSecurityDescriptor" }); s.PageSize = 500; s.SecurityMasks = SecurityMasks.Owner; foreach (SearchResult r in s.FindAll()) { count++; string cn = (string)r.Properties["cn"][0]; string sd = BitConverter.ToString((byte[])r.Properties["ntsecuritydescriptor"][0]).Replace("-", ""); if (sd.Contains(sid)) Console.WriteLine(cn); } Console.WriteLine(); Console.WriteLine("Checked " + count + " objects"); Console.WriteLine("Query finished in " + (DateTime.Now - startTime)); } } }
Subscribe to:
Posts (Atom)