Monday, June 20, 2005 1:45 PM bart

Adventures in Monad - part 2

Okay, let's resume where we suspended :-). In the previous Monad adventure episode I've been talking about the concept of cmdlets or "command-lets" as the atomic units of work in the Monad system. Now, let's dive deeper into this stuff and show some examples of working with cmdlets.

Obtaining a list of cmdlets

In RDBMSs you can query the databases on the system using a database itself (the catalog). In a similar fashion there's a cmdlet in Monad to display all of the cmdlets on the system. It's called Get-Command:

MSH> get-command

Command Type    Name                      Definition
------------    ----                      ----------
Cmdlet          get-command               get-command [-Verb String[]] [-Nou...
Cmdlet          get-help                  get-help [[-Name] String] [-Catego...
Cmdlet          get-history               get-history [[-Id] Int64[]] [[-Cou...
Cmdlet          invoke-history            invoke-history [[-Id] String] [-Ve...
Cmdlet          add-history               add-history [[-InputObject] Object...
Cmdlet          foreach-object            foreach-object [-Process] ScriptBl...
Cmdlet          where-object              where-object [-ScriptToApply] Scri...
Cmdlet          set-mshdebug              set-mshdebug [-Trace Int32] [-Step...
Cmdlet          add-content               add-content [-Path] String[] [-Val...
Cmdlet          clear-content             clear-content [-Path] String[] [-P...
Cmdlet          clear-property            clear-property [-Path] String[] [-...
Cmdlet          combine-path              combine-path [-Path] String[] [-Ch...
Cmdlet          convert-path              convert-path [-Path] String[] [-Ve...
Cmdlet          copy-property             copy-property [-Path] String[] [[-...
Cmdlet          get-eventlog              get-eventlog [-LogName] String [-N...
Cmdlet          get-childitem             get-childitem [[-Path] String[]] [...
Cmdlet          get-content               get-content [-Path] String[] [-Rea...
Cmdlet          get-property              get-property [-Path] String[] [[-P...
Cmdlet          get-WMIObject             get-WMIObject [-Class] String [[-P...
Cmdlet          move-property             move-property [-Path] String[] [-D...
Cmdlet          get-location              get-location [-Provider String[]] ...
Cmdlet          set-location              set-location [[-Path] String] [-Pa...
Cmdlet          push-location             push-location [[-Path] String] [-P...
Cmdlet          pop-location              pop-location [-PassThru] [-StackNa...
Cmdlet          new-drive                 new-drive [-Name] String [-Provide...
Cmdlet          remove-drive              remove-drive [-Name] String[] [-Pr...
Cmdlet          get-drive                 get-drive [[-Name] String[]] [-Sco...
Cmdlet          get-item                  get-item [-Path] String[] [-Filter...
Cmdlet          new-item                  new-item [-Path] String[] [-Type S...
Cmdlet          set-item                  set-item [-Path] String[] [[-Value...
Cmdlet          remove-item               remove-item [-Path] String[] [-Fil...
Cmdlet          move-item                 move-item [-Path] String[] [[-Dest...
Cmdlet          rename-item               rename-item [-Path] String [-Name]...
Cmdlet          copy-item                 copy-item [-Path] String[] [[-Dest...
Cmdlet          clear-item                clear-item [-Path] String[] [-Forc...
Cmdlet          invoke-item               invoke-item [-Path] String[] [-Fil...
Cmdlet          get-provider              get-provider [[-Provider] String[]...
Cmdlet          new-property              new-property [-Path] String[] [-Pr...
Cmdlet          parse-path                parse-path [-Path] String[] [-Pare...
Cmdlet          test-path                 test-path [-Path] String[] [-Filte...
Cmdlet          get-process               get-process [[-ProcessName] String...
Cmdlet          stop-process              stop-process [-Id] Int32[] [-PassT...
Cmdlet          remove-property           remove-property [-Path] String[] [...
Cmdlet          rename-property           rename-property [-Path] String [-P...
Cmdlet          resolve-path              resolve-path [-Path] String[] [-Cr...
Cmdlet          get-service               get-service [[-ServiceName] String...
Cmdlet          stop-service              stop-service [-ServiceName] String...
Cmdlet          start-service             start-service [-ServiceName] Strin...
Cmdlet          suspend-service           suspend-service [-ServiceName] Str...
Cmdlet          resume-service            resume-service [-ServiceName] Stri...
Cmdlet          restart-service           restart-service [-ServiceName] Str...
Cmdlet          set-service               set-service [-ServiceName] String ...
Cmdlet          new-service               new-service [-ServiceName] String ...
Cmdlet          set-content               set-content [-Path] String[] [-Val...
Cmdlet          set-property              set-property [-Path] String[] -Pro...
Cmdlet          format-list               format-list [[-Property] Object[]]...
Cmdlet          format-custom             format-custom [[-Property] Object[...
Cmdlet          format-table              format-table [[-Property] Object[]...
Cmdlet          format-wide               format-wide [[-Property] Object] [...
Cmdlet          out-null                  out-null [-InputObject MshObject] ...
Cmdlet          out-default               out-default [-InputObject MshObjec...
Cmdlet          out-host                  out-host [-Paging] [-InputObject M...
Cmdlet          out-file                  out-file [-Path] String [[-Encodin...
Cmdlet          out-printer               out-printer [[-Printer] String] [-...
Cmdlet          out-string                out-string [-Stream] [-Width Int32...
Cmdlet          update-formatdata         update-formatdata [-Trace] [-Force...
Cmdlet          export-csv                export-csv [-Path] String -InputOb...
Cmdlet          import-csv                import-csv [-Path] String[] [-Verb...
Cmdlet          export-alias              export-alias [-Path] String [[-Nam...
Cmdlet          Invoke-Command            Invoke-Command [-Command] String [...
Cmdlet          get-alias                 get-alias [[-Name] String[]] [-Exc...
Cmdlet          get-Culture               get-Culture [-Verbose] [-Debug] [-...
Cmdlet          get-Date                  get-Date [[-To] DateTime] [-Year I...
Cmdlet          get-host                  get-host [-Verbose] [-Debug] [-Err...
Cmdlet          get-member                get-member [[-Name] String[]] [-In...
Cmdlet          get-UICulture             get-UICulture [-Verbose] [-Debug] ...
Cmdlet          get-unique                get-unique [-InputObject MshObject...
Cmdlet          import-alias              import-alias [-Path] String [-Scop...
Cmdlet          match-string              match-string [-Pattern] String[] -...
Cmdlet          Measure-Object            Measure-Object [-InputObject MshOb...
Cmdlet          new-alias                 new-alias [-Name] String [-Value] ...
Cmdlet          new-Timespan              new-Timespan [[-From] DateTime] [[...
Cmdlet          read-host                 read-host [[-Prompt] Object] [-Sec...
Cmdlet          set-alias                 set-alias [-Name] String [-Value] ...
Cmdlet          set-Date                  set-Date [-To] DateTime [-DisplayH...
Cmdlet          Start-Sleep               Start-Sleep [-Seconds] Int32 [-Ver...
Cmdlet          tee-object                tee-object [-FileName] String [-In...
Cmdlet          Time-Expression           Time-Expression [[-Expression] Scr...
Cmdlet          write-host                write-host [[-Object] Object] [-No...
Cmdlet          write-progress            write-progress [-Activity] String ...
Cmdlet          new-object                new-object [-TypeName] String [[-A...
Cmdlet          select-object             select-object [[-Property] Object[...
Cmdlet          group-object              group-object [[-Property] Object[]...
Cmdlet          sort-object               sort-object [[-Property] Object[]]...
Cmdlet          get-variable              get-variable [[-Name] String[]] [-...
Cmdlet          new-variable              new-variable [-Name] String [[-Val...
Cmdlet          set-variable              set-variable [-Name] String[] [[-V...
Cmdlet          remove-variable           remove-variable [-Name] String[] [...
Cmdlet          clear-variable            clear-variable [-Name] String[] [-...
Cmdlet          Write-debug               Write-debug [-Message] String [-Ve...
Cmdlet          Write-verbose             Write-verbose [-Message] String [-...
Cmdlet          Write-Error               Write-Error [-Message] String [-Ca...
Cmdlet          Write-Object              Write-Object [-InputObject] Object...
Cmdlet          get-tracesource           get-tracesource [[-Name] String[]]...
Cmdlet          set-tracesource           set-tracesource [-Name] String[] [...
Cmdlet          trace-expression          trace-expression [-Name] String[] ...
Cmdlet          get-acl                   get-acl [[-Path] String[]] [-Audit...
Cmdlet          set-acl                   set-acl [-Path] String[] [-ACLObje...
Cmdlet          get-PfxCertificate        get-PfxCertificate [-Path] String[...
Cmdlet          get-credential            get-credential [-Credential] MshCr...
Cmdlet          get-AuthenticodeSignature get-AuthenticodeSignature [-Path] ...
Cmdlet          set-AuthenticodeSignature set-AuthenticodeSignature [-Path] ...
Cmdlet          new-SecureString          new-SecureString [-Verbose] [-Debu...
Cmdlet          export-SecureString       export-SecureString [-SecureString...
Cmdlet          import-SecureString       import-SecureString [-String] Stri...


MSH>

Quite some stuff, right? Now, Get-Process can be used to limit this list, based on the verb, the noun, or a wildcard:

MSH> get-command -verb set

Command Type    Name                      Definition
------------    ----                      ----------
Cmdlet          set-mshdebug              set-mshdebug [-Trace Int32] [-Step...
Cmdlet          set-location              set-location [[-Path] String] [-Pa...
Cmdlet          set-item                  set-item [-Path] String[] [[-Value...
Cmdlet          set-service               set-service [-ServiceName] String ...
Cmdlet          set-content               set-content [-Path] String[] [-Val...
Cmdlet          set-property              set-property [-Path] String[] -Pro...
Cmdlet          set-alias                 set-alias [-Name] String [-Value] ...
Cmdlet          set-Date                  set-Date [-To] DateTime [-DisplayH...
Cmdlet          set-variable              set-variable [-Name] String[] [[-V...
Cmdlet          set-tracesource           set-tracesource [-Name] String[] [...
Cmdlet          set-acl                   set-acl [-Path] String[] [-ACLObje...
Cmdlet          set-AuthenticodeSignature set-AuthenticodeSignature [-Path] ...


MSH> get-command -noun acl

Command Type    Name                      Definition
------------    ----                      ----------
Cmdlet          get-acl                   get-acl [[-Path] String[]] [-Audit...
Cmdlet          set-acl                   set-acl [-Path] String[] [-ACLObje...


MSH> get-command *service

Command Type    Name                      Definition
------------    ----                      ----------
Cmdlet          get-service               get-service [[-ServiceName] String...
Cmdlet          stop-service              stop-service [-ServiceName] String...
Cmdlet          start-service             start-service [-ServiceName] Strin...
Cmdlet          suspend-service           suspend-service [-ServiceName] Str...
Cmdlet          resume-service            resume-service [-ServiceName] Stri...
Cmdlet          restart-service           restart-service [-ServiceName] Str...
Cmdlet          set-service               set-service [-ServiceName] String ...
Cmdlet          new-service               new-service [-ServiceName] String ...


MSH>

Right, there's apparently more to see about cmdlets than what is displayed (look at the ellipsis on the right-hand side). How to show this? The Format-List cmdlet should be your friend in this kind of scenarios:

MSH> get-command get-service | format-list


Name          : get-service
CommandType   : Cmdlet
Definition    : get-service [[-ServiceName] String[]] [-Include String[]] [-Exc
                lude String[]] [-Verbose] [-Debug] [-ErrorAction ActionPreferen
                ce] [-ErrorVariable String] [-OutVariable String] [-OutBuffer I
                nt32]
                get-service -DisplayName String[] [-Include String[]] [-Exclude
                 String[]] [-Verbose] [-Debug] [-ErrorAction ActionPreference]
                [-ErrorVariable String] [-OutVariable String] [-OutBuffer Int32
                ]
                get-service [-Include String[]] [-Exclude String[]] [-Input Ser
                viceController[]] [-Verbose] [-Debug] [-ErrorAction ActionPrefe
                rence] [-ErrorVariable String] [-OutVariable String] [-OutBuffe
                r Int32]

Path          :
AssemblyInfo  :
DLL           : C:\Program Files\Microsoft Command Shell\System.Management.Auto
                mation.Commands.Management.DLL
HelpFile      : System.Management.Automation.Commands.Management.dll-Help.xml
ParameterSets : {Default, DisplayName, Input}
Type          : System.Management.Automation.Commands.GetServiceCommand
Verb          : get
Noun          : service

 

MSH>

Pipelines

The previous sample showed you two things: how to use Format-List and how to use the pipe symbol (|) to combine cmdlets by redirecting the output of one cmdlet to the input of another one in kind of a chain structure. Now, let's try to apply some filtering with Where-Object:

MSH> get-service | where-object { $_.status -eq "Running" }

Status   Name               DisplayName
------   ----               -----------
Running  1-vmsrvc           Virtual Machine Additions Services ...
Running  ADAM_BISGSS        BISGSS
Running  AeLookupSvc        Application Experience Lookup Service
Running  AudioSrv           Windows Audio
Running  Browser            Computer Browser
Running  CiSvc              Indexing Service
Running  CryptSvc           Cryptographic Services
Running  DcomLaunch         DCOM Server Process Launcher
Running  Dhcp               DHCP Client
Running  dmserver           Logical Disk Manager
Running  Dnscache           DNS Client
Running  ERSvc              Error Reporting Service
Running  Eventlog           Event Log
Running  EventSystem        COM+ Event System
Running  helpsvc            Help and Support
Running  HTTPFilter         HTTP SSL
Running  IISADMIN           IIS Admin Service
Running  lanmanserver       Server
Running  lanmanworkstation  Workstation
Running  LmHosts            TCP/IP NetBIOS Helper
Running  MSDTC              Distributed Transaction Coordinator
Running  MSSQL$SHAREPOINT   MSSQL$SHAREPOINT
Running  MSSQL$SQLEXPRESS   SQL Server (SQLEXPRESS)
Running  MSSQLSERVER        SQL Server (MSSQLSERVER)
Running  MSSQLServerOLAP... Analysis Server (MSSQLSERVER)
Running  Netman             Network Connections
Running  Nla                Network Location Awareness (NLA)
Running  PlugPlay           Plug and Play
Running  PolicyAgent        IPSEC Services
Running  ProtectedStorage   Protected Storage
Running  RemoteRegistry     Remote Registry
Running  ReportServer       Report Server (MSSQLSERVER)
Running  RpcSs              Remote Procedure Call (RPC)
Running  SamSs              Security Accounts Manager
Running  Schedule           Task Scheduler
Running  seclogon           Secondary Logon
Running  SENS               System Event Notification
Running  ShellHWDetection   Shell Hardware Detection
Running  Spooler            Print Spooler
Running  SPTimer            SharePoint Timer Service
Running  SQLBrowser         SQL Browser
Running  SQLSERVERAGENT     SQL Server Agent (MSSQLSERVER)
Running  TermService        Terminal Services
Running  TFSServerScheduler TFSServerScheduler
Running  TrkWks             Distributed Link Tracking Client
Running  W32Time            Windows Time
Running  W3SVC              World Wide Web Publishing Service
Running  winmgmt            Windows Management Instrumentation
Running  wuauserv           Automatic Updates
Running  WZCSVC             Wireless Configuration


MSH>

This deserves some extra explanation. The parameter of where-object contains the condition to filter for. In this case, we obtain a reference to every item in the list using the $_ operator. Using the dot operator we can select a property, in this case we choose for status. This value is then compared to the string "Running" for equality (-eq). To show some other operators, consider the following example:

MSH> get-service | where-object { $_.status -eq "Running" -and $_.name -like "MSSQL*" }

Status   Name               DisplayName
------   ----               -----------
Running  MSSQL$SHAREPOINT   MSSQL$SHAREPOINT
Running  MSSQL$SQLEXPRESS   SQL Server (SQLEXPRESS)
Running  MSSQLSERVER        SQL Server (MSSQLSERVER)
Running  MSSQLServerOLAP... Analysis Server (MSSQLSERVER)


MSH>

Should be clear I guess? Now, what can we query on the output of a Get-Service invocation? To find out about this, together wit the types, use Get-Member:

MSH> Get-Service | Get-Member -MemberType property


    TypeName: System.ServiceProcess.ServiceController

Name                MemberType Definition
----                ---------- ----------
CanPauseAndContinue Property   System.Boolean CanPauseAndContinue {get;}
CanShutdown         Property   System.Boolean CanShutdown {get;}
CanStop             Property   System.Boolean CanStop {get;}
Container           Property   System.ComponentModel.IContainer Container {g...
DependentServices   Property   System.ServiceProcess.ServiceController[] Dep...
DisplayName         Property   System.String DisplayName {get;set;}
MachineName         Property   System.String MachineName {get;set;}
ServiceHandle       Property   System.Runtime.InteropServices.SafeHandle Ser...
ServiceName         Property   System.String ServiceName {get;set;}
ServicesDependedOn  Property   System.ServiceProcess.ServiceController[] Ser...
ServiceType         Property   System.ServiceProcess.ServiceType ServiceType...
Site                Property   System.ComponentModel.ISite Site {get;set;}
Status              Property   System.ServiceProcess.ServiceControllerStatus...


MSH>

This is where the .NET types become visible.

Whatif? Confirm!

Now assume we want to take some action for the selected services (e.g. all MSSQL* services as explained above), for example to stop these services. This can be accomplished by piping the output of the Get-Service cmdlet to the input of the Stop-Service cmdlet. However, this can be a little too agressive, we want more control. There are various ways to do this, e.g. by using a foreach construct together with Read-Host to ask the user for input. Monad has built-in functionality however to see the "showplan" of the execution, by using the -whatif parameter:

MSH> get-service | where-object { $_.status -eq "Running" -and $_.name -like "MSSQL*" } | stop-service -whatif
What if: Operation "stop-service" on Target "MSSQL$SHAREPOINT (MSSQL$SHAREPOINT)"
What if: Operation "stop-service" on Target "SQL Server (SQLEXPRESS) (MSSQL$SQLEXPRESS)"
What if: Operation "stop-service" on Target "SQL Server (MSSQLSERVER) (MSSQLSERVER)"
What if: Operation "stop-service" on Target "Analysis Server (MSSQLSERVER) (MSSQLServerOLAPService)"
MSH>

Okay, that's fine. Let's execute it, but we don't want to stop the SHAREPOINT instance. We could extend the filter or ask for manual user intervention using -confirm. Let's use the latter one:

MSH> get-service | where-object { $_.status -eq "Running" -and $_.name -like "MSSQL*" } | stop-service -confirm

Continue with this operation?
Operation "stop-service" on Target "MSSQL$SHAREPOINT (MSSQL$SHAREPOINT)"
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help
(default is "N") :N

Continue with this operation?
Operation "stop-service" on Target "SQL Server (SQLEXPRESS) (MSSQL$SQLEXPRESS)"
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help
(default is "N") :Y

Continue with this operation?
Operation "stop-service" on Target "SQL Server (MSSQLSERVER) (MSSQLSERVER)"
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help
(default is "N") :Y
stop-service : Cannot stop service 'SQL Server (MSSQLSERVER) (MSSQLSERVER)' bec
ause it has dependent services. It can only be stopped if the Force flag is set
.
At line:1 char:98
+ get-service | where-object { $_.status -eq "Running" -and $_.name -like "MSSQ
L*" } | stop-service  <<<< -confirm

Continue with this operation?
Operation "stop-service" on Target "Analysis Server (MSSQLSERVER)
(MSSQLServerOLAPService)"
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help
(default is "N") :Y
MSH>

Okay, SQL Server couldn't be stopped because it has a dependency but it draws the overall picture of the principles of pipelines in Monad.

Aliasing

Right, we saw the use of Where-Object in the previous samples. Pretty powerful but nasty to type. An interesting concept in Monad to solve this problem is the use of aliases. The Get-Alias cmdlet show us all of the defined aliases:

MSH> get-alias

Command Type    Name                      Definition
------------    ----                      ----------
Alias           ac                        add-content
Alias           clc                       clear-content
Alias           cli                       clear-item
Alias           clp                       clear-property
Alias           cpi                       copy-item
Alias           cpp                       copy-property
Alias           cv                        clear-variable
Alias           cvpa                      convert-path
Alias           epal                      export-alias
Alias           fc                        format-custom
Alias           fl                        format-list
Alias           foreach                   foreach-object
Alias           ft                        format-table
Alias           fw                        format-wide
Alias           gal                       get-alias
Alias           gc                        get-content
Alias           gci                       get-childitem
Alias           gcm                       get-command
Alias           gdr                       get-drive
Alias           ghy                       get-history
Alias           gi                        get-item
Alias           gl                        get-location
Alias           gm                        get-member
Alias           gp                        get-property
Alias           gps                       get-process
Alias           group                     group-object
Alias           gsv                       get-service
Alias           gu                        get-unique
Alias           gv                        get-variable
Alias           help                      get-help
Alias           ic                        invoke-command
Alias           ihy                       invoke-history
Alias           ii                        invoke-item
Alias           ipal                      import-alias
Alias           ipcsv                     import-csv
Alias           mi                        move-item
Alias           mp                        move-property
Alias           nal                       new-alias
Alias           ndr                       new-drive
Alias           ni                        new-item
Alias           nv                        new-variable
Alias           oh                        out-host
Alias           rdr                       remove-drive
Alias           ri                        remove-item
Alias           rmi                       rename-item
Alias           rmp                       rename-property
Alias           rp                        remove-property
Alias           rv                        remove-variable
Alias           rvpa                      resolve-path
Alias           sal                       set-alias
Alias           sasv                      start-service
Alias           sc                        set-content
Alias           select                    select-object
Alias           si                        set-item
Alias           sl                        set-location
Alias           sleep                     start-sleep
Alias           sort                      sort-object
Alias           sp                        set-property
Alias           spps                      stop-process
Alias           spsv                      stop-service
Alias           sv                        set-variable
Alias           where                     where-object
Alias           cat                       get-content
Alias           cd                        set-location
Alias           clear                     clear-host
Alias           cp                        copy-item
Alias           h                         get-history
Alias           history                   get-history
Alias           kill                      stop-process
Alias           lp                        out-printer
Alias           ls                        get-childitem
Alias           man                       get-help
Alias           mount                     new-drive
Alias           mv                        move-item
Alias           popd                      pop-location
Alias           ps                        get-process
Alias           pushd                     push-location
Alias           pwd                       get-location
Alias           r                         invoke-history
Alias           rm                        remove-item
Alias           rmdir                     remove-item
Alias           echo                      write-object
Alias           cls                       clear-host
Alias           chdir                     set-location
Alias           copy                      copy-item
Alias           del                       remove-item
Alias           dir                       get-childitem
Alias           erase                     remove-item
Alias           move                      move-item
Alias           rd                        remove-item
Alias           ren                       rename-item
Alias           set                       set-variable
Alias           type                      get-content


MSH>

Nice, so Where-Object can be abbreviated to "where". Maybe you'd like to abbreviate it further down to just w:

MSH> new-alias

Cmdlet new-alias at command pipeline position 1
Supply values for the following parameters:
(Type !? for Help.)
Name: w
Value: where-object
MSH>

So, now w stands for where-object.

What's coming next?

In the next episodes I'll show you how to use various "utility cmdlets", how to create scripts, how to access the registry and other "providers" and how to create your own cmdlets in .NET.

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Filed under:

Comments

# re: Adventures in Monad - part 2

Sunday, August 07, 2005 11:38 AM by bart

Interesting. A sort of souped-up version of the Python interactive command shell?

# re: Adventures in Monad - part 2

Thursday, August 11, 2005 10:45 AM by bart

Nope.. pipes make all the difference.