# Monday, September 21, 2009

Opera 9.x, 10.x failing on Ajax history and the hack to fix it

Part 1 - Introduction
Part 2 - Basic Example
Part 3 - Complex Example
Part 4 - Final Notes
Bonus - Ajax History and the Memento Pattern
Extra Bonus - Issues with Opera

I dedicate this blog to Tomi, who brought this issue to my attention. Without I would be blissfully unaware that my ajax examples did not work with Opera.

To make a long story short, the basic Ajax history points that are demonstrated starting in this blog entry and on the site here fail miserably when used by Opera, even the most recent v 10. It would go forward once and then fail on either the next history point or going backwards. It worked fine if history was not stored.

At first I thought that it might have to do with Validation, so I turned off Event Validation and ValidateRequests but no dice. I tried modifying the LoadScriptBeforeUI setting on the ScriptManager thinking that maybe Opera was attempting to access the controls before they were instantiated. No dice.

Looking at the "Error Console" in Opera gave this confusing information:

JavaScript - http://www.myfriedmind.com/ajaxexamples/AjaxSimplehistory.aspx
Unknown thread
Error:
name: Sys.WebForms.PageRequestManagerServerErrorException
message: Sys.WebForms.PageRequestManagerServerErrorException: An unknown error occurred while processing the request on the server. The status code returned from the server was: 400
stacktrace:   Line 5 of linked script http://www.myfriedmind.com/ScriptResource.axd?d=Ca9Q30sQJzQkznL95cxsbDyIKgsvVPJZcb1rw8ROyNsMckgQG68w3ACHnEiANP
BR_VaW0NUFhahnNTwkTQZ39NfZ8sEeH0NKN9NzfqKtjhs1&t=40a63f28

    function(a,d,f){if(this._request===d.get_webRequest()){this._processingRequest=false;this._additionalInput=null;this._request=null}var e=this._get_eventHandlerList().getHandler("endRequest"),b=false;if(e){var c=new Sys.WebForms.EndRequestEventArgs(a,f?f.dataItems:{},d);e(this,c);b=c.get_errorHandled()}if(a&&!b)throw a}
.....

The key is that it was not returning the 200 that we all know and love, but a 400 status. Per this Msoft article (kb 247249) -

If the contents of a GET request are corrupt, then the server is unable to determine the URL or the host to which the GET request should be sent. IIS is unable to retrieve the host information from the GET request packet in order to look up the meta data for the custom error. This is by design. Errors that result from severely corrupted GET requests are not customizable.

