Powershell快速入门

来源:

https://blog.csdn.net/u011054333/article/details/72567590

https://blog.csdn.net/u011054333/article/details/72568190

https://blog.csdn.net/u011054333/article/details/72798046

一说起 Shell 编程,我们大家想到的应该都是Linux 下的 Shell 编程。其实 Windows 下也可以使用功能强大的 Shell 来编写程序,这就是今天我要介绍的 Powershell。从名字就可以看出来,Powershell的功能很强大,所以才敢叫Powershell。

如果需要看官方文档的话,点击这里。虽然有一些机翻的意味,但是完全可以看。

需要说明一点,Powershell是构建在.NET平台上的,所有命令传递的都是.NET对象。所以为了更好地使用Powershell,最好有一点.NET编程基础,这样学习Powershell就会感觉非常轻松和愉快。

安装Powershell

这里我介绍的是 Powershell 5.0 ,它在 Windows Server 2016 和Windows 10 操作系统中是默认安装的。如果使用的是比较旧的操作系统例如 Windows 7 或者 Windows 8.1 ,就需要手动安装 Powershell 5.0 。下载也很简单,到这里下载 WMF 5.0,它包含了 Powershell 5.0 和一系列工具。

如果要查看当前Powershell版本的话,也很简单。在Powershell窗口中使用下面的命令即可查看相关信息。

C:\Users\asddf> $PSVersionTable

Name                           Value
---- -----
PSVersion 5.1.15063.296
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.15063.296
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1

启动Powershell

启动 Powershell 很简单,从运行对话框或者开始菜单中搜索powershell即可。这样就可以打开 Powershell 命令行窗口了。默认情况下这是一个蓝色的窗口。

在64位操作系统下,有两个版本的 Powershell 。默认情况下,我们使用64位版本就可以了。如果有特殊需求的话,可以选择启动带x86字样的32位版本的 Powershell 。

启动Powershell ISE

在终端中敲命令是一件很麻烦的事情,有没有什么集成环境可以让我们进行交互式学习呢?当然是有的,Windows 附带了一个交互式环境,叫做Powershell ISE,可以帮助我们更方便的学习和使用 Powershell。

启动 Powershell ISE也很简单,在Windows 10下,直接在开始菜单中输入 ISE,就可以打开Powershell ISE了。

命令介绍

首先说明一下,和 Linux Shell 不同,Powershell 的命令基本上都是动词-名词形式的。这样做的好处是命令作用很容易就可以看出,缺点就是输入稍微有些麻烦,习惯了Linux 的简洁的同学可能会不太适应。

Powershell 和Linux Shell 还有一个不同点在于Powershell 是基于 .NET平台的,它的命令叫做cmdletcmdlet功能比普通的Linux 命令更强,因为cmdlet接受的参数不是字符串,而是 .NET 对象,这使得Powershell 的功能更加强大和灵活。

获取命令

如果想要获取当前会话中所有可用的内置命令,可以使用命令Get-Command,它的别名是gcm

PS C:\Users\asddf> Get-Command 

CommandType     Name                                               Version    Source
----------- ---- ------- ------
Cmdlet Get-Command 3.0.0.0 Microsoft.PowerShell.Core
.....

如果希望列出指定名称的命令,可以使用Name参数。

PS C:\Users\asddf> Get-Command -Name Get-Command

CommandType     Name                                               Version    Source
----------- ---- ------- ------
Cmdlet Get-Command 3.0.0.0 Microsoft.PowerShell.Core

获取别名

有些命令比较常用,除了动词-名词版本外,Powershell还提供了和Linux 一样的别名来简化输入。我们可以使用-CommandType Alias参数来显示所有的命令别名。下面列举了一部分输出,可以看到,微软为了照顾Linux用户,很多命令都缩写为Linux 命令的形式。

PS C:\Users\asddf> Get-Command -CommandType Alias

CommandType     Name                                               Version    Source
----------- ---- ------- ------
Alias % -> ForEach-Object
Alias ? -> Where-Object
Alias ac -> Add-Content
Alias blsmba -> 2.0.0.0 SmbShare
Alias cat -> Get-Content
Alias cd -> Set-Location
Alias chdir -> Set-Location
Alias clc -> Clear-Content
Alias clear -> Clear-Host
Alias clhy -> Clear-History
Alias cli -> Clear-Item
Alias clp -> Clear-ItemProperty
Alias cls -> Clear-Host

当然,如果你观察仔细的话,会发现命令类型这一栏有Aliascmdlet以及function三种类型。所以我在前面使用了“内置命令”这个词。函数基本上就是最简单的命令,例如清屏(Clear-Host),不能接受参数,功能比较基本。cmdlet则是功能强大的命令,可以接受各类参数,还能复合使用。Alias则是前两者的别名,作用是简化输入。

获取动词/名词

当然,如果想查找特定动词/名词的命令也是可以的。比方说,如果我想查找所有以Get开头的命令,可以使用下面的命令。

PS C:\Users\asddf> Get-Command -Verb Get

相应的,如果我想获取所有名词是Help的命令,可以使用下面的命令。

PS C:\Users\asddf> Get-Command -Noun Help

CommandType     Name                                               Version    Source
----------- ---- ------- ------
Cmdlet Get-Help 3.0.0.0 Microsoft.PowerShell.Core
Cmdlet Save-Help 3.0.0.0 Microsoft.PowerShell.Core
Cmdlet Update-Help 3.0.0.0 Microsoft.PowerShell.Core

上面的命令都只列出了内置命令。如果需要包含包括普通程序在内的所有命令,可以使用通配符。

PS C:\Users\asddf> Get-Command *

获取帮助

