Showing posts with label c#. Show all posts
Showing posts with label c#. Show all posts

January 8, 2010

AzMan API Library II

To continue my post on the AzMan Library, I wanted to show all the basic classes and makeup and since I briefly discussed it yesterday, I figure it is worth showing:
//AzLibApplication
IAzApplication _app;

public AzLibApplication(object app)
{
_app = (IAzApplication)app;
}

public IAzApplication Native
{
get { return _app; }
}

public string Name
{
get { return _app.Name; }
}

public string Description
{
get { return _app.Description; }
}

public List<AzLibOperation> Operations
{
get { return AzLibAzManHelper.GetOps((IAzOperations)_app.Operations); }
}

public List<AzLibRole> Roles
{
get {
return AzLibAzManHelper.GetRoles(
this,
(IAzRoles)_app.Roles,
(IAzTasks)_app.Tasks
);
}
}

public List<AzLibTask> Tasks
{
get { return AzLibAzManHelper.GetTasks((IAzTasks)_app.Tasks); }
}

public List<AzLibScope> Scopes
{
get { return AzLibAzManHelper.GetScopes(this, (IAzScopes)_app.Scopes); }
}

public List<AzLibApplicationGroup> ApplicationGroups
{
get { return AzLibAzManHelper.GetApplicationGroups((IAzApplicationGroups)_app.ApplicationGroups); }
}

I mentioned yesterday the simple objects...some examples below:

public class AzLibOperation
{
IAzOperation _op;

public AzLibOperation(object op)
{
_op = (IAzOperation)op;
}

public string Name
{
get { return _op.Name; }
}

public string Description
{
get { return _op.Description; }
}

public int OperationID
{
get { return _op.OperationID; }
}
}
Store:
 IAzAuthorizationStore _store;

public AzLibStore(IAzAuthorizationStore store)
{
_store = store;
}

public List<AzLibApplication> Applications
{
get { return AzLibAzManHelper.GetApplications((IAzApplications)_store.Applications); }
}

The API Library as I mentioned is broken out into two assemblies and the first one is what I have been explaining yesterday and today. This weekend I'll explain the second part and post the code for the two assemblies. Next week, I'll get onto secondary applictions built off this API such as the AzMan reporter.

January 7, 2010

AzMan API Library

Over the years my work with AzMan has forced me created many applications and libraries. Having re-worked my original Lib, I feel that I need to first show the lib code before we can even get to the secondary external applications that I built around this. The library contains a ton of classes and I will go through some of them this week and upload them as well. I'll start by going through the main AzManHelper class:


public static List<AzLibRole> GetRoles(ITasksSource tasksSource, IAzRoles roles, IAzTasks tasks)
{
List<AzLibRole> result = new List<AzLibRole>();
NamedTasks namedTasks = new NamedTasks(tasks);
List<string> usedTasks = new List<string>();

for (int it = 0; it < roles.Count; it++)
{
IAzRole role = (IAzRole)roles[it + 1];
IAzTask task = namedTasks.FindMatchingTask(role);

if (task != null)
{
result.Add(new AzLibRole(tasksSource, role, task));

// Keep trach of the used task
usedTasks.Add(task.Name);
}
else
{
result.Add(new AzLibRole(tasksSource, role));
}
}

for (int it = 0; it < tasks.Count; it++)
{
IAzTask task = (IAzTask)tasks[it + 1];

if (usedTasks.Contains(task.Name) == false)
{
if (InteropHelper.IsTrue(task.IsRoleDefinition))
result.Add(new AzLibRole(tasksSource, task));
}
}

return result;
}

public static List<AzLibOperation> GetOps(IAzOperations ops)
{
List<AzLibOperation> result = new List<AzLibOperation>();

for (int it = 0; it < ops.Count; it++)
{
result.Add(new AzLibOperation(ops[it + 1]));
}

return result;
}

public static List<AzLibScope> GetScopes(AzLibApplication app, IAzScopes scopes)
{
List<AzLibScope> result = new List<AzLibScope>();

for (int it = 0; it < scopes.Count; it++)
{
result.Add(new AzLibScope(scopes[it + 1], app));
}

return result;
}

public static List<AzLibApplication> GetApplications(IAzApplications apps)
{
List<AzLibApplication> result = new List<AzLibApplication>();

for (int it = 0; it < apps.Count; it++)
{
result.Add(new AzLibApplication(apps[it + 1]));
}

return result;
}

