Come Speak at PowerShell Summit 2015!

§ September 2, 2014 16:58 by beefarino |

summit2015As you may know, my home town of Charlotte NC will play host to the PowerShell Summit 2015 NA next April.  This event will supplant the Charlotte PowerShell Users Group regularly scheduled PowerShell Saturday event, and it is a rare opportunity that you will not want to miss! 

The summit is currently accepting submissions for talks, and I’d like to suggest that you do so.  You do not need to be an expert, you do not need to be an experienced speaker - you simply need a shell story to tell, and I know you have one you’re dying to share.

The benefits of speaking are many, including free attendance to the event.  You'll get to rub elbows with members of the PowerShell team and interact with industry experts and community leaders from across the globe.

So please, consider sharing your story by submitting a talk.  The deadline for submissions (15 Sept) is approaching rapidly, and I would hate for you to miss out on this singular opportunity.



A Bit of DSC Frustration

§ August 20, 2014 14:42 by beefarino |

DSC is like remoting – when it works it’s amazing.  When it doesn’t work….. who knows why?

While prepping a Desired State Configuration demo for SQL Saturday #328, I hit a small roadblock that proved to waste several hours of my time.  I’m documenting it here in the hopes that it helps someone else.

I’m using DSC to install SQL Server onto an Azure VM.  At some point in the process, running Start-DscConfiguration started to error out, with a cryptic and altogether unhelpful message:

An old configuration is still pending. Please wait for the pending configuration to finish. If the problem persists, 
execute Start-DSCConfiguration command with -Force parameter.
    + CategoryInfo          : ResourceExists: (root/Microsoft/...gurationManager:String) [], CimException
    + FullyQualifiedErrorId : MI RESULT 11
    + PSComputerName        : nottaken.cloudapp.net
 

This error persisted regardless of what I tried, and it eventually took a new form:

Cannot invoke the SendConfigurationApply method. The PerformRequiredConfigurationChecks method is in progress and must 
return before SendConfigurationApply can be invoked.
    + CategoryInfo          : NotSpecified: (root/Microsoft/...gurationManager:String) [], CimException
    + FullyQualifiedErrorId : MI RESULT 1
    + PSComputerName        : nottaken.cloudapp.net

I finally swallowed my pride and reached out to DSC trailblazer Steve Murawski, who was able to quickly and generously point me to the fix.

The Cause

In my case, it would seem that the DSC local service was hard at work on my target node trying to make things work.  The problem was that DSC neglected a failed installer (or the resource in question failed to report it correctly).  In any case, this left DSC in a state where it thought a configurable something is happening, and thus it should prevent new things from happening. 

Specifically, I was trying to install SQL Server using xSqlPs, but the password I specified for sa did not meet the strong password requirements and the installation exited.  For some reason I’m still investigating, the xSqlServerInstall resource failed to notice the error.

The Fix

To get DSC working again, I did the following steps, on the target machine,in this order:

  1. Delete c:\windows\system32\configuration\pending.mof;
  2. Stop all WMI processes;
  3. Restart the WinRM service;

The first step was the only one I hadn’t tried, because I didn’t know anything about that file.  And it’s the key – that file tells DSC what needs to be done.  If it isn’t there, DSC seems to think that everything is back to being cool.

The Code

Here is some code I’ve started using to automate the fix described above.

remove-item $env:systemRoot/system32/configuration/pending.mof -force;
get-process *wmi* | stop-process -force;
restart-service winrm -force

Good luck!



If it’s Worth the Going it’s Worth the Ride

§ August 9, 2014 18:34 by beefarino |

My best friend from childhood is Lee Carpenter. 

He and I lived in adjacent lots that shared a corner.  That corner never grew grass because we were always stomping back and forth between our houses.  He had a swing set in his yard and I had piney woods with trees to climb and access to the creek.  He used to let me ride his larger Big Wheel because I was bigger than him and couldn’t ride mine anymore, but that way we could both cruise around our neighborhood together looking for trouble.  I went to his First Communion even though I had to wear uncomfortable clothes and no idea what a First Communion was or what was happening.  Our Lego collections routinely intermingled.  Once he added pretend wings to our pretend pirate ship because he knew I was deadly afraid of the ocean.  We protected each other when our neighbor’s big mean dog got out of its yard and came after us.  We took a dance class together because our moms wanted us to.  We once spent an afternoon figuring out how matchbox cars are put together by smashing ours apart.  Lee’s awesome, and I just got off the phone with his mother.  He passed away on July 24, 2014 from a rare germ cell cancer he apparently carried in him for his whole 41 years on Earth. 

Getting back in touch with Lee has been on my GTD “someday” list.  For years.  I’m looking at the list right now, and it’s on there.  It just says “Lee?” but I know what it means.  I probably copied that item from list to list maybe a dozen times over the span of years.  Something I should really do at some point.