如果要获取一个命令的帮助,可以使用Get-Help。如果使用上面介绍的列出别名的命令的话,会发现这个命令的别名是man,恰好就是Linux 系统下的获取帮助的命令。当然它们的功能也很相似。

比方说,我们要查看一下清除屏幕这个命令的帮助,就可以简单的输入下面的命令。Powershell 会自动将别名解析为实际命令名称。所以我们可以看到,cls实际上是Clear-Host命令的别名。

PS C:\Users\asddf> man cls

名称
Clear-Host 摘要 语法
Clear-Host [<CommonParameters>] 说明 相关链接
https://go.microsoft.com/fwlink/?LinkID=225747 备注
若要查看示例,请键入: "get-help Clear-Host -examples".
有关详细信息,请键入: "get-help Clear-Host -detailed".
若要获取技术信息,请键入: "get-help Clear-Host -full".
有关在线帮助,请键入: "get-help Clear-Host -online"

其实从这个命令的帮助信息来看,我们就可以获得大部分信息。比方说,如果我们要查看这个命令的在线帮助,就可以如同上面的备注所说,在命令上添加-online参数,这样就会打开浏览器跳转到这个命令的在线帮助页上。

值得一提的还有帮助参数-?、如果一个命令添加了帮助参数,那么Powershell 不会实际执行这个命令,而是显示它的帮助信息。

服务管理

原来,如果我们使用批处理来管理Windows服务的话,一般情况下用的是sc这个命令。这个命令的作用有很多,其中一项就是启动和停止Windows服务。不过在Powershell下有更好用的服务管理命令,功能也更加强大。

首先我们先查看一下有什么管理服务的命令,只需要查询一下名词是service的命令即可。可以看到这些命令涵盖了从创建服务到管理服务的各个方面,功能很丰富。

PS C:\Users\asddf> Get-Command -Noun service

CommandType     Name                                               Version    Source
----------- ---- ------- ------
Cmdlet Get-Service 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet New-Service 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Restart-Service 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Resume-Service 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Set-Service 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Start-Service 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Stop-Service 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Suspend-Service 3.1.0.0 Microsoft.PowerShell.Management

比方说,我们要查询一下当前计算机安装了哪些和MySQL相关的服务,就可以用下面的命令。

PS C:\Users\asddf> Get-Service mysql*

Status   Name               DisplayName
------ ---- -----------
Running MySQL57 MySQL57

然后如果需要停止服务也很简单,需要注意停止服务的话需要管理员权限,因此Powershell需要在管理员模式下运行。

PS C:\WINDOWS\system32> Stop-Service  MySQL57
警告: 正在等待服务“MySQL57 (MySQL57)”停止...

其他命令就不介绍了,配合帮助命令可以很快学习如何使用。

应用实例

最后直接从网上找了个例子来看看Powershell的实际作用。我们可以从中了解到Powershell的强大特性,用它帮助我们方便地管理Windows操作系统。

Office互操作

这里贴一个网络上的例子,我是从知乎上看到的。运行一下会直接打开Excel并填充数据,然后画出占用内存前十的程序的饼状图,一气呵成。我第一次运行的时候简直惊呆了。

# create new excel instance
$objExcel = New-Object -comobject Excel.Application
$objExcel.Visible = $True
$objWorkbook = $objExcel.Workbooks.Add()
$objWorksheet = $objWorkbook.Worksheets.Item(1) # write information to the excel file
$i = 0
$first10 = (ps | sort ws -Descending | select -first 10)
$first10 | foreach -Process {$i++; $objWorksheet.Cells.Item($i,1) = $_.name; $objWorksheet.Cells.Item($i,2) = $_.ws}
$otherMem = (ps | measure ws -s).Sum - ($first10 | measure ws -s).Sum
$objWorksheet.Cells.Item(11,1) = "Others"; $objWorksheet.Cells.Item(11,2) = $otherMem # draw the pie chart
$objCharts = $objWorksheet.ChartObjects()
$objChart = $objCharts.Add(0, 0, 500, 300)
$objChart.Chart.SetSourceData($objWorksheet.range("A1:B11"), 2)
$objChart.Chart.ChartType = 70
$objChart.Chart.ApplyDataLabels(5)

当然其实Powershell能做的事情非常多。微软自从Powershell出现之后就一直推动Windows和Powershell的互操作。到现在为止大概大部分Windows管理和配置功能都可以使用Powershell来进行。

一开始我也对Powershell不太了解。不过了解了一点之后,我感觉Powershell的功能确实对得起它的名字。我已经决定学习完Powershell之后,将来在所有可以使用Powershell的地方全部使用它,享受命令行管理系统的快感。

这一部分着重于介绍Powershell的程序知识,让我们能够编写功能强大的Powershell脚本,执行比较复杂的任务。

变量

变量使用$变量名创建和引用。举个例子,Get-Location命令用于获取当前工作目录位置,它的别名是pwd。那么我们可以使用下面的命令来创建一个变量,存储当前目录位置。

C:\Users\asddf> $current=pwd

然后我们访问$current,就可以获取实际值了。

C:\Users\asddf> $current

Path
----
C:\Users\asddf

如果知道这个命令返回的实际是.NET对象的话,我们还可以更进一步,比方说直接访问这个对象的Path属性,获取值。

C:\Users\asddf> $current.Path
C:\Users\asddf

还有一个命令Get-Member,别名是gm,用于获取对象的属性。比方说,我们将Get-Location命令的结果通过管道传递给Get-Member命令,就会显示下面的输出。如果不了解.NET的话,可能感觉比较陌生。但是如果你懂得.NET和C#的话,就会像我一样大喊一声:“卧槽,还能这样玩?!”

