Welcome to MSDN Blogs Sign in | Join | Help

V2 Interview: Universal Code Execution Model

At TechEd, I did an interview with Kevin Remde where I discussed the V2 Universal Code Execution model in detail.  You can see it at:  Universal Code Execution Model (UCEM)—a vision of how PowerShell scripts can run anywhere, anytime in just the right semantics.

You can access the entire library of interviews HERE.

Jeffrey Snover [MSFT]
Windows Management Partner Architect
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

Some WMI instances can have their first method call fail and get-member not work in PowerShell V1

Due to a problem retrieving the available methods in V1 that we have worked around for the upcoming version of PowerShell, you might experience that the first method call to a WMI object fails with a message that mentions:

           Exception calling GetType() with “0” argument(s): “You cannot call a method on a null-valued expression.”

 

This happens when calling the first method in objects that are not in the root\cimv2 like:

           $instance=([wmiclass]"root\MyNamespace:MyObject").CreateInstance()

           $instance.GetType()

 

As a PowerShell V1 workaround, a first call to GetType() can be performed to prevent the failure in other method calls.

 

Also, the get-member cmdlet will fail to work with the instance above with the following error message:

           Get-Member : Exception retrieving members: “Not Found “

 

As a PowerShell V1 workaround, you can list the properties available in the object by calling:

         $instance.PsObject.Properties | format-table Name

 

We apologize for the inconvenience this might cause.

 

Lucio Silveira [MSFT]
Software Developer Engineer
Visit the Windows PowerShell Team blog at:   
http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx 

Posted by PowerShellTeam | 2 Comments
Filed under: ,

When NOT To Use "WHERE"

I've seen a number of scripts that look like this:

 GET-XXXX | Where {$_.name -eq "foo"} 

or

GET-XXXX | Where {$_.name -like "A*"}

Whenever you see code like this, it is a sign that the GET-XXXX is not designed correctly.   (NOTE:  GET-XXXX is NOT a porn retrieval cmdlet - it is a standin for any GET-<SOMETHING> cmdlet).

The whole point of a cmdlet is to think about the USER and deliver the correct experience.  As a GENERAL rule, we encourage cmdlet developers to leverage PowerShell utilities like WHERE, SORT, FORMAT, etc and NOT to put that function into their cmdlets.  The reason for this is that this makes the cmdlet more complicated and provides NEW semantics that the user has to learn.

There are a couple of exceptions to this general rule:

  1. GET cmdlets should support -NAME.  A VERY large percentage of the time people do a GET, they want a specific item or a set of NAMED items so you should hotrod this experience by directly supporting it.
    • NAME should take a multiple inputs and support wildcards. e.g.  "get-process -name *ss,a*"
  2. GET cmdlets should support -FILTER if your getter has native query capabilities.  Users can decide whether the perf advantage of your cmdlet is worth learning the new syntax [in most cases it will be].
    • e.g.  If/when there are a set of AD cmdlets, they should support -FILTER and take an LDAP query. 
    • The APIs that support Get-Process have no native filtering which is why it doesn't support it but the file system APIs do which is why "DIR -FILTER A*" works.

Cheers!

Jeffrey Snover [MSFT]
Windows Management Partner Architect
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

PowerShell Abstractions & the Community