Now I KNOW that they are not corrupt. It works perfectly fine with IE and Firefox. When I run it on Fiddler (http://www.fiddler2.com/) - my go-to tool for troubleshooting odd Ajax problems I do see the 400 returned. Note in the picture that the first three are for IE which work (all 200s) the second set of three is for opera - the final one being the 400 error.

When I look at the raw data of that entry it tells me that the response is that it is getting a Bad Request <Invalid URL> (see below). hmmmmm, should I trust it?

Hunting and pecking I find various entries dealing with Opera and its issues with Ajax, most of them from years ago. And then I discover this gem: http://www.webmasterworld.com/javascript/3195000.htm which has this notation near the end (italics mine)

opera has a rather annoying bug. This occurred in both 8 and 9: If the URL is exactly the same, the PHP file results are cached, and all the requests terminate as soon as the first result is returned. IE does the same, but I was able to fix it by spitting out a couple of "no-cache" headers. opera ignores these headers.

I fixed that by adding an "id=" parameter to the URL, which made each URL unique. This forced opera to stop caching.

Wha??? So I added a querystring to the end of my url (it does not matter what it is) and it worked! In other words http://www.myfriedmind.com/ajaxexamples/AjaxSimplehistory.aspx?x=y will work in Opera but http://www.myfriedmind.com/ajaxexamples/AjaxSimplehistory.aspx will not.

Now here is the odd part, and to display it I am going to direct you to a slight different simple ajax example I just whipped up -> http://www.myfriedmind.com/ajaxexamples/AjaxSimpleOpera.aspx. I am also going to give you a behind the scenes look (via fiddler) as to what, exactly, Opera is 'requesting'. The main modification I did was to change the length of the text used for the history point (I am only going to store hour, minutes, seconds to expedite this) to make it shorter and easier to view.

Again http://www.myfriedmind.com/ajaxexamples/AjaxSimpleOpera.aspx works for the first one and fails for the second.

First, let us look at what happens in IE per Fiddler (note that I only include the querystring here for comparison, this example works in IE without it).

Now the Opera per Fiddler -

Okay, okay, there was a long time between clicks (I was pasting it over), but do you notice anything different between the two (pay attention to the POST that is done via Ajax)? Internet Explorer ALWAYS Posts to the same URL - it ignores the hash entry. Opera prepends the previous hash entry after encoding it for the url, and so it gets longer and longer.

What is really, really odd is that Opera keeps prepending EVEN WHEN YOU HIT THE BACK BUTTON! So moving back and forth in your ajax history means that you are getting a longer and longer request entry. If you want to see this, snag fiddler -> http://www.fiddler2.com and try it. Your POST request gets longer and longer due to the prepending, but the URL does not reflect this at all. This ALL happens under the covers.

I finally went into Opera and tried turning off ALL caching (disk and otherwise). No luck! And when I set it to pretend to be IE it threw an error on the history point setting, claiming it was not asynchronous. I even went into opera:config under User Prefs and set the "History Navigation Mode" to 1 per this article http://www.opera.com/support/kb/view/827/ to prevent what it calls "fast history navigation". Still no dice! I even set the Opera to "Always Reload Https In History" and then connected via https to the page and that failed as well.

So why does adding a query string work? I honestly don't know. But this might be a clue - when it succeeded the hash was passed as a query string variable in Opera. When it failed, no query string was passed at all. There are a number of posts all over the web that refer to Opera caching when it should not, so I suspect that that may indeed be the issue - Opera is caching the page regardless of what it is told. Only by including the query string can you force Opera to not do whatever it is doing.

So there appear to be three solutions

  1. Don't use Ajax history for Opera unless you use a query string (it might work in systems other than .net, I have not tested this)
  2. Get Opera to fix the issue (good luck!)
  3. Make sure you have a querystring, even a nonsense one, if your users will be using Opera...

Happy coding!

----------

Further notes:

This article -> http://cfis.savagexi.com/2007/06/12/opera-ajax-and-bugs talks about an issue with Opera rejecting status codes other than 200. However that is probably not the issue since it should be returning a 200 code anyway. Just something to keep in mind.

Now I should note assuming that it was a caching issue I added a bunch of code to prevent caching - including the ones below:

Response.ClearHeaders();
Response.AppendHeader("Cache-Control", "no-cache");
Response.AppendHeader("Cache-Control", "private");
Response.AppendHeader("Cache-Control", "no-store");
Response.AppendHeader("Cache-Control", "must-revalidate");
Response.AppendHeader("Cache-Control", "max-stale=0"); 
Response.AppendHeader("Cache-Control", "post-check=0"); 
Response.AppendHeader("Cache-Control", "pre-check=0"); 
Response.AppendHeader("Pragma", "no-cache"); 
Response.AppendHeader("Keep-Alive", "timeout=3, max=993"); 
Response.AppendHeader("Expires", "Mon, 26 Jul 1997 05:00:00 GMT");
Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1));
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetNoStore();

But again, the only thing that appears to resolve the issue is the inclusion of a query string.

# Wednesday, August 26, 2009

HP Universal Print Driver PCL 6, Windows 2008, and Watermarks

For those of you just enter the IT 'biz, let me assure you that Hewlett Packard was once a great company. Good, reliable printers. Functional Drivers. Not the crap we are handed today. It is always sad to see a reliable company start to tube and I can only hope that this is a quirk, but I once again ran into an issue with their drivers.