C:\Users\asddf> Get-Location|Get-Member

   TypeName:System.Management.Automation.PathInfo

Name         MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
Drive Property System.Management.Automation.PSDriveInfo Drive {get;}
Path Property string Path {get;}
Provider Property System.Management.Automation.ProviderInfo Provider {get;}
ProviderPath Property string ProviderPath {get;}

如果我们要获取对象的所有属性,使用MemberType参数。

C:\Users\asddf> pwd|gm -MemberType Property

我们还可以在变量上调用方法, 比如说将路径转换为全小写。


C:\Users\asddf> $current.Path.ToLower()
c:\users\asddf

最后,如果不再需要一个变量,可以使用Remove-Variable删除变量,它的别名是rv

C:\Users\asddf> Remove-Variable current

操作符

来看看Powershell中支持的操作符。

数学运算符

首先,基本的数学运算符都是支持的。

PS D:\Desktop> $i=5
PS D:\Desktop> $sum=3+4*($i-3)/2
PS D:\Desktop> $sum
7

前置后置自增自减运算符也是支持的。

PS D:\Desktop> $i=0
PS D:\Desktop> $i--
PS D:\Desktop> $i++
PS D:\Desktop> ++$i
PS D:\Desktop> --$i

比较运算符

然后是比较运算符,这些和Linux Shell中很相似,有大于(-gt),大于等于(-ge),小于(-lt),小于等于(-le),等于(-eq),不等于(-ne)几个。

字符串匹配运算符

-like-notlike用于?*这样的通配符。

PS D:\Desktop> 'hello' -like '?ello'
True
PS D:\Desktop> 'hello' -notlike '?ello'
False
PS D:\Desktop> 'hello' -like '*o'
True

-match-notmatch用于正则表达式。

PS D:\Desktop> 'aabcc' -match 'a*b?c+'
True
PS D:\Desktop> 'aab' -match 'a*b?c+'
False

包含和替换运算符

-contains查找序列中是否包含某个元素。

PS D:\Desktop> 'hello','zhang3' -contains 'zhang3'
True

-replace用于替换字符串中某个部分,当然正则表达式也是支持的。

PS D:\Desktop> 'hello zhang3' -replace 'zhang3','yitian'
hello yitian

分隔和连接运算符

-split-join用于将一个字符串分为几个子部分,或者将几个子部分组合为一个字符串。

PS D:\Desktop> 'A B C DE' -split ' '
A
B
C
DE
PS D:\Desktop> 'A','B','C' -join ','
A,B,C

上面这些运算符都是大小写不敏感的,如果需要大小写敏感的功能,可以在运算符前面添加c前缀。

PS D:\Desktop> 'yitian' -match 'Yitian'
True
PS D:\Desktop> 'yitian' -cmatch 'Yitian'
False

逻辑运算符

逻辑运算符有与(-and)、或(-or)、非(-not!)以及异或(xor)几个,并且支持短路计算。

如果需要使用真值和假值字面量,可以使用$true$false

类型运算符

Powershell 和.NET平台绑定,所以它是一门强类型的脚本。因此我们可以在脚本中判断数据的类型,只要使用-is-isnot运算符即可,类型需要写到方括号中。这里的类型可以是所有合适的.NET类型。

PS D:\Desktop> 3.14 -is [Double]
True
PS D:\Desktop> 3.14 -isnot [Float]
True

重定向运算符

这个稍微比较麻烦一点。

首先是>>>运算符,用于将标准输出流重定向到文件,前者会覆盖已有文件,后者则是追加到已有文件末尾。

然后我们来说说日志级别,如果有使用过某些语言的日志框架的话,就很好理解了。在这里,2代表错误、3代表警告、4代表信息、5代表调试信息。n>n>>运算符就是用于将对应级别的输出重定向到文件的,这两者的区别和前面相同。n>&1将对应级别的输出和标准输出一起重定向到文件。

最后就是*>*>>了,这两者将所有输出信息重定向到文件。

需要注意,Powershell使用Unicode编码来输出信息。如果你需要使用其他类型的编码,就不能使用重定向运算符了,而应该使用Out-File命令。

特殊运算符

&运算符将它后面的命令设置为后台运行,当运行的命令需要阻塞当前终端的时候很有用。

.\\运算符用于执行一个脚本或命令。如果执行的是Powershell脚本,那么脚本会在自己的作用域中执行,也就是说在当前环境下无法访问被执行的脚本中的变量。

[]运算符用于转换变量的类型,比如说下面的代码,就将pi变量转换为了Float类型。

[Float]$pi = 3.14
$pi -is [Float]

.运算符用于调用.NET对象的成员,它也可以用于执行脚本。当它用于执行脚本的时候,脚本会在当前作用域中执行。所以脚本结束之后,我们可以访问脚本中的元素。

::运算符用于调用类中的静态成员,例如下面就会调用.NET平台中DateTime类的Now属性。

PS D:\Desktop> [DateTime]::Now

2017年5月18日 22:45:42

..运算符用于创建一个范围闭区间,例如下面这样。

PS D:\Desktop> 1..3
1
2
3
PS D:\Desktop> 3..1
3
2
1

-f运算符用于格式化数据,例如下面这样。格式化方法和C#中的完全相同,所以如果不熟悉的话直接看在C#中如何格式化数据就行了。

PS D:\Desktop> 'My name is {0}, I am {1} years old' -f 'yitian',24
My name is yitian, I am 24 years old

$运算符可以将字符串内部的变量转换为实际的值,例如下面这样。需要注意使用内插操作符的时候,外部字符串需要使用双引号,否则Powershell会直接输出字符串内容。

