narrow default width wide
colour style colour style colour style colour style

Great article on SMS boundaries

I was trying to explain how SMS boundaries work to my current client after they ran into some issues due to some misconfiguration when I found this article from Technet Magazine. It is short and sweet and goes over just about everything you need to know on what seems to be a very misunderstood part of SMS.

Documenting OU structure

We have some consultants coming in to assist with a MetaDirectory project that is going on at my current client and they asked me for some information--they wanted some documentation of our OU structure. I figured I already had something in place to document something as simple as this but, alas, I did not. So, I googled around for a freeware utility or script and I couldn't really find anything. I think DSRazor and a couple of other commercial tools would do it but I was disappointed and surprised that I didn't find anything free. 

So, should I write the code from scratch or steal from wherever I can?? Hmmm...easy decision there. I remembered working with the scripts included with the GPMC (Group Policy Management Console) and thought there might be something in there I could use. Jackpot!

"ListSOMPolicyTree.wsf" does what I need (and a bit more--I don't care about GPOs right now, just OUs). So, I just made a copy of the file and commented out lines 72-88 and 204-240. I also updated the text that is displayed via line 66 to ""=== OU structure for domain " instead of ""=== GPO Links for domain ".

Presto magic, we have a nice looking export of the OU structure for the domain.

=== OU structure for domain ===
   OU=Domain Controllers
   OU=EMC Celerra
   OU=Management Workstations
   OU=Policy Free OU
               OU=MLCL Computers
                  OU=MLCL Acquisition Workstations
                  OU=MLCL Review Workstations
               OU=MLCL Server
               OU=MLCL Software Groups
               OU=MLCL Software Only
               OU=MLCL Users
      OU=Citrix Servers
      OU=Citrix Servers - Show Desktop
      OU=Citrix Test Servers
      OU=IAS Servers
      OU=IC Servers
      OU=SIS Servers
      OU=SIS Test Servers

Fixed an annoying problem with running out of GDI Objects

I've had a problem with my desktop for a while now..It appeared that I was running out of resources and I kept having to close apps down in order to open up new windows or access menu items. This was happening even though I still had tons of free available memory. I tried running some memory cleanup tools, changing my pagefile settings (smaller/bigger, fixed size/let windows handle it, etc). Unfortunately, nothing fixed my problem. As a side note, I've run into this before occasionally but lately it has been horrible. It really seemed to get worse when I installed IE7 although I did have the issue a few times when I used FireFox.

Anyway, today I was trying to help someone out with a scripting issue and I kept having to close the windows I needed open. I was finally fed up. I needed to fix this problem or rebuild my system.

Thankfully, I think I found the fix. It has to do with running out of 'GDI Objects'. I opened up Task Manager and added the column so I could view GDI Objects and was not surprised at all to see the my IE processes were using up more than anything else. I usually keep 3-4 separate IE processes running and have 3-5 tabs open in each of them. Now, I don't really care that IE is using them..I just want to run my freaking applications. (Here's a link to someone more knowledgable than I complaining about IE7's usage of GDI objects though). It's a shame to have all of this memory if Windows only puts a small amount of it into a critical area. Thankfully there is a hotfix and a reghack to help with the problem. The hotfix is just to help with a specific problem with Themes in Windows. I went ahead and installed it but that doesn't really fix my problem. I need to increase the amount of memory available for these troublesome GDI Objects.

The reghack details how to go about changing the settings. It affects more than just GDI Objects, it affects the "Desktop Heap". I don't know exactly what that is nor do I care at the moment.

Anyway, I ended up changing my settings from:

Windows SharedSection=1024,3072,512


Windows SharedSection=1024,8192,2048

I went ahead and opened up 5 separate IE processes with 7-8 tabs each, MOM admin, MOM operator, ADSIEdit, AD MMC, GPMC, PrimalScript, Lotus Notes, etc and I am running without any problems at all.

My question is this, what's the point of having all of this RAM if you still can't open up all of the stuff you want to? Maybe Microsoft needs to re-think the default settings for that registry entry now that people have more RAM in their systems. Or at least give you an easier way to change it like they've done with the 'performance' options that you can choose from in a number of Control Panel applets.

EDIT: I couldn't be happier! I can open up as much as I want to now! Also, I was just explaining my joy at fixing this problem to a co-worker and he mentioned that a new clinical application that my current client is starting to implement seems to eat up GDI resources as well. The problem is so bad that they install a special GDI Object monitor to let you know when you are close to running out of them. Once again, I ask the question, why not just increase how many are available?!?!?  Maybe there is a downside to the reg changes I made...I guess I'll find out eventually if there is. Unfortunately, there are a ton of web sites that talk about monitoring GDI objects and how to prevent leaks but there doesn't seem to be a lot of information on making a change like the one that I did.

EDIT #2 - I found a nice article that describes it a lot better. I just had to start searching for "Desktop Heap" instead of "GDI Objects" and I found some pretty good resources. There is a link to a good forum thread at the end of the 3rd page of the article discussing this issue a bit further as well. Apparently there shouldn't be any real negative affects to my change. Apparently you can adjust the total size of the Desktop Heap from the default of 48 MB using the following reg value:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\SessionViewSize

I have no need to mess with that since I just care about my XP desktop but it is handy information to know in case I run into anything like this again.

Determining date format/regional settings in .Net

I've looked for ways to do this for the longest time and I must say I was surprised that no one had a good way. All of the solutions I found were extremely complicated and didn't work all of the time.

Basically, my problem was that I had some date string that was formatted in a specific way (yyyymmddHHMMSS.mmmmmm) and I needed to be able to work with that date. I needed to convert that to a valid date variable type so I could do some date math (it was just a string data type). That would be easy but I need it to work internationally so I can't just parse the string and do a:

strDate = mm & "-" & dd & "-" & yyyy

If I do that on a system that has its regional settings set to something that expects dd-mm-yyyy I will be working with the wrong date, right? I've had this idea in my head for a while but just hadn't gotten around to testing it. It seems to work great though so I figured I would share it.

Basically, I am just converting a specific date that uses the WORD for the month to a string. Then, I just do some string processing to figure out whether the first 2 characters are for the month or for the day.

Obviously, first I have to get each individual part out:

Dim yyyy As String : yyyy = WMITime.Substring(0, 4)
Dim mm As String : mm = Mid(WMITime, 5, 2) 'Month
Dim dd As String : dd = Mid(WMITime, 7, 2) 'Day
Dim hh As String : hh = Mid(WMITime, 9, 2) 'hour
Dim mn As String : mn = Mid(WMITime, 11, 2) 'minutes
Dim ss As String : ss = Mid(WMITime, 13, 2) 'seconds

Here's the good stuff!

 Dim dtmTestDate As Date : dtmTestDate = CDate("January 5, 2000")
 Dim strTestDate As String : strTestDate = dtmTestDate.ToShortDateString
 WriteLogEntry(vbTab & "Testdate: " & strTestDate, 1)
Select Case True
 Case strTestDate.Substring(0, 2) = "05" Or strTestDate.Substring(0, 1) = "5" ' Non-US
  strDateFormat = "NonUS"
 Case strTestDate.Substring(0, 2) = "01" Or strTestDate.Substring(0, 1) = "1" ' US
  strDateFormat = "US"
 Case Else
  strDateFormat = "UNKNOWN"
End Select
Catch ex As Exception
 Call ErrorHandler("ERROR: Cannot determine date format settings", Err, ex)
End Try

I needed to work with the dates multiple times in a loop of code somewhere else. That's why I didn't just set my dates once in the code above. I just figured out what the date format was so I could do what I needed with it in my loop.

Select Case strDateFormat
 Case "US"
  strDate = mm & "-" & dd & "-" & yyyy
 Case "NonUS"
  strDate = dd & "-" & mm & "-" & yyyy
 Case Else
End Select

Then, I combine that with the time (the format doesn't change for this if you have different regional settings--at least as far as I know)

Dim strTime As String = hh & ":" & mn & ":" & ss
CDate(strDate & " " & strTime)

Ta-da! I can now get the correct date regardless of the regional settings that it is running on. This means I don't have to maintain two separate versions depending on where the software will be used.

Last Active tab focus in IE7

I ran across a tip to day to get my tabs working (closer to) the way I want them to. I'm loving IE7 but I miss the flexibility in tab management that FireFox has via extensions. My biggest complaint is that the tab focus doesn't change back to the previous tab that I had opened whenever I close a tab. I do lot's of techie research when I am trying to find solutions and often that involves doing a search and then opening up a bunch of windows in new tabs. But, if I don't want to keep a particular new tab open, it sends me to the tab to the right of the one I closed instead of the last active tab. Or, if the new tab is the one furthest right, tab focus goes to the tab that as next to it.

I was going to submit a feature request on the Microsoft feedback site but it appears I don't need to. They really need to change where this option is set at (move it to the Tabs settings page) but at least it is there!

I can't link to the tip because it was posted as a workaround by someone on the MS Feedback site.

Entered by yOlt on 5/18/2006

You can configure it working like you expected it to work. This option is just hidden very well.

1. Open tools menu in from Internet Explorer window, choose Internet Options...
2. Go to advanced tab, there will be anvanced settings.
3.Under Browsing you will find "Use Most recent order when switching tabswith Ctrl+Tab (3rd last option). Check it and it will work like you wanted although it wont directly say it.

My opinion is that this option should be under tab options. And the text should be changed in that case to something else for easier to understand.

EDIT: This link had the info all along. Like the option itself, it just isn't explained very well.

VBS - Sorting a dictionary object

All of the examples that I found on the internet were WAY too complicated and hard to follow. Here is a very simple dictionary sort function that I figured I would share.

Function SortDict(ByVal objDict)
 'Call using "Set objDictSorted = SortDict(objDict)"
 Dim i, j, temp
 For Each i In objDict
  For Each j In objDict
   If(objDict.Item(i) <= objDict.Item(j)) Then
    temp = objDict.Item(i)
    objDict.Item(i) = objDict.Item(j)
    objDict.Item(j) = temp
   End If
 'For Each i In objDict
 ' WScript.Echo objDict.Item(i)

 Set SortDict = objDict
End Function