Administrative Template to Restrict Write Access to Removable Drives

Looking for a way to restrict access to removable drives in your domain on your workstations?  It's easier than you might think!  There is a registry setting you can set that will turn all removable drives into read-only devices.  This includes USB thumb drives, hard drives, and even CD/DVD writers.  Of course editing the registry is a pain in the butt if you have a domain with dozens or hundreds of workstations, so I created this Administrative Template for use in Group Policy to configure this setting for you. 

Unfortunately, Microsoft did not store these settings in the "true policy" locations of the registry, so in the GPEDIT.MSC you need to click on Administrative Templates, then select View -> Filtering...  Uncheck "Only show policy settings that can be fully managed."  This will allow you to see the "preferences."  (Policy settings that are not fully managed are called Preferences.)  You can google for more information on the differences between policies and preferences. 


Microsoft's explanation of Administrative Templates...

Link to the Remove Storage Device administrative template...


Recursively setting attributes on NTFS files in VB.NET made easy

One thing I love about the new VB.NET in Visual Studio 2005 is the “My” namespace, which offers tons of useful code for common tasks in a single easy to find namespace.  As good as the My.Computer.FileSystem namespace is, however, it is lacking a way to easily change attributes on files. 

I needed to recursively remove all Read-Only and Hidden attributes in a folder hierarchy in order to copy over (write over) those files using the My.Computer.FileSystem.CopyDirectory method.  This method will throw an exception if a file is marked as Read-Only.  So, I wrote the following code segment to remove the Read-Only and Hidden attributes for me.  Of course this can be easily modified to set other attributes too.

Public Sub RemoveReadOnlyAttributes(ByVal folder As String)
  ' Remove attribute on individual files
  For Each filename As String In My.Computer.FileSystem.GetFiles(folder)
    System.IO.File.SetAttributes(filename, IO.FileAttributes.Normal)

  ' Recursively call this routine on all subfolders
  For Each foldername As String In My.Computer.FileSystem.GetDirectories(folder)
End Sub


Changing the default Free/Busy status of an 'All day' appointment in Outlook 2003

When you create a new appointment in your calendar in Outlook 2003, by default 'All day' events show your time as 'free' and all other appointments show your time as 'busy.' Some employees at the company where I work wanted this behavior changed. Specifically, they wanted the 'All day' appointments to default to 'busy' because they schedule many meetings and other appointments that last all day and often forget to set the appointment as 'Busy' manually. This creates confusion when other employees go looking for them and they aren't in their office! I scowered Google, as I usually do when faced with tasks such as this, and could not find a nice short easy solution. Most sources (even some Outlook/Office MVPs) said there was NO way to do this (which is just not true). Others had you create custom forms, which is the answer. However, I couldn't find a custom form answer that wasn't unnecessarily LONG and difficult to implement.

So I toyed around and came up with a simple custom form that changes the behavior. Here's how you do it!

First, create your custom form, using the IPM.Appointment built-in form. If you don't know how to create a custom form, there are bazillions of good walk-throughs out there.  Google for it.

Second, add the following code in the Script Editor...

Sub Item_PropertyChange(ByVal Name)
    Select Case Name
        Case "AllDayEvent"
            BusyStatus = 2
    End Select
End Sub

THAT'S IT. Nothing more is required in the custom form! Publish the new form, then set the default calendar appointment form to the new one and voila!


Website Updates

I am currently in the process of converting the Avian Waves website from ASP to ASP.Net. In addition, the thoughts/links page has been transformed into a full-fledged blog (what you are looking at right now). Over the coming weeks, new features will gradually be added, and a new look (including the new Avian Waves logo) will start to appear. This is a large transition for me and Avian Waves, but will lay the foundation for the future of this website, my music, and the "business" side of Avian Waves.

News and notes will continue to be posted to this blog, comments can be posted by anybody, and an RSS feed is now available!

In order to keep an ongoing interest in my music, rants, tech tools, and everything else, I'm hoping this site can stay dynamic and compelling. Before you know it, I'll finally be done geeking out and I can get back into the studio and write music again. :-) It's been too long, but will be worth the wait.

The new Avian Waves website is combining together several of my personal projects into one: The music stuff, tech stuff, and anything else I can dream up!

The old website was table-based, using all the old techniques I learned in the 90s to format graphics and text for old browsers.  I adopted CSS only when it was a convenient way to make things look "right."  With the new website I am striving for 100% XHTML 2.0 compliance.  The main portions of the site will be compliant very soon (most already are).  The blog software (a customized version of Presstopia that I modified) will take longer to make compliant.  It is currently 100% XHTML 1.1/Transitional compliant (I think). 

