Passion * Technology * Ruthless Competence

Wednesday, February 07, 2007

Perusing Powershell Part 2: Error or No Output?

In yesterday's post on PS, I provided the source for my implementation of Get-SQLServer. I realized after I made the post that there was a significant bug in the ProcessRecord method. If you specify a service instance (default or named), the cmdlet makes no effort to actually validate that such a SQL server instance exists. So if you ask for a instance that doesn't exist, Get-SQLServer will happily write an invalid Server object to the pipeline. So I changed it to actually validate that the specified instance exists. I connect to the specified machine (local machine if not specified) using ManagedComputer and look in it's ServerInstances collection for the specified SQL instance.

The question is, what should you do if the specified SQL instance doesn't exist on the specified machine? One the one hand, you could write an error indicating that the SQL instance doesn't exist. Or, you could simply write nothing to the output pipeline, which may cause an error down the line.

Which is the right approach?

At first, I wrote an error when I couldn't find the instance, but decided that wasn't the right approach. It isn't really an error unless you attempt to act on that instance, right? So I thought the more PS friendly approach would be to write nothing and let the down stream cmdlets deal with it. I do write a debug message if the specified instance doesn't exist, so the scripter isn't completely in the dark.

So here's the new and improved ProcessRecord method of my Get-SQLServer cmdlet:

protected override void ProcessRecord()
{
    //Make sure both -Name and -Default aren't specified
    if (!string.IsNullOrEmpty(_Name) && _Default.IsPresent)
    {
        WriteError(new ErrorRecord(
            new ArgumentException(
                "Default and Name parameters can't both be specified"),
            "DefaultAndName",
            ErrorCategory.InvalidArgument,
            null));

        return;
    }

    //If the machine name is not specified, assume the local machine 
    //(via the "." value)
    string machine = string.IsNullOrEmpty(_MachineName) ? "." : _MachineName;

    //Connect to the specified machine via the SMO WMI ManagedComputer object
    SmoWmi.ManagedComputer mc = new SmoWmi.ManagedComputer(machine);

    if (string.IsNullOrEmpty(_Name) && !_Default.IsPresent)
    {
        //If neither Name or Default are specified, write all the 
        //server instances on specified machine
        foreach (SmoWmi.ServerInstance si in mc.ServerInstances)
            WriteServerObject(si);

        return;
    }

    string instanceName = _Default.IsPresent ? "MSSQLSERVER" : _Name;

    if (mc.ServerInstances.Contains(instanceName))
        WriteServerObject(mc.ServerInstances[instanceName]);
    else
        WriteDebug("The specified SQL instance does not exist");
}

//Helper method to create a SMO Server object from a 
//SMO WMI ServerInstance object and write it to the pipeline
private void WriteServerObject(SmoWmi.ServerInstance si)
{
    if (si.Name == "MSSQLSERVER")
        WriteObject(new Smo.Server(si.Parent.Name));
    else
        WriteObject(new Smo.Server(si.Parent.Name + "\\" + si.Name));
}
Posted By Harry Pierson at 12:00 PM Pacific Standard Time
Comments are closed.

SoCal Code Camp

PDC08

patterns & practices
Summit 2008

Change Congress
Recent Bookmarks
Tags .NET Framework (2) ADO.NET (5) Agile (7) AJAX (3) Architecture (284) Guidance (6) Interop (2) Modelling (61) Patterns (7) Process (4) SOA (93) Web Services (5) ASP.NET (24) Battlestar Galactica (3) BI (2) BizTalk (4) Blogging (115) dasBlog (11) Podcasting (4) BPM (1) C# (10) C++ (4) Capitals (5) CardSpace (3) CLR (2) College Football (10) Comedy Central (1) Community (81) Concurrency (6) Consumer Electronics (1) Database (13) Dependency Injection (2) Development (117) C Plus Plus (1) Embedded (5) Lanugages (37) Media (2) P2P (11) Rotor (1) SharePoint (6) SOP (3) DIY (1) DLR (16) Domain Specific Languages (13) Durable Messaging (5) Dynamic Languages (10) Dynamic Silverlight (1) Education (3) Enterprise 2.0 (1) Entertainment (14) ETech (15) F# (51) Functional Programming (17) Game Development (2) Guidance Automation (3) Hardware (8) HawkEye (3) Hockey (29) Home Electronics (1) Home Network (5) Humor (5) IASA (1) Idempotence (3) infrastructure (5) Instrumentation (4) Integration (2) IronPython (45) IronRuby (12) Java (2) Job (3) LINQ (23) Live Mesh (2) Lost (1) Master Data Management (1) Media 2.0 (6) Microsoft (30) MIX06 (2) Mobile Phone (1) Monads (5) Morning Coffee (172) Object Oriented (4) Office (5) Open Source (5) Open Space (2) Operations (3) Other (135) Art (1) Books (1) Family (31) Games (18) General Geekery (26) Home Theater (1) Movies (23) Music (20) Politics (3) Society (1) Sports (37) Working at MSFT (15) Parallel Programming (3) Parsing Expression Grammar (16) patterns & practices (2) PDC08 (5) Politics (47) PowerPoint (2) PowerShell (34) Presentation (5) Projects (1) HawkWiki (1) Python (4) Quote of the Day (4) Refactoring (1) Research (2) REST (18) Reuse (5) Robotics (2) Rock Band (4) Rome (5) Ruby (23) Ruby on Rails (1) Sci-Fi (2) Scripting (4) Security (3) Service Broker (14) SharePoint (2) Silverlight (18) Social Software (1) Software + Services (2) Software Design (1) Software Factories (11) Software Industry (1) Spark (1) SQL Server (2) Stephen Colbert (1) TechEd (7) TechEd06 (1) TechRec League (1) Television (6) Travel (6) Unified Client (1) Unit Testing (4) USC (1) UX (1) Virtual PC (2) Visual Basic (1) Visual Studio (20) Volta (2) Washington Capitals (34) WCF (31) Web 2.0 (65) Web Services (5) WF (21) Windows Live (23) WPF (7) Xbox (1) Xbox 360 (53) XML (11) XNA (14) Zune (4)
Disclaimer: The information in this weblog is provided "AS IS" with no warranties, and confers no rights. This weblog does not represent the thoughts, intentions, plans or strategies of my employer. It is solely my opinion. Inappropriate comments will be deleted at the authors discretion.