We are using their Universal Print Driver because they have not come out with the necessary drivers for Windows 2008 for our printers (not to mention the issue with their bidirectional channel component) and came across a rather strange bug. Let us say that we are trying to print the following document from Word 2007 that has a watermark. It should look like this:

However, when printed from an XP machine we only get half the letters. It looks like this:

I verify that there are no correct drivers from HP (nope!) and then I try changing a setting - maybe "Send Truetype as Bitmap". Wow! Now we have the other letters, we just dropped most of the original ones that were showing.

So I roll back the driver from PCL6 (v 5.0) to PCL5 (v 5.0). And guess what. It works. PCL 5 works where PCL 6 does not.

A little (true) story. I was about to fly out of town so I took my wife's car into an oil-change place just to get that task done. While there the tech pointed out that the alternator belt was missing a tooth. Now I have changed more alternator belts in my life than you can shake a stick at, and I should know better than to have an oil-change place change my belts, but since I was in a hurry I figured to let them do it for me this time.

Oops.

When I get back I find out that it is squealing when you start the car. Hmm, maybe they need to tighten it. I take it back and they can't repair it. It works on tensioning pulleys in that car and they tell me they think that one of the pulleys is broken. So I take it to the dealer to fix. The rep sits down next me after they have loaded the car up and taken a look and says, "Well, it is kind of good news. The pulleys aren't broken, they simply put on the wrong belt - it is too large."

It seems to me that these "Universal" print drivers from HP fall into that category. What use is a functional engine if the belts that you put on it do not fit.

Come on, HP, spend some time on the belts. Please.

# Monday, August 17, 2009

Exchange 2007 and Certificate Security Alert when using External name vs Internal name

The name on the security certificate is invalid or does not match the name of the site error thrown when using a certificate generated by an external Certificate Authority
# Thursday, August 13, 2009

Printer problem (or It is not a Silicone based problem problem but a Carbon based one)

I just have to share this story to highlight the curiosities caused by supporting users.

A couple of days ago I received a distress call because someone's printer (let's call her "Mary") was asking for cardstock. Knowing what the problem was - look here - I went up and removed/readded her printer. That brought down all the settings from the print server and she was good to go (after she closed out of programs that were holding the old settings). Printing proceeded perfectly.

Today I got a call about the same person having printing issues. But not from her. I will refer to the person who called initially as "Jackie".

*ring*

Me: "Hello, this is Matt."
Jackie: "Mary is having trouble printing again."
Me: "Is Mary there?"
Jackie: "Yes."
Me: "Then why isn't Mary calling me?"
Jackie: "She asked me to call."
Me: "Have Mary call me."

*ring*

Me: "Hello, this is Matt."
Mary: "I am having trouble printing again."

I then proceed, over the phone, to walk her through checking her printer's settings, specifically what the 'Paper Type' is. Everything is perfect. Except that it won't print. I have her try printing from Notepad, no go. I check on the server and there is definitely a backup. So I jog on up there to take a looksee. When I arrive, Mary is kicking back reading the paper. I walk over to her computer and verify, again, that everything is perfect.

Strange...

I walk over to the printer. There, emblazoned on the informational screen, is this message -> "Manually Feed Envelope". I manually feed an envelope. It prints an envelope and then ALL Mary's stuff starts to spew forth...

Jackie: "Oh, that was that envelope that you asked it to print, Mary."

Ironically I am sure that the word will get around that "we are still having printer problems." Ah well, you need to have thick skin if you are going to work in IT. And, of course, I got quite a chuckle at the thought that Jackie had to call for Mary.

# Thursday, August 06, 2009

Hewlett Packer Printers asking for Cardstock (or Recycled, or Glossy) on Windows 2008 Print Server

