抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

Powershell

PowerShell 是一种命令行外壳程序和脚本环境,
使命令行用户和脚本编写者可以方便地使用 .NET Framework的强大功能。

介绍

PowerShell是运行在Windows操作系统上实现对系统以及应用程序进行管理自动化的命令行脚本环境,
PowerShell需要.NET环境的支持,借助 .NET Framework平台强大的类库,几乎让一切都成为可能。
微软起“PowerShell”这个名字并不是夸夸其谈,它完全支持对象,其可读性,易用性,毫不夸张的说可以居所有Shell之首。

受众

Windows PowerShell 入门主要面向IT 专业人员、程序员和高级用户。

特点

通过解决长期存在的问题并添加一些新的功能,Windows PowerShell 旨在改进命令行和脚本环境。
PowerShell以 .NET Framework为平台,接收和返回.NET对象,此举为管理和配置微软系统带来了新的方法和工具。
PowerShell推出了一个功能强大的命令叫做cmdlet,所有的cmdlet命令都遵循动词-名词这样语法结构。
Get-Command, Get-Process等,
即使从来没有接触过PowerShell,也很容易能够明白命令的作用。
Get-Process命令的意思就是获取所有的进程。

新的脚本语言

由于以下原因,Windows PowerShell 使用它自己的语言,而不是重用现有的语言:
Windows PowerShell 需要用于管理.NET 对象的语言。该语言需要为使用cmdlet 提供一致的环境。
该语言需要支持复杂的任务,而不会使简单的任务变得更复杂。 该语言需要与在.NET编程中使用的高级语言(如C#)一致。

  1. PS1文件
    一个PowerShell脚本其实就是一个简单的文本文件,这个文件包含了一系列PowerShell命令,
    每个命令显示为独立的一行,对于被视为PowerShell脚本的文本文件,它的文件名需要使用.PS1扩展。

  2. 执行权限
    为防止恶意脚本的执行,PowerShell有一个执行策略,默认情况下,这个执行策略被设为受限的(Restricted),
    意味着PowerShell脚本无法执行,你可以使用下面的cmdlet命令确定当前的执行策略:

    • Get-ExecutionPolicy 你可以选择使用的执行策略有:
    • Restricted -脚本不能运行。
    • RemoteSigned - 本地创建的脚本可以运行,但网上下载的脚本不能运行(除非它们拥有由受信任的发布者签署的数字签名)。
    • AllSigned – 仅当脚本由受信任的发布者签名才能运行。
    • Unrestricted –脚本执行不受限制,不管来自哪里,也不管它们是否有签名。

你可以使用下面的cmdlet命令设置PowerShell的执行策略:

1
Set-ExecutionPolicy <policy name>
  1. 运行脚本
    如果你想从命令行运行一个可执行文件,多年来一个永恒不变的方法是,
    在命令行转到该执行文件所在的位置,然后键入该执行文件的名称,
    但这个古老的方法现在却不能适用于PowerShell可执行脚本了。
    如果你想执行一个PowerShell脚本,通常必须键入完整的路径和文件名,
    例如,假设你要运行一个名为a.ps1的脚本,你可以键入:
    C:\Scripts\aps1
    最大的例外是,如果PowerShell脚本文件刚好位于你的系统目录中,
    那么你可以直接在命令提示符后键入脚本文件名即可运行,如:
    .\a.ps1 注意前面需要加上.\,这和Linux下执行Shell脚本的方法如出一辙。

  2. 管道
    管道的作用是将一个命令的输出作为另一个命令的输入,两个命令(或cmdlet)之间只需要用管道符号(|)连接即可。
    为了帮助你了解管道是如何工作的,我们以一个例子进行说明,假设你想创建运行在服务器上的进程列表,并按进程的ID号进行排序,
    可以使用Get-Process cmdlet命令获得进程列表,但默认情况下列表不会排序,
    如果将这个cmdlet命令的输出用管道输送给Sort-Object ID命令,进程列表将会按进程ID号进行排序,如:

    1
    Get-Process | Sort-Object ID
  3. 变量
    虽然可以使用管道将一个命令的输出输送给另一个命令,
    但管道本身也是有限制的,当你用管道从一个命令向另一个命令传递输出结果时,输出结果立即被使用,
    但有时候,你可能需要保存输出结果一段时间,以便以后可以使用(或重用),这个时候管道就应该下场,轮到变量上场了。
    人们很容易将变量想象成一个仓库,但在PowerShell中,变量可以保存命令的完整输出,
    例如,假设你想保存服务器处于运行中的进程列表,你可以将它赋给一个变量,如:
    $a = Get-Process
    在这里,变量被命名为$a,如果你想使用这个变量,只需要简单地调用它的名称即可,
    例如,键入$a便可在屏幕上打印变量的内容。
    你可以将多个用管道连接的命令的最终输出赋给一个变量,只需要用一对小括号将命令括起来即可,
    例如,假设你想按进程ID对运行中的进程进行排序,然后将结果输出给一个变量,你可以使用下面这个命令:

    1
    $a = (Get-Process | Sort-Object ID)
  4. @符号
    通过使用@符号,你可以将列表内容转换成一个数组,
    例如,下面的代码创建了一个名为$Procs的变量,它包含多行文本内容(一个数组):
    $procs = @{name="explorer","svchost"}
    使用变量时你也可以使用@符号,为了确保它作为数组而不是单个值处理,
    例如,下面的代码将在我前面定义的变量上运行Get-Process cmdlet命令:

    1
    Get-Process @procsWindows

    将显示Windows资源管理器和Svchost使用的所有进程,注意变量前使用的@符号,而不是常见的$符号。

  5. Split
    Split操作符根据你指定的字符拆分一个文本字符串,例如,假设你想将一个句子拆分成一个单词组成的一个数组,你可以使用下面的命令做到:

    1
    "This is a test" -split " "

    拆分后的结果如下:
    This is a test

  6. Join
    就像Split可以将一个文本字符串拆分成多块一样,Join的操作则是逆向的,将多个独立的块连接成一个整体,
    例如,下面这行代码将会创建一个文本字符串,由我的名字和姓氏组成:

    1
    "Brien","Posey" -join " "

    命令末尾双引号之间的空格告诉Windows在两个文本字符串之间插入一个空格。

  7. 断点
    运行一个新创建的PowerShell脚本时,如果脚本有Bug,会遇到意想不到的后果,
    保护自己的一个方法是在脚本的关键位置插入断点,这样你就可以确保脚本正常运行先,然后再处理可能存在的问题。
    插入断点最简单的方法是根据行号插入,例如,假设你要在第10行插入一个断点,可以使用下面的命令:

    1
    2
    3
    4
    5
    6
    7
    New-PSBreakpoint -Script C:\Scripts\a.ps1 -Line 10

    #你也可以将断点绑定到变量上,如果你希望你的脚本任何时候都可以修改a$的内容,可以使用下面的命令:
    New-PSBreakpoint -Script C:\scripts\a.ps1 -variables a
    #注意,在变量名后并没有包括美元符号。

    #可以和`PSBreakpoint`一起使用的动词包括`New`,`Get`,`Enable`,`Disable`和`Remove`。
  1. Step
    调试一个脚本时,有时可能需要逐行运行脚本,这时你可以使用Step-Into cmdlet命令,它会使脚本一行一行地执行,不管有没有设置断点,如果你想从这种步进式运行模式退出来,使用Step-Out cmdlet命令即可,
    但需要注意的是,使用Step-Out cmdlet命令后,断点仍然有效。
    顺便说一句,如果你的脚本使用了函数,你可能对Step-Out cmdlet更感兴趣,Step-Out 的工作方式和Step-Into 一样,不过,如果调用了一个函数,Windows不会逐步执行,整个函数将会一次性执行。

因此PowerShell实际是一门独立的脚本语言了

PowerShell能干什么?

PowerShell的基本目标是使用户能够以交互方式或通过脚本更好、更容易地对系统进行管理控制,

为了达成这个目标,PowerShell提供了大量命令来执行各种管理任务,让用户轻松完成管理系统任务。

PowerShell能做下面这些事:

.NET/.NET CORE编程, Registry, COM, WMI, ADSI. Exchange, Sharepoint,
Systems Center, Hyper-V, SQL. VMware vCenter, Cisco UCS,
Citrix XenApp and XenDesktop.,Azure, Excel 和 Office applications.
基本上所有的微软产品都提供PowerShell接口。

1、管理进程

前面已经提过管理系统进程的命令,管理进程常用命令就是get-processstop-processget-process获取进程之后可以直接用管道发送给stop-process结束进程。
比如,关闭打开的记事本,可以使用下面的命令很方便的关闭记事本。

1
get-process -Name notepad | stop-process

2、处理文件和文件夹

PowerShell使用Get-ChildItem获取文件夹中直接包含的所有项,
它有系统内置别名dirls,使用CMD和BASH的用户均可以轻松上手。
如果想查看C:中的文件夹和文件,直接使用dir c:,PowerShell立刻就会列出C:中的文件和文件夹。
其它处理文件和文件夹的命令有Copy-ItemNew-ItemRemove-Item等,
具体用法可以使用get-help然后跟命令名称即可查询。

3、处理系统服务

可以像管理进程一样管理系统服务,

  • Get-Service命令获取服务列表,
  • Stop-Service命令停止服务,
  • Start-Service命令启动服务,
  • Suspend-Service命令挂起服务,
  • Restart-Service命令重启服务,
  • Set-Service服务设置服务属性。
    如果想一次性启动已经停止的服务,可以使用以下命令:
    1
    get-service | where-object {$_.Status -eq "Stopped"} -exclude
  • 下面这行命名会把除wisvc之外的命令都启动,这只是一个示例,不要在自己电脑使用,启动所有服务会消耗大量系统资源。*
    wisvc | start-service

4、处理注册表

PowerShell可以非常方便的处理注册表项目,
与进程和服务不同的是,PowerShell并未提供专用的注册表命令,而是使用处理文件和文件夹的命令,
这并不奇怪,PowerShell为用户提供了注册表驱动器,可以很好的处理注册表项目。
由于注册表对系统非常重要错误处理注册表也许会导致系统出问题
处理注册表,特别是删除注册表项目要非常小心
最好能在处理注册表项目之前先备份要处理的项目。没有管理员权限也能处理部分注册表项目
这与regedit注册表编辑器不同,注册表编辑器必须使用管理员权限打开,然后才能操作项目。

5、处理其它任务

PowerShell还可以处理证书、防火墙、appx应用、打印机等任务,篇幅所限,不具体举例。大家可以使用get-command命令查找相关命令。

6、编写脚本程序

借助于.Net/.Net Core 实际上来说其他的编程语言能干什么,
PowerShell都可以做到,PowerShell能够充分利用.Net类型和COM对象,
来简单地与各种系统交互,完成各种复杂的、自动化的操作,因此PowerShell现在也是很不错的编程语言了,
有人还做出了ps1 to exe的脚本,可以将PowerShell编写的脚本文件编译成exe可执行文件。

一个有趣的例子

这是PowerShell界常见的一段神代码,很多初学者被其带入了PowerShell的大门。
有效代码不过20来行,作用是把当前系统中最占内存的10个进程的数据发送到Excel中,并绘制成三维饼图。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 创建新的excel com对象
$objExcel = New-Object -comobject Excel.Application
$objExcel.Visible = $True
$objWorkbook = $objExcel.Workbooks.Add()
$objWorksheet = $objWorkbook.Worksheets.Item(1)

# 把信息写入excel
$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

# 画饼图
$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)

#暂停
pause
$objExcel.Quit()
$objExcel = $null
[GC]::Collect()

执行结果:

执行结果

评论