Smart guy Don Jones has a good blog entry where he discusses ABSTRACTIONs with the question, "Do I need .NET, WMI, COM, and all that to use PowerShell?" 

  • I agree that the correct abstraction for users (admins, etc)  is Cmdlets (and Providers [Don didn't mention this but he should have]).
  • Getting full cmdlet coverage what I call "digging ourselves out of a 30 year hole".
  • PS provides access to lower level abstractions (.Net, COM, WMI, ADO, ADSI, XML, text-parsing, etc).
  • PS V2 allows you to write Cmdlets using PS.
  • PS V2 supports Modules which make it easy to share PS Scripts between users.

ERGO:  PS V2 enables the community to create and share the correct user abstractions so you don't have to wait for MSFT.

NOTE: Even when MSFT provides full cmdlet coverage - you'll still need to know which cmdlets to use and how to stich them together to solve your specific problem.

This is why I tell everyone that ALL ADMINS NEED TO BE ACTIVELY ENGAGED IN THE COMMUNITY

  1. You need to look to the community for the solutions for your problems. 
  2. When you have a question, ask that question in a community forum.  Your question and the answer will get indexed by the search engines and help the next hundred people that have the same question.
  3. Don't just be a freeloader :-) - help the community.  When you figure something out - you need to share it with a newsgroup post or a blog. 
    • I'm sure that most of you are were all of us were a few years ago and are active readers but not posters thinking that no one would be interested in your work.  If that describes you - you are wrong. 
    • We can all learn from each other. 
    • JUST DO IT.  The next blog entry is easier than the last one so make a commitment to start a blog and post a few entries. 

What's the best way to start with the community?     If you haven't already bookmarked http://powershellcommunity.org/ - do it now. 

Cheers! 

Jeffrey Snover [MSFT]
Windows Management Partner Architect
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

All About Modules

One of the coolest new features of Windows PowerShell is PowerShell modules.  I've just written a tutorial about how to use them on my personal blog.

You can check out the full post for more details, but here are some easy things to remember about modules:

  • Modules can be scripts with functions, scripts that include other functions, or assemblies (DLLs) containing Cmdlets or providers
  • Modules let you cleanly separate code
  • Modules make it easy to depend on other code
  • Modules can contain private variables or functions
  • Modules let you refer to functions more explicitly (with & (Get-Module ModuleName) FunctionName )
  • You can take any .PS1 file that contains functions, and save it as a .PSM1, and you have made a module

The module examples also include a few PowerShell functions you might use in day-to-day life, such as being able to Search-WindowsDesktop, Get-RecordedTV, or Remove-RecordedTVBySeries, and are a great practical example of how you can use modules to cleanly separate code.   Check it out.

Hope this helps,

James Brundage [MSFT]

VMWare PowerShell Cmdlets Released (And Opportunity to Win $$$$)

On Monday VMWare offically released their PowerShell cmdlets in a ship vehicle called the VMWare Infrastructure (VI) Toolkit.  What could be better than that?  Yup - you guessed it - it's FREE!!  Check out the details HERE.

Download the free toolkit HERE.

Free!  What could be better than that?  Well they could pay you to use it.  :-)  

Well ...  actually, it's almost that good.   VMWare is holding a Scripting Contest for the best scripts using the VI toolkit.  The winner will receive an all-expense paid trip to VMWorld 2008 Las Vegas or $5,000!  This is a great opportunity to show off your PowerShell skills and profit thereby.  Is this a wonderful world or what!   Check out the details HERE.

Vegas ... hmmmm.  All expense paid trip to Vegas .... hmmmm.   I wonder if that would include the divorce lawyer.   I'm not sure they though that one out.  ha ha!  :-)

Congratulations on the great job VMWare!

Jeffrey Snover [MSFT]
Windows Management Partner Architect
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

Invoking PowerShell from VBScript (COM)

There are a number of scenarios where you might want to call PowerShell from VBScript. 

  • You might already have an VBScript that does some function and you want to update it to include some PowerShell operation but don't want to convert the entire script to PowerShell. 
  • You might have some people on your staff that are very comfortable with VBScipt and aren't ready to put it down and do everything in PowerShell. 
  • You might have a management tool that is hardwired to invoke VBScripts and doesn't know anything about PowerShell (yet!).

These are some of the scenarios we thought about when we considered providing a COM interface to the PowerShell engine.  To ship is to choose and this scenario got a lower priority than other features so we never got around to it.  Luckily, the superstars at Sapien have come to the rescue with ActiveXPosh .   ActiveXPosh is a COM component which gives you easy access to PowerShell from any COM capable scripting language (VBScript, JScript and others).   This has been out for a while but it came out during a period when my hair was on fire so I don't recall seeing it.  There is a good description of its capabilities HERE.

With ActiveXPosh you can do things like:

Set ActiveXPosh = CreateObject("SAPIEN.ActiveXPosh")
if ActiveXPosh.Eval("Get-Process Winword") = vbTrue Then
     WScript.Echo "Word is running"
Else
     WScript.Echo "Word is NOT running"
End If

Pretty simple stuff!  So - how could it get any better?  Yup - you guessed it, ActiveXPosh is FREE.  Is this a wonderful world or what?

Thank you SAPIEN!

Jeffrey Snover [MSFT]
Windows Management Partner Architect
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

Naming Shells and Consoles

Recently a product team asked me what entries they should put into their Program Groups folder.  They need an entry to launch their admin GUI and to launch  PowerShell with their snapin (they could do this by launching a Minishell which is a non-extensible version of PowerShell that has that products snapins baked in or they could do this by launching PowerShell specifying a console file (-PSConsoleFile ) which has their snapins).

The question was - what should they call the PowerShell link.  I thought a number of different options and then decided to look and see what the Exchange team had done.  Those guys are great so you are never wrong to go take a look at how they do things. 

Exchange has the following links in their Program Groups folder:

  • "Exchange Management Console" for their GUI (EMC)

  • "Exchange Management Shell" for their Powershell Link (EMS)

That looks like a pretty good solution to me.  Use the term "Console" for your GUI and "Shell" for your PowerShell shell.

 

So remember -the lesson for the day is:  When in doubt, see what Exchange did.  :-)

 