We moved to our w08 print server and as noted in yesterday's post ran into issues with slooooooooooooooooow printing. These were resolved by moving to the Universal Print Driver (UPD) which had an updated bidirectional channel portion. There was one surprising result of the move - all of a sudden people were being prompted to load a type of paper (recycled, heavy-weight, glossy) into the Manual Feed tray on the 4250s. If they hit the continue button (the checkmark) it would print, but they had to do it FOR EVERY PAGE.

Not something to make your end users happy.

The issue appears to be a rather odd interaction with the driver in which it sets modifies the default settings of the printer. To fix:

1 - Open up the printer properties on the Print Server and go to the Advanced Tab. Selecting "Printer Defaults"



2 - Go to the Paper/Quality tab and look at the Paper type. It is probably set at a specific (undesired) type.



3 - Click on the Paper type and select "Unspecified"



A couple of notes:
  1. Users may need to remove/add the printer back for this to get pushed down.
  2. This is NOT Printing Preferences. The same screens are there, but they will not fix this, although they should be changed as well.

# Wednesday, August 05, 2009

Windows 2008 Print Services, HP LaserJet Printers and SLOW Printing

If you have moved to Windows 2008 for your Print Server and have encountered slow printing to your HP Laserjets, the issue may be the driver.

According to this support document by HP the issue lies in the HP Bidirectional Channel component - namely hpzbid.dll and hpzbidXX.msi). You can read all about the symptoms/cause there but to make a long story short it appears that this lies with issues where it continually tries to reinstall the .dll and fails.

The solution, according to HP, is NOT to call up and get updated .dlls (they probably will not give them to you) but to use their updated Universal Print Driver (UPD) version 5.0. This changes the .dll to cioum.dll for the bidirectional channel control rather than hpzbid.dll. HP has no intention of updating hpzbid.dll so get used to it.

The symptoms are hard to miss (for example it takes 30 seconds just to view the properties of a printer on a client machine) so this one should not be hard to miss. Just remember to use the 5.0 version of the UPD.

Printers noted by HP:

  • Laserjet 4250 series
  • Laserjet 4350 series
  • Laserjet 9040 series
  • Laserjet 9050 series
  • Laserjet 5200 series
  • Laserjet P3005 series
# Friday, July 31, 2009

Anonymous Form Submissions to Sharepoint 2007, or another MOSS issue on the Internet

I was exceedingly excited to think about using Sharepoint 2007 (MOSS to some) as our Internet facing site. I had written the code for our previous site in Cold Fusion over the a few years and was looking forward to laying down that burden...
 
MOSS seemed to have almost everything we did, plus a whole lot more. Imagine my surprise when I discovered that as an Internet-facing site it leaves a lot to be desired (and that at $40k). Now imagine me staying up until 2am for a few nights running trying to find solutions. Now imagine me blowing milk out my nostrils... maybe not...
 
For a variety of reasons (which I will not go into here) I selected a "Publishing Site with Workflow". Those of you who have worked with MOSS know that this automates LOCKDOWN on all Lists so that Anon users can not view them. What they don't tell you is that no matter what you do, even if you give them permissions to VIEW the list, they can not ADD to the list.
 
Now this is a problem because one of the reasons (among many) that I chose Sharepoint was their integration with Infopath to easily create and publish forms. Now I was discovering that anonymous users could pull up the form, they just could not submit it. Unless, of course, we allowed them access to all the forms. The reason seems to be tie back into Sharepoint's rather complex permission schemes. There are actually three areas that need to be checked for permissions, sort of like three distinct committees. Each has a stranglehold on one area and one type of connection. Since Sharepoint does not recognize that there can be a variety of Anonymous users, and it can not distinguish them, it becomes all or nothing.
 
I have tried a number of solutions - note these rather creative solutions -

1 - http://kwizcom.blogspot.com/2007/06/anonymous-users-cannot-access-list.html. Which does not work for submitting but does allow viewing. Note the steps on "unlocking", "set permissions", "lock". Not easy or fun...