Well that's all fine and dandy, but why go through the trouble?

I want the site to be styled completely using CSS so that the site's data can quickly and easily be "skinned."  Eventually, I will check how the site is being accessed and offer an optimized view depending on the device.  Increasingly, websites are being visited by phones and pocket devices, which can only implement a subset of layouts features that IE, Firefox, and Opera can.  Since the substance of the site will just be XHTML tags styled using CSS classes, reformatting the website for other devices is as simple as referencing a different style-sheet.  The easiest way for me to be flexible in the future is to strictly adopt XHTML 2.0 now. 

It is very interesting balancing the way styles are used to make things look "right" under all the different browsers.  I thought CSS replacing table-based layout was supposed to make that concern go away?  I suppose that's another rant for another day!

Avian Waves is also moving from an ASP site to an ASP.Net 2.0 site.  The reasons for this are pretty obvious: ASP.Net is faster, more robust, easier to code, and easier to debug!

Master pages are awesome...


VB.Net, P/Invoke, Windows Mobile 5.0 SDK, and ActiveSync

Update: I emailed Microsoft and they have acknowledged their KB was incorrect and have since corrected it.  Below is my original post, which I wrote shortly after discovering the typo in MS's KB on this subject.

If you are a Windows Mobile developer, you have probably noticed all the new whiz-bang new APIs in the 5.0 SDK. Many are available only to unmanaged calls (either from unmanaged C or P/Invoke from .Net). Most of the documentation is correct and helpful, but I noticed a problem when I was trying to P/Invoke the new API calls ActiveSyncStart and ActiveSyncStop when I was trying to write a teensy little app that needed to use these.

In MS's knowledgebase (which is located here), we see that ActiveSyncStart is defined in ActiveSync.h and references the library actsyncc.lib. The problem is that there is no actsyncc.lib in the SDK! Perhaps there was in one of the beta/CTPs -- I'm not sure. So when you create your P/Invoke call and reference actsyncc.dll, you are out of luck. I googled for help, but with no luck. I dug through the libs and finally found out where it actually is referenced, which is aygshell.lib (aygshell.dll).

Here are the P/Invoke declarations for the unmanaged function calls for use in VB.Net...

Private Declare Function ActiveSyncStart Lib "aygshell.dll" () As Integer

Private Declare Function ActiveSyncStop Lib "aygshell.dll" () As Integer

Obviously you need to change the definition a teeny bit to get it to work in C#.

So if you are writing managed code on Windows Mobile and, like me, frustratingly coudln't find out how to use the unmanaged API calls ActiveSyncStart and ActiveSyncStop, I hope this helps! :-)



Administrative Template for Configuring SCHANNEL

Windows' SChannel is the "service" that handles all the secure internet communications, such as PCT, SSL, and TLS.  Sometimes for security reasons, you may want to disable the older secure communication protocols, such as SSL 2.0.  SSL 3.0 has been in use for years now and enhances SSL 2.0, making it more cryptographically secure.  You may also want to disable PCT 1.0 since it's non-standard (although be careful with this as some built-in systems in windows, such as the Message Queue, rely on PCT).  Or perhaps you want to disable the newer protocols for compatibility reasons.  Who knows?

Before you would have to manually edit the registry on every affected machine.  So I created this Administrative Template for Group Policy to control these settings.  Unfortunately, Microsoft did not store these settings in the "true policy" locations of the registry, so in the GPEDIT.MSC you need to click on Administrative Templates, then select View -> Filtering...  Uncheck "Only show policy settings that can be fully managed."  This will allow you to see the "preferences."  (Policy settings that are not fully managed are called Preferences.)  You can google for more information on the differences between policies and preferences.

Anyway, this administrative template will be handy if you need to disable SSL 2.0 on a large array of web servers, for instance.  Or if you want to make sure that all outgoing communications are secure for workstations. 

Microsoft's explanation of Administrative Templates...

Link to the SCHANNEL.ADM administrative template...


Exchange 2003 SP2 Storage Limit Tool

Serivce Pack 2 for Exchange Server 2003 introduced some new configurable settings for information store database limits.  These limits used to be hard coded depending on the version of Exchange you were using.  Standard Edition was capped at 16GB and Enterprise Edition was capped at 8TB (which is the largest an Exchange Jet database can be).  After applying SP2, administrators can now set arbitrary limits to the sizes of their information stores.  Standard Edition users are still limited to one private and one public store, but can set both of them to a maximum size of 75GB!  It is not configured this way out of the box, however!