Jeffrey Snover [MSFT]
Windows Management Partner Architect
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

PowerShell Build Environment for Windows SDK

The Windows SDK team would like your feedback on what features you would like most in a future Windows SDK.  One of your choices is a PowerShell Build Environment.  If this is something that would be useful to you, go HERE and take the survey and let them know.

 Cheers!

Jeffrey Snover [MSFT]
Windows Management Partner Architect
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

 

PowerShell Laptop Stickers

I think I've blogged about this in the past but I keep getting asked about the cool PowerShell sticker I have on my laptop so I'll mention it again.  The superstars at Nsoftware are giving away free PowerShell stickers HERE

No laptop is complete without one!  :-)
Hmmmm there's a thought:  "PowerShell Inside". 

Jeffrey Snover [MSFT]
Windows Management Partner Architect
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

Shift-FileIndex

Klaus Graefensteiner has a great blog entry HERE where he publishes a great function called Shift-FileIndex.  He was scanning files which created names with indexes (e.g. Vacation_0021.jpg ).  Being the real world - things went wrong and he had duplicated pages which he then deleted which then left holes in the numbering and so on.  He is halfway through Bruce Payette's PowerShell in Action book and decided to get his money's worth and solve this problem using PowerShell to great effect.

It is a very nice script which takes good advantage of Regular Expressions.  During my talk in Atlanta someone asked me for an example of using "Capture Groups" in Regular Expressions.  Klaus' script uses then to very good effect so check out his script (line 21).  The capture group itself is quite chewy (which is why I didn't have an answer off the top of my head in Atlanta [I always need to start with an example]): 
    '^(?<NAME>.*?)(?<INDEX>\d{4})(?<EXT>\..*$)'
You might ask, "why would I put up with that mess?" and the answer is that syntactic headache allows you a ton of syntactic simplicy downstream:
   $matches.NAME

 

Here is a sample usage of the function he wrote.

dir $Home\Desktop\Scans | Shift-FileIndex -firstIndex 39 -lastIndex 40 -shiftBy 100
dir $Home\Desktop\Scans | Shift-FileIndex -firstIndex 41 -lastIndex 121 -shiftDown -shiftBy 2
dir $Home\Desktop\Scans | Shift-FileIndex -firstIndex 139 -lastIndex 140 -shiftDown -shiftBy 19

