Monad The New Microsoft Command Shell Peter Provost peter.provost@microsoft.com

Post on 01-Jan-2016

216 views 1 download

Transcript of Monad The New Microsoft Command Shell Peter Provost peter.provost@microsoft.com

MonadThe New Microsoft Command Shell

Peter Provostpeter.provost@microsoft.comhttp://www.peterprovost.org/

Unix Shell Example

List a file in a directory with details# ls –l hosts-rw-r—r--  1 root root 41 Mar 18  2005 hosts

Modify fields displayed# ls –go hosts-rw-r—r--  1  41 Mar 18  2005 hosts

Extract size and filename# ls –l hosts | cut –c 24-27,41- 41 hosts

Unix Shell Example (continued)

Show access time?# ls –lu

Sort by size?# ls –lS

Sort by modification time?# ls -lt

Monad Example

List a file in a directory with detailsMSH> ls hosts

Mode LastWriteTime Length Name---- ------------- ------ -----a--- 8/29/2002 5:00 AM 734 hosts

Modify fields displayedMSH> ls hosts | format-table LastWriteTime,Name

LastWriteTime Name------------- ----8/29/2002 5:00:00 AM hosts

Extract size and filenameMSH> ls –l hosts | format-table Length,Name

Length Name------ ---- 734 hosts

Monad Example (continued)

Show access time?MSH> ls hosts | format-table Name,LastAccessTime

Sort by size?MSH> ls hosts | sort-object Length

Sort by modification time?MSH> ls hosts | sort-object LastWriteTime

More Monad Examples!

Show files modified in last 7 daysMSH> ls | where-object { $_.LastWriteTime –ge [System.DateTime]::Now.AddDays(-7) }

Show processes using 500 handles, sorted by IdMSH> ps | where-object { $_.HandleCount –ge 500 } |

sort-object Id Show signer of each process binary