By default, post-SP2 Standard Edition servers have their information stores set to a maximum size of 18GB with a 10arning threshold.  This warning percentage replaces the "dies at 16GB, then set a registry tweak to give you 1GB more temporarily" way of dealing with the database cap previously.  The new way warns administrators via the event log 24 hours in advance that the warning threshold has been reached.  If no action is taken in that time period, the information store gracefully shuts down.  When everybody at your company cries that their email doesn't work, you can turn it back on for another 24 hours and clean up the space in the mean time.  However, if your store reaches it's hard limit, you are back to the old "registry tweak to get one more GB" scenario.  But at least you have new options and more time now.

If you have the hard drive space to increase your information store from 18GB to 75GB (or anything inbetween) you have to set a few registry values to make these changes.

I was bored, so I made a tool to do this for you.  Keep in mind that it tinkers with Information Store registry keys, so use it with caution and test it first, as you should any new piece of software before deploying it to production servers!!

Exchange 2003 Enterprise Edition users might find this useful too, should they want to cap their databases to fit within the constraints of their hard drive and create warning thresholds to keep it from potentially corrupting the database by reaching that limit of the hard drive.  Graceful shutdowns are your friend!  By default, Enterprise Edition has no limit set (other than the 8TB hard limit which is constrained by the fact that Exchange just can't handle a single information store larger than that).

Let me know if you use this tool!

Here is the link...



Bulk Local Administrator Password Management Tool

I manage a domain of about 70 Windows machines. About 30 are 2003 servers. The rest are XP workstations. Initially I disabled all the local built-in admins for security purposes using Group Policy, but then I ran into a trouble PC that couldn't communicate with the domain. Uh oh. What do I do now? Turns out the network card was bad, so when it was replaced, everything was fine. But since I had never logged onto that machine with a domain admin account before, there was no way for it to authenticate that I was a domain admin (no cached credentials for the domain admin account). The local admin was still disabled and there was basically no way to administer that machine. What if this happened and it wasn't the NIC? Heck if I'm going to reinstall Windows for an oversight like that!

So I re-enabled all the local admins using GPO again. I had every admin I ran into changed to the same password for a little while. But this is insecure too because what if that password is compromised? I'd have to walk around to every computer, or at least connect to every computer via Computer Management MMC, to reset the passwords. Ugh! Not fun.

So I looked around for a tool to automate this. The only solutions I could find involved writing startup scripts and implementing it through a GPO. This is bad for several reasons. (1) The new password is stored in plain text and transmitted in plain text over the network (or, at best, obfiscated somewhat, but not truly encrypted). (2) Startup scripts cannot be guaranteed to run. If the machine connects with a wireless card, the pre-logon state where startup scripts run may not have an active connection in time for it to run. This means that the script never executes, but the event log kindly tells you it didn't execute. Also, some people never reboot their machines. That's fine normally, but if you rely on a startup script and a mandatory reboot from Windows Update, this isn't a good solution.

So I created XS BAP. XS because that's the name of the company I work for and they signed my paycheck while I designed this happy tool. BAP is for Bulk Admin Password tool. This tool is currently freeware and is provided with no warranty. This tool is not open source, so don't ask for the source code. The licensing agreement on subsequent versions of this tool may change without notice.

XS BAP allows you to import or manually enter each computer you want to manage on your domain. You can then specify the administrative password you want to use, or use the random password feature and get a unique random complex password for every machine. You can then update all machines at once, or only selected machines. After updating the password, you can verify that the password works using the verification feature.

XS BAP requires the .Net Framework 1.1. XS BAP works by resetting the Administrator password to whatever you specify, so you do not need to know the old password of the adminsitrator ("reset password" method, as opposed to "change password" method). However, you do need to have local administrative access on every target machine. In a default Windows domain, Domain Admins have the appropriate level of access, so run this tool as a domain admin. I do not know how well this application scales, but I have used it on every machine in my domain at once. If you use it on a very large domain (hundreds or thousands of computers), let me know how it works! It will probably be slow, but hey... Slow and unattended is better than nothing!

You can save the data in an AES encrypted file (encrypted by supplying a password). This way when you need the password of that workstation you've never looked at before, just open the file and there it is! For additional security, I highly recommend also implementing EFS (NTFS's Encryption) on the saved password files. After all, compromise of the saved file will give an attacker the local passwords of every machine! Since the password file is symmetrically encrypted with a password, a brute force attack could theoretically, eventually, lead to a decrypted file. The encryption will certainly buy you time to change the passwords, should you ever discover that the password file was obtained by unauthorized personnel. But it is not hack-proof!