PS D:\Desktop> $name='yitian'
PS D:\Desktop> $age=24
PS D:\Desktop> "My name is $name, I am $age years old."
My name is yitian, I am 24 years old.

@()运算符用于将一系列值转换为一个数组。假如在脚本中有一个函数可能返回0、1或多个值,就可以使用这个操作符,将一系列值合并为一个数组,方便后续处理。

,逗号运算符如果放置在单个值前面,就会创建一个包含这个值的单元素数组。

条件判断

if判断

Powershell中的条件判断和一般的编程语言以及Shell编程都很类似,直接看代码就能理解。

$condition = $true

if ($condition -eq $true) {
Write-Output "condition is $true"
}
elseif ($condition -ne $true ) {
Write-Output "condition is $false"
}
else {
Write-Output "other ocndition"
}

switch判断

如果需要多重判断,可以考虑使用switch语句。一个典型的switch如下所示。

$n = 4
switch ($n) {
1 {"n is 1"}
2 {"n is 2"}
3 {"n is 3"}
default {"n is others"}
}

其实细说起来,这个switch的坑还是不少的。例如,switch语句可以接受多个值来测试,在switch语句中还可以编写多个case相同的语句。这里我就不细说了,想具体了解的话直接看官方文档 about_Switch吧。

循环语句

提醒一下,不管是哪种循环语句,在循环体内都可以使用breakcontinue中断/继续循环。

do循环

首先来看看do-while循环,先执行循环体,然后判断是否满足条件,如果满足条件则继续执行。

$i = 0
do {
$i++
Write-Output $i
}while ($i -ne 3)

然后是do-until循环,和do-while类似,不过当条件不满足的时候才会继续循环,如果满足条件则退出循环。

$i = 0
do {
$i++
Write-Output $i
}until ($i -eq 3)

while循环

while循环是先判断循环条件,满足条件时执行循环。

$i = 0
while ($i -lt 3) {
Write-Output $i
$i++
}

for循环

for循环可以看做是while循环的另一种形式,常用于固定次数的循环。

for ($i = 0; $i -ne 3; $i++) {
Write-Output $i
}

for-each循环

for-each循环用于遍历一个集合中的所有元素。

$array = @(1, 2, 3, 4)
foreach ($i in $array) {
Write-Output $i
}

值得一提的是,for-each语句用在管道上时,还有以下一种用法。

<command> | foreach {<beginning command_block>}{<middle command_block>}{<ending command_block>}

使用这种方法时,for-each后面可以跟三个语句块,第一个语句块是开始语句块,在循环前执行一次,常用来初始化一些数据;第三个是结束语句块,在循环结束之后执行一次,常用于统计一些循环数据;第二个就是正常的循环语句块,会循环多次。

函数

定义函数

定义函数使用function关键字。

function hello {
Write-Output 'Hello Powershell'
}

定义好函数之后,就可以使用函数名来调用函数了。

hello

函数的参数

函数当然也可以带参数了,参数列表有两种写法:第一种是C风格的,参数列表写在函数名后面,使用小括号分隔开;第二种方式是在方法体中,使用param关键字声明参数。这两种方法是完全等价的,当然我习惯上还是喜欢使用第一种方式。

Powershell是一种强类型的脚本语言,所以可以在参数列表上添加参数类型,参数类型是可选的,不过我还是推荐写的时候带上类型,方便阅读和类型检查。

function Say-Hello ([string] $name) {
Write-Output "Hello, $name"
} function Say-Hello2 {
param([string] $name)
Write-Output "Hello, $name"
}

调用带参数的函数时,需要向调用命令那样,使用-参数名来传递参数,例如下面这样。

Say-Hello -name 'yitian'

默认参数

Powershell支持默认参数,直接用赋值号=在参数列表上指定参数默认值即可。


function Say-Hello3 {
param([string] $name = 'zhang3')
Write-Output "Hello, $name"
}

位置参数

Powershell也支持位置参数,它会把所有参数包装到$args数组中,所以我们可以通过这个变量访问所有位置的参数。例如下面,将所有参数合并一个字符串,然后打印出来。

function Say-Hellos {
$names = $args -join ','
Write-Output "Hello, $names"
}

这个函数调用时候需要指定多个参数,注意不要在多个参数之间添加括号,否则会变成一个数组参数,而不是多个参数。

Say-Hellos 'yitian' 'zhang3' 'li4'

开关参数

开关参数没有类型,作用仅仅是标志是或者否。如果在使用函数的时候带上开关参数,那么它就是开的状态,否则就是关的状态。开关参数需要指定参数类型为switch

function Answer-Hello ([switch] $yes) {
if ($yes) {
Write-Output "Hi"
}
}

然后在调用时就可以看出区别了。

Answer-Hello -yes
Answer-Hello

函数返回值

最后来说说函数返回值。这个其实也很简单,只要使用return语句就可以了。

function Add ([double]$a, [double]$b) {
$c = $a + $b
return $c
}

然后我们调用函数,就可以看到结果了。

Add -a 3 -b 5

关于Powershell编程的知识就介绍到这里,其实如果看看官方文档的话,就知道这里介绍的也仅仅是一部分而已。不过这一部分对于我们日常使用和学习基本上也够用了。

如果要查看详细帮助的话,可以运行一下下面的命令,这样会显示所有和Powershell相关的帮助文档。

Get-Help about*

然后,就可以阅读自己感兴趣的部分了。比方说,如果我们想了解用Powershell编写类,就可以使用下面的命令。如果想在浏览器中浏览器在线版本,加上-online参数即可。

Get-Help about_Classes

参考资料

https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.core/about/about_operators?f=255&MSPPError=-2147217396

