Jerald.Net

A little VB.Net, SQL, and whatever else comes to mind...
Welcome to Jerald.Net Sign in | Join | Help
in Search

Jerald .Net

  • VB.Net: Returning AD UserName from Multi-Domain Forrest

    Growth sometimes brings out the unexpected flaws in designs. What seems like a quick solution, may intern lead to what I have affectionately call 'Learning Opportunities'.After a recent expansion from a single domain environment to a multi-domain forest, the following VB.Net function ceased functioning for retrieving the user's full name.

    Public
    Shared Function GetADUserName() As String
        
    Dim returnString As String = String.Empty     
           
    If HttpContext.Current.User.Identity.IsAuthenticated Then            
                
    Try
                  
    Dim DomainUser As String = WindowsIdentity.GetCurrent.Name.Replace("\", "/")
                  
    Dim ADEntry As New DirectoryEntry("WinNT://" & DomainUser)
                   
    Dim FullName As String = ADEntry.Properties("FullName").Value

                   returnString = FullName.Substring(FullName.LastIndexOf(",") + 1)
                   
    returnString &=
    " " & FullName.Substring(0, FullName.LastIndexOf(","))
                Catch ex As Exception

               
    Finally

               
    End Try
          End If
         
    Return returnString
    End Function

    Doing some research resulted in the realization that the WinNT provider would only work correctly in a 'flat domain'. Some modifications to an existing application allowed for the following replacement utilizing the LDAP provider in the DirectoryServices library. The key is to enable Referral Chasing.

    Public Shared Function GetADUserName() As String
       Dim returnString As String = String.Empty        
         
    If HttpContext.Current.User.Identity.IsAuthenticated Then           
            
    Try                
                
    ' Set the root search path
                 Dim ldapPath As String = "LDAP://DC=MyDomain,DC=COM"     
                
    Dim entry As New DirectoryEntry(ldapPath)
                ' AppSettings holds username and password
                ' This allows the query to run outside the context of the impersonated user
                ' This user currently is delegated rights in AD               
               
    entry.Username = ConfigurationManager.AppSettings(
    "AdUser").ToString
                entry.Password = ConfigurationManager.AppSettings("ADPassword").ToString
                entry.AuthenticationType = AuthenticationTypes.Secure
               
               
    ' Retrieve the current user's ntid                
               
    Dim DomainUser As StringWindowsIdentity.GetCurrent.Name.Substring
                             (WindowsIdentity.GetCurrent.Name.LastIndexOf("\"))

               
    ' Set your filter
                Dim filter As String
                       
    String.Format("(&(objectClass=user)(sAMAccountName={0}))", DomainUser)
                Dim searcher As New DirectorySearcher(entry, filter, New String() {"displayName"})

               ' Allow searches to span multiple domain referrals
               searcher.ReferralChasing = ReferralChasingOption.All
               Dim result As SearchResult = searcher.FindOne()

              If Not IsNothing(result) Then
                 'Verify the property was returned
                 If (result.Properties.Contains("displayName")) Then
                    returnString = result.Properties("displayName")(0)
                 End If
              End If
           Catch ex As Exception
               'Some error handling here
           Finally
      
          
    End Try
       End If
       
       Return
    returnString
    End Function
  • Migrating to Community Server 2007

    I have finally decided to take my server down at home and conserve the resources (primarily electricity). In doing so I went looking for a blogging engine that would allow me to continue on, without reinventing the wheel.

    Criteria:

    1. Feature rich
    2. ASP.Net / SQL based
    3. Customizable

    In the end I decided to go with telligent's Community Server 2007. Provides me with two of the features I already had (blogging and photo galleries) and more.

    Posted Jun 18 2007, 08:01 PM by admin with no comments
    Filed under:
  • More LDAP Queries

    In continuing to audit a network, the number of accounts in Active Directory did not match employee records, nor previous asset records.

    While using the interval variable for lastLogonTimeStamp will find accounts that have not logged on in a specific time period, it will not find accounts which have never logged on. The following queries will find them:

    • (&(objectCategory=Computer)(!lastLogonTimeStamp=*)(!userAccountControl:1.2.840.113556.1.4.803:=2))
    • (&(objectCategory=User)(!lastLogonTimeStamp=*)(!userAccountControl:1.2.840.113556.1.4.803:=2))

     

  • LDAP to find users with Remote Access Privileges

    We have all been in the position where we have started a new job with an existing organization where security was somewhat lax. Inevitably during the process of locking the network down you have to deal with the VPN / Dial-up access problem.

    The first step is to determine who already has access. This is fairly easy to accomplish using LDAP filters.

    • (&(objectCategory=person)(objectClass=user)(msNPAllowDialin=TRUE))

    This filter will show you all of the user accounts that have Allow Access checked for Remote Access on the Dialin Tab of the ADUC MMC.

     

  • MS ExMerge error 0x8004011d

    When trying to export a mailbox to a PST, I received the following error in ExMerge :

    Error opening message store (MSEMS). Verify that the Microsoft Exchange Information Store service is running and that you have the correct permissions to log on. (0x8004011d)

    I verified the account I was using to export the mailbox had full control over the database per http://www.microsoft.com/technet/prodtechnol/exchange/guides/UseE2k3RecStorGrps/1ed0d5af-7dff-4cc3-9a05-f46d292ac5f4.mspx. This did not seem to help.

    What I finally ended up doing to resolve the problem was detaching the mailbox from the user account and reattaching it. (Remove Exchange Attributes) For some reason this seemed to work.

    Update:
    I have also discovered this will happen when trying to export the mailbox on an account that is disabled. If your security policy allows, enable the account to export mailbox.

     

  • Exchange 2003 Query Based Distribution Lists

    This week I was faced with finding a way to clean up a few of the query based distribution lists that were created by a previous consultant group. The major problem with the queries is that they didn't take into account the dynamics of organizational turn over. The query based DL's were configured to send to every object that had an email address in that exchange store for each OU. This meant that NDR's (Non Deliverable Reciepts) were being sent for every disabled account in those OU's.

    Without addressing the business rules of user account retention, I adjusted the LDAP filters to check the disabled flag on the userAccountControl. Now the queries will only send email to active accounts.

    • Global All Users Distribution List
      (&(&(&(&(mailnickname=*)(|(&(objectCategory=person)(objectClass=user)(!userAccountControl:1.2.840.113556.1.4.803:=2)(|(homeMDB=*)(msExchHomeServerName=*))))))))

     

  • Active Directory Custom Filters

    Over the last month I have been working more intensely with Windows 2003 Active Directory. In this process I have found the need to create custom filters to make finding objects and updating security policies easier. So thought it would be helpful to others to share my set of custom filters.

    To use these filters you need to open the ADUC snap in and right click on Saved Queries. Select 'New' then 'Query'. Click the 'Define Query' button. A new window will open. In the Find drop down menu, choose 'Custom Search', and click the 'Advanced' tab. Paste the query into the textbox and select 'OK'. Now you can give your query a name and click 'OK' again. You should immediately see the results of your query in the right hand window portion of the snap in.

    User Management
    • Locked out Accounts
      (&(objectCategory=person)(objectClass=user)(lockoutTime:1.2.840.113556.1.4.804:=4294967295)(&(objectCategory=person)(objectClass=user)(!userAccountControl:1.2.840.113556.1.4.803:=2)))
    • All Contacts
      (&(objectClass=contact))
    • All Users
      (&(objectCategory=User)(!userAccountControl:1.2.840.113556.1.4.803:=2)(!objectClass=Contact))
    • Disabled User Accounts
      (&(objectCategory=User)(userAccountControl:1.2.840.113556.1.4.803:=2))
    • Account Passwords Never Expire
      (&(objectCategory=User)(userAccountControl:1.2.840.113556.1.4.803:=65536))
    • User Accounts Inactive for 60 Days
      (&(&(objectCategory=User)(lastLogonTimeStamp<=XXX)(!userAccountControl:1.2.840.113556.1.4.803:=2)))

      This filter requires a bit of massaging to get it to work correctly. I modified a vbscript to produce the correct number of 100 nanosecond intervals between January 1, 1601 and 60 days prior to the current date. I found the script; however, I can not remember to whom the credit should be long. The Get_60_Day_Interval.vbs script will respond with a message box with the correct long integer you need. You will then need to replace XXXX in the filter with that number (e.g. 127578167790000000). 
      Dim dtmDate, dbl100NanoSecs Const MAXIMUM_PASSWORD_AGE = 60 dtmDate = DateAdd("d", -MAXIMUM_PASSWORD_AGE, Now()) dbl100NanoSecs = 10000000 * (DateDiff("s", "1/1/1601", dtmDate)) dbl100NanoSecs = FormatNumber(dbl100NanoSecs, 0, False, False ,0) WScript.Echo ("Value for query = " & dbl100NanoSecs)
      Get_60_Day_Interval.vbs
    Computer Management
    • Disabled Computer Accounts
      (&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=2))
    • All Computer Accounts
      (&(objectCategory=computer)(name=*))
    • Windows XP Computers
      (&(sAMAccountType=805306369)(objectCategory=computer)(operatingSystem=Windows XP*))
    • Windows Server 2003
      (&(sAMAccountType=805306369)(objectCategory=computer)(operatingSystem=*Server 2003))
    • Windows 2000 Server
      (&(sAMAccountType=805306369)(objectCategory=computer)(operatingSystem=Server 2000*))
    • Windows NT
      (&(sAMAccountType=805306369)(objectCategory=computer)(operatingSystem=Windows NT*))
    • Windows 2000
      (&(sAMAccountType=805306369)(objectCategory=computer)(operatingSystem=Windows 2000*))
    • Windows Server 2003 no Service Packs
      (&(sAMAccountType=805306369)(objectCategory=computer)(operatingSystem=*Server 2003)(!operatingSystemServicePack=*))
    • Windows XP no Service Packs
      (&(sAMAccountType=805306369)(objectCategory=computer)(operatingSystem=Windows XP*)(!operatingSystemServicePack=*))
    • Windows 2000 no Service Packs
      (&(sAMAccountType=805306369)(objectCategory=computer)(operatingSystem=Windows 2000*)(!operatingSystemServicePack=*))
    • Computer Accounts Inactive for 60 Days
      (&(objectCategory=Computer)(lastLogonTimeStamp<=XXXX)(!userAccountControl:1.2.840.113556.1.4.803:=2))

      Again this filter uses the Get_60_Day_Interval.vbs script. You will then need to replace XXXX in the filter with that number (e.g. 127578167790000000)
    Group Management
    • All Distribution Groups
      (&(objectCategory=group)(sAMAccountType=268435457))
    • Mail Enabled Groups
      (&(objectCategory=group)(mail=*)(!sAMAccountType=268435457))
    • All Empty Groups
      (&(&(|(&(objectCategory=person)(objectSid=*)(!samAccountType:1.2.840.113556.1.4.804:=3))(&(objectCategory=person)(!objectSid=*))(&(objectCategory=group)(groupType:1.2.840.113556.1.4.804:=14)))(objectCategory=group)(!member=*)))

     

  • It has arrived!

    I received my copy of Visual Studio 2005 Team Suite, Team Foundation Server, and SQL Server 2005 Developer Edition.

    I was considering just upgrading everything this weekend... but I am taking a class in C# this summer. So... here come the virtual machines.

    More on these when I get then installed.

  • Windows Server 2003 SP1

    A couple of weeks ago I decided I would jump ahead and install SP1. Being the technically savvy person I am, I also decided to forgo the practice of reading before installing.

    Everything was working fine for approximately one week. And for no apparent reason known to me, my server lost all connectivity. I couldn't even ping it. So I logged into the console and much to my surprise I couldn't even ping my gateway from the server. Of course I checked the network cable. Rebooted my switch. Still nothing.

    Thanks to Google, I found out that there were some serious changes to security in SP1. After about 6 hours of wrestling with Exchange, SQL, and all the other applications I had running on the server, everything was working again. Did I mention I had to turn off Windows Firewall and re-enable it for the settings to take? Didn't think so.

    So about 4 AM this morning (I guess 4AM because that was the last email I received), something happened and my server lost Internet connectivity again. I was at work before I knew this though. So when I got home I started going through the normal troubleshooting... network cable, nic, Ipconfig... and nothing stood out. I could ping with no problem. So I checked the Windows Firewall and the Security Config Wizard to see if I missed something. Nada.

    About 4 hours of off and on troubleshooting, I took a look back at the ipconfig /all and saw there were two IP's. One for each NIC. One was supposed to be disabled. It was on, and had an IP... even though it had no cable plugged in. Weird I though... checked the Nic setting and there staring me in the face was my answer. Microsoft Network Load Balancing was enabled.

    This wrecked havoc on my AD, DNS, and DHCP. Not to mention SQL and Exchange were flipping out as well. So I disabled NLBS, and went about fixing AD, DNS, and DHCP. Once internal name resolution was working again, SQL and Exchange stopped throwing errors.

    Sometimes what seems like a perfectly good idea, in the end comes back to haunt you.

  • The Waiting Game

    I ordered my copy of Visual Studio 2005 Beta 2 weeks ago. Apparently I ordered it at the wrong time. It has been on Back Order since then.

    Today though I received an overly formal email letting me know that my copy had shipped and would arrive in 2-3 weeks. What method of shipping takes 2-3 weeks? And from where is it coming?

    I am looking forward to getting it. I have Visual Studio 2002 which I purchased from school and there are some road blocks I have run into in developing my website. I just have to figure out the impact using 2005 with the 2.0 FrameWork will have on my webserver.

    Up next is the SQL 2005 release!

     

  • Windows Longhorn build 5048 with Virtual Server 2005

    After some dedicated research, I was able figure out how to install the new build of Longhorn as a Windows Virtual Server guest OS. The trick is in that you have to partition the virtual hard drive first, as Longhorn does not recognize RAW drives.

    To do this, I downloaded a copy of the Windows ME boot disk from http://www.bootdisk.com/ and extracted the image using WinRar. I then changed the file extension from .IMA to .VFD which is the virtual floppy drive extension used by Virtual Server. I created an 8GB virtual hard drive, and I booted the guest OS. The Windows ME virtual floppy mounted and I ran fdisk creating a single primary partition on the virtual hard drive. Now you can turn off the guest OS, but make sure to unmount the virtual floppy drive.

    The Longhorn install process should run as normal now.

    While I have not had the chance to fully explore the OS, I like the changes to the interface. As I explore some more, I will keep you posted!

    Jerald's Custom Longhorn build 5048 CD Cover

    Jerald's custom Longhorn build 5048 CD cover image

     

    Posted Apr 29 2005, 05:12 PM by Jerald with no comments
    Filed under:
  • Dynamic Page Titles for ASP.Net

    I was wondering if there was a clean way to programatically control the page title in ASP.Net. This is helpful with search engine optimizing techniques. I found a few examples across the web. I tried out a couple and to me, this solution seemed to be a very efficient way to handle the problem.

    In the HTML remove the existing <title></title> tags and replace it with the following:

    <asp:PlaceHolder id="titlePlaceHolder" runat="server" />

    In the Code Behind add the following code:

    PageTitle= new System.Web.UI.HtmlControls.HtmlGenericControl("title");
    titlePlaceHolder.Controls.Add(PageTitle);
    PageTitle.InnerHtml="Some programatically generated information";

    Additionally if you have a large number of dynamic pages, adding the Code Behind to each page would be time consuming. By adding it to a User Control like a site navigation control, you minimize the additions for code.

     

    Posted Apr 29 2005, 12:47 AM by Jerald with no comments
    Filed under:
  • Determining Day Lights Savings for Time Zones in ASP.Net

    I needed to determine what the real TimeZone (CST vs CDT) was for my blog application. So here is what I came up with:

    // instantiate a DateTime Object
    DateTime dT = DateTime.Now;

    // create a string to hold the full date and time
    string pubDate = dT.ToLongDateString() + " " + dT.ToShortTimeString();

    // determine if daylights savings and add the appropriate TimeZone
    if(TimeZone.CurrentTimeZone.IsDaylightSavingTime(dT))
    {
     pubDate += " CDT";
    }

    else
    {
     pubDate += " CST";
    }

    Granted I am really cheating and not using the full capabilities of the DateTime Class. But time is of the essence and I needed working code without a lot of testing to get the "right code".

    Posted Apr 11 2005, 11:34 PM by Jerald with no comments
    Filed under:
  • Awesome Photo Gallery

    Looking for an easy to configure and low maintenance .Net Photo Gallery web control? Wow did I find one! I highly recommend the Image Gallery from Rebex.

    • Easy to use
    • Design-time support and an integration with Visual Studio.NET
    • Thumbnails generated at the first access
    • Image description in XML file
    • Templates and CSS styles for a visual appearance
    • Sorting and paging

    The absolute best thing about this web control is that you just create a sub-folder and drop your images in. Add a reference to their DLL, add the control to your toolbar. Then edit the gallery.xml file to describe your folders and you are done. Compile your Project and its smooth sailing.

    One problem I have run across so far is that once an image is in the directory, I had to stop the WWW service to delete it. Stopping the individual website didn't seem to do the trick. I am sure they have a way around this, I just wasn't able to find it  in the documentation.

    Download the Rebex Image Gallery.
    See the samples on the Rebex website.

     

    Posted Apr 06 2005, 01:14 AM by Jerald with no comments
    Filed under:
  • GoogleControls for Asp.Net

    While I have not tested this http://www.pagebox.net/GoogleControl/google-internals.html, it does look very interesting.

    Posted Apr 02 2005, 01:37 AM by Jerald with no comments
    Filed under:
Powered by Community Server (Commercial Edition), by Telligent Systems