CONTENTS IN DETAIL - No Starch Press

CONTENTS IN DETAIL

ACKNOWLEDGMENTS

xix

INTRODUCTION

xxi

Why PowerShell? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxii Who This Book Is For . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxii About This Book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxii

PART I: FUNDAMENTALS

1

1

GETTING STARTED

3

Opening the PowerShell Console . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 Using DOS Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 Exploring PowerShell Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Getting Help . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

Displaying the Docs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 Learning About General Topics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 Updating the Docs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

2

BASIC POWERSHELL CONCEPTS

13

Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 Displaying and Changing a Variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 User-Defined Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 Automatic Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 Boolean Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 Integers and Floating Points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 Inspecting Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 Using the Get-Member cmdlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 Calling Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

Data Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 ArrayLists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 Hashtables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

Creating Custom Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

3

COMBINING COMMANDS

37

Starting a Windows Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 Using the Pipeline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

Piping Objects Between Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 Piping Arrays Between Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 Looking at Parameter Binding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 Writing Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 Setting the Execution Policy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 Scripting in PowerShell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

4

CONTROL FLOW

47

Understanding Control Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 Using Conditional Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

Building Expressions by Using Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 The if Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 The else Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 The elseif Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 The switch Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 Using Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 The foreach Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 The for Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 The while Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 The do/while and do/until Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

5

ERROR HANDLING

61

Working with Exceptions and Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 Handling Nonterminating Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 Handling Terminating Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 Exploring the $Error Automatic Variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67

6

WRITING FUNCTIONS

69

Functions vs. Cmdlets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 Defining a Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 Adding Parameters to Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

Creating a Simple Parameter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 The Mandatory Parameter Attribute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 Default Parameter Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 Adding Parameter Validation Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74

xii Contents in Detail

Accepting Pipeline Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 Adding Another Parameter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 Making the Function Pipeline Compatible . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 Adding a process Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77

Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78

7

EXPLORING MODULES

79

Exploring Default Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 Finding Modules in Your Session . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 Finding Modules on Your Computer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 Importing Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82

The Components of a PowerShell Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 The .psm1 File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 The Module Manifest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

Working with Custom Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 Finding Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 Installing Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 Uninstalling Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88

Creating Your Own Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89

8

RUNNING SCRIPTS REMOTELY

91

Working with Scriptblocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 Using Invoke-Command to Execute Code on Remote Systems . . . . . . . . . . . . . 93 Running Local Scripts on Remote Computers . . . . . . . . . . . . . . . . . . . . . . . . . 94 Using Local Variables Remotely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95

Working with Sessions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96 Creating a New Session . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 Invoking Commands in a Session . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 Opening Interactive Sessions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 Disconnecting from and Reconnecting to Sessions . . . . . . . . . . . . . . . . . . . . . 99 Removing Sessions with Remove-PSSession . . . . . . . . . . . . . . . . . . . . . . . . . 101

Understanding PowerShell Remoting Authentication . . . . . . . . . . . . . . . . . . . . . . . . . . 101 The Double Hop Problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 Double Hopping with CredSSP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103

Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105

9 TESTING WITH PESTER

107

Introducing Pester . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 Pester Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108

A Pester File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 The describe Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 The context Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 The it Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 Assertions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 Executing a Pester Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112

Contents in Detail xiii

PART II: AUTOMATING DAY-TO-DAY TASKS

113

10 PARSING STRUCTURED DATA

117

CSV Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 Reading CSV Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 Creating CSV Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 Project 1: Building a Computer Inventory Report . . . . . . . . . . . . . . . . . . . . . 123

Excel Spreadsheets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 Creating Excel Spreadsheets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 Reading Excel Spreadsheets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 Adding to Excel Spreadsheets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128 Project 2: Creating a Windows Service Monitoring Tool . . . . . . . . . . . . . . . . 129

JSON Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 Reading JSON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 Creating JSON Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 Project 3: Querying and Parsing a REST API . . . . . . . . . . . . . . . . . . . . . . . . 134

Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136

11 AUTOMATING ACTIVE DIRECTORY

137

Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 Installing the ActiveDirectory PowerShell Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 Querying and Filtering AD Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139

Filtering Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 Returning Single Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141 Project 4: Finding User Accounts That Haven't Changed

Their Password in 30 Days . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141 Creating and Changing AD Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143

Users and Computers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 Groups . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 Project 5: Creating an Employee Provisioning Script . . . . . . . . . . . . . . . . . . . 146 Syncing from Other Data Sources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149 Project 6: Creating a Syncing Script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 Mapping Data Source Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 Creating Functions to Return Similar Properties . . . . . . . . . . . . . . . . . . . . . . . 151 Finding Matches in Active Directory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 Changing Active Directory Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156

12 WORKING WITH AZURE

157

Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 Azure Authentication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158

Creating a Service Principal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 Noninteractively Authenticating with Connect-AzAccount . . . . . . . . . . . . . . . 160 Creating an Azure Virtual Machine and All Dependencies . . . . . . . . . . . . . . . . . . . . . 161 Creating a Resource Group . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 Creating the Network Stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162

xiv Contents in Detail

Creating a Storage Account . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164 Creating the Operating System Image . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164 Wrapping Up . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166 Automating the VM Creation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 Deploying an Azure Web App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 Creating an App Service Plan and Web App . . . . . . . . . . . . . . . . . . . . . . . 167 Deploying an Azure SQL Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 Creating an Azure SQL Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 Creating the Azure SQL Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 Creating the SQL Server Firewall Rule . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170 Testing Your SQL Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172

13 WORKING WITH AWS

173

Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174 AWS Authentication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174

Authenticating with the Root User . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174 Creating an IAM User and Role . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 Authenticating Your IAM User . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 Creating an AWS EC2 Instance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178 The Virtual Private Cloud . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178 The Internet Gateway . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 Routes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 Subnet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 Assigning an AMI to Your EC2 Instance . . . . . . . . . . . . . . . . . . . . . . . . . . . 181 Wrapping Up . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182 Deploying an Elastic Beanstalk Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184 Creating the Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184 Deploying a Package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186 Creating a SQL Server Database in AWS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191

14 CREATING A SERVER INVENTORY SCRIPT

193

Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194 Creating the Project Script(s) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194 Defining the Final Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194 Discovery and Script Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194 Querying Each Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196 Thinking Ahead: Combining Different Types of Information . . . . . . . . . . . . . . . . . . . . 196 Querying Remote Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199 Querying Windows Management Instrumentation . . . . . . . . . . . . . . . . . . . . . . . . . . . 201

Disk Free Space . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202 Operating System Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202 Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203 Network Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205 Windows Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208 Script Cleanup and Optimization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212

Contents in Detail xv

................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download