http://windowsitpro.com/powershell/windows-powershell-operators

好像关于Powershell说的已经差不多了,所以最后一篇文章就来使用Powershell写一些脚本,帮助我们完成一些日常工作。

文件管理

常用命令

先来看看常用的文件管理命令。

Set-Location命令用于切换工作目录,它的别名是cd

Get-Location命令用于获取当前工作目录,它的别名是pwd

Get-ChildItem命令用于获取当前目录下的所有文件。

Get-Item命令用于获取给定文件的信息。

还有文件移动、删除、复制、粘贴、重命名等命令,输入Get-Command -Noun item就可以看到这些命令,这里就不做介绍了。

获取文件信息

获取文件信息可以利用命令Get-Item。下面获取了我电脑上的cmder.exe可执行文件的信息。

λ  Get-Item .\Cmder.exe

    目录: D:\devtools\cmder_mini

Mode                LastWriteTime         Length Name
---- ------------- ------ ----
-a---- 2016/12/2 7:15 130560 Cmder.exe

默认只列出这么三个属性,当然其实文件属性远不止这些。我们可以通过管道,将文件信息对象传递给命令Select-Object,让它帮我们显示所有属性。这里只粘贴了一点点内容,其实文件信息很长,大家可以自行尝试。

λ  Get-Item .\Cmder.exe|Select-Object *

PSPath            : Microsoft.PowerShell.Core\FileSystem::D:\devtools\cmder_mini\Cmder.exe
PSParentPath : Microsoft.PowerShell.Core\FileSystem::D:\devtools\cmder_mini

过滤文件

Get-ChildItem显示当前当前文件的时候,会显示所有文件。有时候我们可能仅仅需要搜索或者过滤部分文件。

首先,如果是比较简单的需求,可以使用?*通配符来搞定,问号用于匹配任意单个字符,星号用于匹配任意多个字符。比方说,我想要列出所有.md格式的文件,就可以使用下面的命令。

PS D:\devtools\cmder_mini> Get-ChildItem *.md

    目录: D:\devtools\cmder_mini

Mode                LastWriteTime         Length Name
---- ------------- ------ ----
-a---- 2016/12/2 7:14 73491 CHANGELOG.md
-a---- 2016/12/2 7:14 1784 CONTRIBUTING.md
-a---- 2016/12/2 7:14 10039 README.md

有时候可能需要使用正则表达式来查找文件,不过好像Get-ChildItem没有正则表达式查询的命令行,不过我们可以使用Where-Object命令来自定义查询。如果了解C#语言的LINQ的话,应该可以猜到,这个命令对应于LINQ的where语句。

下面同样是查找所有.md格式的文件,不过这次使用了Where-Object和正则表达式,其中Where-Object里面的$_是形式变量,代表每次迭代的文件。如果了解过C#的LINQ,或者Java 8的流类库,应该对这种形式会比较熟悉。

Get-ChildItem|Where-Object {$_ -match '\w*.md$'}

如果仅仅为了搜索文件名的话,这种方式好像一点优势都没有。实际上Where-Object的功能非常强大。比方说,我现在想查找大于5kb的所有.md格式文件,那么就可以这么写。这里又用到了Powershell的一个方便的特性,文件大小单位,KB GB MB TB等单位都支持。当然其实并不仅仅可以查询文件大小属性,基本上所有文件信息都可以用来查询。

 Get-ChildItem|Where-Object {$_ -match '\w*.md$' -and $_.Length/1kb -gt 5}

最后,Get-ChildItem不仅可以列出当前文件夹下的所有内容,还可以递归查询所有子文件夹。比方说,我要查找一下迅雷文件夹下所有可执行文件,就可以使用下面的命令。如果添加-Depth参数的话,还可以指定递归深度。

 Get-ChildItem -Recurse *.exe

修改hosts

访问谷歌的一种方式就是更改hosts文件。这里就用Powershell做一个修改hosts的功能。

首先先来介绍一个命令Invoke-WebRequest,利用它我们可以获取网页内容、下载文件甚至是填写表单。这个命令的别名是iwrcurlwget。我们就使用它来下载网上的hosts文件。

剩余就没有什么难度了,无非就是读写文件、追加文件、复制和粘贴这种基本操作。最后写完这个功能发现有一百多行,就不往这里复制粘贴了。如果有兴趣的话,可以直接看我的Github上面的脚本

进程管理

查看进程

首先我们看看有多少和进程相关的命令,这个很简单,只要查看一下名词是Process的命令即可。

PS C:\WINDOWS\system32> Get-Command -Noun process

CommandType     Name                                               Version    Source
----------- ---- ------- ------
Cmdlet Debug-Process 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Get-Process 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Start-Process 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Stop-Process 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Wait-Process 3.1.0.0 Microsoft.PowerShell.Management

使用这些命令,我们就可以非常方便的管理进程了。比方说,我想查询现在运行的所有进程,就可以使用下面的命令,这样就会列出所有运行的进程,就像任务管理器里显示的那样。

PS C:\WINDOWS\system32> Get-ProcessGet-Process

上面这个命令会显示所有进程。如果需要,我们可以按照某个属性对进程进行排序显示,这需要使用另外一个命令Sort-Object。另外,如果只需要显示前几个进程,可以使用命令Select-Object来选择显示多少数据。比方说,如果我们要查看当前占用CPU前5的chrome进程,就可以使用下面的命令。

Get-Process chrome|Sort-Object cpu -Descending|Select-Object -First 5

利用这几个命令,我们可以按照任何想要的方式来查询进程。

管理进程

先来看看MSDN上的一个官方例子。首先先打开三个记事本进程,然后使用名称获取这些进程,然后调用进程的Kill()函数即可把这些进程全杀掉。中间调用了Count属性测试了一下总共获取到了几个进程。

