Microsoft’s next generation command shell

Back in June 2004, I got in a panic because I heard that VBScript was about to be phased out. Don Jones commented that VBScript will still be there in Windows, it just won’t be developed any further, then later I heard about the new Microsoft scripting host (MSH) shell (codenamed Monad).

At yesterday’s IT Forum ’05 highlights (part 2) event, Thomas Lee gave a preview of Monad. Although I am enrolled on the Microsoft command shell beta program, pressures of work and family life have left very little time to do anything with it up to now, but having seen Thomas’ demo, I’ve installed MSH beta 3 on my day-to-day notebook computer and will try to use it instead of cmd.exe, regedit.exe and some of my other everyday tools.

Those of us who have worked with Windows since… well since MS-DOS… will remember the command prompt, as will those who use other operating systems. Graphical user interfaces (GUIs) are all very well (and a well designed GUI can be remarkably intuitive), but a command line interface (CLI) is my preference. Despite a whole load of new and powerful commands in recent Windows releases (like netsh.exe), Windows still lags behind Unix in many ways when it comes to command line operations and MSH is an attempt to catch up with, and then exceed, the tools provided by other operating systems.

MSH is a next-generation shell that is intended to:

  • Be as interactive and scriptable as BASH or KSH.
  • Be as programmatic as Perl or Ruby.
  • Be as production-oriented as AS/400 CL or VMS DCL.
  • Allow access to data stores as easily as accessing file systems.

It sounds like a tall order but amazingly, Microsoft seem to have cracked it. MSH is also pretty easy to use and, it’s secure by default, avoiding many of the issues associated with VBScript. So secure, in fact, that before running MSH you may wish to execute the following registry change:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSH\1\ShellIds\Microsoft.Management.Automation.msh]
"Path"="C:\\Program Files\\Microsoft Command Shell\\v1.0\\msh.exe"
"ExecutionPolicy"="Unrestricted"

(There’s more on MSH security below).

MSH is instantly recognisable. If I was to type cmd, I would be greeted with something similar to the following:

Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\>

If I type msh instead, everything is very familiar:

Microsoft Command Shell
Copyright (C) 2005 Microsoft Corporation. All rights reserved.

MSH C:\>

Type dir and guess what happens? For that matter, type ls! If you want to see the contents of a file then either type filename or cat filename will work too. get-history returns a list of commands, to re-run, save, or edit.

Whereas Unix (and Unix-like) systems tend to store configuration in text files, Windows configurations are incredibly complex with multiple data stores (the registry, text files, DNS, Active Directory, etc.). These data stores normally fall into one of two categories: hierarchical, highly recursive data structures (file system directories, registry keys, Active Directory organizational units, etc.) or fairly flat structures (e.g. DNS zones and records). MSH makes them all easy to navigate using a system of data providers.

For example, I can type cd hklm: followed by dir to see all the HKEY_LOCAL_MACHINE keys, navigating the registry as though it were a file system. This simplicity is both elegant and incredibly powerful. There are no AD or DNS providers yet, but the next version of Exchange (codenamed Exchange 12) will include MSH support, treating Exchange databases as just another data store (get-mailbox, etc.). Exchange 12 support is not implemented as a data provider, but as a commandlet (cmdlet), because its data structure is not really hierarchical (at least down to the mailbox level) – the full list of Exchange commands can be found using get-excommand.

For example, if I want to see the details of my system, I can use get-wmiobject command. That’s a bit long to type, so I can actually use get-w and then complete the command with the tab key (as can in cmd.exe these days). get-wmiobject win32_computersystem returns the details of my system as an object with attributes, that I can assign to a variable (e.g. $mysystem=get-wmiobject win32_computersystem). After that, $mysystem.name returns the name of my computer, $mysystem.manufacturer returns Fujitsu Siemens and $mysystem.model returns Lifebook S7010. That would have been so much harder to obtain in VBscript. Take it to the next level and you can see how the data can be queried and actions taken according to the results (e.g. if ($mysystem.model -eq "Lifebook S7010") {"Do something"}).

MSH has built in help (e.g. get-wmiobject -?) and more is no longer an external command so get-wmiobject -? | more works too.

Some commands will return an array of objects, for example get-wmiobject -list. That’s a pretty long and unmanageable list but if I use $wmilist=get-wmiobject -list, I can use $wmilist.length to see how many objects were returned, $wmilist[objectnumber] to view a single object and of course I can also use $wmilist[objectnumber].attributename to refer to a single item.

On a typical Unix system, pipes are used to pass text between commands. Scripts can be used to split strings and extract data (also known as prayer-based parsing, because if the command output is changed, the scripts break). MSH pipes are .NET objects with metadata. That means that a hierarchy of objects can be passed between commands. So, I can also show my WMI array as a table by piping it through format table (ft), i.e. $wmilist | ft (fl is format list).

Having looked at how simple to use, yet powerful, MSH is, let’s look at some of the product specifications:

  • MSH is intended to support a number of different administrative levels:
  • Operators – command line only.
  • Simple scripters – simple sequences, untyped variables and functions with unnamed parameters.
  • Advanced scripters – typed variables and functions with named parameters.
  • Sophisticated scripters – scoped variables, functions with initialised parameters, function cmdlets and scriptblocks.
  • The four administrative levels are supported with different script types:
    • Text – .NET interpretations of the traditional Unix scripting model.
    • COMWindows script host (WSH)/VBScript-style scripting.
    • .NET – for manipulating any native .NET object.
    • Commands – MSH cmdlets emitting objects.
  • These script types are supported with a variety of data types, including .NET, XML, WMI/ADSI and ADO.
  • MSH is intended to be tremendously customisable and it will eventually allow dispense with the style separation between GUI, CLI and systems programming skills so that even an infrastructure bod like me will be able to issue a GUI command (or use a Win32 program) and see what the MSH equivalent command is, so that I can build my own scripts and run a task repeatedly! Unfortunately this GUI-CLI functionality has been dropped from the first release, but hopefully we’ll see it in a service pack later.

    From a security perspective, MSH is extremely secure, with four operational modes:

    • Restricted mode allows interactive operations only, with no script execution.
    • AllSigned mode requires that scripts must be signed by a trusted source.
    • RemoteSigned mode requires that scripts from the Internet must be signed by a trusted source.
    • Unrestricted mode will allow any script to run, but will always warn before remote scripts are executed.

    Other security measures include:

    • No file association for .msh files.
    • The current folder (.) is not on the path by default.

    So when can we get MSH? Beta 3 is available for download now and the final release is expected with Exchange 12. Although MSH will not included with Windows Vista, I’m told that it does work on a Vista/Longhorn platform.

    Finally, for one more example of how easy Monad can be to use, try this:

    "Monad Rocks " * 200

    Links
    Thomas Lee’s Monad information centre
    Monad on Channel 9
    Monad product team blog
    MSH on Wikipedia
    microsoft.public.windows.server.scripting newsgroup

    5 thoughts on “Microsoft’s next generation command shell


    1. Hi Thomas,
      I didn’t know you still read my blog ;-)

      I hope you didn’t mind me stealing your thunder! As you can tell, I was impressed with the simplicity and yet enormous potential of Monad.

      All the best, Mark

    Leave a Reply