One of my peer departments is working on spamming the corporation. This internal spam, aka Corporate Newsletter, is to go out to everyone with a mailbox in the corporation. Unfortunately, a number of these people have abused their rights and their mailboxes are limited to receiving e-mail from only their managers.
In Exchange 5.5, you could create a simple CSV file and run the Admin tool to gather this information. Unfortunately, in Exchange 2003, mailbox settings are now integrated into Active Directory (AD). AD maintains all the mailbox information and settings, whereas the Exchange Admin tool is simply for server management (mail routing and global limits, etc.).
Then, how do you gather this information? I being the lazy, programmer-at-heart, that I am, wrote a VBScript to export the information. This worked great as I could set variables in the script to export the information I needed. This only worked for about a month, as I wanted pass this tool along to the internal employee for use (no way I was going to run this each time someone new was hired!!). That's why I put an HTA front-end on it!
To Use The Script
Select Case statement to include each of the OU's.
NOTE: We have set Custom Attribute 1 (aka ExtensionAttribute1) to a value (1, 2 or 3) for group or resource mailboxes. For example, the Postmaster mailbox has a value of 1,Conference rooms have a value of 2. Line 121 of the code is designed to filter on these values. Remove the line completely to get all mailboxes, or modify it for your environment.
Update August 16, 2007: I've modified the code to query the local AD for it's structure, so the above modifications are not necessary. After I made the changes, it started timing out when running the query, which shouldn't be related to the script changes. I suspect slowness in my AD.
| Attachment | Size |
|---|---|
| User Export Report.zip | 3.72 KB |
| User Export Report 2.zip | 4.7 KB |
The company I am working for has a slightly different security model than I've seen before. It is probably because the largest Exchange server I've supported previously only had 3,000 mailboxes. This one supports 10x that number, with plans to grow to over 100,000 mailboxes by this time next year.
With that, they use a seperate "security" domain for logon and authentication than the "resource" domain where their mailboxes reside. This means that the account you logon to your computer, may not be the same account you read your email from. That account will need to be granted secondary permissions to that mailbox, aka "Associated Exernal Account".
Along that same strain, you can no longer simply assign permissions to a user via the Managed By tab. Their mailbox is assigned permissions, but you need to grant their security account permissions also if the group owner wants to add/remove members.
That's why I developed this script. This script will assign Manager permissions to a distribution list. It assigns the selected name rights on the Managed By tab, then assigns the "Send As" and "Write Members" permissions on the Security tab to the selected user's Associated External Account.
There are a few limitations/warnings:
I've cleaned up the code, so it no longer asks for a specific OU. It will query your entire domain for the specified DL. To run, double-click on the downloaded HTA and have fun!
Note: I have recently (3/26) updated this script to filter on the entries, instead of search each one. This makes the overall process rather quick.
Update (6/6/2008): I have added code to allow you to remove people from the security settings on a DL also. Currently working on an issue that generates an error when dealing with an apostrophe in the distinguished name (for example ldap://cn=Eric's Big List,ou=groups,ou=ericwoodford,ou=local). VBScript is taking it as the end of string and breaking..
| Attachment | Size |
|---|---|
| SetNewDLManager.hta | 18.81 KB |
This HTA applet allows you to grant extended AD permissions to a specific user. I use it to assign permissions to the Associated External Account of an AD user rights to modify their own delegates.
I found what values I needed by configuring a single user with permissions, then using Richard's DACL export script to dump that user. I then modify the script (see line 248) to match the permissions I want to grant.
The applet runs faster on the DC, but is usable on my local workstation.
| Attachment | Size |
|---|---|
| SetDelegatePerms.hta | 12.8 KB |
Today I had the honor of working with a company after a catastrophic failure of their Exchange server. One day their hardware was working just fine, the next the server will no longer boot and Exchange is down.
As part of the repair, I installed Exchange 2000 on a new server, and attempted to mount the databases from the mirrored drive. After a few manual uninstalls of Exchange and the the typical passes with ESEUTIL to repair the dirty shutdown the database was coming up clean, but still would not mount.
Checking the Application event log, I found that the server was built in the wrong Exchange Organization. Ugh! As Microsoft states repeatedly, to change the Org, one must reinstall Exchange. In Exchange 5.5 it was so bad, that we would worry about the case of the Organization name when adding new servers to an Exchange site.
That was COMPANY and not Company for the Organization name, right??
In 2000 and 2003, I've always understood that this had not changed. Plan ahead and do it right the first time. So, I started an uninstall of Exchange 2000 off this client's server while scouring Technet and Google for a better solution. Of course, as soon as I started the uninstall, I found that Exchange will NOT uninstall because it sees mailboxes are still on the server. Despite not successfully mounting, it must have partially mounted the database and Exchange now thinks they are on the server.
Using the Manual uninstall procedure again, I remove Exchange one more time, do another reinstall, but this time it also fails. Exchange never asked me to change the Organization as it is still registered in AD. Oh well. That's when I found this tool. LegacyDN.
Like RegEdit, this tool has tons of disclaimers:
Never use [name of tool] on a production database, never use unless you have backups, never use on unless you have PSS on hold on the phone and we tell you to run it..
So, I closed my eyes, crossed my fingers and double clicked on it. By default it comes up in read-only mode. I immediately see that it found the First Administrative Group on the server. Clicking on the fields do nothing, but I can see I have hope. So I close it, and reopen it in /FORCEWRITE mode. Click and the Organization field populates. I replace the text with the correct entry, click Update, wait 30 seconds and "The Organization has been updated successfully.". I imagine that my 30 second wait was in part to only having 8 mailboxes in this information store. If this had been a store with a couple hundred or thousand mailboxes, this process may have taken much longer.
Now the database mounted successfully and all is happy. The users can send and receive email without issue. Next, migrate them to Exchange 2003...
Some useful references.
When running through the latest version of the Exchange calendar update process, it has you assign permissions to all mailboxes on the server. To modify all the mailboxes, you need to provide a list of distinguished names (DN) for each mailbox. Unfortunately this is not simply the DistiguishedName field that you would query from AD, but the LegacyDN entry. You need to query the Exchange environment to get this information.
The following script, I pulled from various sources (primarily my Advanced VBScript book off my desk). It echos the DN to the screen, and also creates a CSV file in the folder it was run from. I did have to run it from the Exchange server, but it may also run from a workstation running the Exchange system admin tools.
In my environment, I am always looking up a user's email address, or trying to find out what Exchange server their mailbox is on. That's why I developed the attached script.
It will do a wild-card search against your currently logged on domain to find any account with those values. It searches the Displayname, proxyaddresses and mail fields.
| Attachment | Size |
|---|---|
| FindEmail.zip | 7.03 KB |
Scenario: I was given a list of 15,000 email addresses and asked if they were still valid in our Exchange environment.
Easy method: I ran a simple VBScript that does an LDAP query against each email address. This worked great, except that it took close to 5 seconds per email address to query our environment. (~20 hrs!) The over-all run time was going to be too extreme.
Next method: Read all entries into a datalist using the tricks from Microsoft Scripting Guys. The script would read each object (primary;proxy) into seperate records, then search each one. This ran for 2 hours before the server logged me off. Even if I deleted entries that I found, it still took too long.
Final method: Read each email address and append it to a string for each letter (for example "administrator@example.com;author@example.com" went in A) accessible via an array. Now I have a 50ish (a..z,0..9,!#$%^) row array containing unsorted lists. The script just needs to find the correct row, and see if the email address exists there.
The entire process took approximately 14-15 minutes. This inclides 12 minutes to read in all 250k email addresses from Active Directory(AD) and then sort them. Processing it creates a NEW csv containing the original line, then appends TRUE or FALSE. If it finds the email address, it puts a TRUE, otherwise it puts FALSE. It does very little clean-up of the email addresses it reads from the CSV, but that could be improved rather easily.
| Attachment | Size |
|---|---|
| Find_Duplicates_in_File_v2.zip | 2.64 KB |
We recently finished a project updating the naming standard for all our Windows AD accounts. Once completed, I found that approximately 3% of the accounts had the alias field set to this old naming standard. Googled high-and-low, I could not find a simple script to set the alias field. So...
This script reads a text file of account distinguished names, then modifies the mailbox alias (aka mailnickname) field to match the SAMAccountName field. Added protection for accounts without mailboxes associated with them. Found that by setting a mailnickname, mail-enabled the account.
Attending a class this week for Exchange 2007. The question came up to export all SMTP email addresses for all mailboxes. In the lab environment, I worked up this script.
I have not tested this in a production environment, so I am not sure what will display for users with other than SMTP email addresses.
The migration process used to move a number of mailboxes created a couple hundred dead mailboxes objects in our environment. Their mailbox information needed to be cleared before their mailboxes could be migrated to the server for the final time. To fix this, I looked into a script. First I found the script at TelnetPort25, here. This script goes through the entire environment and purges all deleted and non-system mailboxes. This would work great, but querying an environment with literally thousands of mailboxes is a daunting task.
That's when I found this script that would simply dump all the deleted-not-purged mailboxes on a specific server. Running this script generates a CSV file with their displayname, and some additional information. I copied the displayname field out of Glen's script and pasted to a text file to use and re-wrote Telnet's to fit my purpose.
Note: uncomment the line ' objExchange_Mailbox.Purge when you feel the script is working correctly.
Here is a small HTA applet that I have built to export the membership of various groups in Windows Active Directory. It provides some basic filtering (owner, specific OU, name contains), plus 3 modes of export, XLS, CSV, or HTML to screen. Beware, if you have office 2007, XLS is XLSX format.
To run this in your environment, it will need to be modified:
line 27 & 28
line 55 & 56
CSV mode gives the best detail as XLS has a 255 character limit on single fields.
Just fixed issue where it required you to pick a subOU in order to continue.
| Attachment | Size |
|---|---|
| DL Export Report.zip | 6.3 KB |
Friend is working on the dirty deed of removing a series of accounts from AD. As part of that clean-up he is to find all the distribution lists that each account is assigned manager on. Using the Quest ActiveRoles Powershell tools, you can quickly find these unfortunate people using:
I am working on a project to recover 30 individual days of email from a clients mailbox. This requires me to restore 30 days worth of backups to the Recovery Storage Group(RSG) on a specific server. I have quickly grown tired of selecting the name from the giant Exmerge list and worked out how to use a batch file to run Exmerge against the RSG.
Part 1: Exmerge.ini
Part 2: database.txt
Part 3: mailboxes.txt
Part 4: the Batch file (exportMbx.bat)
I've now put a shortcut to the bat file on my desktop and double-click it after the restore completes. If I could only find a script that would then dismount the database, mark it for overwrite and start a new restore from the server, I'd be done! Unfortunately, I've been told by Microsoft you can't script against the RSG, so still got a bunch of clicks for each day.
Back to work...
I needed a quick script to create a series of distribution lists on an Exchange environment. I thought, "Cool, a chance to flex my PowerShell muscles!" From that I found new-qadgroup from the quest tools set and new-distributiongroup from the Exchange tools. After quite a bit of muddling around, I was never able to recreate my script.
Requirements I was trying to meet:
import-csv)| %{new-distributiongroup -name $_.name}Unfortunately, after working on the first 3-4 items, I was stumped. VBScript failed me on a number of these, just in the fact that it's not widely published and a few answers varied. So, here is what I developed. The script fails when adding more than 1 additional proxy address, otherwise it worked for all my other tests.
(Sorry for the wrappage..)