Cannot get properties of some groups in my AD - directoryservices

I am trying to retrieve all the email gruops and their mail address from company's AD system. I've got about 1800 groups but I've found there are about 20 gourps which I cannot get their properties. I tried in my outlook and got properties like mail address correctly. But I cannot get them by code, someone please help. Thanks. Below is my code snippet:
static void TestGroupEmails()
{
ICollection<DirectoryEntry> groups = GetGroups();
Console.WriteLine(groups.Count + "groups");
List<String> noNameGroups = new List<String>();
foreach (DirectoryEntry de in groups)
{
String name = de.Properties["sAMAccountName"].Value as String;
String email = de.Properties["mail"].Value as String;
if (String.IsNullOrEmpty(email))
noNameGroups.Add(name);
}
StreamWriter writer = new StreamWriter(#"C:\ad\group mails.txt");
noNameGroups.Sort();
foreach (String name in noNameGroups)
{
writer.WriteLine(name);
}
writer.Close();
Console.ReadLine();
}
public static List<DirectoryEntry> GetGroups()
{
String filter = #"(&(objectCategory=group))";
List<DirectoryEntry> groups = new List<DirectoryEntry>();
using (DirectoryEntry root = new DirectoryEntry(Constants.ADConnPrefix))
{
using (DirectorySearcher searcher = new DirectorySearcher(filter, null))
{
searcher.PageSize = 10000;
searcher.ReferralChasing = ReferralChasingOption.All;
searcher.SearchScope = SearchScope.Subtree;
searcher.SearchRoot = root;
root.Username = Constants.UserName;
root.Password = Constants.Password;
using (SearchResultCollection searchResult = searcher.FindAll())
{
foreach (SearchResult sr in searchResult)
{
DirectoryEntry de = sr.GetDirectoryEntry();
groups.Add(de);
}
}
}
}
return groups;
}
public static SearchResult GetGroupInfo(String groupName)
{
String normalName = Utility.RemoveLoginNamePrefix(groupName);
String filterFormat = "(&(objectCategory=group)(sAMAccountName={0}))";
using (SearchResultCollection searchResult = Search(ADConnPrefix, null, filterFormat, normalName))
{
int count = searchResult.Count;
SearchResult sr = searchResult[0];
return sr;
}
}

Are you certain the groups in question actually have email addresses? It is possible for groups in AD to not have them.
If you modify your search filter to (&(objectCategory=group)(mail=*)) it will filter out any groups that don't have email addresses.

Related

how we can return a status code for the serialized JSON object using Newtonsoft.net

I have this Action method which act as an API end point inside our ASP.NET MVC-5, where it search for a username and return the username Phone number and Department from Active Directory (we are serializing the object using Newtonsoft.net):-
public ActionResult UsersInfo2()
{
DomainContext result = new DomainContext();
try
{
// create LDAP connection object
DirectoryEntry myLdapConnection = createDirectoryEntry();
string ADServerName = System.Web.Configuration.WebConfigurationManager.AppSettings["ADServerName"];
string ADusername = System.Web.Configuration.WebConfigurationManager.AppSettings["ADUserName"];
string ADpassword = System.Web.Configuration.WebConfigurationManager.AppSettings["ADPassword"];
using (var context = new DirectoryEntry("LDAP://mydomain.com:389/DC=mydomain,DC=com", ADusername, ADpassword))
using (var search = new DirectorySearcher(context))
{
// create search object which operates on LDAP connection object
// and set search object to only find the user specified
// DirectorySearcher search = new DirectorySearcher(myLdapConnection);
// search.PropertiesToLoad.Add("telephoneNumber");
search.Filter = "(&(objectClass=user)(sAMAccountName=test.test))";
SearchResult r = search.FindOne();
ResultPropertyCollection fields = r.Properties;
foreach (String ldapField in fields.PropertyNames)
{
// cycle through objects in each field e.g. group membership
// (for many fields there will only be one object such as name)
string temp;
// foreach (Object myCollection in fields[ldapField])
// {
// temp = String.Format("{0,-20} : {1}",
// ldapField, myCollection.ToString());
if (ldapField.ToLower() == "telephonenumber")
{
foreach (Object myCollection in fields[ldapField])
{
result.Telephone = myCollection.ToString();
}
}
else if (ldapField.ToLower() == "department")
{
foreach (Object myCollection in fields[ldapField])
{
result.Department = myCollection.ToString();
}
}
// }
}
string output = JsonConvert.SerializeObject(result);
return Json(output,JsonRequestBehavior.AllowGet);
}
}
catch (Exception e)
{
Console.WriteLine("Exception caught:\n\n" + e.ToString());
}
return View(result);
}
now the return JSON will be as follow:-
"\"DisplayName\":null,\"Telephone\":\"123123\",\"Department\":\"IT\",\"Name\":null,\"SamAccountName\":null,\"DistinguishedName\":null,\"UserPrincipalName\":null}"
but in our case we need to return a status code beside the return json data. for example inccase there is an exception we need to return an error code,also if we are able to get the user's info we need to pass succes code 200, and so on.. so how we can achieve this?
you can try something like this
var statusCode=200;
string output = JsonConvert.SerializeObject( new { result = result, StatusCode = statusCode);
but nobody usually do this. When users call API they can check status code that HTTP Client returns, using code like this
var response = await client.GetAsync(api);
//or
var response = await client.PutAsJsonAsync(api, data);
var statusCode = response.StatusCode.ToString();
//or usually
if (response.IsSuccessStatusCode) {...}
else {...}

Reading a RSS feed using visual C#

I am trying to a read a RSS feed and display in my C# application. i have used the code below and it works perfectly for other RSS feeds. I want to read this RSS feed ---> http://ptwc.weather.gov/ptwc/feeds/ptwc_rss_indian.xml and the code below doesn't work for it. I don't get any errors but nothing happens, the text box which i want the RSS feed to be displayed is empty. Please help. What am I doing wrong?
public class RssNews
{
public string Title;
public string PublicationDate;
public string Description;
}
public class RssReader
{
public static List<RssNews> Read(string url)
{
var webResponse = WebRequest.Create(url).GetResponse();
if (webResponse == null)
return null;
var ds = new DataSet();
ds.ReadXml(webResponse.GetResponseStream());
var news = (from row in ds.Tables["item"].AsEnumerable()
select new RssNews
{
Title = row.Field<string>("title"),
PublicationDate = row.Field<string>("pubDate"),
Description = row.Field<string>("description")
}).ToList();
return news;
}
}
private string covertRss(string url)
{
var s = RssReader.Read(url);
StringBuilder sb = new StringBuilder();
foreach (RssNews rs in s)
{
sb.AppendLine(rs.Title);
sb.AppendLine(rs.PublicationDate);
sb.AppendLine(rs.Description);
}
return sb.ToString();
}
//Form Load code///
string readableRss;
readableRss = covertRss("http://ptwc.weather.gov/ptwc/feeds/ptwc_rss_indian.xml");
textBox5.Text = readableRss;
It seems that the DataSet.ReadXml method fails because there category is specified twice in the item, however under a different namespace.
This seems to work better:
public static List<RssNews> Read(string url)
{
var webClient = new WebClient();
string result = webClient.DownloadString(url);
XDocument document = XDocument.Parse(result);
return (from descendant in document.Descendants("item")
select new RssNews()
{
Description = descendant.Element("description").Value,
Title = descendant.Element("title").Value,
PublicationDate = descendant.Element("pubDate").Value
}).ToList();
}

getting contacts from gmail

I am retrieving contacts from gmail using Google Data API. I have used below code:
string token = Request.QueryString["token"];
RequestSettings rs = new RequestSettings("myapp", token);
rs.AutoPaging = true;
List<string> lstEmails = new List<string>();
try
{
rs.AutoPaging = true;
ContactsRequest cr = new ContactsRequest(rs);
Feed<Contact> f = cr.GetContacts();
foreach (Contact e in f.Entries)
{
foreach (EMail email in e.Emails)
{
lstEmails.Add(email.Address);
}
}
}
catch
{
}
But it reads only 25 gmail contacts only
and it throws the following error:
Execution Failed: {https://www.google.com/m8/feeds/contacts/{email}/full?start-index=26&max-results=25}
but i want to get total contacts from gmail.

send email from asp.net via gmail smtp

I have dedicated server. my IP was blocked with only yahoo, since first day. currently i nead 40000 email per day. i decided to create 400 Gmail account and send email from server via gmail smtp server (every gmail account limited to send email to 100 recipients).
the benefit of this solution is all email send to Inbox no SPAM!
what about u?
do you have any better solution?
do you know any better free email provider with lower limitation?
SmtpClient client = new SmtpClient();
This sounds exactly like a spam setup.
I suspect that's why you're blocked from yahoo.
I'm sure you are in violation of the Gmail terms of service. I'm sure they'll take less time to ban you than yahoo.
You're also missing the point of the 100 recipient limit entirely.
What would I do? Get out of the spam business.
You should register for a professional SMTP service, where they will batch-send your emails. Creating 400 emails account on gmail and access them with code? That sounds VERY un-manageable.
There are commersial websites that work with sending emails that you can integrate with, 40 000 emails per month is a lot of emails, I even think you violate some of googles terms of usage when you adapt this solution.
A normal SMTP service that you can purchase works like this:
You purchase an email-limit per day/year/month. 40 000 emails will probably be quite costly.
You integrate with the service with either a Web Service or other API's you DO NOT use SmtpClient ( in some cases you do, but normaly when you send 40 000 emails, that's a NO NO! ).
You use a template that you've set up in their system, hence, you do not send you own "html" from your code, you use a confirmed / verified template.
Another option is to create a SMTP sender yourself, that batches 40 000 emails during a long time period, but this might get you blacklisted as well.
I'm sure that setting up 400 GMail accounts to send, what sounds a lot like SPAM, is against their T&Cs and it's only a matter of time before they close you down as well.
I would suggest that if you have a legitimate need for sending 40000 emails per day that you sign up with a mail provider who specialises in bulk mailing.
See this for more info: Bulk Mail Sending On The Cheap
MailMessage EmailMsg = new MailMessage();
// EmailMsg.From = new MailAddress("yourmail", "dsd");
// EmailMsg.To.Add(new MailAddress(txtEmail.Text, "from plain text name"));
// EmailMsg.Body = txtMsg.Text;
// EmailMsg.IsBodyHtml = true;
// EmailMsg.Priority = MailPriority.Normal;
// SmtpClient mailClient = new SmtpClient();
// mailClient.Host = ("10.10.11.112");
// //mailClient.Credentials = new System.Net.NetworkCredential("yourmail", "pass");
// mailClient.EnableSsl = false;
// mailClient.Port = 25;
// mailClient.Send(EmailMsg);
i did it this way.Hope it will help you.
public class MailMgmt
{
private string _From = "asd#gmail.com";
private string _SMTPServer = "smtp.gmail.com";
private int _SMTPPort = "587";
private string _Password = "password";
private bool _EnableSSL = true;
private string _To = string.Empty;
private string _CC = string.Empty;
private string _BCC = string.Empty;
private string _Subject = string.Empty;
private string _Body = string.Empty;
private string _AttachmentFile = string.Empty;
public string From
{
get { return _From; }
set { _From = value; }
}
public string SMTPServer
{
get { return _SMTPServer; }
set { _SMTPServer = value; }
}
public int SMTPPort
{
get { return _SMTPPort; }
set { _SMTPPort = value; }
}
public string Password
{
get { return _Password; }
set { _Password = value; }
}
public bool EnableSSL
{
get { return _EnableSSL; }
set { _EnableSSL = value; }
}
public string To
{
get { return _To; }
set { _To = value.Trim(); }
}
public string CC
{
get { return _CC; }
set { _CC = value.Trim(); }
}
public string BCC
{
get { return _BCC; }
set { _BCC = value.Trim(); }
}
public string Subject
{
get { return _Subject; }
set { _Subject = value.Trim(); }
}
public string Body
{
get { return _Body; }
set { _Body = value.Trim(); }
}
public string AttachmentFile
{
get { return _AttachmentFile; }
set { _AttachmentFile = value.Trim(); }
}
public MailMgmt()
{
}
public void SendMail()
{
bool result = false;
MailMessage obj = new MailMessage();
try
{
string Expression = #"\w+([-+.']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*";
string[] StrSpl;
string[] StrSpl1;
obj.From = new MailAddress(_From);
if (_To != "")
{
StrSpl = _To.Split(',');
foreach (string Str in StrSpl)
{
if (Regex.IsMatch(Str, Expression))
{
obj.To.Add(Str);
}
}
}
if (_CC != "")
{
StrSpl = _CC.Split(',');
foreach (string Str in StrSpl)
{
if (Regex.IsMatch(Str, Expression))
{
obj.CC.Add(Str);
}
}
}
if (_BCC != "")
{
StrSpl = _BCC.Split(',');
foreach (string Str in StrSpl)
{
if (Regex.IsMatch(Str, Expression))
{
obj.Bcc.Add(Str);
}
}
}
if (_Subject != "")
{
obj.Subject = _Subject;
}
if (_Body != "")
{
obj.Body = _Body;
}
if (_AttachmentFile != string.Empty)
{
StrSpl1 = _AttachmentFile.Split(',');
foreach (string Str in StrSpl1)
{
Attachment at = new Attachment(Str);
obj.Attachments.Add(at);
}
}
obj.IsBodyHtml = true;
obj.Priority = MailPriority.High;
SmtpClient client = new SmtpClient(_SMTPServer, _SMTPPort);
client.EnableSsl = _EnableSSL;
System.Net.NetworkCredential SMTPUserInfo = new System.Net.NetworkCredential(_From, _Password);
client.UseDefaultCredentials = false;
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.Credentials = SMTPUserInfo;
client.Send(obj);
// return result = true;
}
catch (Exception ex)
{
//return result = false;
}
}
}
Use this class and send mail easily

Creating user in active directory

I'm gonna build a webpart for creating user in active directory .
For creating user account i use method like this :
public string CreateUserAccount(string ldapPath, string userName,
string userPassword)
{
try
{
string oGUID = string.Empty;
string connectionPrefix = "LDAP://" + ldapPath;
DirectoryEntry dirEntry = new DirectoryEntry(connectionPrefix);
DirectoryEntry newUser = dirEntry.Children.Add
("CN=" + userName, "user");
newUser.Properties["samAccountName"].Value = userName;
newUser.CommitChanges();
oGUID = newUser.Guid.ToString();
newUser.Invoke("SetPassword", new object[] { userPassword });
newUser.CommitChanges();
dirEntry.Close();
newUser.Close();
}
catch (System.DirectoryServices.DirectoryServicesCOMException E)
{
//DoSomethingwith --> E.Message.ToString();
}
return oGUID;
}
When executing this method the following error occurred:
"The server is not operational"
say we have active directory installed with domain TestDomain.com and you have a OU ( Organization Unit ) called USERS and you have a user in it called TestUser
so we can saye the following
ldapDomain: the fully qualified domain as TestDomain.com or dc=contoso,dc=com
objectPath: the fully qualified path to the object: CN=TestUser, OU=USERS, DC=TestDomain, DC=com
userDn: the distinguishedName of the user: CN=TestUser, OU=USERS, DC=TestDomain, DC=com
in creating user you should determine where you want to create by determining its path ( ldap path )
In our sample we can consider it as below :
string ldapPath = "LDAP://OU=USERS, DC=TestDomain, DC=com"
For more information check the following links :
http://www.selfadsi.org/ldap-path.htm
http://www.informit.com/articles/article.aspx?p=101405&seqNum=7
http://msdn.microsoft.com/en-us/library/system.directoryservices.directoryentry.path.aspx
Using System.DirectoryServices
To use this namespace you need to add reference System.DirectoryServices.dll
DirectoryEntry ouEntry = new DirectoryEntry("LDAP://OU=TestOU,DC=TestDomain,DC=local");
for (int i = 3; i < 6; i++)
{
try
{
DirectoryEntry childEntry = ouEntry.Children.Add("CN=TestUser" + i, "user");
childEntry.CommitChanges();
ouEntry.CommitChanges();
childEntry.Invoke("SetPassword", new object[] { "password" });
childEntry.CommitChanges();
}
catch (Exception ex)
{
}
}
Using System.DirectoryServices.AccountManagement
To use this namespace you need to add reference System.DirectoryServices.AccountManagement.dll
PrincipalContext ouContex = new PrincipalContext(ContextType.Domain, "TestDomain.local", "OU=TestOU,DC=TestDomain,DC=local");
for (int i = 0; i < 3; i++)
{
try
{
UserPrincipal up = new UserPrincipal(ouContex);
up.SamAccountName = "TestUser" + i;
up.SetPassword("password");
up.Enabled = true;
up.ExpirePasswordNow();
up.Save();
}
catch (Exception ex)
{
}
}

Resources