Great work Klaus!
Jeffrey Snover [MSFT]
Windows Management Partner Architect
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

PowerShell ASP - Too cool!

For the longest time, people have been asking me when they'll be able to use PowerShell in ASP.  It makes perfect sense - PowerShell is a great language that let's you do amazing things quickly.  Sadly, my answer has always been:

At Microsoft, to ship is to choose.

We are trying to solve the problem of administrating and automating Windows and until we get things like Remoting, Jobs, Eventing, etc done, it would be a breach of our responsibilities to pursue ASP programming no matter how cool and useful it would be.  Now let me be clear, I believe ASP programming is SUPER useful to Admins (as well as everyone else).  It is just that we need to do first things first.

So now to the great news:  The superstars at NSoftware have finally solved this problem and published PowerShellASP.  Here is their description of it:

PowerShellASP is an ASP-like template language for Web Applications; templates contain a mixture of markup (HTML, XML or whatever you want to generate) and inline PowerShell code. At runtime, templates/pages are fully translated to PowerShell code and executed as a single unit inside a PowerShell pipeline, with the results sent to the client browser.

PowerShellASP runs off the ASP.NET platform, implemented as a custom IHttpHandler mapped to *.ps1x files. Because of this, you can mix PowerShellASP pages alongside any ASP.NET application. This provides a great way to leverage PowerShellASP inside your existing applications as needed or you can create complete applications from scratch based only on *.ps1x pages.

 Are you drooling yet?  If not, check out this example:

<html>
  <body>
    <table>
      <tr><td>ID</td></tr>
      <% get-process | foreach { %> 
        <tr>
          <td><%=$_.ID%></td>
          <td><%=$_.ProcessName%></td>
        </tr>
      <% } %>
    </table>
  </body>
</html>

Is that awesome or what? 
Still not drooling?  Check this out:  it's FREE!
I told you they were superstars!
Download it and blog about your experiences - I'd love to hear what you think.

BTW:  NSoftware is also ships NetCmdlets, a rich collection of cmdlets to deal a wide range of protocols including SSH and SNMP.  Did you know that you can do remote PowerShell over SSH today?  With NetCmdlets you can.  Check those out HERE.

Enjoy!

Jeffrey Snover [MSFT]
Windows Management Partner Architect
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

 

 

Dude, Where's My Manual?

Windows PowerShell comes with a lot of help files and documents, but, somehow, my favorite and most frequently used help is the help that  I get by typing "Get-Help" in the console.

 

And I have always wondered why this help is not readily available as a  single document, ready to be viewed, searched, and printed. Well, now it is, with this simple Get-Manual script.

 

This script merges all of the about*.txt files in the C:\Windows\System32\WindowsPowerShell\V1.0 directory and puts them all into one nicely formatted Microsoft Word document (.doc). Once you have this document, you can search it for any specific content. Or, you can print it and enjoy reading it while sitting in your favorite armchair by the fireplace during the long winter evenings :)

 

---------------------------------------------------------------------

 

# Get-Manual.ps1

# This script merges the text from all about* help files in the Windows

# PowerShell installation directory ($pshome) into one Microsoft Word

# document (.doc) file and opens the file that was created.

 

 

# Set the file name for generated WordML document.

$doc = "AboutHelp.doc"

 

"Generating MS Word document..."

 

$sb=new-object system.text.stringbuilder

 

