KEMBAR78
No-script PowerShell v2 | PPT
The Windows PowerShell v2 No-Scripting Crash Course Don Jones ConcentratedTech.com Pre-requisites for this presentation:  1) Strong understanding of basic Windows administration Level:  Intermediate
This slide deck was used in one of our many conference presentations. We hope you enjoy it, and invite you to use it within your own organization however you like. For more information on our company, including information on private classes and upcoming conference appearances, please visit our Web site,  www.ConcentratedTech.com .  For links to newly-posted decks, follow us on Twitter: @concentrateddon or @concentratdgreg This work is copyright ©Concentrated Technology, LLC
About the Instructor Don Jones Contributing Editor,  technetmagazine.com IT author, consultant, and speaker Co-founder of Concentrated Technology Seven-time recipient of Microsoft ’s Most Valuable Professional (MVP) Award Author and Editor-in-Chief for Realtime Publishers Trainer for www.CBTNuggets.com
Notes Sample Code I ’ll save as I go I ’ll make everything available as a download from my Web site – details on the last slide I ’ll also include a copy of this slide deck Please… personal use only. Agenda This deck is really just a guide to make sure you have certain things in writing to take home We might change up the order a bit, and you ’ll see a lot more than I list here
The Agenda PowerShell backgrounder and crash course Accomplishing real IT admin tasks using PowerShell
Resources ConcentratedTech.com New tech content  every day  (including PowerShell tips & series) PowerGUI.org PowerShell.com / Idera.com PrimalScript.com Blogs.Msdn.Com/PowerShell
If you ’re following along… Start-Transcript  filename Records a transcript of everything you type in the shell, including output Helps create a log of what you do here in class Simple text file Stop-Transcript
What is Windows PowerShell? A command-line interface (CLI) used to administer Windows and other products and technologies… … but also a new way of developing Windows and other products to be more manageable An  interactive  shell  as well as  a simplified scripting language
Why a CLI? A GUI is great for creating  one  user, or modifying  one  server, or reconfiguring  one  service Performing anything multiple times in a GUI becomes repetitive, boring, and error-prone A CLI is inherently better when it comes to automating repetitive tasks
But the GUI can do mass administration! Tools (often third party) can be written to perform specific repetitive tasks… … do you want to spend all your time hunting down, learning, and possibly paying for dozens of  “point solution” tools? A CLI provides a  single way  to do it all, in a consistent fashion
The Dark Ages of Administration Windows / Server Product Functionality (Services, Configuration Database, etc) Graphical User Interface for Administration (MMC Snap-Ins) COM Objects (DLLs) Command-Line Utilities WMI Provider Scripts (Batch, VBScript, etc.) The Missing Pieces
The Dark Ages ’ Problem Some command-line tools do some things Some COM objects do some things Some WMI providers do some things Nothing  does  everything ! Means learning many different tools, which all work differently
The PowerShell Age of Administration Windows / Server Product Functionality (Services, Configuration Database, etc) Microsoft .NET Framework Windows PowerShell Scripts GUI
The PowerShell Advantage Bring  all functionality  together in a single place (the CLI) Expose the functionality in a way which can be automated (scripting)  and  used to  “power” a GUI Create that functionality in a consistent fashion (e.g., learn  one  way to do  everything )
How it Happens Microsoft builds new products so that their administrative functionality  “lives” in PowerShell GUI consoles just  “sit on top” of PowerShell Over time, more and more products become  “fully exposed” in PowerShell
Fully PowerShell-ed Products Exchange Server 2007 System Center Operations Manager 2007 System Center Virtual Machine Manager System Center Data Protection Manager More coming… including non-Microsoft products! Win2008 R2 adds  significantly  to the list
In the Meantime… PowerShell still connects to  existing  administrative functionality Windows Management Instrumentation Microsoft .NET Framework Component Object Model (COM) Active Directory Services Interface (ADSI) Allows you to (partially) administer non-PowerShell technologies  today
System Requirements Windows XP or later (ships with Windows Server 2008 as an  optional  component; installed by default in 2008R2 and Win7) Microsoft .NET Framework v2.0 or later Install  everywhere  (remote shell!)
Installing PowerShell Download from www.Microsoft.com/PowerShell (if not included with your version of Windows) Run installer Installs to  systemroot \WindowsPowerShell
How it Works - Overview Cmdlets  are the  “command-line utilities” within PowerShell They work with  objects,  not text, and can  “plug into” one another to perform more complex tasks “ Nicknames” called  aliases  make cmdlet names easier to type Cmdlets can be  “snapped in” to extend the shell’s functionality
Navigating your system You probably already know how to do this! Start thinking of the commands you'd use to navigate your system using Cmd.exe Or, if you prefer the commands you'd use in a Linux or Unix operating system Quiz follows…
Same command… different parameters Try  Dir /s Doesn't work! The  command names  are similar to what you're used to in Cmd.exe… … but the way in which the commands work are significantly different Fortunately, PowerShell can help you learn how to use the new commands
Asking for help PowerShell includes a robust built-in help system Ask for help on any command using the  Help  keyword (or  Man  if you prefer) Help  accepts wildcards – lets you look up commands when you're not sure of their name Provides a quick reference to the correct parameters and syntax Add  –online  for latest version of help files
Single, consistent skill set If you know one set of commands to navigate one type of hierarchical file system…  … why not use the commands for other types of storage systems?  The registry The certificate store Environment variables Active Directory
How it works PowerShell uses  PSDrive Providers  to connect to various storage systems The providers  adapt  a storage system to look like a "disk drive" The providers translate commands like CD and DIR into whatever the underlying store needs to see
Just a few changes PowerShell does have a few quirks when compared to Cmd.exe… Cd .. , not  Cd..  (needs the space) Cd "Program Files"  not  Cd Program Files  (paths with spaces need to be in quotes) Etc. You usually get used to these minor changes pretty quickly
You've already used cmdlets! Cd, Ls, Dir, Copy, and Cp are all  cmdlets  (pronounced "command-lets") Technically, these are  aliases,  or nicknames, to actual cmdlets Cmdlets are written in a .NET Framework language Cmdlets are bundled into DLL files called  snap-ins  or  PSSnapIns
Aliases Aliases are just "short names" for cmdlets They're easier to type They provide consistency with old-style command names Many aliases come built in, and you can create your own
That's why  dir /s  doesn't work Dir  is an alias for  Get-ChildItem The alias only covers the cmdlet name – it doesn't change the parameters the cmdlet uses Get-ChildItem  uses a different parameter to recurse subdirectories Dir –recurse  or  Dir –r  will do the trick Using an alias is exactly the same as using the cmdlet that the alias 'points' to
Finding cmdlet/alias names You know the alias, and want to find the cmdlet name: Help  alias You know the cmdlet, and want to find aliases: gal | where { $_.ResolvedCommandName -eq " cmdlet " }
Working with aliases Get all alias:  Get-Alias  or  Gal or  Dir Alias: Add an alias:  New-Alias Remove an alias:  Remove-Item  in the Alias: drive
Working with cmdlets See all cmdlets:  Get-Command See all "Get" cmdlets: Get-Command –verb Get See all "Command" cmdlets: Get-Command –noun Command Notice the naming convention? Verb-SingularNoun
Snap-ins Cmdlets are "packaged" in a snap-in Multiple snap-ins can be loaded into the shell ( Add-PSSnapIn ), extending its capabilities 120+ cmdlets provided in the default snapins ( Get-PSSnapin ) Just see the cmdlets added by a particular snapin: Get-Command –PSSnapin  snapin
Consistency! Cmdlet names might seem long (that's why you have aliases)… but there's a reason! Consistent  verb-noun  naming means you can  guess  what a cmdlet name would be based on the functionality you want This makes learning to use the shell easier
Parameters Like old-style command-line utilities, cmdlets have parameters (or "switches") These customize the behavior of a cmdlet Parameter names are preceded by a dash A space separates the parameter name and its value
Parameters  (con't) Parameters are documented in  Help Parameter names may seem long… but they're  clear… … and you only have to type enough to differentiate from other parameter names (e.g., you can be lazy) Positional  parameters don't need the name at all – just type the values in the correct order
Parameter help
Remember! PowerShell is all about self-discovery When you need to do something but don't know the cmdlet name… look it up! Help *Service* Get-Command -noun  whatever Get-Command Help
Cmdlets: Objects, not text So far the cmdlets you've run have seemed to produce text lists as their output… … not so! They actually work with  objects Object  is a generic term that refers to some functional piece of software, like a process, or a service, or an event log
Objects When you run a cmdlet, it generally produces objects as its output These objects are  actual functioning pieces of Windows Get-Service  doesn't produce a  list  of services… it grabs all the  actual services  which are installed on the computer
Objects Everything in PowerShell is an "object" "Object" is just a generic word for "functional thingy" Objects have  properties  which describe them… … and  methods,  which cause them to take some action Services, processes, event logs, etc. are all objects
Get-Member Piping an object to Get-Member (gm) tells you about the object What  type  it is (e.g., what kind of object) What properties it has What methods it has Get-Member  teaches  you about objects by revealing what they are and what they can do for you
Object properties A service has certain properties that describe it: Name Started (True or False) DisplayName ServiceType Status  (Running or Stopped) Etc. The text list you see consists of some of these properties' values (the ones highlighted here)
The Pipeline All cmdlets run in a  pipeline At the end of the pipeline is a special cmdlet called  Out-Default Out-Default takes whatever objects are in the pipeline, and uses some of their properties to construct a text list That's why you see text output when you run a cmdlet like Get-Service
A Simple Pipeline Example Property = Value Property = Value Property = Value Property = Value
Piping cmdlets Because nothing is converted to text until the  end  of the pipeline… … you can "pipe" objects from one cmdlet to another Each cmdlet can then work directly with the objects' properties
Multi-Cmdlet Pipeline Property = Value Property = Value Property = Value Property = Value
Action Cmdlets Many times, the common things you can "do" with an are available as PowerShell cmdlets Stop-Service, Start-Service,  Pause-Service, Resume-Service, etc. Many of these "action" cmdlets don't output objects at all – so you see no text output when using them
Multi-Cmdlet Pipeline
Object passthrough Cmdlets that "consume" objects (but don't normally output any) often have a  –passThru  parameter which  forces  them to pass their objects down the pipeline Stop-Service  is an example of one of these cmdlets
Multi-Cmdlet Pipeline Property = Value Property = Value Property = Value Property = Value
Remember! You only see text output when there are objects left in the pipeline No objects remaining… no output Some cmdlets "consume" objects and do something with them, but don't output any objects A  –passThru  parameter forces a cmdlet to pass its objects down the pipeline for further use
Remember! Object have  properties The cmdlets we're going to look at utilize these properties Wonder what properties an object has? Pipe the object to  Get-Member  to find out
Sorting objects Sorts objects in descending or ascending (default) order, using the property or properties you specify Sort-Object Name Sort-Object DisplayName -descending Pipe objects in to sort them; the sorted objects are piped out
Measuring objects By default, counts the number of objects piped in The objects are not piped out – only the measurement results are piped out (meaning your original objects are "lost")
Selecting object properties Takes piped-in objects and just keeps the properties you specify Select-Object Name,DisplayName Good for "narrowing down" the properties that show in your output The original objects are not piped out (they are "lost") New, custom objects – with just the properties you specify – are piped out
Keeping the first/last object(s) You can also keep just the first "x" or last "x" number of objects Select-Object –first 10 Select-Object –last 20 If you just do this, the original objects are piped out
Exporting objects Objects can be exported to CSV or an XML format Export-CSV  filename Export-CliXML  filename Useful for generating reports, or persisting objects across sessions
Importing objects Reads in a CSV or XML file and constructs objects from them Each line in the CSV, or each XML node, becomes an object with all the properties contained in the file Import-CSV  filename Import-CliXML  filename
Secure by Default By default: PowerShell won't run scripts When configured to run scripts, the shell can require that they be digitally signed .PS1 filename extension not associated with the shell Must specify a path in order to run a script
SBD: Won't run scripts PowerShell has an  ExecutionPolicy  which is set to Restricted by default – no scripts will run Other ExecutionPolicy settings: AllSigned: Only signed scripts run RemoteSigned: Local scripts don't need to be signed, remote ones (downloaded) do Unrestricted: All scripts will run (bad idea in a production environment)
What is script signing? Signed .PS1 files contain a "signature block" in comments at the end of the file Intact signature means… The script has not been modified since signed The identity of the script author/signer is verified
Script Signing
Controlling ExecutionPolicy Get-ExecutionPolicy  and  Set-ExecutionPolicy  cmdlets Download ExecutionPolicy ADM template (for Group Policy) from Microsoft (URL on class CD)
SBD: .PS1 association .PS1 filename extension associated (by default) with Notepad, not the shell Double-clicking a script file won't execute it, it'll just open it for editing Helps prevent scripts sent via e-mail from being accidentally executed a la VBScript
SBD: Must specify a path Create a script named dir.ps1 Try to execute it by running  Dir You can't: In order to run a script, you must specify a path -  ./dir  will work Helps visually distinguish a script from a built-in command
Alternate Credentials Some PowerShell cmdlets have a  -credential  parameter which accepts either a username or a PSCredential object that specifies alternate credentials to use Get-WMIObject  is a good example Providing a username launches a graphical dialog where you enter the password
Storing alternate credentials Get-Credential  prompts for a credential and securely stores it in a variable The variable can then be provided as the value of a  –credential  parameter Lets you create a credential once, and then use it multiple times Hint: Put this in your PowerShell profile to have it create the credential each time the shell runs
Sidebar: Profiles A .PS1 file that is automatically executed each time the shell loads No profile exists by default Create  …\Documents\WindowsPowerShell  folder, create  Microsoft.PowerShell_Profile.PS1  file Simply fill the file with commands that you want run each time the shell loads
What is WMI? A system for remotely obtaining management information… … and in limited cases, reconfiguring settings Implemented as a service since Windows 2000 (and available for NT 4) Based in industry-standard techniques developed by the Desktop Management Task Force (DMTF)
WMI structure Namespaces  typically align to products (Windows, SQL, IIS, DNS, etc) Classes  live in namespaces and represent manageable components (disks, users, Web sites, NICs, etc) Instances  are real-world occurrences of a class (two logical disks = two instances of the disk class)
Classes & instances Instances are  objects,  meaning they have properties They can also have  methods,  which are the things you can do with an object (e.g., Disk objects have a Defrag method) Review properties to see management information; execute methods to make configuration changes
WMI query options Get all properties for instances of a given class Get all objects that match a WMI Query Language (WQL) query In both cases, the  Get-WMIObject  cmdlet does the work
Simple WMI Get-WMIObject   classname [-computerName  computername ] [-credential  PSCredential ] Retrieves all instances of the designated class (optionally, from the specified computer using the specified credentials)
WMI Classes Where can you get a list of classes? For the core root\cimv2 namespace… Use the WMI Documentation Ask PowerShell for a list of classes Use the WMI Explorer (scriptinganswers.com, click  “Free Tools”)
WQL Queries SQL-like syntax Specify the properties you want… … the class you're querying… … and the criteria (to filter out instances you don't want)
WQL Example SELECT { * | Property,Property } FROM { Class } [ WHERE Property = Value ] SELECT * FROM Win32_LogicalDisk WHERE DriveType = 3
Testing WQL Queries Use the built-in Wbemtest.exe GUI tool Connect to a namespace (root\cimv2 is the default namespace used by PowerShell) Enter a WQL query See the objects that come back Great way to prototype, test, and refine queries in a graphical environment
WQL Queries in PowerShell Get-WMIObject –query " WQL query " Gwmi –qu "SELECT * FROM Win32_LogicalDisk WHERE DriveType = 3"
WMI and the pipeline Get-WMIObject returns  objects  with  properties … … pipe them to Get-Member to see those properties… … or use the objects in the pipeline with Sort, Select, Group, and the other cmdlets you've learned
Comparisons The purpose of a comparison is to generate a True or False result PowerShell provides the $True and $False variables to represent these Boolean values All comparisons  result in either $True or $False
Comparison operators -eq Equality -ne Inequality -gt Greater than -lt Less than -ge Greater than or equal to -le Less than or equal to
Comparison examples Supposing $_ represents a process… $_.Handles –gt 1000 $_.Name –eq "Notepad" $_.Responding Note that the Responding property  is  either True or False; it does not have to be  compared  to $True or $False to generate a True/False result
Filtering in the pipeline Where-Object  accepts a collection of objects and examines each one Only those objects meeting the criteria you specify are passed down the pipeline In your comparison expression, $_ represents "the current pipeline object we're examining."
Where-Object Get-Service |  Where-Object { $_.Status –eq "Running" }  | Sort-Object Name -descending
Complex comparisons Need to compare more than one condition in a single expression? -and returns True if both are True -or returns True if either is True -not reverse True/False
Complex example Supposing $_ represents a WMI Win32_Service instance… $_.StartMode –eq "Auto" -and $_.State –ne "Running"
Formatting output We've talked before about how the pipeline ends in Out-Default, which turns objects into text The actual process is somewhat more complicated than that! Out-Default actually redirects objects to Out-Host, which does the work of displaying objects
Out-Host Out-Host can't display normal objects… … it can only display special PowerShell formatting objects So when Out-Host receives normal objects, it calls on PowerShell's formatting system to turn them into formatting objects
Formatting rule #1 Does the object type have a view defined in one of the .format.ps1xml files? If yes… use that view, which specifies either table, list, or wide layout. If not… go to rule 2.
Formatting rule #2 Does this type of object have a set of Default Display Properties define in a .ps1xml file? If Yes, use  only the default properties  for the next decision If No, use  all of the object's properties  for the next decision
Formatting rule #3 Are we displaying >=5 properties? If Yes, choose a List layout If No, choose a Table layout
Formatting rule #4 Using the properties we've chosen, and using the layout we've chosen, call a formatting cmdlet to create the formatting objects Format-Table (ft) Format-Wide (fw) Format-List (fl)
Formatting process Get-Service Out-Default Out-Host Format-Table
That's just the default… You can pipe objects to any of the Format-* cmdlets on your own This lets you specify the layout you want Use the Format-* cmdlets to specify the properties you want displayed, too Produces formatting objects (meaning the Format-* cmdlet has to be the last thing in the pipeline)
Let ’s Play Let ’s see what we can do with FT and FL… Select properties to display in the output Control table sizing Grouping the output by a selected property (sort the objects first!)
Input and output Read-Host and Write-Host read and write input directly from the console Write-Output writes output to the Success pipeline Anything in the pipeline can potentially end up displayed in the console At the end of the pipeline is Out-Default.
Write-Host vs. Write-Output Write-Output Out-Default Write-Host Out-Host Where-Object
Fun Trick Try piping output (say, of Get-Service) to ConvertTo-HTML Try piping  that  output to Out-File and specifying a file name Neat, huh?
Variables PowerShell uses variables as temporary, named storage for objects Variable names begin with $ Names can contain (mainly) letters, numbers, and underscores Variables are not automatically persisted by the shell
Variable FAQ How long can variable names be? Long enough. Can I declare them in advance?  Yes, using New-Variable Do I have to declare them in advance? No, and there's no way to force yourself. Are all variables the same "type?" No, they are the "type" of whatever object they contain…
Variables are objects Variables are really just names for an area in memory where objects are stored Variables aren't  things  themselves; they're just  containers  for actual objects A variable exposes the properties and methods of the object(s) it contains Pipe a variable to Get-Member to see what it can do!
Variable types PowerShell automatically tries to figure out what "type" a variable is when you create it  and  when you use it This allows "5" to be treated as a number when appropriate, and as a text string when appropriate… … although sometimes PowerShell gets confused about which type it should be using
Common types [string] [int] [boolean] [regex] [single] [double] [array] [adsi] [wmi] [hashtable] [xml] [char] Lots more!
Arrays A special kind of variable capable of holding multiple objects… … usually of the same type, but not necessarily Each object in the array has an  index , which is its location within the array 0 is the bottom index (the first item) The special index -1 always returns the last item in the array
Creating an array Any cmdlet which returns a collection of objects is returning an array – and that collection can be stored in a single variable You can also create your own arrays $arr =  @( 1,2,3,4,5 ) PowerShell always treats any comma-separated list as an array – remember this!!!
Using an array You can pipe arrays to cmdlets – just like you can pipe any collection of objects to most cmdlets Access individual elements in the array by specifying an [index] in square brackets: $arr[0]
Array tip: Arrays and collections aren't  technically  the same thing, but for most purposes you can think of them as the same thing Collection of objects = Array of objects
Escape characters ` (backtick) is the universal escape character in PowerShell ` at the end of a line "escapes" the carriage return (e.g., line continuation) ` before a space "escapes" it (e.g., makes it a literal space) ` before certain characters performs special functions
Inventorying Information Let ’s use WMI to inventory information The neat bit is that a single command can pull info from multiple computers How will we know which computer each bit came back from? We ’ll look at technique that uses no scripting! We ’ll be using Service Pack info
Scripting Scripting in PowerShell is really just pasting commands into a text file There are a few  “scripting constructs” you can use to implement logic and flow control for more complex processes Scripts are just text files with a .PS1 filename extension You can edit with Notepad, although a PowerShell-specific editor is far better
Foreach Used to take a collection of objects and go through them, one at a time Lets you perform  multiple operations per object Let ’s modify our WMI inventory command to work in this fashion
Customizing objects Pipe an object to  Add-Member  to add a  NoteProperty , which contains a static value $obj | Add-Member NoteProperty  PropertyName PropertyValue Use  Write-Output  to output the new object Let ’s use this to add a “ComputerName” property to our WMI object
Switch Used to compare a variable or property value to a range of possible values, and take some action We ’ll use this to translate the build number into a more readable OS WinVersion property
Multiple Sources? What if we also wanted our output to include a BIOS serial number / call tag property? We could query Win32_BIOS… how do we combine it with our existing output? Ideally, our output should be a SINGLE object that has properties for the COMBINED information…
Create a Custom Object We ’ll use  New-Object PSObject  to create a new, blank object We ’ll use  Add-Member  to add the information we want – from various sources We ’ll output the combined object
Making it a Tool Let ’s wrap the whole thing in a parameterized function that accepts an input filename We ’ll expect the input file to contain one computer name per line
Making it a Pipeline Tool Instead of specifying a filename, let ’s modify the function to accept a collection of computer names from the pipeline as its input This lets us use a variety of input sources, so long as they generate a collection of computer names – doesn ’t need to be a file (maybe from AD?)
Output Flexibility By accepting pipeline input, we add flexibility By producing pipeline  output , we add  lots  of flexibility! Let ’s see
Managing AD Let ’s look at how to import users from a CSV file and make them into AD user accounts We ’ll use the Import-CSV and New-DUser cmdlets We ’ll allow the CSV file to contain arbitrary headings (not AD attribute names)
Thank You! Please feel free to pick up a card if you ’d like copies of my session materials I ’ll be happy to take any last questions while I pack up Please complete and submit an evaluation form for this and every session you attend!
 
This slide deck was used in one of our many conference presentations. We hope you enjoy it, and invite you to use it within your own organization however you like. For more information on our company, including information on private classes and upcoming conference appearances, please visit our Web site,  www.ConcentratedTech.com .  For links to newly-posted decks, follow us on Twitter: @concentrateddon or @concentratdgreg This work is copyright ©Concentrated Technology, LLC

No-script PowerShell v2

  • 1.
    The Windows PowerShellv2 No-Scripting Crash Course Don Jones ConcentratedTech.com Pre-requisites for this presentation: 1) Strong understanding of basic Windows administration Level: Intermediate
  • 2.
    This slide deckwas used in one of our many conference presentations. We hope you enjoy it, and invite you to use it within your own organization however you like. For more information on our company, including information on private classes and upcoming conference appearances, please visit our Web site, www.ConcentratedTech.com . For links to newly-posted decks, follow us on Twitter: @concentrateddon or @concentratdgreg This work is copyright ©Concentrated Technology, LLC
  • 3.
    About the InstructorDon Jones Contributing Editor, technetmagazine.com IT author, consultant, and speaker Co-founder of Concentrated Technology Seven-time recipient of Microsoft ’s Most Valuable Professional (MVP) Award Author and Editor-in-Chief for Realtime Publishers Trainer for www.CBTNuggets.com
  • 4.
    Notes Sample CodeI ’ll save as I go I ’ll make everything available as a download from my Web site – details on the last slide I ’ll also include a copy of this slide deck Please… personal use only. Agenda This deck is really just a guide to make sure you have certain things in writing to take home We might change up the order a bit, and you ’ll see a lot more than I list here
  • 5.
    The Agenda PowerShellbackgrounder and crash course Accomplishing real IT admin tasks using PowerShell
  • 6.
    Resources ConcentratedTech.com Newtech content every day (including PowerShell tips & series) PowerGUI.org PowerShell.com / Idera.com PrimalScript.com Blogs.Msdn.Com/PowerShell
  • 7.
    If you ’refollowing along… Start-Transcript filename Records a transcript of everything you type in the shell, including output Helps create a log of what you do here in class Simple text file Stop-Transcript
  • 8.
    What is WindowsPowerShell? A command-line interface (CLI) used to administer Windows and other products and technologies… … but also a new way of developing Windows and other products to be more manageable An interactive shell as well as a simplified scripting language
  • 9.
    Why a CLI?A GUI is great for creating one user, or modifying one server, or reconfiguring one service Performing anything multiple times in a GUI becomes repetitive, boring, and error-prone A CLI is inherently better when it comes to automating repetitive tasks
  • 10.
    But the GUIcan do mass administration! Tools (often third party) can be written to perform specific repetitive tasks… … do you want to spend all your time hunting down, learning, and possibly paying for dozens of “point solution” tools? A CLI provides a single way to do it all, in a consistent fashion
  • 11.
    The Dark Agesof Administration Windows / Server Product Functionality (Services, Configuration Database, etc) Graphical User Interface for Administration (MMC Snap-Ins) COM Objects (DLLs) Command-Line Utilities WMI Provider Scripts (Batch, VBScript, etc.) The Missing Pieces
  • 12.
    The Dark Ages’ Problem Some command-line tools do some things Some COM objects do some things Some WMI providers do some things Nothing does everything ! Means learning many different tools, which all work differently
  • 13.
    The PowerShell Ageof Administration Windows / Server Product Functionality (Services, Configuration Database, etc) Microsoft .NET Framework Windows PowerShell Scripts GUI
  • 14.
    The PowerShell AdvantageBring all functionality together in a single place (the CLI) Expose the functionality in a way which can be automated (scripting) and used to “power” a GUI Create that functionality in a consistent fashion (e.g., learn one way to do everything )
  • 15.
    How it HappensMicrosoft builds new products so that their administrative functionality “lives” in PowerShell GUI consoles just “sit on top” of PowerShell Over time, more and more products become “fully exposed” in PowerShell
  • 16.
    Fully PowerShell-ed ProductsExchange Server 2007 System Center Operations Manager 2007 System Center Virtual Machine Manager System Center Data Protection Manager More coming… including non-Microsoft products! Win2008 R2 adds significantly to the list
  • 17.
    In the Meantime…PowerShell still connects to existing administrative functionality Windows Management Instrumentation Microsoft .NET Framework Component Object Model (COM) Active Directory Services Interface (ADSI) Allows you to (partially) administer non-PowerShell technologies today
  • 18.
    System Requirements WindowsXP or later (ships with Windows Server 2008 as an optional component; installed by default in 2008R2 and Win7) Microsoft .NET Framework v2.0 or later Install everywhere (remote shell!)
  • 19.
    Installing PowerShell Downloadfrom www.Microsoft.com/PowerShell (if not included with your version of Windows) Run installer Installs to systemroot \WindowsPowerShell
  • 20.
    How it Works- Overview Cmdlets are the “command-line utilities” within PowerShell They work with objects, not text, and can “plug into” one another to perform more complex tasks “ Nicknames” called aliases make cmdlet names easier to type Cmdlets can be “snapped in” to extend the shell’s functionality
  • 21.
    Navigating your systemYou probably already know how to do this! Start thinking of the commands you'd use to navigate your system using Cmd.exe Or, if you prefer the commands you'd use in a Linux or Unix operating system Quiz follows…
  • 22.
    Same command… differentparameters Try Dir /s Doesn't work! The command names are similar to what you're used to in Cmd.exe… … but the way in which the commands work are significantly different Fortunately, PowerShell can help you learn how to use the new commands
  • 23.
    Asking for helpPowerShell includes a robust built-in help system Ask for help on any command using the Help keyword (or Man if you prefer) Help accepts wildcards – lets you look up commands when you're not sure of their name Provides a quick reference to the correct parameters and syntax Add –online for latest version of help files
  • 24.
    Single, consistent skillset If you know one set of commands to navigate one type of hierarchical file system… … why not use the commands for other types of storage systems? The registry The certificate store Environment variables Active Directory
  • 25.
    How it worksPowerShell uses PSDrive Providers to connect to various storage systems The providers adapt a storage system to look like a "disk drive" The providers translate commands like CD and DIR into whatever the underlying store needs to see
  • 26.
    Just a fewchanges PowerShell does have a few quirks when compared to Cmd.exe… Cd .. , not Cd.. (needs the space) Cd "Program Files" not Cd Program Files (paths with spaces need to be in quotes) Etc. You usually get used to these minor changes pretty quickly
  • 27.
    You've already usedcmdlets! Cd, Ls, Dir, Copy, and Cp are all cmdlets (pronounced "command-lets") Technically, these are aliases, or nicknames, to actual cmdlets Cmdlets are written in a .NET Framework language Cmdlets are bundled into DLL files called snap-ins or PSSnapIns
  • 28.
    Aliases Aliases arejust "short names" for cmdlets They're easier to type They provide consistency with old-style command names Many aliases come built in, and you can create your own
  • 29.
    That's why dir /s doesn't work Dir is an alias for Get-ChildItem The alias only covers the cmdlet name – it doesn't change the parameters the cmdlet uses Get-ChildItem uses a different parameter to recurse subdirectories Dir –recurse or Dir –r will do the trick Using an alias is exactly the same as using the cmdlet that the alias 'points' to
  • 30.
    Finding cmdlet/alias namesYou know the alias, and want to find the cmdlet name: Help alias You know the cmdlet, and want to find aliases: gal | where { $_.ResolvedCommandName -eq " cmdlet " }
  • 31.
    Working with aliasesGet all alias: Get-Alias or Gal or Dir Alias: Add an alias: New-Alias Remove an alias: Remove-Item in the Alias: drive
  • 32.
    Working with cmdletsSee all cmdlets: Get-Command See all "Get" cmdlets: Get-Command –verb Get See all "Command" cmdlets: Get-Command –noun Command Notice the naming convention? Verb-SingularNoun
  • 33.
    Snap-ins Cmdlets are"packaged" in a snap-in Multiple snap-ins can be loaded into the shell ( Add-PSSnapIn ), extending its capabilities 120+ cmdlets provided in the default snapins ( Get-PSSnapin ) Just see the cmdlets added by a particular snapin: Get-Command –PSSnapin snapin
  • 34.
    Consistency! Cmdlet namesmight seem long (that's why you have aliases)… but there's a reason! Consistent verb-noun naming means you can guess what a cmdlet name would be based on the functionality you want This makes learning to use the shell easier
  • 35.
    Parameters Like old-stylecommand-line utilities, cmdlets have parameters (or "switches") These customize the behavior of a cmdlet Parameter names are preceded by a dash A space separates the parameter name and its value
  • 36.
    Parameters (con't)Parameters are documented in Help Parameter names may seem long… but they're clear… … and you only have to type enough to differentiate from other parameter names (e.g., you can be lazy) Positional parameters don't need the name at all – just type the values in the correct order
  • 37.
  • 38.
    Remember! PowerShell isall about self-discovery When you need to do something but don't know the cmdlet name… look it up! Help *Service* Get-Command -noun whatever Get-Command Help
  • 39.
    Cmdlets: Objects, nottext So far the cmdlets you've run have seemed to produce text lists as their output… … not so! They actually work with objects Object is a generic term that refers to some functional piece of software, like a process, or a service, or an event log
  • 40.
    Objects When yourun a cmdlet, it generally produces objects as its output These objects are actual functioning pieces of Windows Get-Service doesn't produce a list of services… it grabs all the actual services which are installed on the computer
  • 41.
    Objects Everything inPowerShell is an "object" "Object" is just a generic word for "functional thingy" Objects have properties which describe them… … and methods, which cause them to take some action Services, processes, event logs, etc. are all objects
  • 42.
    Get-Member Piping anobject to Get-Member (gm) tells you about the object What type it is (e.g., what kind of object) What properties it has What methods it has Get-Member teaches you about objects by revealing what they are and what they can do for you
  • 43.
    Object properties Aservice has certain properties that describe it: Name Started (True or False) DisplayName ServiceType Status (Running or Stopped) Etc. The text list you see consists of some of these properties' values (the ones highlighted here)
  • 44.
    The Pipeline Allcmdlets run in a pipeline At the end of the pipeline is a special cmdlet called Out-Default Out-Default takes whatever objects are in the pipeline, and uses some of their properties to construct a text list That's why you see text output when you run a cmdlet like Get-Service
  • 45.
    A Simple PipelineExample Property = Value Property = Value Property = Value Property = Value
  • 46.
    Piping cmdlets Becausenothing is converted to text until the end of the pipeline… … you can "pipe" objects from one cmdlet to another Each cmdlet can then work directly with the objects' properties
  • 47.
    Multi-Cmdlet Pipeline Property= Value Property = Value Property = Value Property = Value
  • 48.
    Action Cmdlets Manytimes, the common things you can "do" with an are available as PowerShell cmdlets Stop-Service, Start-Service, Pause-Service, Resume-Service, etc. Many of these "action" cmdlets don't output objects at all – so you see no text output when using them
  • 49.
  • 50.
    Object passthrough Cmdletsthat "consume" objects (but don't normally output any) often have a –passThru parameter which forces them to pass their objects down the pipeline Stop-Service is an example of one of these cmdlets
  • 51.
    Multi-Cmdlet Pipeline Property= Value Property = Value Property = Value Property = Value
  • 52.
    Remember! You onlysee text output when there are objects left in the pipeline No objects remaining… no output Some cmdlets "consume" objects and do something with them, but don't output any objects A –passThru parameter forces a cmdlet to pass its objects down the pipeline for further use
  • 53.
    Remember! Object have properties The cmdlets we're going to look at utilize these properties Wonder what properties an object has? Pipe the object to Get-Member to find out
  • 54.
    Sorting objects Sortsobjects in descending or ascending (default) order, using the property or properties you specify Sort-Object Name Sort-Object DisplayName -descending Pipe objects in to sort them; the sorted objects are piped out
  • 55.
    Measuring objects Bydefault, counts the number of objects piped in The objects are not piped out – only the measurement results are piped out (meaning your original objects are "lost")
  • 56.
    Selecting object propertiesTakes piped-in objects and just keeps the properties you specify Select-Object Name,DisplayName Good for "narrowing down" the properties that show in your output The original objects are not piped out (they are "lost") New, custom objects – with just the properties you specify – are piped out
  • 57.
    Keeping the first/lastobject(s) You can also keep just the first "x" or last "x" number of objects Select-Object –first 10 Select-Object –last 20 If you just do this, the original objects are piped out
  • 58.
    Exporting objects Objectscan be exported to CSV or an XML format Export-CSV filename Export-CliXML filename Useful for generating reports, or persisting objects across sessions
  • 59.
    Importing objects Readsin a CSV or XML file and constructs objects from them Each line in the CSV, or each XML node, becomes an object with all the properties contained in the file Import-CSV filename Import-CliXML filename
  • 60.
    Secure by DefaultBy default: PowerShell won't run scripts When configured to run scripts, the shell can require that they be digitally signed .PS1 filename extension not associated with the shell Must specify a path in order to run a script
  • 61.
    SBD: Won't runscripts PowerShell has an ExecutionPolicy which is set to Restricted by default – no scripts will run Other ExecutionPolicy settings: AllSigned: Only signed scripts run RemoteSigned: Local scripts don't need to be signed, remote ones (downloaded) do Unrestricted: All scripts will run (bad idea in a production environment)
  • 62.
    What is scriptsigning? Signed .PS1 files contain a "signature block" in comments at the end of the file Intact signature means… The script has not been modified since signed The identity of the script author/signer is verified
  • 63.
  • 64.
    Controlling ExecutionPolicy Get-ExecutionPolicy and Set-ExecutionPolicy cmdlets Download ExecutionPolicy ADM template (for Group Policy) from Microsoft (URL on class CD)
  • 65.
    SBD: .PS1 association.PS1 filename extension associated (by default) with Notepad, not the shell Double-clicking a script file won't execute it, it'll just open it for editing Helps prevent scripts sent via e-mail from being accidentally executed a la VBScript
  • 66.
    SBD: Must specifya path Create a script named dir.ps1 Try to execute it by running Dir You can't: In order to run a script, you must specify a path - ./dir will work Helps visually distinguish a script from a built-in command
  • 67.
    Alternate Credentials SomePowerShell cmdlets have a -credential parameter which accepts either a username or a PSCredential object that specifies alternate credentials to use Get-WMIObject is a good example Providing a username launches a graphical dialog where you enter the password
  • 68.
    Storing alternate credentialsGet-Credential prompts for a credential and securely stores it in a variable The variable can then be provided as the value of a –credential parameter Lets you create a credential once, and then use it multiple times Hint: Put this in your PowerShell profile to have it create the credential each time the shell runs
  • 69.
    Sidebar: Profiles A.PS1 file that is automatically executed each time the shell loads No profile exists by default Create …\Documents\WindowsPowerShell folder, create Microsoft.PowerShell_Profile.PS1 file Simply fill the file with commands that you want run each time the shell loads
  • 70.
    What is WMI?A system for remotely obtaining management information… … and in limited cases, reconfiguring settings Implemented as a service since Windows 2000 (and available for NT 4) Based in industry-standard techniques developed by the Desktop Management Task Force (DMTF)
  • 71.
    WMI structure Namespaces typically align to products (Windows, SQL, IIS, DNS, etc) Classes live in namespaces and represent manageable components (disks, users, Web sites, NICs, etc) Instances are real-world occurrences of a class (two logical disks = two instances of the disk class)
  • 72.
    Classes & instancesInstances are objects, meaning they have properties They can also have methods, which are the things you can do with an object (e.g., Disk objects have a Defrag method) Review properties to see management information; execute methods to make configuration changes
  • 73.
    WMI query optionsGet all properties for instances of a given class Get all objects that match a WMI Query Language (WQL) query In both cases, the Get-WMIObject cmdlet does the work
  • 74.
    Simple WMI Get-WMIObject classname [-computerName computername ] [-credential PSCredential ] Retrieves all instances of the designated class (optionally, from the specified computer using the specified credentials)
  • 75.
    WMI Classes Wherecan you get a list of classes? For the core root\cimv2 namespace… Use the WMI Documentation Ask PowerShell for a list of classes Use the WMI Explorer (scriptinganswers.com, click “Free Tools”)
  • 76.
    WQL Queries SQL-likesyntax Specify the properties you want… … the class you're querying… … and the criteria (to filter out instances you don't want)
  • 77.
    WQL Example SELECT{ * | Property,Property } FROM { Class } [ WHERE Property = Value ] SELECT * FROM Win32_LogicalDisk WHERE DriveType = 3
  • 78.
    Testing WQL QueriesUse the built-in Wbemtest.exe GUI tool Connect to a namespace (root\cimv2 is the default namespace used by PowerShell) Enter a WQL query See the objects that come back Great way to prototype, test, and refine queries in a graphical environment
  • 79.
    WQL Queries inPowerShell Get-WMIObject –query " WQL query " Gwmi –qu "SELECT * FROM Win32_LogicalDisk WHERE DriveType = 3"
  • 80.
    WMI and thepipeline Get-WMIObject returns objects with properties … … pipe them to Get-Member to see those properties… … or use the objects in the pipeline with Sort, Select, Group, and the other cmdlets you've learned
  • 81.
    Comparisons The purposeof a comparison is to generate a True or False result PowerShell provides the $True and $False variables to represent these Boolean values All comparisons result in either $True or $False
  • 82.
    Comparison operators -eqEquality -ne Inequality -gt Greater than -lt Less than -ge Greater than or equal to -le Less than or equal to
  • 83.
    Comparison examples Supposing$_ represents a process… $_.Handles –gt 1000 $_.Name –eq "Notepad" $_.Responding Note that the Responding property is either True or False; it does not have to be compared to $True or $False to generate a True/False result
  • 84.
    Filtering in thepipeline Where-Object accepts a collection of objects and examines each one Only those objects meeting the criteria you specify are passed down the pipeline In your comparison expression, $_ represents "the current pipeline object we're examining."
  • 85.
    Where-Object Get-Service | Where-Object { $_.Status –eq "Running" } | Sort-Object Name -descending
  • 86.
    Complex comparisons Needto compare more than one condition in a single expression? -and returns True if both are True -or returns True if either is True -not reverse True/False
  • 87.
    Complex example Supposing$_ represents a WMI Win32_Service instance… $_.StartMode –eq "Auto" -and $_.State –ne "Running"
  • 88.
    Formatting output We'vetalked before about how the pipeline ends in Out-Default, which turns objects into text The actual process is somewhat more complicated than that! Out-Default actually redirects objects to Out-Host, which does the work of displaying objects
  • 89.
    Out-Host Out-Host can'tdisplay normal objects… … it can only display special PowerShell formatting objects So when Out-Host receives normal objects, it calls on PowerShell's formatting system to turn them into formatting objects
  • 90.
    Formatting rule #1Does the object type have a view defined in one of the .format.ps1xml files? If yes… use that view, which specifies either table, list, or wide layout. If not… go to rule 2.
  • 91.
    Formatting rule #2Does this type of object have a set of Default Display Properties define in a .ps1xml file? If Yes, use only the default properties for the next decision If No, use all of the object's properties for the next decision
  • 92.
    Formatting rule #3Are we displaying >=5 properties? If Yes, choose a List layout If No, choose a Table layout
  • 93.
    Formatting rule #4Using the properties we've chosen, and using the layout we've chosen, call a formatting cmdlet to create the formatting objects Format-Table (ft) Format-Wide (fw) Format-List (fl)
  • 94.
    Formatting process Get-ServiceOut-Default Out-Host Format-Table
  • 95.
    That's just thedefault… You can pipe objects to any of the Format-* cmdlets on your own This lets you specify the layout you want Use the Format-* cmdlets to specify the properties you want displayed, too Produces formatting objects (meaning the Format-* cmdlet has to be the last thing in the pipeline)
  • 96.
    Let ’s PlayLet ’s see what we can do with FT and FL… Select properties to display in the output Control table sizing Grouping the output by a selected property (sort the objects first!)
  • 97.
    Input and outputRead-Host and Write-Host read and write input directly from the console Write-Output writes output to the Success pipeline Anything in the pipeline can potentially end up displayed in the console At the end of the pipeline is Out-Default.
  • 98.
    Write-Host vs. Write-OutputWrite-Output Out-Default Write-Host Out-Host Where-Object
  • 99.
    Fun Trick Trypiping output (say, of Get-Service) to ConvertTo-HTML Try piping that output to Out-File and specifying a file name Neat, huh?
  • 100.
    Variables PowerShell usesvariables as temporary, named storage for objects Variable names begin with $ Names can contain (mainly) letters, numbers, and underscores Variables are not automatically persisted by the shell
  • 101.
    Variable FAQ Howlong can variable names be? Long enough. Can I declare them in advance? Yes, using New-Variable Do I have to declare them in advance? No, and there's no way to force yourself. Are all variables the same "type?" No, they are the "type" of whatever object they contain…
  • 102.
    Variables are objectsVariables are really just names for an area in memory where objects are stored Variables aren't things themselves; they're just containers for actual objects A variable exposes the properties and methods of the object(s) it contains Pipe a variable to Get-Member to see what it can do!
  • 103.
    Variable types PowerShellautomatically tries to figure out what "type" a variable is when you create it and when you use it This allows "5" to be treated as a number when appropriate, and as a text string when appropriate… … although sometimes PowerShell gets confused about which type it should be using
  • 104.
    Common types [string][int] [boolean] [regex] [single] [double] [array] [adsi] [wmi] [hashtable] [xml] [char] Lots more!
  • 105.
    Arrays A specialkind of variable capable of holding multiple objects… … usually of the same type, but not necessarily Each object in the array has an index , which is its location within the array 0 is the bottom index (the first item) The special index -1 always returns the last item in the array
  • 106.
    Creating an arrayAny cmdlet which returns a collection of objects is returning an array – and that collection can be stored in a single variable You can also create your own arrays $arr = @( 1,2,3,4,5 ) PowerShell always treats any comma-separated list as an array – remember this!!!
  • 107.
    Using an arrayYou can pipe arrays to cmdlets – just like you can pipe any collection of objects to most cmdlets Access individual elements in the array by specifying an [index] in square brackets: $arr[0]
  • 108.
    Array tip: Arraysand collections aren't technically the same thing, but for most purposes you can think of them as the same thing Collection of objects = Array of objects
  • 109.
    Escape characters `(backtick) is the universal escape character in PowerShell ` at the end of a line "escapes" the carriage return (e.g., line continuation) ` before a space "escapes" it (e.g., makes it a literal space) ` before certain characters performs special functions
  • 110.
    Inventorying Information Let’s use WMI to inventory information The neat bit is that a single command can pull info from multiple computers How will we know which computer each bit came back from? We ’ll look at technique that uses no scripting! We ’ll be using Service Pack info
  • 111.
    Scripting Scripting inPowerShell is really just pasting commands into a text file There are a few “scripting constructs” you can use to implement logic and flow control for more complex processes Scripts are just text files with a .PS1 filename extension You can edit with Notepad, although a PowerShell-specific editor is far better
  • 112.
    Foreach Used totake a collection of objects and go through them, one at a time Lets you perform multiple operations per object Let ’s modify our WMI inventory command to work in this fashion
  • 113.
    Customizing objects Pipean object to Add-Member to add a NoteProperty , which contains a static value $obj | Add-Member NoteProperty PropertyName PropertyValue Use Write-Output to output the new object Let ’s use this to add a “ComputerName” property to our WMI object
  • 114.
    Switch Used tocompare a variable or property value to a range of possible values, and take some action We ’ll use this to translate the build number into a more readable OS WinVersion property
  • 115.
    Multiple Sources? Whatif we also wanted our output to include a BIOS serial number / call tag property? We could query Win32_BIOS… how do we combine it with our existing output? Ideally, our output should be a SINGLE object that has properties for the COMBINED information…
  • 116.
    Create a CustomObject We ’ll use New-Object PSObject to create a new, blank object We ’ll use Add-Member to add the information we want – from various sources We ’ll output the combined object
  • 117.
    Making it aTool Let ’s wrap the whole thing in a parameterized function that accepts an input filename We ’ll expect the input file to contain one computer name per line
  • 118.
    Making it aPipeline Tool Instead of specifying a filename, let ’s modify the function to accept a collection of computer names from the pipeline as its input This lets us use a variety of input sources, so long as they generate a collection of computer names – doesn ’t need to be a file (maybe from AD?)
  • 119.
    Output Flexibility Byaccepting pipeline input, we add flexibility By producing pipeline output , we add lots of flexibility! Let ’s see
  • 120.
    Managing AD Let’s look at how to import users from a CSV file and make them into AD user accounts We ’ll use the Import-CSV and New-DUser cmdlets We ’ll allow the CSV file to contain arbitrary headings (not AD attribute names)
  • 121.
    Thank You! Pleasefeel free to pick up a card if you ’d like copies of my session materials I ’ll be happy to take any last questions while I pack up Please complete and submit an evaluation form for this and every session you attend!
  • 122.
  • 123.
    This slide deckwas used in one of our many conference presentations. We hope you enjoy it, and invite you to use it within your own organization however you like. For more information on our company, including information on private classes and upcoming conference appearances, please visit our Web site, www.ConcentratedTech.com . For links to newly-posted decks, follow us on Twitter: @concentrateddon or @concentratdgreg This work is copyright ©Concentrated Technology, LLC

Editor's Notes

  • #2 MGB 2003 © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
  • #64 Windows PowerShell 101 Based upon Windows PowerShell: TFM by Jones and Hicks Copyright ©2007 SAPIEN Technologies, Inc. Here's how script signing and the execution policy work. You've *got your PowerShell script that you want to run, and you've got a *computer that you want to copy the script to so that you can run the script there. Simple enough. Let's say you've got your Execution Policy set to AllSigned. Well, if your script isn't signed, then PowerShell isn't going to run it. So you're going to need to go to a *certificate server, either one internal to your network or a commercial one, and obtain what's called a *code-signing certificate. After the certification authority – that's the folks who own the certificate server – verify your identity in some way, they'll *issue you the certificate, and you'll use it to digitally sign your script. PowerShell knows how to do that once the certificate is installed on your local computer. *Once signed, you can copy your script to the computer where you want it to run. When you ask the computer to *run the script, it performs three *checks: First checks to see if it's signed. *Well, it is. So now it checks to see if the signature is intact, meaning that the script hasn't been changed since it was signed. And that check *passes. Finally, it *checks to see if it trusts the certification authority who issued the certificate in the first place. Basically, the computer is asking, "do I trust this CA to have accurately verified the identity of the script author before they have him a certificate?" *Provided the computer trusts the certificate authority, *the third check will pass, and the script will run. For more details on how to sign a script, consult the PowerShell docs, Windows PowerShell: TFM, or use SAPIEN PrimalScript Professional or Enterprise Editions, which have script-signing functionality built right in.
  • #122 MGB 2003 © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.