And that’s as far as my effort went.  The stupid line item doesn’t matter anymore.  It’s no longer within my purview as to whether it happens.  It’s a terribly harsh reminder that as important as goals are, they’re just meaningless noise if you don’t make the effort.

So I know a Lee whose father left, but I’ll never know the Lee who raised a son on his own.

I know a Lee who couldn’t read.  I’ll never know the Lee who taught himself to do so in his Twenties. 

I know a Lee who went to some “special” school no adult would elaborate on.  I’ll never know the Lee that worked in the Smithsonian restoring historical pieces.

I know a Lee who could build homes for Star Wars action figures out of Legos.  I’ll never know the Lee who could recreate authentic furniture stains and polishes from different historical periods.

I’m happy to know the Lee I know.  But I think I’ll always wonder about the other one.  He sounds like a pretty great guy.

So hey, why don’t you stop reading this and do that thing you’ve wanted to do that you haven’t done.  Please.



Introducing Simplex

§ July 31, 2014 10:05 by beefarino |

imageDuring my P2F talk at the PowerShell Summit NA 2014, I announced a project that would make creating a PowerShell Provider “stupid simple.”  I happily present you the first iteration of this stupid simplicity in the form of the Simplex open source project.

The goal of Simplex is to remove any barrier between the operator and the items they would like to access as a PowerShell drive.  Instead of focusing on C# types, interfaces, and cmdlet support, Simplex keeps you in script, using a simple domain-specific language (DSL) based on PowerShell to define a drive hierarchy.  Here is an example of the DSL:

root { # the root folder of the drive
    folder System { # a folder named System
        script Processes -id Id { # a folder named Processes
            get-process                   # that contains Process objects
        }
        script Errors -id Index { # a folder named Errors containing event log entries
            get-eventLog -log application -entrytype error -newest 25
        }
    }
}

To mount this Simplex script as a PowerShell drive, you just need to use the Simplex module, like so:

import-module simplex;
new-psdrive -name s -psprovider simplex -root "c:\path\to\simplexscript.ps1"

Once the script it mounted, you can navigate the folders and script containers as if they were a filesystem:

PS C:\Windows\SysWOW64\WindowsPowerShell\v1.0> cd s:

PS s:\> dir


    Container: Simplex\Simplex::C:\share\simplex.ps1


           Type       Name                    
---------- ----       ----                    
d+~<       Folder     System                  



PS s:\> cd system

PS s:\system> dir


    Container: Simplex\Simplex::C:\share\simplex.ps1\system


           Type       Name                    
---------- ----       ----                    
d+~<       Script     Processes               
d+~<       Script     Errors                  



PS s:\system> cd errors

PS s:\system\errors> dir

   Index Time          EntryType   Source                 InstanceID Message                                                                                                                      
   ----- ----          ---------   ------                 ---------- -------                                                                                                                      
   63846 Jul 31 09:05  Error       Application Error            1000 ...

Simplex DSL

The Simplex DSL has three elements: root, folders, and scripts.  Each element defines a container location on the drive.  The root element defines the root of the drive and contains any number of script and folder elements.

root {
    # any number of script and/or folder elements
}

Folders can also contain other folders and script elements, and folders must have a name.

folder <foldername> {
    # any number of script and/or folder elements
}

Scripts are containers that use bits of PowerShell to supply the items they contain.  Scripts elements also must have a name, and they can optionally specify an –idField parameter to identify a property to be used as the item’s child name.

script <foldername> [-idField <propertyname>] {
    # PowerShell script to return objects from this folder
}

The DSL is “just PowerShell,” so you can actually do any PowerShell things you want to do.  In this example, the DSL generates folders on demand based on the available performance counter sets:

root {
    get-counter -list * | foreach {
        $folderName = $_.CounterSetName;
        
        script $folderName {
            #...   
        }
    }
}

When you mount and explore the drive, you’ll find a set of folders generated from the script:

PS g:\> dir


    Container: Simplex\Simplex::C:\share\gen.ps1


           Type       Name                    
---------- ----       ----                    
d+~<       Script     RAS                     
d+~<       Script     WSMan Quota Statistics  
d+~<       Script     Network QoS Policy      
d+~<       Script     SMB Client Shares       
d+~<       Script     SynchronizationNuma     
d+~<       Script     Synchronization         
d+~<       Script     Event Tracing for Win...
d+~<       Script     Thermal Zone Information
d+~<       Script     Processor Information   
d+~<       Script     Event Tracing for Win...
d+~<       Script     FileSystem Disk Activity
# ...

So please check out the project, submit any issues/features you find/want.  And as always, enjoy!