public static List<AzLibApplicationGroup> GetApplicationGroups(IAzApplicationGroups groups)
{
List<AzLibApplicationGroup> result = new List<AzLibApplicationGroup>();

for (int it = 0; it < groups.Count; it++)
{
result.Add(new AzLibApplicationGroup(groups[it + 1]));
}

return result;
}

public static AzLibClientContext GetContext(AzLibApplication app)
{
IAzClientContext context = app.Native.InitializeClientContextFromToken(0, null);
return new AzLibClientContext(context);
}

The above does not show, but the AzLibOperation (and tasks, roles, etc.) just are simple objects that are gets of the Name, Description, and ID from AzMan. It will be clear once you look at all the code...but let's take it one step at a time.

November 30, 2009

Alphabet in C#

I saw some code that someone wrote at our company and he was reading the English alphabet from a config file. Granted, that I don't like that...I was looking for an easy way to do it and add to an array not from a config...or build it on the fly. I know I can easily add it to an array like:
char[] alpheng = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
I came across this:
char[] az = Enumerable.Range('a', 'z' - 'a' + 1).Select(i => (Char)i).ToArray();
foreach (var c in az)
{
Console.WriteLine(c);
}
Even funnier was that the suggested answer was what I said at the begining of this post and then someone came after that and gave this unique solution.

November 25, 2009

MSMQ Count with C#

We had a bug in our production environment that filled up MSMQ and would be tied to a specific windows service that we had running. In order to fix this, the solution was to stop and start the windows service. The catch was that we only wanted to do this when the MessageQueue count was above a certain number. You can get access to the class here. A snippet of the main code is below:
public void Run()
{
if (TotalMessagesInAllQueues() >= MessagesCriticalCount)
{
StopService();
SendEmail();
StartService();
}
}

private ManagementObject GetServiceByName(string name)
{
List list = SearchObjects(string.Format("Select * From Win32_Service WHERE Name='{0}'", name));

if (list.Count == 0)
throw new Exception(string.Format("Service '{0}' can not be found", name));

return list[0];
}

private ulong TotalMessagesInAllQueues()
{
var list = SearchObjects("Select * From Win32_PerfRawData_MSMQ_MSMQService");
return (ulong)list[0].GetPropertyValue("TotalMessagesInAllQueues");
}

November 18, 2009

Add Uses to Group in Bulk using C#

So I had a task to take a list of usernames in a text document and add them to AD and map them to group(s). I am sure I could have done this quickly in Powershell, but I wanted to do it in C#. You can get the code here. The application is console based and uses some of our past AD classes.

The format was simple:
user1
user2
user3
A snippet of the code is below:
//using log4net;
//using ActiveDs;
public void Run()
{
foreach (AdUser user in ReadUsers())
{
using (user)
{
Dictionary userGroups = GetUserGroupsDn(user.Entry);

foreach (string groupDn in _groupsToAddUserTo.Keys)
{
if (userGroups.ContainsKey(groupDn))
continue; // User already in this group

AdGroup group = _groupsToAddUserTo[groupDn];

try
{
group.NativeObject.Add(user.Entry.Path);

log.Info(string.Format("User: {0} added to Group: {1}",
user.Entry.Properties["sAMAccountName"][0], group.NativeObject.Name));
}
catch (Exception)
{
log.Error(string.Format("User: {0} can't be added to Group: {1}. Possibly this is it's primary group already.",
user.Entry.Properties["sAMAccountName"][0], group.NativeObject.Name));
}
}
}
}
}
...and main:
 private void Run(string[] args)
{

//logging removed for brevity in snippet

Settings settings = SettingsReader.ReadFromConfig();

Adder adder = new Adder(settings);
adder.UsersToProcess = ReadUsersToProcess(settings.UsersFilePath);

adder.Run();
}
Anyone want to show how this can be done in powershell in 25 or so lines?

November 17, 2009

Reflection to invoke objects

So where did the ComWrapper come from yesterday? What is the point of this article in regards to reflection? Well, in short I wanted to show some some of the classes that helped me with my new AzMan library. Here is the TypeUtilities class:

//using System.Reflection;
public class TypeUtilities
{
private static string ToString(Type[] types)
{
string str = "";

foreach (Type type in types)
{
if (str.Length != 0)
str += ", ";

str += type.Name;
}

return str;
}

public static object GetProperty(object obj, string prop)
{
PropertyInfo pi = obj.GetType().GetProperty(prop);
return pi.GetValue(obj, new object[0]);
}

public static object GetProperty(Type type, object obj, string prop)
{
PropertyInfo pi = type.GetProperty(prop);
return pi.GetValue(obj, new object[0]);
}

public static Type[] GetTypes(object[] parameters)
{
Type[] types = new Type[parameters.Length];

for (int it = 0; it < parameters.Length; it++)
{
Type type = parameters[it].GetType();

if (type == typeof(ComWrapper))
{
ComWrapper wrapper = (ComWrapper)parameters[it];
type = wrapper.Type;
parameters[it] = wrapper.Object;
}

types[it] = type;
}

return types;
}

public static object InvokeOverloaded(object obj, string method, params object[] parameters)
{
Type objType = obj.GetType();
Type[] types = GetTypes(parameters);
MethodInfo mi = obj.GetType().GetMethod(method, types);
Assert(mi, objType, method, types);
return mi.Invoke(obj, parameters);
}

public static object Invoke(object obj, string method, Type[] types, object[] args)
{
Type objType = obj.GetType();
MethodInfo mi = objType.GetMethod(method, types);
Assert(mi, objType, method, types);

try
{
return mi.Invoke(obj, args);
}
catch (Exception ex)
{
Logger.Error(ex);
throw;
}
}

public static void Assert(MethodInfo mi, Type objType, string method, Type[] types)
{
if(mi == null)
throw new Exception(string.Format("Can't find method: {0}.{1}({2})", objType, method, ToString(types)));
}
Using the above classes, I'll show how in my AzMan library I was able to do things like:
while (!(entity is AzStore)) {
entity = (IAzParent)TypeUtils.GetProperty(entity, "Parent");

November 16, 2009

C# COM Wrapper

One of the classes that I use often, will show in details this with other classes that are part of my AzMan main solution.
public class ComWrapper
{
public object Object { get; set; }
public Type Type { get; private set; }

public ComWrapper(object obj, Type type)
{
this.Object = obj;
this.Type = type;
}

public static ComWrapper Create(T obj)
{
return new ComWrapper(obj, typeof(T));
}
}

October 27, 2009

Logparser and Charts

I'll start off with this subject with some of the basics, then I'll try and get a bit more complex and perhaps even write up a helper class.

Logparser uses OWC (only 2003 and earlier...)which is a blessing and a curse. It is a curse since not much is out there on OWC but a blessing in that OWC has a lot of charts! Having said this, logparser has OWC built in, but that should not stop any developer from sending output to a jquery or flash charting application and charting it that way. It is just easier with OWC. After you install the OWC on your server, here is a quick script to see if it works:
COMTSVInputContextClassClass inputFormat = new COMTSVInputContextClassClass();
chartOuputFormat = new COMChartOutputContextClassClass();
chartOuputFormat.chartType = "ColumnStacked";

string query = "select * from abc.log"
LogQueryClass logQuery = new LogQueryClassClass();

logQuery.ExecuteBatch(query, inputFormat, chartOuputFormat);
The above code is hacked up and I did not really test it, but should do the trick. I'll start posting more detailed helper classes this week.

October 23, 2009

Charting with Logparser and C#

I have been asked to show some examples on how to use logparser with charts and specifically from c#. I will try and post those up this weekend.

October 15, 2009

AzMan Bulk Import/Export Tool V2

So I started writing a v2 a while back that was a complete UI using .NET 3.5 and XAML. It was done so that I can finally upgrade the code and play a bit with XAML. I never finished that code and plan to go back to it, but will have to label it v3.0. The v2.0 that I am adding here is a console based application based off my original work and some work done by David E. This code will do a bulk import/export for:
  • Xml store
  • AD store
  • SQL Store
The code was modified a bit and can be used like this:
AzManBulkImport.exe {source policy store}{source policy store}{copy users}
There are a few minor things to keep in mind with this new version:
  • Migrating App Groups with incorrect LDAP Strings crashes the migration.
  • There is no check to make sure the database in the connection string exists.
  • XML AzMan store defaults to no-users in policy store administrators group, meaning everyone has access. SQL AzMan says that no-one in the policy store administrators group means no one has access. Migrating an XML store without any administrators to a SQL store results in an access problem, as no-one will have access to the policy store after the policy store administrators are deleted from SQL server. There is an error message to reflect this situation.
  • David has changed the Operations migration to compare old and new operations using the Operation ID, instead of the old comparison on Operation Name.
An example of the usage can be:
AzManBulkImport.exe "mssql://Driver=SQL Server;Server=dbserver01;Trusted_Connec
tion=True;/MyAzmanDatabase/MyPolicyStore" "d:\Azman.xml" "true"
This basically says to copy from the specified SQL Server store to the specified XML Store, including all user role assignments. You can change from XML to AD Ldap connection string or Ldap connection string to SQL server.

To recap, v2.0 of this code is console based and has a few updates with the major being SQL Server capability. Some of the code is a bit rough, but it works :) I do hope to release v3.0 if I ever get time to work on it again.

You can download the code here.

October 5, 2009

Working with Active Directory and C# -- sample code

After 8 posts on this, I think it makes sense to just give the link to the files here:

The ADLib code can be found here. This contains:

1. AdGroup: interface (IADsGroup) for group
2. AdUser: interface (IADsUser) for user
3. GroupType: enum of group types in AD
4. AdDomain: Policy, Password, Group and User Interaction within AD
5. Go here for the dotnetdevguide...and buy the book as well!

Active Directory and C# VII

Time to continue this series of posts on the domain side. You can download all the files from here. I will upload this file from this post this week. You can see the first post related to this class file here. This post refers to policy and password in AD.
 public DateTime GetPasswordLastChanged(DirectoryEntry entry)
{
return ((IADsUser)entry.NativeObject).PasswordLastChanged;
}

public DateTime GetPasswordExpirationDate(DirectoryEntry entry)
{
return ((IADsUser)entry.NativeObject).PasswordExpirationDate;
}

public bool ChangePasswordAtNextLogon(DirectoryEntry entry)
{
// MSDN: pswLastSet
// If this value is set to 0 and the User-Account-Control attribute
// does not contain the UF_DONT_EXPIRE_PASSWD flag, then the user must
// set the password at the next logon.

if (PasswordNeverExpires(entry))
return false;

Int64 val = 0;

try
{
val = UnboxAdsiInt64(entry.Properties["pwdLastSet"].Value);
}
catch (Exception)
{
val = 0;
}

return (val == 0);
}

public bool PasswordNeverExpires(DirectoryEntry entry)
{
return GetUserAccountControlFlag(entry, ADS_USER_FLAG.ADS_UF_DONT_EXPIRE_PASSWD);
}

public bool GetUserAccountControlFlag(DirectoryEntry entry, ADS_USER_FLAG flag)
{
int userAccountControl = (int)entry.Properties["userAccountControl"].Value;
return (userAccountControl & (int)flag) != 0;
}

///
/// Gets the Password Expiration
/// Date for a domain user
/// Returns MaxValue if never expiring
/// Returns MinValue if user must
/// change password at next logon
///

///
///
public DateTime GetPasswordExpiration(DirectoryEntry user)
{
return new PasswordExpires(GetPolicy()).GetExpiration(user);
}

private DomainPolicy GetPolicy()
{
lock(this)
{
if(_policy == null)
_policy = new DomainPolicy(OpenRootDSE());

return _policy;
}
}

October 2, 2009

Active Directory and C# VI

Time to continue this series of posts on the domain side. You can download all the files from here. I will upload this file from this post this week. You can see the first post related to this class file here. This post once again refers to the sAMAccount, Groups and SID administration in AD.

public DirectoryEntry OpenEntryBySAMAccountName(string sAMAccountName)
{
//from config
string rootPath = SearchPath;
String filter = string.Format("(&(|(objectClass=user)(objectClass=group))(sAMAccountName={0}))", sAMAccountName);
string[] propsToLoad = new string[0];

using (DirectoryEntry entry = OpenExistingEntry(rootPath))
{
if (entry == null)
throw new Exception(string.Format("Failed to open root for search by SAMAccountName. {0}", rootPath));

using (DirectorySearcher searcher = new DirectorySearcher(entry, filter, propsToLoad))
{
SearchResult sr = searcher.FindOne();

if (sr == null)
return null;

return sr.GetDirectoryEntry();
}
}
}

public List GetAllGroupsSAMAccountNames()
{
List adGroups = GetAllGroups(new string[] { "sAMAccountName" });

try
{
List groups = new List();

foreach (AdGroup adGroup in adGroups)
groups.Add((string)adGroup.Entry.Properties["sAMAccountName"].Value);

return groups;
}
finally
{
Dispose(adGroups);
}
}

public List GetAllGroups(string[] propsToLoad)
{
//from config
string rootPath = GroupsSearchPath;
String filter = "(objectClass=group)";
List groups = new List();

using (DirectoryEntry entry = OpenExistingEntry(rootPath))
{
if (entry == null)
throw new Exception(string.Format("Root to search groups by SAMAccountName failed to open. {0}", rootPath));

using (DirectorySearcher searcher = new DirectorySearcher(entry, filter, propsToLoad))
{
using (SearchResultCollection src = searcher.FindAll())
{
foreach (SearchResult sr in src)
{
groups.Add(new AdGroup(sr.GetDirectoryEntry()));
}
}
}
}

return groups;
}

private DirectoryEntry OpenRootDSE()
{
return OpenEntry("rootDSE");
}

public static Int64 UnboxAdsiInt64(object ADsLargeInteger)
{
IADsLargeInteger val = (IADsLargeInteger)ADsLargeInteger;
Int64 res = ((Int64)val.HighPart <<>
Turns out I need one more post for this to discuss password expiration and policy. Then this huge class file will be uploaded for you to use!

October 1, 2009

Active Directory and C# V

Time to continue this series of posts on the domain side. You can download all the files from here. I will upload this file from this post this week. You can see the first post related to this class file here. This post refers to the sAMAccount, Groups and SID administration in AD.
 
public AdUser OpenUserBySAMAccountName(string userSAMAccountName, params string[] propsToLoad)
{
//usersearchpath from config
string rootPath = UsersSearchPath;
String filter = string.Format("(&(objectClass=user)(sAMAccountName={0}))", userSAMAccountName);

using (DirectoryEntry entry = OpenExistingEntry(rootPath))
{
if (entry == null)
throw new Exception(string.Format("Root to search user by SAMAccountName failed to open. {0}", rootPath));

using (DirectorySearcher searcher = new DirectorySearcher(entry, filter, propsToLoad))
{
SearchResult sr = searcher.FindOne();

if (sr == null)
return null;

return new AdUser(sr.GetDirectoryEntry());
}
}
}

public string GetSidPath(DirectoryEntry entry)
{
byte[] sidBytes = (byte[])entry.Properties["objectSid"][0];
SecurityIdentifier sid = new SecurityIdentifier(sidBytes, 0);
return string.Format("LDAP://", sid.ToString());
}

public List GetUserGroups(DirectoryEntry user)
{
List groups = new List();

//we are building an '|' clause
List sids = new List();
user.RefreshCache(new string[] { "tokenGroups" });
foreach (byte[] sid in user.Properties["tokenGroups"])
{
//append each member into the filter
sids.Add(string.Format("(objectSid={0})", BuildFilterOctetString(sid)));
}

if (sids.Count == 0)
return groups;

//end our initial filter
string filter = "(|" + string.Join("", sids.ToArray()) + ")";
//GroupsSearchPath from config
DirectoryEntry searchRoot = OpenEntry(GroupsSearchPath);
using (searchRoot)
{

//we now have our filter, we can just search for the groups
DirectorySearcher ds = new DirectorySearcher(
searchRoot,
filter
);

using (SearchResultCollection src = ds.FindAll())
{
foreach (SearchResult sr in src)
{
groups.Add((string)sr.Properties["samAccountName"][0]);
}
}
}

return groups;
}

private string BuildFilterOctetString(byte[] bytes)
{
StringBuilder sb = new StringBuilder();

for (int i = 0; i < bytes.Length; i++)
{
sb.AppendFormat("\\{0}", bytes[i].ToString("X2"));
}

return sb.ToString();
}


I'll upload this file tomorrow. This will make it a lot easier to follow.

September 29, 2009

Active Directory and C# IV

To continue this series of posts, I'd now like to talk about groups and my group helper class. It is actually quite simple and kind of looks just like the User helper. You can download all the files from here. I will upload this file from this post this week. You can see the first post related to this class file here. This post refers to the groups administration in AD.
  public AdGroup OpenGroup(string groupName)
{
if (groupName.IndexOf('=') != -1)
return OpenGroupByDN(groupName);
else
{
//GroupsSearchPath from config
if (string.IsNullOrEmpty(GroupsSearchPath))
throw new Exception("To search groups by SAMAccountName the PathToSearchForGroupsBySAMAcountName setting should be specified.");

return OpenGroupBySAMAccountName(groupName);
}
}

public AdGroup OpenGroupByDN(string groupDN)
{
DirectoryEntry entry = OpenExistingEntry(groupDN);

if (entry == null)
return null;

return new AdGroup(entry);
}

public AdGroup OpenGroupBySAMAccountName(string groupSAMAccountName)
{
//GroupsSearchPath from config
string rootPath = GroupsSearchPath;

String filter = string.Format("(&(objectClass=group)(sAMAccountName={0}))", groupSAMAccountName);
string[] propsToLoad = new string[0];

using (DirectoryEntry entry = OpenExistingEntry(rootPath))
{
if (entry == null)
throw new Exception(string.Format("Root to search groups by SAMAccountName failed to open. {0}", rootPath));

using (DirectorySearcher searcher = new DirectorySearcher(entry, filter, propsToLoad))
{
SearchResult sr = searcher.FindOne();

if (sr == null)
return null;

return new AdGroup(sr.GetDirectoryEntry());
}
}
}
I'll post one more time on this and also upload the file for you to download.

September 25, 2009

Active Directory and C# III

To continue this series of posts, I'd now like to talk about groups and my group helper class. It is actually quite simple and kind of looks just like the User helper. You can download all the files from here. I will upload this file from this post next week.

Before we get started, I wanted to tell you all that if you do any AD programming you should look at a book written by Joe Kaplan and Ryan Dunn . It is really the best book out there. The authors also have a site here for you to look at and a forum which is helpful. My next bit of code actually relies on code from their book. They have the code available on thei site and it can be found here. You can use the entire build or just some of the files. The main one for me was PasswordExpires (Listing 10.8, 10.9, & 10.10 in full). I use a few others in the root of their project as well ... it might be just easier to include their project. Go out and buy the book though...it is great!
using System;
using System.Collections.Generic;
using System.Text;
using System.DirectoryServices;
using System.Security.Principal;
using DotNetDevGuide.DirectoryServices;
using ActiveDs;
using DotNetDevGuide.DirectoryServices.Chapter10;

namespace AdLib
{
public class AdDomain
{
private const int ADS_UF_ACCOUNTDISABLE = 2;
private DomainPolicy _policy;

//UsersSearchPath can be from a config location
public void CreateUser(string userName, Dictionary props)
{
CreateUser(userName, UsersSearchPath, props);
}

public void CreateUser(string userName, string path, Dictionary props)
{
path = GetFullPath(path);

using (DirectoryEntry parent = OpenEntry(path))
{
DirectoryEntry user = parent.Children.Add(
String.Format("CN={0}", userName),
"user"
);

using (user)
{
// Set default props
user.Properties["sAMAccountName"].Add(userName);
user.CommitChanges();


// Set user defined props
foreach (string propName in props.Keys)
{
if (propName.ToLower() == "password")
continue;

user.Properties[propName].Add(props[propName]);
user.CommitChanges();
}

if (props.ContainsKey("password"))
((IADsUser)user.NativeObject).SetPassword((string)props["password"]);

user.CommitChanges();

EnableAccount(user);
}
}
}

private void EnableAccount(DirectoryEntry entry)
{
int userAccountControl = (int)entry.Properties["userAccountControl"][0];
userAccountControl &= ~ADS_UF_ACCOUNTDISABLE;
entry.Properties["userAccountControl"][0] = userAccountControl;
entry.CommitChanges();
}

//GroupsSearchPath can be from a config location
public void CreateGroup(string groupName, int type)
{
CreateGroup(groupName, type, GroupsSearchPath);
}

public void CreateGroup(string groupName, int type, string groupOU)
{
groupOU = GetFullPath(groupOU);

using (DirectoryEntry parent = OpenEntry(groupOU))
{
DirectoryEntry group = parent.Children.Add(
String.Format("CN={0}", groupName),
"group"
);

using (group)
{
group.Properties["sAMAccountName"].Add(groupName);

if(type != (int)GroupType.Unknown)
group.Properties["groupType"].Add(type);

group.CommitChanges();
}
}
}

private string GetFullPath(string subPath)
{
//server from config
if (string.IsNullOrEmpty(Server))
return string.Format("LDAP://{0}", subPath);
else
//server from config
return string.Format("LDAP://{0}/{1}", Server, subPath);
}

public DirectoryEntry OpenEntry(string path)
{
if (path.StartsWith("LDAP://", StringComparison.InvariantCultureIgnoreCase) == false)
{
path = GetFullPath(path);
}

return new DirectoryEntry(
path,
Username, //from config
Password, //from config
AuthenticationTypes.Secure
);
}
I'll finish this class up next week.

September 24, 2009

Active Directory and C# II

To continue this series of posts, I'd now like to talk about groups and my group helper class. It is actually quite simple and kind of looks just like the User helper. You can download all the files from here.
using System;
using System.Collections.Generic;
using System.Text;
using System.DirectoryServices;
using ActiveDs;

namespace AdLib
{
public class AdGroup : IDisposable
{
private DirectoryEntry _entry;
private IADsGroup _group;

public AdGroup(DirectoryEntry entry)
{
if (entry == null)
throw new ArgumentNullException("entry");

_entry = entry;
_group = (IADsGroup)entry.NativeObject;
}

public DirectoryEntry Entry
{
get { return _entry; }
}

public IADsGroup NativeObject
{
get { return _group; }
}

#region IDisposable Members

public void Dispose()
{
_entry.Dispose();
}

void IDisposable.Dispose()
{
Dispose();
}

#endregion
}
}
Of course, we would also need to understand what a GroupType in AD really is:
using System;
using System.Collections.Generic;
using System.Text;

namespace AdLib
{
[Flags]
public enum GroupType : int
{
Unknown = 0,
LocalDistribution = 4,
LocalSecurity = (4 | -2147483648),
GlobalDistribution = 2,
GlobalSecurity = (2 | -2147483648),
UniversalDistribution = 8,
UniversalSecurity = (8 | -2147483648)
}
}
In the next post, we will talk about domains and eventually how this all fits together.

September 23, 2009

Active Directory and C#

I have done a lot of work in the last few years with AD and C#. I figured now that I shared a whole bunch of AzMan stuff, it is only logical that I share some AD helper classes as well. Some of the code can of course be written differently now in the world of .NET 3.5. However, what is written is still relevant and works well. Like the AzMan posts, this will be a bunch of posts tied together to make an application. Unlike AzMan, this will be slower since there is a A LOT more in AD than in AzMan.

One thing that I'll point out is that I rely on ActiveDS more than DirectoryEntry....so for those against this, I am sorry :)

I'd like to start off with the AdUser class that I use from my AdLibrary which you can download from here:
using System;
using System.Collections.Generic;
using System.Text;
using ActiveDs;
using System.DirectoryServices;

namespace AdLib
{
public class AdUser : IDisposable
{
private DirectoryEntry _entry;
private IADsUser _user;

public AdUser(DirectoryEntry entry)
{
if (entry == null)
throw new ArgumentNullException("entry");

_entry = entry;
_user = (IADsUser)entry.NativeObject;
}

public DirectoryEntry Entry
{
get { return _entry; }
}

public IADsUser NativeObject
{
get { return _user; }
}

#region IDisposable Members

public void Dispose()
{
_entry.Dispose();
}

void IDisposable.Dispose()
{
Dispose();
}

#endregion
}
}
To be honest, not much can be done with this. However, combined with all the other classes in the upcoming posts you will see how it all ties together.

September 18, 2009

Using the AzMan Helper Classes VI

We have seen how to add a store,create an application, add an operation, add tasks, create roles, add application groups, and add users via SID or UPN to groups in AzMan using C#. All of these are available here.

Here is the sixth and final post regarding the usage of these helper classes:
public string[] GetApplicationGroupMemberNames(string storeUrl, string applicationName, string applicationGroupName)
{
IAzApplication app = ApplicationHelper.GetApplication(storeUrl, applicationName);
IAzApplicationGroup applicationGroup = ApplicationGroupHelper.GetApplicationGroup(app, applicationGroupName);
return ApplicationGroupHelper.GetApplicationGroupMemberNames(applicationGroup);
}


public bool IsApplicationGroupMemberNameExists(string storeUrl, string applicationName, string applicationGroupName, string memberName)
{
IAzApplication app = ApplicationHelper.GetApplication(storeUrl, applicationName);
IAzApplicationGroup applicationGroup = ApplicationGroupHelper.GetApplicationGroup(app, applicationGroupName);
return ApplicationGroupHelper.IsApplicationGroupMemberNameExists(applicationGroup, memberName);
}

//Get the SIDs
public string[] GetApplicationGroupMembers(string storeUrl, string applicationName, string applicationGroupName)
{
IAzApplication app = ApplicationHelper.GetApplication(storeUrl, applicationName);
IAzApplicationGroup applicationGroup = ApplicationGroupHelper.GetApplicationGroup(app, applicationGroupName);
return ApplicationGroupHelper.GetApplicationGroupMembers(applicationGroup);
}

public bool IsApplicationGroupMemberExists(string storeUrl, string applicationName, string applicationGroupName, string memberSID)
{
IAzApplication app = ApplicationHelper.GetApplication(storeUrl, applicationName);
IAzApplicationGroup applicationGroup = ApplicationGroupHelper.GetApplicationGroup(app, applicationGroupName);
return ApplicationGroupHelper.IsApplicationGroupMemberExists(applicationGroup, memberSID);
}


This concludes what is basically almost everything in AzMan via C#. In the upcoming weeks, I will move to show some more Active Directory code using C#.

September 17, 2009

Using the AzMan Helper Classes V

We have seen how to add a store,create an application, add an operation, add tasks, create roles, add application groups, and add users via SID or UPN to groups in AzMan using C#. All of these are available here.

Here is the fifth post regarding the usage of these helper classes:
 public void AddMemberToApplicationGroup(string storeUrl, string applicationName, string applicationGroupName, string memberSID)
{
IAzApplication app = ApplicationHelper.GetApplication(storeUrl, applicationName);
IAzApplicationGroup appGroup = ApplicationGroupHelper.GetApplicationGroup(app, applicationGroupName);
appGroup.AddMember(memberSID, null);
appGroup.Submit(0, null);
}

public void RemoveMemberFromApplicationGroup(string storeUrl, string applicationName, string applicationGroupName, string memberSID)
{
IAzApplication app = ApplicationHelper.GetApplication(storeUrl, applicationName);
IAzApplicationGroup appGroup = ApplicationGroupHelper.GetApplicationGroup(app, applicationGroupName);
appGroup.DeleteMember(memberSID, null);
appGroup.Submit(0, null);
}

public void AddMemberNameToApplicationGroup(string storeUrl, string applicationName, string applicationGroupName, string memberName)
{
IAzApplication app = ApplicationHelper.GetApplication(storeUrl, applicationName);
IAzApplicationGroup appGroup = ApplicationGroupHelper.GetApplicationGroup(app, applicationGroupName);
appGroup.AddMemberName(memberName, null);
appGroup.Submit(0, null);
}

public void RemoveMemberNameFromApplicationGroup(string storeUrl, string applicationName, string applicationGroupName, string memberName)
{
IAzApplication app = ApplicationHelper.GetApplication(storeUrl, applicationName);
IAzApplicationGroup appGroup = ApplicationGroupHelper.GetApplicationGroup(app, applicationGroupName);
appGroup.DeleteMemberName(memberName, null);
appGroup.Submit(0, null);
}

//Add Member to denied list
public void AddDeniedMemberToApplicationGroup(string storeUrl, string applicationName, string applicationGroupName, string memberSID)
{
IAzApplication app = ApplicationHelper.GetApplication(storeUrl, applicationName);
IAzApplicationGroup appGroup = ApplicationGroupHelper.GetApplicationGroup(app, applicationGroupName);
appGroup.AddNonMember(memberSID, null);
appGroup.Submit(0, null);
}

public void RemoveDeniedMemberFromApplicationGroup(string storeUrl, string applicationName, string applicationGroupName, string memberSID)
{
IAzApplication app = ApplicationHelper.GetApplication(storeUrl, applicationName);
IAzApplicationGroup appGroup = ApplicationGroupHelper.GetApplicationGroup(app, applicationGroupName);
appGroup.DeleteNonMember(memberSID, null);
appGroup.Submit(0, null);
}

public void AddDeniedMemberNameToApplicationGroup(string storeUrl, string applicationName, string applicationGroupName, string memberName)
{
IAzApplication app = ApplicationHelper.GetApplication(storeUrl, applicationName);
IAzApplicationGroup appGroup = ApplicationGroupHelper.GetApplicationGroup(app, applicationGroupName);
appGroup.AddNonMember(memberName, null);
appGroup.Submit(0, null);
}

public void RemoveDeniedMemberNameFromApplicationGroup(string storeUrl, string applicationName, string applicationGroupName, string memberName)
{
IAzApplication app = ApplicationHelper.GetApplication(storeUrl, applicationName);
IAzApplicationGroup appGroup = ApplicationGroupHelper.GetApplicationGroup(app, applicationGroupName);
appGroup.DeleteNonMemberName(memberName, null);
appGroup.Submit(0, null);
}