Skip to content

PowerShell

认识PowerShell

PowerShell介绍

  • Powershell 是运行在windows机器上实现系统和应用程序管理自动化的命令行脚本环境。你可以把它看成是命令行提示符cmd.exe的扩充,不对,应当是颠覆。 powershell需要.NET环境的支持,同时支持.NET对象。微软之所以将Powershell 定位为Power,并不是夸大其词,因为它完全支持对象。其可读性,易用性,可以位居当前所有shell之首。 当前powershell有四版本,分别为1.0,2.0,3.0 ,4.0
  • 如果您的系统是window7或者Windows Server 2008,那么PowerShell 2.0已经内置了,可以升级为3.0,4.0。 如果您的系统是Windows 8 或者Windows server 2012,那么PowerShell 3.0已经内置了,可以升级为4.0。 如果您的系统为Windows 8.1或者Windows server 2012 R2,那默认已经是4.0了

PowerShell的快捷键

快捷键 说明
ALT+F7 清除命令的历史记录
PgUp PgDn 显示当前会话的第一个命令和最后一个命令
Enter 执行当前命令
End 将光标移至当前命令的末尾
Del 从右开始删除输入的命令字符
Esc 清空当前命令行
F2 自动补充历史命令至指定字符(例如历史记录中存在Get-Process,按F2,提示”Enter char to copy up to”,键入‘s’,自动补齐命令:Get-Proce)
F4 删除命令行至光标右边指定字符处
F7 对话框显示命令行历史记录
F8 检索包含指定字符的命令行历史记录
F9 根据命令行的历史记录编号选择命令,历史记录编号可以通过F7查看
左/右方向键 左右移动光标
上/下方向键 切换命令行的历史记录
Home 光标移至命令行最左端
Backspace 从右删除命令行字符
Ctrl+C 取消正在执行的命令
Ctrl+左右方向键 在单词之间移动光标
Ctrl+Home 删除光标最左端的所有字符
Tab 自动补齐命令或者文件名

PowerShell的管道和重定向

  • 管道指把上一条命令的输出作为下一条命令的输入 ls |sort -descending Name
  • 重定向 把命令的输出保存到文件中‘>’为覆盖,’>>’追加。pwd >test.txt

PowerShell交互式

数学计算

  • 我们可以把powershell当成一个计算器。象键入命令行那样输入数学表达式,回车,powershell会自动计算并把结果输出。常用的加减乘除模(+,-,*,/,%)运算和小括号表达式都支持

执行外部命令

  • 查看网络端口状态 netstat
  • 查看IP配置 ipconfig
  • 执行ls命令的方式:&”ls” 或 ls
  • 启动外部程序 notepad test.txt

命令集cmdlets

  • cmdlets是Powershell的内部命令,cmdlet的类型名为System.Management.Automation.CmdletInfo,包含下列属性和方法