PS C:\WINDOWS\system32> notepad;notepad;notepad;
PS C:\WINDOWS\system32> $notepads=Get-Process -Name notepad
PS C:\WINDOWS\system32> $notepads.Count
3
PS C:\WINDOWS\system32> $notepads.Kill()

再学习Powershell编程的时候,我们常常会同时开几个Powershell窗口。不再使用的时候一个一个关闭它们也是一件麻烦事情,所以官方文档还为我们介绍了如何关闭除当前窗口外的所有Powershell进程。

每个Powershell进程都有一个变量$PID,用于标志当前进程的进程号,利用这一点我们就可以实现这个功能。这里的-WhatIf参数表示不真正关闭进程,仅列出将要关闭的进程。

PS C:\WINDOWS\system32> Get-Process powershell |Where-Object {$_.Id -ne $PID}|Stop-Process -WhatIf
WhatIf: 正在目标“powershell (2676)”上执行操作“Stop-Process”。

如果既想要关闭进程,还想知道关闭了哪些进程,可以使用-PassThru参数。

PS C:\WINDOWS\system32> Get-Process powershell |Where-Object {$_.Id -ne $PID}|Stop-Process -PassThru

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName
------- ------ ----- ----- ------ -- -- -----------
573 30 56884 68992 0.92 2676 1 powershell

轮询关闭进程

如果在死循环中不断查找任务管理器进程,发现它在运行就把它关闭,就可以做一个小小的“病毒”。代码很简单,基本上一下子就能看懂。一开始我没有加Sleep,然后CPU使用率飚的非常高,加了之后基本上对电脑性能没有影响了。

$process_name = "taskmgr"
while ($true) {
$processes = Get-Process
if ($processes.Name -contains $process_name) {
Get-Process $process_name|Stop-Process
}
else {
Start-Sleep -Milliseconds 500
} }

如果把上面代码中的taskmgr换成英雄联盟的进程名字,我们就可以做一个简单的“熊孩子防火墙”,防止熊孩子用电脑来玩游戏了。

注册表操作

读写注册表

读取注册表

首先来介绍一下注册表根的简写,例如HKEY_CURRENT_USER的简写就是HKCUHKEY_LOCAL_MACHINE的简写就是HKLM。知道了简写,我们就可以将Powershell的工作目录切换到注册表内。例如,如果我们想查看HKEY_CURRENT_USER\Control Panel\Desktop\MuiCached下的值,就可以先把工作目录切换到这个位置内部。这里需要将对应的注册表根修改为对应的简写加冒号的形式。

PS C:\WINDOWS\system32> Set-Location 'HKCU:\Control Panel\Desktop\MuiCached'
PS HKCU:\Control Panel\Desktop\MuiCached>

切换到了注册表内部,我们就可以利用Get-Item命令获取注册表的值了。比如说,要获取这个注册表键的值,就可以直接输入Get-Item .了。注意这个点不能省去,它代表当前工作目录。

PS HKCU:\Control Panel\Desktop\MuiCached> Get-Item .

    Hive: HKEY_CURRENT_USER\Control Panel\Desktop

Name                           Property
---- --------
MuiCached MachinePreferredUILanguages : {zh-CN}

如果要获取当前注册表项的属性值,可以利用Get-ItemProperty命令。

PS HKCU:\Control Panel\Desktop\MuiCached> Get-ItemProperty .  MachinePreferredUILanguages

MachinePreferredUILanguages : {zh-CN}
PSPath : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Control Panel\Desktop\MuiCached
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Control Panel\Desktop
PSChildName : MuiCached
PSDrive : HKCU
PSProvider : Microsoft.PowerShell.Core\Registry

当然,切换工作目录这件事情也可以不做。直接利用Get-ItemProperty命令通过路径参数来获取属性。

Get-ItemProperty -Path 'HKCU:\Control Panel\Desktop\MuiCached' -Name MachinePreferredUILanguages

编辑注册表项

下面这个路径是一个安全的注册表路径,在这里修改注册表不会造成严重的系统问题。所以我们把它保存为一个变量。

 $path = "HKCU:\Control Panel\Desktop"

如果要新建注册表项,可以使用New-Item命令。我们可以使用注册表编辑器regedit来验证项是否创建成功。

 New-Item –Path $path –Name HelloKey

如果要修改项的属性,使用Set-ItemProperty命令。

Set-ItemProperty -path $path\hellokey -name Fake -Value fuck

最后,如果要删除项的属性,使用Remove-ItemProperty命令。

Remove-ItemProperty -path $path\hellokey -name Fake

如果要删除整个注册表项,使用Remove-Item命令。

Remove-Item -path $path\hellokey -Recurse

获取当前.NET版本

下面的参考资料中列出了一个MSDN上的文档,告诉我们如何读取注册表的值来判断当前安装了.NET Framework的版本,并给出了相应的C#代码。下面的代码做的就是将C#代码改写成Powershell脚本。

# 判断系统当前安装.NET框架版本的脚本

$path = 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full'
$not_found_msg = ".net framework 4.5 or later not installed on your system" function CheckFor45PlusVersion([int] $releaseKey) {
if ($releaseKey -ge 460798) {
return "4.7 or later";
}
if ($releaseKey -ge 394802) {
return "4.6.2";
}
if ($releaseKey -ge 394254) {
return "4.6.1";
}
if ($releaseKey -ge 393295) {
return "4.6";
}
if (($releaseKey -ge 379893)) {
return "4.5.2";
}
if (($releaseKey -ge 378675)) {
return "4.5.1";
}
if (($releaseKey -ge 378389)) {
return "4.5";
}
return $not_found_msg;
} try {
$key = get-item $path
$releaseKey = Get-ItemPropertyValue $path 'release'
if ($releaseKey -is [int]) {
$releaseKey = [int]$releaseKey
$version = CheckFor45PlusVersion($releaseKey)
Write-Host ".NET framework ${version}"
}
else {
Write-Host $not_found_msg
}
}catch {
Write-Host $not_found_msg
}