2 - Alternately you can use email -> http://www.click2learn.ch/blog/Lists/Posts/Post.aspx?List=6b8a723c-02e0-48bb-a075-8f9eb21dbfbe&ID=13 which basically means they can fill out the form, but not submit it the library.

3 - My favorite is this one -> http://www.sharepointblogs.com/ervingayle/archive/2006/10/13/enabling-anonymous-users-to-open-and-submit-data-via-infopath-forms-published-to-sharepoint-2007.aspx WHICH DID NOT WORK FOR ME!!!!!!!!!!!!! However, it does display the really cool thing about changing the querystring from DOCLIB to LIST. Who woulda thunk? If only it worked...
 
So, I am desperately asking, WHAT DO I DO????
 
You can always use surveys (which won't work for a LOT of things), or you can do some ninja-backdoor-coding, which I found on this amazing site for you -->
http://www.paylasimnoktasi.com/en/anonymousinfopathforms.aspx
 
Basically you must
  1. setup a separate IIS Web App running a Webservice (it does not need to be exposed externally)
  2. Write a webservice to handle this (it will use identity impersonation and the app pool account to convince the List that you really ARE someone).
  3. Muck with InfoPath forms to pass the necc data to the webservice when submitting to it.
I must admit I probably would never have thought of this - so big thanks to Nezih Tinas! I love techies on the web!!!
 
So here (as an example) is my very simple webservice code
 
<%@ WebService Language="C#" Class="AnonFormSubmission" %>
using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Security.Principal;
using System.IO;
using System.Text;
using Microsoft.SharePoint;
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class AnonFormSubmission  : System.Web.Services.WebService {
    [WebMethod]
    public void SubmitToFormLibrary(string siteName, string webName, string formLibraryName, string formXml)
    {
        WindowsImpersonationContext wic =
        WindowsIdentity.GetCurrent().Impersonate();
        string formName = Guid.NewGuid().ToString();
        using (SPSite site = new SPSite(siteName + "/"))
        {
            site.AllowUnsafeUpdates = true;
            using (SPWeb web = site.OpenWeb(webName))
            {
                SPFolder folder = web.GetFolder(formLibraryName);
                foreach (SPFile file in folder.Files)
                {
                    if (file.Name.Replace(".xml", "") == formName)
                        throw new Exception("File name exists.");
                }
                folder.Files.Add(formName + ".xml", UnicodeEncoding.UTF8.GetBytes(formXml));
                web.Dispose();
            }
            site.Dispose();
        }
        wic.Undo();
    }
}
 
Note 1 - If you are tweaking this, remember to either use
Dispose your Web and Site objects or do the using container (which Disposes of them for you). Otherwise you will start hemorraghing memory. I am paranoid and do both. Incidently Disposing will automatically Close.
 
Note 2 - I use a random GUID to create the Form name because it must be unique, but as long as you make sure it is unique you should be good to go.
 
Note 3 - You will need to tweak your web.config (at least I did) to include a username/password that has permissions. This does not need to submit to the web app extension that is Internet facing (I submit it to the root app which using NTLM since it all goes into the same list and then use an NTLM account that I know has access). Ex:

<compilation debug="false">
    <assemblies>
        <add assembly="Microsoft.SharePoint,
           Version=12.0.0.0, Culture=neutral,
           PublicKeyToken=71E9BCE111E9429C"/>
        </assemblies>
    </compilation>
<authorization>
<allow users="?" />
</authorization>
<identity impersonate="true"
      userName="myDom\myUser"
      password="mypassword" />
<authentication mode="Windows"/>
 
This should enable you to submit to that list as myDom\myUser. You can encrypt the web.config to be paranoid. Remember, paranoia is not a problem in IT, it is a job requirement.
 
You can follow Nezih's directons for creating the infopath form. I should note that this will have to be an administratively approved form.
 
WAIT!!! You're not done!!!
 
What you then need to do is go into the form library that you want to submit it to and set this up as the default form. Then you can use all these nifty fields in whatever view you want!!! Plus you have to modify the form library itself to not launch it as Infopath. Then you will want to grab the URL. O, and DON'T FORGET TO CHANGE THE TIMEOUT SETTINGS FOR INFOPATH!!!

# Wednesday, July 29, 2009

Windows 2008 Spooler Warning on clustered print server - Event ID 4 -> Missing S-1-5-18\Printers\Connections

After installing our clustered w08 Print Server I noticed that there was a particular Warning in the System Log. Event ID 4 "The print spooler failed to reopen an existing printer connection because it could not read the configuration information from the registry key S-1-5-18\Printers\Connections. The print spooler could not open the registry key. This can occur if the registry key is corrupt or missing, or if the registry recently became unavailable."

I looked in the registry and, no surprise, that key was missing. I hunted around a bit and found this entry. Basically to resolve this was fairly simple - add the key back in:

  1. Open up the registry on the computer (I did it on all nodes individually)
  2. Go to HKEY_USERS/S-1-5-18/Printers
  3. Add a new Key called "Connections" (no quotes)
  4. Right-click and select Permissions on the new key to verify that System has "Full Control"

Now I am not sure if this is an issue with Clustering or just a strange whacky event that happened. But if it happens to you, hopefully this will resolve it.

# Tuesday, July 28, 2009

Msoft AddRule example is Incorrect

I could not find a mention anywhere that with SP1 you still need to use Addrule.exe for Forms based authentication crawls. I have hunted and hunted to verify, but yes, Virginia, it appears you still do need to still use Addrule.exe with its XML.
 
(Don't know what I am talking about -check it out here --> http://technet.microsoft.com/en-us/library/bb852172.aspx)
 
Incidently - this whole mess with not being able to crawl FBA sites and having to create a specific trimmer is another point demonstrating how it appears that Microsoft's inclusion of the "internet facing site" FBA site in MOSS was an afterthought.
 
Suffice to say, not merely is there no documentation pointing out that you STILL NEED TO USE ADDRULE, but the sample XML is wrong.
 
Here is the INCORRECT XML sample
<rules>
  <rule>
    <path>http://YourFormsAuthSite/*</path>
    <type>FORM</type>
    <error_pages>
      <error_page>Logon.aspx</error_page>
    </error_pages>
    <auth_url>Logon.aspx</auth_url>
    <login_type>POST</login_type>
    <parameters>
      <param name="__VIEWSTATE">dDw0OTQzMjI0MjQ7O2w8UGVyc2lzdDs%2BPvhWhKKTnHpM3RIvgkgC9jJVpN%2Bg</param>
      <param name="Login1%24UserName">FormsAuthUserName</param>
      <param name="Login1%24LoginButton">FormsAuthPassword</param>
      <param name="Login1%24LoginButton">Log+In</param>
    </parameters>
  </rule>
</rules>
Here is a CORRECT XML sample
<rules ssp="SharedServices for MyServer">
 <rule>
  <path>http://www.myserver.com/*</path>
  <type>FORMS</type>
  <auth_url>http://www.myserver.com/_layouts/login.aspx?ReturnUrl=/</auth_url>
  <login_type>POST</login_type>
  <error_pages>
   <error_page>login.aspx</error_page>
  </error_pages>
  <parameters>
   <param public="true" name="__VIEWSTATE">%2FwEPDwUKMTc0NDQ2ODkFgJmD2QWAmYYCAgMPZBYCAjU
PZBYCAgEPZBYCZg9kFgICDQ8QDxYCHgdDaGVja2VkaGRkZGQYAQUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja
0tleV9fFgEFJmN0bDAwJFBsYWNlSG9sZGVyTWFpbiRsb2dpbiRSZW1lbWJlck1lYuMscsbPMGpHkju7j4uv5Gv%2BR
ds%3D</param>
   <param public="true" name="ctl00%24PlaceHolderMain%24login%24UserName">myFBASearcherName</param>
   <param public="true" name="ctl00%24PlaceHolderMain%24login%24password">myFBASearcherAccount</param>
   <param public="true" name="ctl00%24PlaceHolderMain%24login%24login">Sign+In</param>
   <param public="true" name="__EVENTVALIDATION">%2FwEWBQLxxc7nDwLE96mtBQLLtsPBAgLkkP7MCgK%2FlZyy
Bxv%sdf2B3qFhTCz8CUMXQiMVw</param>
  </parameters>
 </rule>
</rules>
 
What are the differences?
  1. They have incorrect fieldnames (missing the Placeholders) and note the repetition of LoginButton for the Password portion of the XML demo. Obviously someone simply cut and pasted sections rather than pasting a complete, correct, XML
  2. They do not have __EventValidation. Testing this with Fiddler emphasized the need for that
  3. They do not have public="true" in their params which can be useful - public: If this value is not present, the parameter specified will be encrypted and stored in the search system. For encrypted parameters, the size limit is 1,024 characters. If you specify public = "true", the parameter will not be encrypted before storing in the search system. Also, the parameters size limit increases to 4,096 characters. 
Other Caveats
# Monday, July 27, 2009

Add-ADPermission with Exchange 2007 databases

http://technet.microsoft.com/en-us/library/aa996343.aspx discusses means to grant access to mailboxes. The Console can grant it to individual mailboxes, but what if you want the whole kit and kaboodle? They mention using the Add-ADPermission like this from the Shell:

Add-ADPermission -Identity "Mailbox Store" -User "Trusted User" -ExtendedRights Receive-As

This seem to be fairly straightforward. For example:

Add-ADPermission -Identity "myServer\mySG\myDB" -User "myDomain\my.name" -ExtendedRights - Receive-As

But if you do that you get yelled at:

Add-ADPermission : myServer\mySG\myDB was not found. Please make sure you have typed it correctly.
At line:1 char:17
+ ADD-ADPermission  <<<< -Identity "myServer\mySG\myDB " -User "myDomain\my.name" -ExtendedRights Receive-As

The trick here is that in this case the "Mailbox Store" means something different than every other time I have run across that phrase. In this case it is looking for the AD Distinguished Name:

[PS] C:\Windows\System32>add-adpermission -identity "CN=InformationStore,CN=EX07ServerName,CN=Servers,CN=Exchange Administrative Group,CN=Administrative Groups,CN=Our Company,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=myDomain,DC=com" -User "myDomain\my.name" -ExtendedRights Receive-As

That works. Kind of intuitive, no? No? Well here is a way to find that beast:

1 - Install ADSI Edit (if you have not already) http://technet.microsoft.com/en-us/library/cc773354%28WS.10%29.aspx

2 - Open up "Configuration (NOT Domain) by selecting it in the "Select a well known Naming Context

3 - Drill down to (ready, take a breath)

  • Configuration
  • Your domain
  • CN=Services
  • CN=Microsoft Exchange
  • CN=%Organization Name as stored in Exchange%
  • CN=Servers
  • CN=%Server Name that has the database%
  • CN=%Mailbox Storage Name%
  • CN="Database% (optional)
  • Right Click and select 'Properties'

4. What you need to know is stored in distinguishedName. You can double-click and it will popup a textbox (as shown below). You can copy that, just DO NOT DELETE IT!!! This will give you the information you need to supply in the -Identity entry. You can also select a particular database if you so choose.

If you have been observant you will note that the DistinguishedName (which is what is passed into the -Identity variable) matches the path you drilled down. So theoretically, you do not need to go through this. Your entry should be something like:

CN=InformationStore,CN=%Exchange Server That Has Databases%,CN=Servers,CN=Exchange Administrative Group,CN=Administrative Groups,CN=%Your Exchange Organizational Name,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=%Your Domain%,DC=%your DomainExtension"

Good luck!