There are literally hundreds of thousands of trained and experienced American software engineers "on the bench" right now and 50% of graduates of U.S. computer science and IS programs don't even manage to find a job in the field. Google gets over 1,000,000 resumes per year. Microsoft may not get that many due to Microsoft's reputation as a "stodgy" and "yesterday's technology" company amongst the best and brightest (yes, I know that's unfair, but that's MS's reputation outside the MS "bubble") but I would be seriously surprised if Microsoft got less than 500,000 resumes per year. Microsoft hires about 3,000 people per year -- or roughly 0.6% of the people who submit resumes.
Given that, the notion that Microsoft can't find sufficient talent without H1B's says more about Microsoft's hiring process and Microsoft's reputation than it says about the availability of Americans with a background and training in software engineering. Especially telling is your notion that Microsoft should only look at the "top 20%" from a few "elite" universities. Frankly, given the criteria you mentioned, I wouldn't have been qualified to work for Microsoft upon college graduation because I wasn't "in the top 20%" -- mostly because I'd been working multiple jobs while in college, including writing actual software products shipped to actual real paying customers either as a contractor for various local companies or as an employee of a relative's company. I think my record over the past twenty years (multiple products shipped in multiple technologies ranging from PIC firmware for a front panel processor to Linux kernel driver work to Groovy/Grails code for a web app) shows just how silly Microsoft's criteria really are. There's a lot of talent out there that never makes it past that initial pre-screen where Microsoft immediately discards 80% of the applicants as "not good enough" without a single technical person ever talking to the applicant.
Frankly, our biggest problem when we go to hire people is not a shortage of candidates. It's too *many* candidates. My team doesn't have time to interview all the possible candidates who are submitted when we have a job opening, meaning it's a heavy filtering process. We rely on recruiters that we trust to do the initial prescreening, the ones we work with have technical backgrounds. Once they do the prescreening my boss is the guy doing the next level of filtering, and luckily he has a technical background too. The handful of candidates who make it to actual interviews generally all would be capable of doing the job, it becomes a case of deciding whether a candidate would fit with the team, stands out in some way, etc.
Unfortunately at many major corporations the people doing the initial filtering don't have a technical background and end up filtering on trivial criteria that discard good candidates for no good reason. That mostly lame people get dumped on your desk doesn't surprise me. It seems to be the norm for major corporations today where HR is doing the filtering. But that says more about a broken hiring process than it says about any shortage of trained and often experienced software talent.