Cover | Table of Contents | Colophon
http://msdn.microsoft.com/netframework/downloads/updates/default.aspx. Several versions are available for different machine architectures (32-bit and 64-bit); pick the one suitable for your machine.http://download.microsoft.com and search for "Monad". Download and install the latest release.get, set, add, and remove). Although the number of these verbs may seem excessively large, consistent naming does make learning and using MSH easier in the long run.
Microsoft Command Shell
Copyright (C) 2005 Microsoft Corporation. All rights reserved.
MSH D:\MshScripts>|), is used to create this pipeline. When present, it instructs the shell to redirect the output of one command to the input stream of another, effectively chaining the commands together. For example, while the command type win.ini | more is a familiar way of paging through a long text file, what's really happening is that the output of the type command, which lists the contents of a file in its entirety, is being piped to the more command, which knows how big the screen is and how to pause when it's full.format-* family) and/or outputting cmdlets
(from the out-* family) in the pipeline for more explicit control over how and where objects should be displayed.get-process. Save the script, shown in Example 2-1, as get-processHandlesGt500.msh in a convenient directory. (We'll use D:\MshScripts in the examples that follow.)
get-process | where-object { $_.Handles -gt 500 }get-process. Save the script, shown in Example 2-1, as get-processHandlesGt500.msh in a convenient directory. (We'll use D:\MshScripts in the examples that follow.)
get-process | where-object { $_.Handles -gt 500 }
MSH C:\> D:\MshScripts\get-processHandlesGt500.msh
Handles NPM(K) PM(K) WS(K) VS(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
788 14 13832 16132 70 202.02 1656 CcmExec
764 12 36760 34084 175 20.41 1864 msh
1792 54 22476 24336 106 418.00 824 svchost
557 60 7352 3820 51 58.92 488 winlogoncd, dir, and echo still work in MSH? These commands don't follow the regular verb-noun format for cmdlets, yet MSH will happily work with them. This is an example of aliases at work. An alias is a mapping from one string to another, usually used to map a short name to any longer name for convenience.dir command, MSH is silently translating it to get-childitem (the equivalent cmdlet) and running that instead. This feature helps to shorten command length (and keystrokes) and bridge the syntax gap for the transition to MSH.get-alias cmdlet lists all active aliases:
MSH D:\MshScripts> get-alias
CommandType Name Definition
----------- ---- ----------
Alias ac add-content
Alias clc clear-content
Alias cli clear-item
Alias clp clear-property
Alias clv clear-variable
Alias cpi copy-item
Alias cpp copy-property
Alias cvpa convert-path
Alias epal export-alias
Alias epcsv export-csv
Alias fc format-custom
Alias fl format-list
Alias foreach foreach-object
Alias ft format-table
Alias fw format-wide
Alias gal get-
...profile.msh in the MSH directory of your My Documents folder. We can edit this file as we would any other script, but its name and location have special meaning: when MSH starts up, it will look for this script and run it. For now, let's write a script that configures some aliases, sets up a couple of useful functions, and prints a welcome message, as shown in Example 2-3.
# my personal aliases
set-alias ms get-member
set-alias prop get-property
set-alias displaytext write-object
# my personal functions
function prompt { "$((get-date).Month)/$((get-date).Day) " }
function day { (get-date).Day }
# increase the history buffer size
$MaximumHistoryCount=1024
# welcome message
"Welcome to MSH, " + $env:Username-Verbose, -WhatIf, and -Confirm, tell you exactly what's going on, tell you what should be going on and check whether you'd like it to be going on (respectively) when running any MSH command. They can be used to get a better picture of how a script will perform before it is run, allowing you to verify the actions before they are performed.get-childitem cmdlet, it's an easy task to walk through a folder tree and pick out the files that match a certain criteria. Casting caution aside, you could pipe that output into remove-item to delete the matching files. This could remove more files than expected, however, so it's a good idea to use the -WhatIf switch to see what would happen before making any irreparable changes:
MSH D:\MshScripts> get-childitem . *.bak -Recurse | remove-item -WhatIf
What if: Operation "Remove File" on Target "test.bak"
What if: Operation "Remove File" on Target "reports.bak"
What if: Operation "Remove File" on Target "authors.bak"
What if: Operation "Remove File" on Target "contracts.bak"
What if: Operation "Remove File" on Target "accounts.bak"DateTime object has properties for year, month, day, and so on, so too do the other types we've already seen. The Process class includes process ID, name, and other information, and the get-process cmdlet generates a sequence of objects, one for each process running on a system, with each of these values set accordingly. It's not immediately obvious from the output of get-process how much information is lurking within these objects. Next, we'll see that there's far more than just process name and ID.get-member cmdlet is here to make life easier. With no parameters, it lists every detail about the object. For the following examples, we'll be focusing on the properties (the "public" values and settings). Therefore, we'll tell get-member to just return those:
MSH D:\MshScripts> get-process | get-member -MemberType Property
TypeName: System.Diagnostics.Process
Name MemberType Definition
---- ---------- ----------
BasePriority Property System.Int32 BasePriority {get;}
ExitCode Property System.Int32 ExitCode {get;}
HasExited Property System.Boolean HasExited {get;}
ExitTime Property System.DateTime ExitTime {get;}
Handle Property System.IntPtr Handle {get;}
HandleCount Property System.Int32 HandleCount {get;}
Id Property System.Int32 Id {get;}
MachineName Property System.String MachineName {get;}
MainWindowHandle Property System.IntPtr MainWindowHandle {get;}
MainWindowTitle Property System.String MainWindowTitle {get;}
MainModule Property System.Diagnostics.ProcessModule MainM...
MaxWorkingSet Property System.IntPtr MaxWorkingSet {get;set;}
MinWorkingSet Property System.IntPtr MinWorkingSet {get;set;}
Modules Property System.Diagnostics.ProcessModuleCollec...
NonpagedSystemMemorySize Property System.Int32 NonpagedSystemMemorySize ...
NonpagedSystemMemorySize64 Property System.Int64 NonpagedSystemMemorySize6...
PagedMemorySize Property System.Int32 PagedMemorySize {get;}
PagedMemorySize64 Property System.Int64 PagedMemorySize64 {get;}
PagedSystemMemorySize Property System.Int32 PagedSystemMemorySize {get;}
PagedSystemMemorySize64 Property System.Int64 PagedSystemMemorySize64 {...
PeakPagedMemorySize Property System.Int32 PeakPagedMemorySize {get;}
PeakPagedMemorySize64 Property System.Int64 PeakPagedMemorySize64 {get;}
PeakWorkingSet Property System.Int32 PeakWorkingSet {get;}
PeakWorkingSet64 Property System.Int64 PeakWorkingSet64 {get;}
PeakVirtualMemorySize Property System.Int32 PeakVirtualMemorySize {get;}
PeakVirtualMemorySize64 Property System.Int64 PeakVirtualMemorySize64 {...
PriorityBoostEnabled Property System.Boolean PriorityBoostEnabled {g...
PriorityClass Property System.Diagnostics.ProcessPriorityClas...
PrivateMemorySize Property System.Int32 PrivateMemorySize {get;}
PrivateMemorySize64 Property System.Int64 PrivateMemorySize64 {get;}
PrivilegedProcessorTime Property System.TimeSpan PrivilegedProcessorTim...
ProcessName Property System.String ProcessName {get;}
ProcessorAffinity Property System.IntPtr ProcessorAffinity {get;s...
Responding Property System.Boolean Responding {get;}
SessionId Property System.Int32 SessionId {get;}
StartInfo Property System.Diagnostics.ProcessStartInfo St...
StartTime Property System.DateTime StartTime {get;}
SynchronizingObject Property System.ComponentModel.ISynchronizeInvo...
Threads Property System.Diagnostics.ProcessThreadCollec...
TotalProcessorTime Property System.TimeSpan TotalProcessorTime {get;}
UserProcessorTime Property System.TimeSpan UserProcessorTime {get;}
VirtualMemorySize Property System.Int32 VirtualMemorySize {get;}
VirtualMemorySize64 Property System.Int64 VirtualMemorySize64 {get;}
EnableRaisingEvents Property System.Boolean EnableRaisingEvents {ge...
StandardInput Property System.IO.StreamWriter StandardInput {...
StandardOutput Property System.IO.StreamReader StandardOutput ...
StandardError Property System.IO.StreamReader StandardError {...
WorkingSet Property System.Int32 WorkingSet {get;}
WorkingSet64 Property System.Int64 WorkingSet64 {get;}
Site Property System.ComponentModel.ISite Site {get;...
Container Property System.ComponentModel.IContainer Conta...$ prefix. This helps separate variables from cmdlets, aliases, filenames, and other identifiers used in the shell. There is no forced naming convention for variables, although it's always good practice to use a name that actually represents the information stored within; if nothing else, it can dramatically help readability and understanding of scripts later on. Variable names are always case-insensitive, and they can contain any combination of alphanumeric characters (if and switch statements and see how they can be used, depending on certain conditions, to execute different parts of a script.
MSH D:\MshScripts> 7 -gt 5
True
MSH D:\MshScripts> 7 -eq 5
False
MSH D:\MshScripts> "alpha" -lt "zulu"
True
MSH D:\MshScripts> set-location c:\windows\system32
MSH C:\WINDOWS\system32> $lotsOfFiles = ((get-childitem).Count -gt 50)
MSH C:\WINDOWS\system32> $lotsOfFiles
Trueif statement and its relations
MSH D:\MshScripts> new-item -Name "Reports" -Type Directory
MSH D:\MshScripts> "Weekly report template" >WeeklyTemplate.txt
MSH D:\MshScripts> "Monthly report template" >MonthlyTemplate.txt
for ($week=1; $week -le 52; $week++)
{
copy-item "WeeklyTemplate.txt" "Reports\Week $week.txt"
}clear-host, are, in fact, functions that perform tests, determine parameters, and invoke cmdlets based on their inputs. The new-item cmdlet is very flexible, yet at the same time, it can have a cumbersome syntax; thus, MSH creates these short-cut functions for convenience. Even familiar commands such as C: and D: are functions that call the set-location cmdlet.
MSH D:\MshScripts> function say-greeting { "Hello" }
MSH D:\MshScripts> say-greeting
Hello$input variable. Let's say we're going through each line of a 400 MB daily IIS logfile to figure out the set of requested URLs that resulted in a 404 error message. Loading all 400 MB into memory probably isn't the best approach; we would do better to create a small script block that could match a 404 line in the log and record the requested URL into a variable.$input, we again make use of the special variable $_:
MSH D:\MshScripts> filter double { $_ * 2 }
MSH D:\MshScripts>
MSH D:\MshScripts> function showA { write-host $a }
MSH D:\MshScripts> $a = 10
MSH D:\MshScripts>