MSH> ps | foreach-object { $p = $_.MainModule.FileName $sig = get-authenticodesignature $p echo ($p + ": “ + $sig.SignerCertificate.Issuer)

}

Monad is a New Shell

Similar to Unix shells, but… Pipelines of .Net objects Object properties/methods directly accessible

and discoverable COM, WMI, XML, etc. accessed with same

semantics User-controlled formatting of objects Standardized command parameter processing Rich scripting language Providers extend the navigation namespace

Commands

Verb-NounMSH> verb-noun –param1 value1 –param2 value2a,value2b –param3:value3

You can aliasMSH> set-alias gps get-processls and dir are aliases for get-childitemps is alias for get-process

Parameters can be positionalMSH> get-process –processname lsassMSH> get-process lsass

Many parameters can be wildcardedMSH> get-process c*

Partial parameter names allowedMSH> get-process -p lsass

Commands Emit Objects

Traditional text parsing replaced with direct object manipulation

A default text view of objects is dynamically computedTable for objects with < 5 propertiesList for objects with 5 or more properties

Get-Member tells you about the objects MSH> get-process | get-member

Finding Information

Finding CommandsMSH> get-command i*MSH> get-command –verb processMSH> get-command –type {Alias | Function | Filter | Cmdlet | ExternalScript | Application | Script | All }

Man-page style help on language and commandsMSH> get-helpMSH> get-help <command>MSH> <command> -?MSH> get-help about_whileMSH> get-help * | where {$_.Synopsis -match "process"}

Object Manipulation

Objects can be pipelined to other functions Related commands

MSH> get-process notep* | stop-process Object utilities

MSH> get-process | where {$_.Handles –ge 500} |group-object Company | sort-object Count

Your functions Direct object manipulation

MSH> $np = get-process notepadMSH> $np.Workingset / 1024MSH> $np.WaitForExit()

Ubiquitous Parameters

-Debug Programmer-level information

-ErrorAction SilentlyContinue | Stop | Continue | Inquire What to do if an error occurs?

-ErrorVariable VariableName Assign errors to a variable

-OutputVariable VariableName Output assigned to a variable

-Verbose Additional information about the activities being

performed

Trusting Operations

Commands with side-effects support:-Whatif

MSH> get-process | where-object {$_.Handles –ge 500} | stop-process –whatif

-ConfirmMSH> stop-process –pr s* -confirm

Can also use -VerboseMSH> stop-process –pr [a-x]*[q]*[r-t] -verbose

Extending the Namespace

Providers allow namespace navigation to go beyond the filesystem

Monad includes a default setFileSystem, Registry, Certificate, Alias,

Environment, Function, Variable You can write your own Navigation commands work

MSH> cd Registry::\MSH> dir YourProvider::\foo

Finding Data Data stores surfaced as “drives” in providers

MSH> get-driveMSH> dir HKLM:\SOFTWARE\Microsoft

Drive is a namespace with numerous pieces of information Item, ChildItem, Content, Property, ACL, etc.

New navigation/interaction model supported with aliases for existing commands

get-childItem dir ls

get-location cd pwd

get-content type cat

new-item –type Directory md mkdir

set-location cd cd

Namespace Functions

Mounting new drives with namesMSH> new-drive -name SRC -provider FileSystem

-root c:\development\cab\main -description “CAB source code”

MSH> cd SRC:\parser Great wildcarding

MSH> dir [a-f]*[tc]MSH> dir T?.msh

Rich common semanticsMSH> dir \logs –include *.txt –exclude A* -recurse

-force Drive specific extensions

MSH> dir cert: -recurse –codesigning Tab-Completion in all Drives

MSH> dir HKLM:\So<TAB>\Mi<TAB> => HLKM:\Software\Microsoft

Scripting

A script is executed the same as if the commands were typed interactively

Supports scripting .NET objects Loose, strong, and extensible typing models Uniform syntax for wide range of types

WMI, XML, COM, ADSI, ADO Rich variable semantics (typed, read-only, constraints,

descriptions) Rich operators and control structures (C#-like with

access to commands & utilities) Functions (positional, named, typed,

constrained params)

Scripting .NET

Creating .Net objectsMSH> $d=New-Object System.DateTime 2005,4,20MSH> [DateTime]"4-20-2005"Will try Parse() method, Constructor, Converter

Inspecting properties and methodsMSH> [DateTime]"4-20-2005" | get-memberMSH> [DateTime] | get-member -static

Accessing properties-methods Instance

MSH> $d.DayOfWeekMSH> $d.AddMonths(6)

StaticMSH> [DateTime]::NowMSH> [DateTime]::IsLeapYear(2005)

Typing

LooseMSH> $d="4/20/2005“MSH> Function foo() {$args[0]}

“Strong”MSH> [datetime]$d=“4/20/2005”MSH> function foo([datetime]$date) {$date}MSH> [int] [char] “a”

Extensible Can extend types via $MSHHOME\types.mshxml See .NET DateTime class – DateTime property

MSH works on any .NET type - not a fixed set of “scripting types”

Typing Examples

MSH> [char] “a”MSH> [int] [char] “a”MSH> [char] ([int][char]"a" - 32)

MSH> $w = get-wmiobject win32_bios

MSH> $w.VersionMSH> (dir)[0].mshPath

Text Processing Model

.NET String class is the foundation Contains(), EndsWith(), Equals(), IndexOf(), Insert(),

Join(), LastIndexOf(), Length, PadLeft(), PadRight(), Remove(), Replace(), Split(), StartsWith(), Substring(), ToLower(), ToUpper(), Trim(), TrimEnd(), TrimStart()

Native support for useful datatypes Regular expressions, XML, arrays, hash tables

Rich string operators +, *, -replace, -match, -like, -eq, -ne, gt, -ge, -lt, -le Implicit/explicit casting and coercion

Rich utilities match-string, foreach, group, select, sort, where

Leveraging .Net classes

Script to rotate every image in a directory

[System.Reflection.Assembly]:: LoadWithPartialName("System.Drawing") | out-null foreach ($f in resolve-path *) { trap [OutOfMemoryException] { write-host "Error processing" $f; continue } { $img = [System.Drawing.Image]::FromFile($f) $format = $img.RawFormat $img.RotateFlip("Rotate90FlipNone") $fi = get-childitem $f $newname = combine-path ($fi.DirectoryName)

("rot." + $fi.Name) $img.Save($newname,$format) } }

Uniform Data Access Syntax

Provides a common user interface to objects of different typesystems

XMLMSH> $x = [xml]"<a><b><c>TEST</c></b></a>"MSH> $x.a.b.cMSH> $wc = new-object System.Net.WebClientMSH> $rssdata = [xml]$wc.DownloadString ("http://slashdot.org/index.rss")

MSH> if ($rssdata.rss.version –eq "2.0") { echo $rssdata.rss.channel.title }

COM Automation (Internet Explorer) Bind to Internet Explorer COM object

MSH> $ie = new-object –com InternetExplorer.Application

Reflect against properties/methodsMSH> $ie | get-member

Display propertiesMSH> $ie.Visible

Invoke methods/set propertiesMSH> $ie.Navigate2("www.uiuc.edu")MSH> $ie.Visible = $trueMSH> $ie.StatusText = "Hello World"

COM Automation (Word)

Bind to Word COM ObjectMSH> $word = new-object –com Word.Application

Use in pipelinesMSH> $word.RecentFiles | sort name | format-table name,index,path –auto

Access document propertiesMSH> $doc = $word.Documents.Open("c:\foo.doc")

MSH> $doc.characters.count MSH> $doc.sentences.count

COM Automation (WScript)

Bind to WScript objectMSH> $ws = new-object -com Wscript.Shell

Display popupMSH> $ws.popup("This is a popup",100,"Title",64) Last parameter is a button/icon bit mask: 0 OK 1 OK and Cancel 2 Abort, Retry, and Ignore 3 Yes, No, and Cancel 4 Yes and No 5 Retry and Cancel

Access other shell functionalityMSH> $ws | get-member CreateShortcut(), LogEvent(), etc.

16 “Stop Mark”16 “Stop Mark”32 “Question Mark”32 “Question Mark”48 “Exclamation Mark”48 “Exclamation Mark”64 “Information Marl”64 “Information Marl”

Writing Cmdlets

.Net class, inherits from Cmdlet Declare parameters as class members Override methods BeginProcessing(),

ProcessRecord(), EndProcessing() Monad provides

Parameter parsing/binding Ubiquitous parameters -Confirm/-Whatif (if you call ShouldProcess()) Access to session state Invoke other cmdlets, providers, and host API

Cmdlet Example (C#)

1 [Cmdlet("stop", "ps", SupportsShouldProcess=true)]2 public class StopPs: Cmdlet 3 {4 [Parameter(Mandatory=true)]5 public string Name;6 protected override void ProcessRecord() {7 Process [] ps = Process.GetProcessesByName(Name);8 foreach (Process p in ps) {9 if (ShouldProcess(p.ProcessName + "ID= " +

p.Id))10 {11 p.Kill();12 }13 }14 }15 }

Get Monad!

Monad Shell Beta 2 available from Microsoft Download Center

Search for “Monad” Supported on x86 and x64 platforms Documentation Pack also available Requires .Net 2.0 Beta 2 (also available

from Download Center)

Shameless Plug

patterns & practices is hiring

See me after the talk or e-mailDarrel Snow – dsnow@microsoft.com