Learn Windows PowerShell 3 in a Month of Lunches(2rd)
2013, DON JONES
这本书基于 PowerShell 3.0,做初学者教材极好,若有 Linux shell 基础则可一目十行。如下便是摘录式笔记,仅记录一些感兴趣的重点,涉及大部分章节。
书中甚少涉及语法,因为按作者的说法:操起命令直接上,这才是 PS 的主要使用模式(PowerShell-ish ways),而非一般的脚本编程,流控之类的语法都只是命令的粘合剂。
读完一遍,对 PS 突出印象:
- 现代化的、风格一致的设计
应该借鉴了 Linux shell、python、C# 等;一致性降低了学习使用成本 - 面向对象、基于 .NET 框架
一切皆对象,消除了无结构文本的弊端;可以直接使用 .NET 对象,Amazing! - 命令式
开发迭代模型:run—result—modify—run
ch2. Meet PowerShell(初识 PS)
PowerShell 包含两个组件:
- PS console
轻快,不支持双字节字符集,无补全 - PS ISE (integrated scripting environment)
基于 WPF,支持中文,强大的帮助与补全
查看当前 PS 版本: $PSVersionTable
ch3. Using the help system(帮助系统)
媲美 GUI 的 CLI 帮助系统:能迅速找到命令并了解其用法(支持通配符)
- Get-Command 查找匹配的命令
- Get-Help 查看命令用法
- Get-Member 查看对象的类型和成员
- Help 是 function,相当于 Get-Help | More
查看示例:Help Get-EventLog -example
详细信息:Help Get-EventLog -full - Show-command 带 GUI 帮助的填写
4 种命令 Command:cmdlet(命名约定 verbs + nouns),function,workflow,externApp。
例: Get-Service -name e,s*
多个参数搭配路径
ch4. Running commands(命令)
cmdlet:原生命令,使用 .Net 语言编写。参数类型如下:
- 可选 optional 参数整个在方括号里
[-ComputerName <string[]>]
,这里的数组用逗号分隔的列表表示;用参数缩写时能唯一标识即可,如 -comp - 否则为强制 mandatory 参数,
[-LogName] <string>
- 若参数名称在方括号里,则亦为位置 positional 参数
- 开关参数
MS 会尽力提供 cmdlet 作为原生解决方法,故总应优先用 cmdlet
externApp(外部命令)
$exe = “C:\mount.exe”
$host = “srv”
$user = “nick”
& $exe -h $host -u $user
新写法:-- C:\mount.exe -h srv -u nick
,会直接传给 cmd,不解析
ch5. Working with providers
PSProvider 适配器,以类文件系统的方式,来导航与管理数据存储(动态结构),如注册表。
查看可用:Get-PSProvider
相关 cmdlet 的 noun 常带 “Item”(指单独对象,如文件)
ItemProperty 表示 item 属性,如只读,一般都有 -Path 属性,支持通配符;ChildItem 指子对象
ch6. The pipeline: connecting commands(Pipeline)
ch7. Adding commands(PS 扩展机制)
两种:module 和 snap-in(dll+xml)
get-pssnapin -registered 注册
add-pssnapin sqlservercmdletsnapin100,sqlserverprovidersnapin100
Get-Command -pssnapin sqlservercmdletsnapin100
module 不用注册,根据 $PSModulePath 自动发现,按需加载
get-command -Module DnsClient
有些特定的管理 shell 其实是带参数启动 powershell.exe -noexit -command import-module ActiveDirectory
ch8. Objects: data by another name(对象)
查看:get-process | get-member
a collection of objects as a big in-memory table of information
, with propertiesas the columns and individual objects the rows.
PS 对象一般来自 .net 框架,但 ETS(Extensible Type System)会添加些额外属性(ScriptProperty,NoteProperty,AliasProperty)以利使用。
对象的 property 用的很多,但 action/method 用的很少,因为功能通常由 cmdlet 实现
Get-Process | Sort-Object VM,ID -desc
Get-Process | Select-Object Name,ID,VM,PM
Select-Objectis 用来选择或新建 properties(会产生新对象), 以及特定行,-expandProperty 可以获取其值列表. 而 Where-Object 根据指定条件删除或过滤 pipeline 里的 objects。
pipeline 的每一步都可能产生不同对象,可使用 gm 来确定
ch9. The pipeline,deeper(深入 pipeline)
Try1. ByValue:把输入与参数类型进行匹配;参数需支持 pipelineInputByValue(可通过 Help -full 查看);仅能匹配一个参数(能否手动指定?)
Try2. ByPropertyName:仅名字匹配;需支持 pipInByPropertyName;多参数匹配
Get-WmiObject -class Win32_BIOS -ComputerName (Get-Content .\comput
ers.txt)
ch10. Formatting—and why it’s done on the right(格式化)
ch11. Filtering and comparisons(过滤与比较)
- Filter left (命令需支持 -filter 参数)
- Where-Object(使用类似的比较符)
Get-Service | Where { $_.Status -eq 'Running' } --> Get-Service | Where Status -eq 'Running'
(单条件简化写法)
(5 -gt 10) -and (10 -gt 100)
$_.Responding -eq $False
ch12. A practical interlude(实践)
- 需求:remove all print jobs from a local printer “Accounting” every 3 a.m.
- 寻找命令
help *task*;get-command -module scheduledtasks
- 学习用法
help new-scheduledtask -full
ch13. Remote control: one to one, and one to many(远程控制)
ch14. Using Windows Management Instrumentation(WMI)
WMI 能够获取大量系统信息,但不好用(缺乏统一规划,文档缺乏)。对 PS 来说只是个可以借用的外部技术,建议使用 CIM 封装命令与之交互
wmi 必知必会
repository
— namespace 例如 root\CIMv2 就包含了所有系统和硬件信息
— class 代表管理组件,一个实例对应一个现实组件
可用查看软件:wmi explorer
- Get-WmiObject(retrieve all instances of that class from the computer specified,Legacy!) + Invoke-WmiMethod
查看 Get-WmiObject -Namespace root\CIMv2 -list | where name -like ‘dis‘
gwmi -class win32_desktop -filter “name=’COMPANY\Administrator’” - Get-CimInstance + Invoke-CimMethod
查看 Get-CimClass -Namespace root\CIMv2
Get-CimInstance -ClassName Win32_LogicalDisk
ch15. Multitasking with background jobs(后台多任务)
Help * -parameter asjob
ch16. Working with many objects, one at a time(批量操作)
批量操作的三种方法:batch cmdlets, WMImethods, and object enumeration.
- Get-Service -name BITS,Spooler,W32Time -computer Server1,Server2,Server3 | Set-Service -passthru -startuptype Automatic
Stop-Service -name *B*
缺点是批量处理时一般没有输出,此时可以使用 -passThru 来查看被处理的输入 - gwmi win32_networkadapterconfiguration -filter “description like ‘%intel%’” | Invoke-WmiMethod -name EnableDHCP
会输出一个 result object,可以看到每个操作的 ReturnValue,但无法分辨 - gwmi win32_service -filter “name = ‘BITS’” | foreach-object {$_.change($null,$null,$null,$null,$null,$null,$null,”[email protected]”) }
ch17. Security alert(安全警告)
ch18. Variables: a place to store your stuff(变量)
${My Variable} = ‘SERVER-R2’,’SERVER1’,’localhost’
[int]$number = Read-Host “Enter a number”(强制类型声明)
'$' is a cue to the shell that what follows is going to be a variable
name, and that we want to access the contents of that variable.
变量能够存放多个不同类型的对象,类数组操作
单引号 — a literal string
双引号 — expansion string,但仅在初始解析时替换!
转义符 — ˜
subexpression — $(cmd) ==> string
ch19. Input and output
ch20. Sessions: remote control with less work(会话管理)
长连接
$iis_servers = new-pssession -comp web1,web2,web3
- Using sessions with Enter-PSSession(interactive)
- Using sessions with Invoke-Command
invoke-command -command { get-wmiobject -class win32_process } -session (get-pssession -comp loc*) - Disconnect & Reconnect session
ch21. You call this scripting?
如何写 help 文档
One script, one pipeline
within a script, you only have one pipeline to work with.
Normally, your scripts should strive to only output one kind of object, so that PowerShell can produce sensible text output.
ch22. Improving your parameterized script(命令行选项)
ch23. Advanced remoting configuration
ch24. Using regular expressions to parse text files
ch25. Additional random tips, tricks, and techniques
ch26. Using someone else’s script
ch27. Never the end
进阶学习:
- PowerShell’s simplified scripting language
- Scope
- Functions, and the ability to build multiple tools into a single script file
- Error handling
- Writing help
- Debugging
- Custom formatting views
- Custom type extensions
- Script and manifest modules
- Using databases
- Workflows
- Pipeline troubleshooting
- Complex object hierarchies
- Globalization and localization
- GUI-based PowerShell tools
- Proxy functions
- Constrained remoting and delegated administration
- Using .NET
例一:批量查询 ip 所属的 ISP
get-content IPs.txt | % -Process { Write-Host -NoNewline "$_ : "; (curl "http://www.whoismyisp.org/ip/$_").AllElements }
| Where {$_.TagName -eq "H1"} | select -Expand 'innerText'
例二:数据库的备份与备份清理
- 在 2008R2 系统下,备份 MySQL data 文件夹,通过任务计划实现每天自动备份数据库和删除 5 天前的备份。
- 备份到 E:/mysqlBackup/日期_data/,例如 E:/mysqlBackup/0801_data/
- ———- 需要备份 ———
D:/mysql/data/dz138/
D:/mysql/data/wyt8/
———以下文件/文件夹不备份———
D:/mysql/data/performance_schema/ #数据库自带不备份
D:/mysql/data/mysql/
代码:
$datPath = "D:/mysql/data/*" # '*' 不可少,限定在此层
$data = "dz138", "wyt8"
$bakCount = 5 # 保留 5 个备份
$bakPath = "E:/mysqlBackup/"
$bakDir = (Get-Date).Tostring("yyyyMMdd") + "_data" # 有年份更明确点
New-Item -type directory -path ($bakPath + $bakDir)
Copy-Item $datPath -Include $data -Destination ($bakPath + $bakDir) -Recurse -Force
Get-ChildItem $bakPath -Filter *_data | Sort-Object -Property LastWriteTime -Descending
| Select-Object -Skip $bakCount | Remove-Item
参考:
- Windows PowerShell IN ACTION 2nd, 2011, Bruce Payette