Office互操作

操作Excel

虽然Powershell可以通过COM接口和Office程序交互,不过最常用的还是操作Excel,所以我这里只介绍如何控制Excel表。下面最后一个参考资料就是我参考的操作Excel的文章,可能需要梯子才能访问。需要注意一点,既然是操作Excel,当然首先电脑上需要先安装Excel才能正常使用。

打开和关闭

首先,我们来创建一个Excel对象,这样实际上会创建一个Excel应用程序。

$excel = New-Object -ComObject Excel.Application

执行了上面的命令,什么事情都没有发生。这是因为默认启动的实例是隐藏的,要显示Excel的窗口的话,将它设置为可见即可。

$excel.Visible=$true

如果要打开一个现成的工作簿,使用Open函数。

$workbook = $excel.Workbooks.Open("XXX.xlsx")

如果要创建一个新的工作簿,使用Add函数。

$workbook = $excel.Workbooks.Add()

一个工作簿可以有多个工作表,要选择某一个工作表,使用Worksheets.Item属性,需要注意这里的下标从一开始。

$worksheet = $workbook.Worksheets.Item(1)

对数据完成操作之后,需要保存的话,使用SaveAs函数。

$workbook.SaveAs("D:\Desktop\hello.xlsx")

操作数据

前面只说了打开和关闭操作,下面来看看如何具体读取和写入数据。首先回到上面那步工作表,因为如果要操作数据,需要在工作表对象上进行操作。

$worksheet = $workbook.Worksheets.Item(1)

要操作数据,调用工作表对象的Cells属性即可。比方说我要打印九九乘法表,那么就可以用类似下面的代码来迭代写入数据。

for ($i = 1; $i -le 9; ++$i) {
# 第一行
$worksheet.Cells(1, $i + 1) = $i
# 第一列
$worksheet.Cells($i + 1, 1) = $i
# 它们的乘积
for ($j = 1; $j -le 9; ++$j) {
$worksheet.Cells($i + 1, $j + 1) = $i * $j
}
}

操作之后,Excel表中应该存在如图所示的数据。

类似的,读取数据也很简单,只要读取Cells属性即可。

for ($i = 1; $i -le 10; ++$i) {
for ($j = 1; $j -le 10; ++$j) {
Write-Host -NoNewline $worksheet.Cells($i, $j).Text "`t"
}
Write-Host
}

上面的代码获取了我们刚才写入Excel的数据,然后将其转换为文本并输出,每个数据之间使用制表符\t分隔,注意Powershell中的转义字符使用的这个特殊字符。结果应该类似如图所示。

绘制图表

Excel很常用的一种操作就是绘制图表,这里也简单说说。不过由于这种资料在网上面实在太少,我就算用谷歌搜索英文网页也搜不出来多少资料,大部分都属于一点小脚本。所以这里只能随便说说了。

首先准备一下数据,我准备了如图所示的数据。

然后来创建一个图表对象。如果使用交互式环境Powershell ISE的话,智能提示会显示这里有AddChartAddChart2两个方法,不过我看了下文档,前面那个过时了,所以这里使用带2的那个版本。

$chart=$worksheet.Shapes.AddChart2().Chart

创建了图表对象之后,我们为它指定数据源。

$chart.SetSourceData($worksheet.Range('a1', 'd5'))

这时候如果观察Excel的话,会发现已经出现了一个初步的图形。如果希望改变图形样式的话,设置图标的类型即可。这里将图表类型保存为一个变量,之后就可以省略长长的类名了。这里推荐使用Powershell ISE,因为自动补全可以显示所有类型的图标,只需要修改一下图表类型并观察Excel中图标类型的变化就可以明白类型和图标的对应关系了。

$chartTypes = [Microsoft.Office.Interop.Excel.XLChartType]
$chart.ChartType = $chartTypes::xlColumnClustered

最后效果如图所示,我看到人家可以使用方法显示图例。但是我使用这个方法却不知道为什么显示不了。所以这里只能将就一下了。

最后再来画个饼状图,数据还是上面的数据,不过这次只使用语文那一列的数据。基本上和上面的一样,只有类型那里改成xlPie

$chartTypes = [Microsoft.Office.Interop.Excel.XLChartType]
$chart = $worksheet.Shapes.AddChart2().Chart
$chart.SetSourceData($worksheet.Range('a1', 'b5'))
$chart.ChartType = $chartTypes::xlPie
$chart.ApplyDataLabels(5)

最终效果图如下。

ImportExcel

上面的方法好像只能在安装Excel的环境下运行,如果没有安装Office,但是也想使用编程功能,可以使用第三方的模块。这就是这里要介绍的ImportExcel。使用它,我们可以在没有安装Excel的情况下编辑Excel文件。

首先需要安装它,可以利用Powershell的包管理器方便的安装。

Install-Module ImportExcel -scope CurrentUser

如果想让所有用户都可以使用这个模块,需要安装到全局位置,不过这需要管理员权限,所以需要在管理员模式的Powershell窗口中运行。

Install-Module ImportExcel

这个模块如何使用我就不作介绍了,这个项目的README文件上基本列出了所有功能和对应的GIF图,需要什么功能只要看一看应该就可以使用了。