$null = $sb.Append(@'

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>

<?mso-application progid="Word.Document"?>

<w:wordDocument

  xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml"

  xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint"

       w:macrosPresent="no" w:embeddedObjPresent="no" w:ocxPresent="no" xml:space="preserve">

       <w:styles>

              <w:versionOfBuiltInStylenames w:val="4" />

              <w:style w:type="paragraph" w:default="on" w:styleId="Normal">

                     <w:name w:val="Normal" />

                     <w:rPr>

                           <w:rFonts w:ascii="Lucida Console" w:h-ansi="Lucida Console" w:cs="Lucida Console" />

                           <w:sz w:val="24" />

                           <w:sz-cs w:val="24" />

                           <w:lang w:val="EN-US" w:fareast="ZH-CN" w:bidi="AR-SA" />

                     </w:rPr>

              </w:style>

              <w:style w:type="paragraph" w:styleId="Heading1">

                     <w:name w:val="heading 1" />

                     <wx:uiName wx:val="Heading 1" />

                     <w:basedOn w:val="Normal" />

                     <w:next w:val="Normal" />

                     <w:pPr>

                           <w:pStyle w:val="Heading1" />

                           <w:keepNext />

                           <w:spacing w:before="240" w:after="120" />

                           <w:outlineLvl w:val="0" />

                     </w:pPr>

                     <w:rPr>

                           <w:b />

                           <w:b-cs />

                           <w:kern w:val="32" />

                           <w:sz w:val="32" />

                           <w:sz-cs w:val="32" />

                     </w:rPr>

              </w:style>

       </w:styles>

       <w:body>

'@)

 

# Get all text lines in about* help files.

$filter = "about*.txt"

dir $pshome -filter $filter -recurse | %{

       $null = $sb.Append("<w:p><w:pPr><w:pStyle w:val=`"Heading1`" /></w:pPr><w:r><w:t>")

       $null = $sb.Append($_)

       $null = $sb.Append("</w:t></w:r></w:p>")

      

       get-content $_.FullName | %{

              $null = $sb.Append("<w:p><w:r><w:t>")

              $null = $sb.Append($_.replace("&", "&amp;").replace("<","&lt;").replace(">","&gt;"))

              $null = $sb.Append("</w:t></w:r></w:p>")

       }

}

 

 

$null = $sb.Append("</w:body></w:wordDocument>")

 

#Write generated string to document file.

$sb.ToString() | out-file $doc -encoding UTF8

 

# Open the resulting file in MS-Word.

$null = [System.Diagnostics.Process]::Start("$pwd\$doc")

 

"Done"

 

------------------------------------------------------------------------------

 

Vladimir Averkin

Windows PowerShell Test

Atlanta Talk

I has a blast talking to a group of customers in Atlanta today about where PowerShell is and where it is going.  Attached is the deck I presented.

Jeffrey Snover [MSFT]
Windows Management Partner Architect
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

Posted by PowerShellTeam | 7 Comments

Attachment(s): Atlanta.pptx

Translating Literature Into PowerShell

James O'Neill got it into his head that he could translate literature into PowerShell.  He has a hilarious one-line Waiting for Godot and a one screen MacBeth HERE

Dmitry Sotnikov picked up the challenge and has a Hamlet blog HERE.

I like the idea and have decided to do the world a favor and finish the job that Jean Paul Satre's editors failed to do.  Here is "No Exit"

           While ($True) { $OtherPeople = "Hell" } Exit

[Monday evening update: I decided this was a better interpretation of NoExit] 

I bet old Jean Paul was the life at a party!

I remember a great story about Kurt Vonnegut speaking at a book fair and during the Q&A a 13 year old boy asked the following question:  "Mr Vonnegut, I've read all your books and it seems like what you are trying to say is, 'Life comes and goes but courtesy must prevail'".  Vonnegut replied something to the effect that he was taken aback the his entire literary career could be so accurately stated in a single statement and that he was going to have to have a severe discussion with his editors. 

So with a great deal of respect, I give you the entire works of Kurt Vonnegut:

          While ($NotDead) {$Courtesy = $True }

Jeffrey Snover [MSFT]
Windows Management Partner Architect
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

More Posts Next page »
 
Page view tracker