The interface "feels" like Microsoft Access since it uses the DataGrid control interface. The help file sucks, but well.. I'm a developer, not a tech writer. Maybe I'll add to it later! Hopefully it will be somewhat self-explanatory. If you have a question, post it to the blog here.

Known limitations: (1) If you import multiple domain controllers and modify the same account on each of them with a different password, the LAST password that was successfully "updated" is the current password. There is no feature to let you know if you are updating a local workstation/server SAM database or Active Directory through a domain controller. As a general rule, don't update domain controllers to save yourself hassle. (2) The verification process attempts to change the password to the same value to make sure the password works. This seems like a weird way to do it, but all the other logon methods I could find did not allow you authenticate to a remote machine's SAM in .Net. If somebody knows of a better way, let me know. Anyway, since local administrators are exempt from certain password policies (such as minimum age), this method should always work. However, I make no guarantees that the verification process will not say "Failed" but then work when you try it manually on the target machine. On the flip-side, though, if it says "Correct" it definitely works.

If you have any questions, comments, or suggestions, reply to this post!

Here is the link to the file:


At the time of this posting, there is only one version (1.0), and I will post to here when newer versions are released. I will probably keep a little bit of a history on the download server, but may not keep all the versions online. Haven't decided yet.

Let me know if you find this tool useful!


My tech oriented blog!

I'm mainly starting this blog to have a place to post Windows administrative tips I discover, post tools I've written, and to discuss with other Windows administrators administrativey things! I will also post other techy topics and hopefully people will visit, despite the gazillion other blogs out there... If somebody out there in the great vast ethos of the internet finds some of this stuff useful, I will be happy.

Update: This blog was moved from MySpace to my personal website on April 22, 2006. (Just FYI)


Misty Carroll Memorial Exhibit

Donations are being accepted for the Misty Rachelle Carroll Memorial Bird Flight Exhibit at the Riverbanks Zoo in Columbia, SC. The exhibit introduces visitors to a variety of birds, their lives and struggles in the wild, while entertaining the crowd with the birds flying through audience. It is an excellent exhibit which does a lot, in my opinion, at educating the average person about how incredible birds are. The memorial will add a stage, housing facility, and a new Macaw to the exhibit. The exhibit currently only shows birds of prey. I think the new Macaw will add balance since Macaws are very gentle vegetarians. I will post more details in the future. If you are interested in donating, you can send money to the Riverbanks Zoo in Misty's name. The donation is tax-deductible.

Avian Waves on Twitter Avian Waves on Facebook Avian Waves on Spotify

Recent Comments
  1. Re: DPM 2016 + SQL 2016 and "An unexpected error occurred during the installation" ID: 4387
    Camilo: Edward comment solved the issue! After installing the 16.5.3 (from the link provided and without uninstalling...
  2. Re: It's Coming Any Day Now...
    Tim: Awesome to hear. Can't wait to check it out.
  3. Re: RD Tabs Security Advisory - 2.0 and 2.1 Beta
    Roman: Hi admin having same materiel as i need. Also get some extra stuff here: [url="hit5k.com"]Patch Applications...
  4. Re: RD Tabs Security Advisory - 2.0 and 2.1 Beta
    Roman: Hi admin having same materiel as i need. Also get some extra stuff here: Patch Applications
  5. Re: 3.0 is coming...
    Sean: Great news, can't wait!
  6. Re: DPM 2016 + SQL 2016 and "An unexpected error occurred during the installation" ID: 4387
    Funny Guy: To add my 2 cents - after a day of fight it appears that DPM installation uses WMI queries to detect...
  7. Re: DPM 2016 + SQL 2016 and "An unexpected error occurred during the installation" ID: 4387
    Funny Guy: To add my 2 cents - after a day of fight it appears that DPM installation uses WMI queries to detect...
  8. Re: DPM 2016 + SQL 2016 and "An unexpected error occurred during the installation" ID: 4387
    Funny Guy: To add my 2 cents - after a day of fight it appears that DPM installation uses WMI queries to detect...
  9. Re: DPM 2016 + SQL 2016 and "An unexpected error occurred during the installation" ID: 4387
    kAM aCOSTA: Thanks Edward !!!
  10. Re: 3.0 is coming...
    Dave: Very Cool!