参考资料

https://4sysops.com/archives/interacting-with-the-registry-in-powershell/

https://msdn.microsoft.com/en-us/library/hh925568(v=vs.110).aspx

https://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.aspx

http://www.lazywinadmin.com/2014/03/powershell-read-excel-file-using-com.html

Powershell快速入门的更多相关文章

  1. [PowerShell] 快速入门, 基本语法, 常用类型, 函数, .NET 互操作

    PowerShell 快速入门 开始之前, 我们认定你已经有一定的编程基础, 熟悉 .NET 中的类型与对象. 此文章对于 .NET 开发者来说更简单哦! 在 PowerShell 中, 几乎一切都是 ...

  2. 快速入门:触摸输入(使用 C#/VB/C++ 和 XAML 的 Windows 应用商店应用)

    原文 http://technet.microsoft.com/zh-cn/subscriptions/hh465387 快速入门:触摸输入(使用 C#/VB/C++ 和 XAML 的 Windows ...

  3. 从零开始——PowerShell应用入门(全例子入门讲解)

    学习一门技术,不止要会,还要善用,例子就是带你快速入门的最佳利器.本文就是要用例子,不,大量的例子来带你走进PowerShell应用世界. 本文主要介绍一些PowerShell入门的基础知识,对技术小 ...

  4. .NET Core快速入门教程 2、我的第一个.NET Core App(Windows篇)

    一.前言 本篇开发环境?1.操作系统: Windows 10 X642.SDK: .NET Core 2.0 Preview 二.安装 .NET Core SDK 1.下载 .NET Core下载地址 ...

  5. .NET Core快速入门教程 4、使用VS Code开发.NET Core控制台应用程序

    一.前言 为什么选择VS Code?VS Code 是一款跨平台的代码编辑器,想想他的哥哥VS,并是微软出品的宇宙第一IDE,那作为VS的弟弟,VS Code 也不会差,毕竟微软出品.反正ken是这么 ...

  6. .NET Core实战项目之CMS 第二章 入门篇-快速入门ASP.NET Core看这篇就够了

    作者:依乐祝 原文链接:https://www.cnblogs.com/yilezhu/p/9985451.html 本来这篇只是想简单介绍下ASP.NET Core MVC项目的(毕竟要照顾到很多新 ...

  7. Git 快速入门--Git 基础

    Git 快速入门 Git 基础 那么,简单地说,Git 究竟是怎样的一个系统呢? 请注意接下来的内容非常重要,若你理解了 Git 的思想和基本工作原理,用起来就会知其所以然,游刃有余. 在开始学习 G ...

  8. net core体系-web应用程序-4asp.net core2.0 项目实战(CMS)-第二章 入门篇-快速入门ASP.NET Core看这篇就够了

    .NET Core实战项目之CMS 第二章 入门篇-快速入门ASP.NET Core看这篇就够了   原文链接:https://www.cnblogs.com/yilezhu/p/9985451.ht ...

  9. [易学易懂系列|rustlang语言|零基础|快速入门|(25)|实战2:命令行工具minigrep(2)]

    [易学易懂系列|rustlang语言|零基础|快速入门|(25)|实战2:命令行工具minigrep(2)] 项目实战 实战2:命令行工具minigrep 我们继续开发我们的minigrep. 我们现 ...

随机推荐

  1. Python的virtualenv你用过吗?

    1. 为什么要有virtualenv 在使用 Python 开发的过程中,工程一多,难免会碰到不同的工程依赖不同版本的库的问题: 亦或者是在开发过程中不想让物理环境里充斥各种各样的库,引发未来的依赖灾 ...

  2. js实现监听浏览器窗口大小改变事件

    window.onresize = function(){   }

  3. 【Nginx一】Nginx服务器搭建

    Nginx服务器搭建 Nginx服务器搭建 下载Nginx源码包 安装Nginx 解压Nginx安装包 安装Nginx依赖 启动Nginx 下载Nginx源码包 官网下载地址 命令:wget http ...

  4. python学习——函数

     一.在python的世界里什么是函数: 答:函数通常是用来实现某一个功能二被封装成的一个对象,是用来实现代码复用的常用方式 现在有一个需求,假如你在不知道len()方法的情况下,要你计算字符串‘he ...

  5. 微信公众号--JS-SDK

    JS-SDK 微信JS-SDK是微信公众平台 面向网页开发者提供的基于微信内的网页开发工具包. 通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照.选图.语音.位置等手机系统的能力,同时可以 ...

  6. codeforces 845A Chess Tourney

    参考:https://blog.csdn.net/zhongyuchen/article/details/77478039 #include <iostream> #include < ...

  7. UVA 1593 Alignment of Code(紫书习题5-1 字符串流)

    You are working in a team that writes Incredibly Customizable Programming Codewriter (ICPC) which is ...

  8. 分支push不上去的问题

    还原一下现场,我在自己的项目里面,从master里面checkout的一个分支,当我在我这个分支里面进行 push代码的操作,我突然发现我的代码不能执行push的操作,如图 这个原因是由于远端的仓库没 ...

  9. P2340 奶牛会展(状压dp)

    P2340 奶牛会展 题目背景 奶牛想证明它们是聪明而风趣的.为此,贝西筹备了一个奶牛博览会,她已经对N 头奶牛进行 了面试,确定了每头奶牛的智商和情商. 题目描述 贝西有权选择让哪些奶牛参加展览.由 ...

  10. 解析HTML利器AngleSharp介绍

    解析HTML利器AngleSharp介绍 AngleSharp是基于.NET(C#)开发的专门为解析xHTML源码的DLL组件. 项目地址:https://github.com/FlorianRapp ...