Name MemberType Definition
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
CommandType Property System.Management.Automation.CommandTypes CommandType {get;}
DefaultParameterSet Property System.String DefaultParameterSet {get;}
Definition Property System.String Definition {get;}
HelpFile Property System.String HelpFile {get;}
ImplementingType Property System.Type ImplementingType {get;}
Module Property System.Management.Automation.PSModuleInfo Module {get;}
ModuleName Property System.String ModuleName {get;}
Name Property System.String Name {get;}
Noun Property System.String Noun {get;}
OutputType Property System.Collections.ObjectModel.ReadOnlyCollection`1[[System.Management.Automation.PSTypeName, System.Management.Automation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]] OutputType {get;}
Parameters Property System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Management.Automation.ParameterMetadata, System.Management.Automation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]] Parameters {get;}
ParameterSets Property System.Collections.ObjectModel.ReadOnlyCollection`1[[System.Management.Automation.CommandParameterSetInfo, System.Management.Automation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]] ParameterSets {get;}
PSSnapIn Property System.Management.Automation.PSSnapInInfo PSSnapIn {get;}
Verb Property System.String Verb {get;}
Visibility Property System.Management.Automation.SessionStateEntryVisibility Visibility {get;set;}
DLL ScriptProperty text System.Object DLL {get=$this.ImplementingType.Assembly.Location;}
HelpUri ScriptProperty System.Object HelpUri {get=try{# ok to cast CommandTypes enum to HelpCategory because string/indentifier for # cmdlet,function,filter,alias,externalscript is identical.# it is ok to fail for other enum values (i.e. for Application)helpObject = get-help -Name (this.Name) -Category (string { return null }if (helpObject.psobject.properties[‘relatedLinks’] -eq $null) { return null } if (helpObject.relatedLinks.psobject.properties[‘navigationLink’] -eq $null) { return $null } helpUri = [string]( helpObject.relatedLinks.navigationLink | %{if (.psobject.properties[‘uri’] -ne $null) { $.uri } } | ?{ $_ } | select -first 1 )return $helpUri}catch {};}

别名

  • cmdlet 的名称由一个动词和一个名词组成,其功能对用户来讲一目了然。但是对于一个经常使用powershell命令的人每天敲那么多命令也很麻烦啊。能不能把命令缩短一点呢?于是“别名”就应运而生了。Powershell内部也实现了很多常用命令的别名。例如Get-ChildItem,列出当前的子文件或目录。它有两个别名:ls 和 dir,这两个别名来源于unix 的shell和windows的cmd。 因此别名有两个作用:
  • 继承:继承unix-shell和windows-cmd。
  • 方便:方便用户使用。
  • 获取某个别名的cmdlets名称Get-Alias -name pwd
  • 获取可用的别名dir alias: | where {$_.Definition.Startswith("Remove")}
  • 设置自己的别名Set-Alias -Name Edit -Value notepad
  • 导入导出自己的别名 Export-Alias alias.ps1 Import-Alias -Force alias.ps1

PowerShell变量

PowerShell定义变量

  • 以$符开头命名变量 $a="1" ${a+1}="2"
  • 变量值互换 $a,$b=$b,$a
  • 查看在用的变量 ls variable:a*
  • 使用专门的变量命令New-Variable num -Value 100 -Force -Option readonly

自动化变量

  • Powershell 自动化变量 是那些一旦打开Powershell就会自动加载的变量。 这些变量一般存放的内容包括
    1. 用户信息:例如用户的根目录$home
    2. 配置信息:例如powershell控制台的大小,颜色,背景等。
    3. 运行时信息:例如一个函数由谁调用,一个脚本运行的目录等
  • 详细说明
    1. $$ 包含会话所收到的最后一行中的最后一个令牌。
    2. $? 包含最后一个操作的执行状态。如果最后一个操作成功,则包含 TRUE,失败则包含 FALSE。
    3. $^ 包含会话所收到的最后一行中的第一个令牌。
    4. $_ 包含管道对象中的当前对象。在对管道中的每个对象或所选对象执行操作的命令中,可以使用此变量。
    5. $Args 包含由未声明参数和/或传递给函数、脚本或脚本块的参数值组成的数组。在创建函数时可以声明参数,方法是使用 param 关键字或在函数名称后添加以圆括号括起、逗号分隔的参数列表。
    6. $ConsoleFileName 包含在会话中最近使用的控制台文件 (.psc1) 的路径。在通过 PSConsoleFile 参数启动Windows PowerShell 或使用 Export-Console cmdlet 将管理单元名称导出到控制台文件时,将填充此变量。在使用不带参数的 Export-Console cmdlet 时,它自动更新在会话中最近使用的控制台文件。可以使用此自动变量确定要更新的文件
    7. $Error 包含错误对象的数组,这些对象表示最近的一些错误。最近的错误是该数组中的第一个错误对象($Error[0])。
    8. $Event 包含一个 PSEventArgs 对象,该对象表示一个正在被处理的事件。此变量只在事件注册命令(例如 Register-ObjectEvent)的 Action 块内填充。此变量的值是 Get-Event cmdlet 返回的同一个对象。因此,可以在 Action 脚本块中使用 $Event 变量的属性(例如$Event.TimeGenerated)。
    9. $Home 包含用户的主目录的完整路径。此变量等效于 %homedrive%%homepath% 环境变量。
    10. $Host 包含一个对象,该对象表示 Windows PowerShell 的当前主机应用程序。可以使用此变量在命令中表示当前主机,或者显示或更改主机的属性,如 $Host.version、$Host.CurrentCulture或 $host.ui.rawui.setbackgroundcolor(“Red”)
    11. $Profile包含当前用户和当前主机应用程序的 Windows PowerShell 配置文件的完整路径。可以在命令中使用此变量表示配置文件。例如,可以在命令中使用此变量确定是否已创建某个配置文件:

环境变量

  • 传统的控制台一般没有象Powershell这么高级的变量系统。它们都是依赖于机器本身的环境变量,进行操作 。环境变量对于powershell显得很重要,因为它涵盖了许多操作系统的细节信息。此外,powershell中的变量只存在于powershell内部的会话中,一旦powershell关闭,这些变量就会自生自灭。但是如果环境变量被更新了,它会继续保存在操作系统中,即使其它程序也可以调用它。
  • 通过环境变量读取Windows操作系统的安装路径,和默认应用程序的安装路径。
    • 操作系统的安装目录$env:windir
    • 引用程序的安装目录$env:ProgramFiles
  • 操作环境变量
    • 查看所有环境变量 ls $env:
    • 创建新的环境变量 $env:xx="xx"
    • 删除环境变量 del $env:xx
    • 这样直接操作环境变量,会不会不安全?事实上很安全,因为$env:中的环境变量只是机器环境变量的一个副本,即使你更改了它,下一次重新打开时,又会恢复如初。(.NET方法更新环境变量除外)
    • .NET方法更新环境变量 [environment]::SetEnvironmentvariable("a", "newval", "User") [environment]::GetEnvironmentvariable("a", "User")

驱动器变量

  • Powershell中所有不是我们自己的定义的变量都属于驱动器变量(比如环境变量),它的前缀只是提供给我们一个可以访问信息的虚拟驱动器.。例如env:windir,象env:驱动器上的一个”文件”,我们通过$访问它,就会返回”文件”的内容。
  • 直接访问文件路径。通过驱动器直接访问文件路径,也支持物理驱动器,必须把文件路径放在封闭的大括号中,因为正常的文件路径包含两个特殊字符“:”和“”,有可能会被powershell解释器误解。 Invoke-Expression “`${$env:HOMEDRIVE/Powershell/ping.bat}” 注:因为反引号”`”放在$前,会把$解析成普通字符,解释器会继续去解析第二个$,发现env:HOMEDRIVE,将其替换成c,到此 Invoke-Expression的参数就变成了${C:/Powershell/ping.bat},继续执行这个表达式就可以了。查看Powershell支持的驱动器,可以使用Get-PSDrive查看。
  • 定义function和调用 function hellow(){ Write-Host "Hellow,Powershell" } $function:hellow
  • 特殊的变量:子表达式 "The size of Powershell_Cmdlets.html is $($file.Length)"

PowerShell变量的作用域

  • Powershell所有的变量都有一个决定变量是否可用的作用域。Powershell支持四个作用域:全局、当前、私有和脚本。有了这些作用域就可以限制变量的可见性了,尤其是在函数和脚本中。
  • 变量的作用域分4中:
    • $global: 全局变量,在所有的作用域中有效,如果你在脚本或者函数中设置了全局变量,即使脚本和函数都运行结束,这个变量也任然有效。
    • $script 脚本变量,只会在脚本内部有效,包括脚本中的函数,一旦脚本运行结束,这个变量就会被回收。
    • $private 私有变量,只会在当前作用域有效,不能贯穿到其他作用域。
    • $local 默认变量,可以省略修饰符,在当前作用域有效,其它作用域只对它有只读权限。
  • 打开Powershell控制台后,Powershell会自动生成一个新的全局作用域。如果增加了函数和脚本,或者特殊的定义,才会生成其它作用域。在当前控制台,只存在一个作用域,通过修饰符访问,其实访问的是同一个变量:
  • 当调用一个已定义的函数,Powershell会生成第二个作用域,它可以对调用者的作用域中的变量执行读操作,但是不能执行写操作

PowerShell变量的类型和强类型

  • 获取类型 (1.2).GetType().Name
  • 默认支持的类型 [array],[bool],[byte],[char],[datetime],[decimal],[double],[guid],[hashtable],[int16],[int32],[int],[int64],[long],[nullable],[psobject],[regex],[sbyte].[scriptblock],[single],[float],[string],[switch],[timespan],[type],[uint16],[uint32],[uint64],[ XML ]

PowerShell变量的幕后管理

  • 在Powershell中创建一个变量,会在后台生成一个PSVariable对象,这个对象不仅包含变量的值,也包含变量的其它信息,例如”只写保护”这样的描述。 如果在Powershell中输出一个变量,只会输出这个变量的值。不能够显示它的其它信息,如果想查看一个变量的其它保留信息,就需要变量的基类PSVariable对象,这个可以通过Get-Variable命令得到,下面的例子演示如何查看一个变量的全部信息。
  • 获取变量的详细信息 Get-Variable a | fl *
  • 变量的选型 $var="test" Set-Variable var -Option "ReadOnly"
  • 变量的选项
    • “None”:默认设置
    • “ReadOnly”:变量只读,但是可以通过-Force 选项更新。
    • “Constant”:常量一旦声明,在当前控制台不能更新。
    • “Private”:只在当前作用域可见,不能贯穿到其它作用域
    • “AllScope”:全局,可以贯穿于任何作用域
  • 变量的内容验证
    • ValidateNotNullAttribute:限制变量不能为空
    • ValidateNotNullOrEmptyAttribute:限制变量不等为空,不能为空字符串,不能为空集合
    • ValidatePatternAttribute:限制变量要满足制定的正则表达式
    • ValidateRangeAttribute:限制变量的取值范围
    • ValidateSetAttribute:限制变量的取值集合 $a=123 $validate=New-Object ValidateNotNull (Get-Variable a).Attributes.Add($validate) $a=$null 报错

PowerShell数组和哈希表

PowerShell命令返回数组

  • 保存命令返回的数组 $ip=ipconfig
  • 判断对象是否为数组 $ip -is [array]
  • 使用管道对数组进一步处理 ipconfig | Select-String "IP"
  • 使用真正的对象操作:ipconfig只是简单的字符串,若用ls,将看到复杂对象的数组。 $result=ls $result[0] |format-list *

PowerShell命令创建数组

  • 创建数组的方式 $nums=1,2,3 $nums=1..5 $nums=1,"123",(get-date)
  • 创建空数组和一个元素的数组 $nums=@() $nums=,"single"

PowerShell访问数组

  • 通过下标索引访问 $nums[1,2,3]
  • 逆序输出 $nums[$nums.count..1]
  • 增加数组元素 $nums+=4

PowerShell数组的复制

数组是引用类型,复制时只复制一个引用

强类型数组

**[int[]] $nums=@()**这个数组只支持int类型

PowerShell使用Hash表

  • 哈希表存放的是对,在哈希表中不再仅仅限制使用数字寻址,可以使用任意类型的数据类型寻址。
  • 创建哈希表之前使用@()创建数组,现在使用@{}创建哈希表,使用哈希表的键访问对应的值。
  • 在哈希表中插入新的键值很方便,象定义变量一样,可以直接拿来使用 $stu.Name=”刘备”
  • 删除操作:$stu.remove(‘Name’)
  • 使用哈希表格式化输出 $column1 = @{expression="Name"; width=30;label="filename"; alignment="left"} $column2 = @{expression="LastWriteTime"; width=40;label="last modification"; alignment="right"} ls | format-table $column1,$column2

PowerShell管道

使用管道

  • 举例:ls | Sort-Object -Descending Name | Select-Object Name,Length,LastWriteTime | ConvertTo-Html | Out-File ls.html

PowerShell对象转为文本

  • 怎样将Powershell的对象结果转换成文本并显示在控制台上。Powershell已经内置Out-Default命令追加在管道的命令串的末尾。因此你使用dir 和dir | out-default的结果是相同的。
  • Out-Default可以将对象转换成可视的文本。事实上Out-Default会首先调用Format-Table,将更多的属性默认隐藏。再调用Out-Host将结果输出在控制台上。因此下面的三组命令执行结果是相同的。dir dir|out-default dir|format-table|out-host
  • 显示隐藏的对象属性ls|format-table * 属性文字较多时,支持换行ls|format-table * -wrap
  • 修改列标题 $column = @{Expression={ [int]($_.Length/1KB) }; Label="KB" } Dir | Format-Table Name, $column
  • 优化列宽度 ls |format-table -autosize

PowerShell对结果进行排序和分组

  • 使用Sort-Object和Group-Object可以对管道结果进行分组。 其实每条命令执行后的结果已经排过序了。例如通过ls 查看文件列表,默认会根据Name属性进行排序,但是你可以通过指定属性进行排序例如: dir|Sort-Object @{expression="length";descending=$true},@{expression="name";descending=$true}
  • 使用分组
    • Get-Process | Group-Object Company -NoElement
    • Dir | Sort-Object Extension, Name | Format-Table -groupBy Extension

PowerShell过滤管道结果

  • 通过where-object get-service | Where-Object {$_.Status -eq "Running"}
  • 选择对象的属性 Get-WmiObject Win32_UserAccount -filter "LocalAccount=True AND Name='guest'"
  • 获取占用CPU最大的5个进程 get-process | sort -Descending cpu | select -First 5
  • 逐个处理所有管道结果 ls | ForEach-Object {"文件名:{0} 文件大小{1}KB: " -f $_.Name,($_.length/1kb).tostring()}

PowerShell分析和比较管道

  • Measure-Object允许指定待统计对象的属性 ls | measure length -Average -Sum -Maximum -Minimum
  • 有时需要比较前后两个时间段开启了那些进程,服务状态有什么变化。类似这样的工作可以交给Compare-Object。比较不同的时间段可以先将所有开启的进程信息快照保存到一个变量中,过一段时间,再保存一份新的进程快照,然后就可以通过Compare-Object进行对比了。 $s1=Get-Service wsearch $s1.stop() $s2=Get-Service wsearch Compare-Object $s1 $2 -property status,name =>表示新增的对象
  • 保存快照以便后期使用 Get-Process | Export-Clixml before.xml $before=Import-Clixml .before.xml $after=Get-Process Compare-Object -ReferenceObject $before -DifferenceObject $after

PowerShell导出管道结果

  • 获取导出的命令 get-command -verb out
  • 导出类型
    • Out-Default 将输出发送到默认的格式化程序和默认的输出 cmdlet。
    • Out-File 将输出发送到文件。
    • Out-GridView 将输出发送到单独窗口中的交互表。
    • Out-Host 将输出发送到命令行。
    • Out-Null 删除输出,不将其发送到控制台。
    • Out-Printer 将输出发送到打印机。
    • Out-String 将对象作为一列字符串发送到主机。

拓展类型系统(ETS)

PowerShell使用对象

PowerShell对象=属性+方法

  • 在现实世界中,你可能已经了解对象就是那些能够摸到的东西。Powershell中的对象和现实生活很相似。例如要在现实生活中描述一把小刀。我们可能会分两方面描述它
    • 属性一把小刀拥有一些特殊的属性,比如它的颜色、制造商、大小、刀片数。这个对象是红色的,重55克,有3个刀片,ABC公司生产的。因此属性描述了一个对象是什么。
    • 方法可以使用这个对象做什么,比如切东西、当螺丝钉用、开啤酒盖。一个对象能干什么就属于这个对象的方法。
  • 例子
    • 创建对象 $pocketknife=New-Object object
    • 增加属性 Add-Member -InputObject $pocketknife -Name Color -Value "Red" -MemberType NoteProperty
    • 增加方法 Add-Member -memberType ScriptMethod -In $pocketknife -name cut -Value { "I'm whittling now" }

PowerShell属性:描述对象是什么

  • 属性可以描述一个对象,对象的属性可以被Powershell自动转换成文本,并且输出到控制台。因此可以通过这种方法查看任何对象,例如$host:
  • 查看对象的所有属性 $host | Get-Member -memberType property

PowerShell方法:描述对象能做什么

  • 方法定义了一个对象可以做什么事情。当你把一个对象输出在控制台时,它的属性可能会被转换成可视的文本。但是它的方法却不可见。列出一个对象的所有方法可是使用Get-Member命令,给“MemeberType”参数 传入“Method”: $Host | Get-Member -MemberType Method

PowerShell条件判断

PowerShell循环

PowerShell函数

PowerShell脚本

使用脚本

  • 编写脚本@'........'@
  • 启动脚本.\myscript.ps1

PowerShell学习网站