Windows PowerShell1-基础知识

介绍

PowerShell作为Windows系统中的默认脚本,其实在开发中,我们用的很少。接下来的几篇文章都将PowerShell的相关知识,本章介绍PowerShell基本的知识。

安装及简介

Windows Server 2008Windows Server 2008 R2Windows7操作系统开始,我们已经可以使用第三版本的Windows PowerShell。而Windows 10默认安装的版本已经到了5.1。具体可以通过在PowerShell中输入$PSVersionTable命令查看。

在这里插入图片描述

而如果要更新到最新的版本,可以访问此地址进行更新。

Windows 10上安装后,我们可以看到PowerShell的控制台程序和集成脚本环境(ISE)。如上图所示的,打开控制台程序,我们可以直接输入命令后回车,即可看到相应的运行结果。但是ISE界面更加的友好,后面可以看到使用此ISE编辑命令和脚本可以提供更多的帮助,复制和黏贴等也更加的方便。但是ISE相对的启动时间会较长,而通常也就几秒的差异。

在这里插入图片描述

如图,默认打开及分为三部分,分别是脚本编辑区域、命令管理器和控制台。在脚本编辑区域编辑的脚本命令不会马上执行,需要点击菜单栏上的运行按钮才会在控制台看到运行结果。

当然也可以通过点击【工具】->【选项】来配置窗口的相关属性,如字体大小、颜色等。同样PowerShell控制台也可以进行相应的设置。这些相对简单,可以自行根据自己的喜好进行调整,这里就不过多的介绍了。

使用帮助系统

Command 对比 Cmdlet
PowerShell包含了多种类型的可执行命令,有些叫Cmdlet,有些叫函数,还有一些被称为工作流等。他们的共同点都是命令,所有这些命令都在帮助系统囊括的范围内。Cmdlet的概念是Powershell中独有的,你可运行的大多数命令都属于Cmdlet。但在谈论更通用的可执行工具时,我们使用“命令”来表示,从而保证一致性。

更新帮助

在使用帮助系统之前,最好是更新到最新的版本,可以通过Update-Help命令进行更新(最好是通过管理员身份运行)。

微软的PowerShell帮助文件已经在https://github.com/powershell开源。该网址是查看最新源码的好地方,该部分帮助可能在PowerShell中无法下载。

查看帮助

更新好后我们可以输入下面命令观察一下。

在这里插入图片描述

如上,WindowsPowerShell提供了Get-Help这个Cmdlet命令访问帮助系统。你可以看到很多示例都是使用“Help”或者“Man”(来自UNIX,指代Manual)关键字来代替Get-HelpHelpMan都不是原始的Cmdlet命令,而是对核心Cmdlet命令封装后的函数。

Help的工作原理类似Get-Help,但是它可以把输出的信息通过管道传递给More命令。(ManHelp的别名或者昵称,因此也可使用More命令)所有我们可以使用Help Get-Content命令,也可以更友好的使用Help Get-Content | More命令。

使用帮助系统查找命令

和大多数命令一样,Get-Help命令有几个参数。其中最重要的是-Name。该参数指定你想要访问帮助的主题名称,并且它是一个位置参数,所以你无需输入-Name,只需要提供要查找的命令名称。它也支持通配符(*),这让帮助系统更容易查找命令。

如你想查看操作系统日志,但不知道命令,可通过下面的方式进行搜索

Help *log*
Help *event*

在这里插入图片描述

另外一种,你大概知道命令的一部分,那可以输入“Help Get-Eve”然后通过Tab键进行自动补全,如果不是你需要的,可以继续按Tab键,帮助系统会循环查找以“Get-Eve”开头的所有命令。

帮助详解

参数集和通用参数

在这里插入图片描述

如上红框中标识的就是参数集,这表示,此Get-EventLog命令有两个参数集,你可能已经注意到,有些参数是这两个参数集共有的,它们是通用参数。

可选和必选参数

PowerShell的帮助稳定把可选参数放到一个方括号中。如,[-ComputerName <System.String[]>]表示-ComputerName是可选参数。几乎所有的Cmdlet命令都最少有一个可选参数。

对于必须的参数,如果没有输入值的情况下,如下所示。控制台会提示你继续输入必须的参数后才会继续运行。

在这里插入图片描述

位置参数

PowerShell设计者知道有些参数会被频繁的使用,而你不希望不断的输入参数名称。通常来说,参数是具有位置的。着意味着只要你把参数值放在正确的位置,你就可以值提供这个参数值,而不需要输入具体的参数名称。

下面介绍使用位置参数时的几个技巧。

  • 位置参数可以同时出现指定和不指定参数名称的情况,但是位置参数必须处在正确的位置。如:Get-EventLog -newest 20 -Log Application 是正确的。Application会被匹配到-Log参数,因为这是第一个位置的参数值

  • 指定参数名称总是合法的

  • 如果使用多个位置参数,不要忘了它们的位置

我们的建议是:总是使用参数名称

使用Help Get-EventLog -Full命令可以查看具体的参数说明,通用可以把-Full改为-ShowWindow,其会提供一个窗口来显示详细的说明详细。

参数值

帮助文档通用给你提供了每个参数的数据类型。有些参数被称为开关参数,无需任何输入值。如:[-AsString]

-AsString [<SwitchParameter>]
    以字符串而非对象的形式返回输出。

    是否必须?          False
    位置?              False
    默认值
    是否接收管道输入?   False
    是否接收通配符?     False

通过[<SwitchParameter>]可以确定这是一个开关参数,并需要任何输入。开关参数位置可随便放置,但必须输入参数名(或缩写)并总是可选的。

其他参数希望获得的数据类型,通常会跟在参数名后面,并使用空格与参数名分开。在缩写语法中,用尖括号表明。如[-LogName] <string> 。除了string,还有IntInt32Int64Datetime等等。

另外,如[-ComputerName <string[]>]表示参数后可以跟多个值,即string后的方括号表示数组、集合。

Get-EventLog Security -ComputerName Server-R2
Get-EventLog Security -ComputerName Server-R2,DC4,Files02

再次说明,任何一个单一值中如果包含了空格,就必须使用引号。但是作为一个整体的列表,不需要使用银行,只有单一值才需要。以下内容合法。

Get-EventLog Security -ComputerName 'Server-R2','DC4','Files02'

另外一种提供列表值的方式是将其放入一个文本文件中,每个值一列。如下:

Server-R2
DC4
Files02

可以使用Get-Content命令来进行获取,具体如下:

Get-EventLog Security  -ComputerName (Get-Content names.txt)

发现命令示例及访问在线帮助

其实在使用-Full参数中是可以查看的,但是我们也可以使用-Example参数替换-Full参数,直接查看命令的示例。

Help Get-EventLog -Example

PowerShell的帮助文档是有人编写的,这意味着它们并不一定准确。除了使用Update-Help命令外,可以使用Help命令的-Online参数查看在线的实时帮助信息。

Help Get-EventLog -Online

运行命令

Cmdlet命名规则应该以标准的动词开始,比如GetSetNewPause。以可以运行Get-Verb查看运行使用的动词列表。对于有些命令,其命名非常的长,不方便记忆,所以我们可以使用命令的别名或者叫昵称。通过以下命令可以查看。

Get-Alias -Definition Get-Service

结果如下:

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Alias           gsv -> Get-Service

而使用Help gsv和使用Help Get-Service的效果是一样的。

另外,参数也可简化或者使用别名。如可以使用-comp代替-ComputerName,也可以输入-comp后按下Tab键来完成参数名称的补全。当然也可以通过以下命令获取参数的昵称或者别名。

(Get-Command Get-EventLog | select -ExpandProperty parameters).computername.aliases

由此命令可以知道-ComputerName的别名是-Cn

当然如ping等命令也可以使用PowerShell进行执行。但是对于一些第三方的程序,仅仅需要在外部命令名称后面加上两个破折号和一个百分号。比如我们想尝试使用命令行工具sc.exe查询一个服务,可以使用以下形式。

在这里插入图片描述

使用提供程序

一个PowerShell提供程序,或者说PSProvider,其本质上是一个适配器。它可以接收某些数据存储,并使得这些介质看起来像是磁盘驱动器一样。使用以下命令查看当前Shell总已经存在的提供程序。

在这里插入图片描述

以下是一些常见的功能描述。

  • ShouldProcess——这部分提供程序支持-WhatIf-Confirm参数,保证我们在正式执行这部分脚本之前可以对它们进行测试

  • Filter——在Cmdlet中操作提供程序的数据是,支持-Filter参数

  • Credentials——该提供程序允许使用可变更的凭据连接数据存储

  • Transactions——该提供程序支持事务,也就是允许你在该提供程序中将多个变更作为一个原子操作进行提交或者全部回滚

你也可以使用某些提供程序创建一个PSDrive。其可以通过一个特定的提供程序连接到某些存储数据的介质。

在这里插入图片描述

大多数情况下,操作PSDriveCmdlet名称部分都会包含“Item”。

在这里插入图片描述

在使用提供程序时,需要熟悉几个Cmdlet命令。

  • Set-Location:作用和cmd.exe中的cd是一样的

  • New-Item:创建新的项,可以用来新建文件夹、文件、注册表项以及其他项,所以必须告诉它你希望创建的类型是什么

PowerShell中也包含MKDir命令,其是一个函数,并不是一个别名。它也调用了New-Item,只是隐式赋予了-Type Directory这个参数

大多数分项的Cmdlet都包含了-Path属性。默认情况下,该属性支持通配符输入。 “*”通配符代表0个或者多个字符;“?”通配符代表单个字符。有这些情况下,比如注册表的某些项名称中包含了“*”或“?”,如果此时需要查询名称中带有*或者?,就需要使用-LiteralPath参数,而不是-Path参数。

看下面一个使用的例子。

Set-Location -Path HKCU:
Set-Location -Path SoftWare
Get-ChildItem
Set-Location -Path Microsoft
Set-Location -Path .\Windows
Get-ChildItem
Set-ItemProperty -Path DWM -PSProperty EnableWindowColorization -Value 0

在这里插入图片描述

管道:连接命令

PowerShell通过管道(pipline)把命令互相连接起来。管道通过传递一个命令,把其输出作为另一个Cmdlet的输入,是的第二个命令可以通过第一个的结果作为输入并联合起来运行。

查看以下案例,文件保存在当前目录下。分别输出为csvxml格式的文件。

Get-Process | Export-CSV procs-csv.csv
Get-Process | Export-CliXML procs-xml.xml

接下来我们,看下使用Diff命令来比较下文件内容。DiffCompare-Object命令的别名。通过Help Diff查看帮助文档,我们重点关注三个属性:-ReferenceObject,-DifferenceObject-Property。具体看以下例子(生成xml文件后可以考虑打开几个新软件在执行第二条命令)。

Get-Process | Export-CliXML reference.xml
Diff -reference (Import-CliXML reference.xml) -difference (Get-Process) -property Name

接下来看一个通过管道输出到文件的例子。

Dir > DirectoryList.txt
Dir | Out-File DirectoryList.txt

符合“>”是PowerShell向后兼容旧版本cmd命令的一个快捷方式。实际上还是执行第二条命令的。但是使用Out-File,通过其提供的一些参数可以定制替代的字符编码(UTF8等)、追加内容到现有文件等。默认情况下,其创建的文件有80列宽。

如果是单独的使用Dir命令,实际上是执行了“Dir | Out-Default | Out-Host”,Out-Host是输出到显示器上。以Out开头的命令中还有一个比较实用的是输出到打印机,即Out-Printer(只能在Windows系统中使用)。

如果需要以html形式输出的,查看以下示例。

Get-Service | ConvertTo-HTML | Out-File services.html

注意:以ConvertTo开头的命令,只是进行文本的转换,并不会保存到磁盘上

接下来的例子是通过管道来修改系统——终止进程和停止服务。

# 绝对不能执行
Get-Service | Stop-Service

Get-Process -name Notepad | Stop-Process

# 执行提示
Get-Process | Stop-Process -confirm
Get-Process | Stop-Process -whatif

最后要说明的是,通过Export-CSV等命令保存的文件,如果通过Get-Content获取并显示,则只是获取到了原始文本,即不包括文本格式,而如果通过对应的Import-CSV后去文件内容并显示,则相对比较友好了。所以建议只有文本文件考虑使用Get-Content命令。

对象:数据的另一个名称

PowerShell中通过Get-Member命令来了解对象,其别名是Gm

Get-Process | Gm

在查看Gm的输出结果中,你会注意到一些不同的属性。

  • 脚本属性
  • 属性
  • NoteProperty
  • 别名属性

很多对象都支持一个或多个方法。进程对象包含了一个Kill方法,它会终止进程。而要终止一个进程,可以通过3种方式。其中一个办法是获取对象并执行Kill方法,另两种如下:

Get-Process -Name Notepad | Stop-Process
Stop-Process-Name Notepad

PowerShell提供了Sort-Object命令来进行排序,可简写为sort。如对进程列表的虚拟内存(Virtual Memory,VM)的消耗由高到低进行排序。

Get-Process | Sort-Object -Property VM

通过Help命令,我们可以发现Sort-Object命令有一个参数:-Descending,其可以反向进行排序,简写为-desc

既然可以进行排序,那肯定也是可以选择我们需要的对象属性的。PowerShell提供了Select-Object命令,简写为select。同时也可以通过Where-Object进行条件的过滤。

Get-Process | ConvertTo-HTML | Out-File test1.html
Get-Process | Select-Object -Property Name,ID,VM,PM | ConvertTo-HTML | Out-File test2.html

PowerShell管道在最后一个命令执行之前总是传递对象。在最后一个命令执行时,PowerShell将会查看管道中所包含的对象,并根据不同的配置文件决定哪一个属性被用于构建展示在屏幕上的最终结果。

Get-Process | Sort-Object -Property VM -Desc | Gm
Get-Process | Sort-Object -Property VM -Desc | Select Name,ID,VM | Gm

掌握PowerShell的一个关键点是在任意时间点知道当前管道中的对象类型。而Gm将会帮助你实现这一点。

下面列出了一些注意点。

  • 请记住,PowerShell帮助文件不包含有关对象属性的信息。你必须将对象利用管道传递给Gm从而查看属性列表
  • 请记住,你可以在产生结果的任意管道末尾添加Gm命令
  • 请注意输入的整洁性。请在管道操作符两侧加入空格
  • 请记住,管道中在不同阶段可以包含不同类型的对象。请考虑当前的管道中的对象类型是什么,并把精力集中在下一个命令对当前类型的对象所做的操作

深入理解管道

我们先来看看下面的例子,通过此列子我们来了解PowerShell中通过ByValue进行管道输入的方法。

Get-Content .\remote.txt | Get-Service

当前用ByValue这种方式实现管道参数绑定时,PowerShell会确认命令A产生的数据对象类型,然后查看命令B中哪个参数可以接收经由管道传来对象的类型。

如下,你会看到Get-Content命令产生结果对象的类型是System.String。通过查看帮助信息,可以到达Get-Service中的确也存在可以从ByValue管道中接收String类型数据的参数。

在这里插入图片描述

PowerShell只允许使用一个参数接收ByValue管道返回对象类型。也就意味着,由-Name参数接收了来自ByValue管道返回的String类型数据,那么其他参数就无法再接收该数据。

而使用ByPropertyName进行管道传输的方法通用需要将命令A输出结果传递给命令B的参数。不同的是通过该方法,命令B的多个参数可以被同时使用。看下面的例子。Shell对该功能的实现非常简单:仅仅是寻找能够匹配参数名称的属性名称。

Get-Service -Name s* | Stop-Process

在这里插入图片描述

在该示例中,-Name参数可以接收来自ByPropertyName管道的输出结果,所以这个连接可以正常工作。

接下来看一个通过管道显示自定义属性的例子。

Get-Process | Select-Object -Property *, @{name='myName'; expression={$_.ProcessName}},@{label="myId";expression={$_.Id}}

除了显示自定义的属性外,还可以提取单个属性的值,查看以下例子。通过gm命令先查看具体的属性有哪些,然后可通过Select-Object-ExpandProperty参数来提取具体的属性值。甚至还可以转成列表html等形式进行显示。

Get-Process | gm
Get-Process | Select-Object -ExpandProperty ProcessName

格式化及如何正确使用

默认的格式化文件你可以在PowerShell的安装目录中找到一个名为“*.format.ps1xml”的文件。其中进程对象的格式化目录在“DotNetTypes.format.ps1xml”中。可以通过下面的方式查看。

cd $pshome
notepad DotNetTypes.format.ps1xml

对于大部分以Out开头的命令,都会自动出发格式化系统,以便找到所需的格式化指令。

PowerShell中,有个用于格式化的Cmdlets。我们将介绍日常使用最多的 3 种。首先是“Format-Table”,其别名为“Ft”。

Format-Table常用的参数有:

  • -AutoSize:使用此参数,可以强制结果集仅保存足够的列空间,使得表格更加紧凑,但是会使得Shell花费额外的时间来生成结果
  • -Property:该参数接收一个逗号分隔的列表,该列表包含期望显示的属性值
  • -GroupBy:该参数会导致每当指定的属性值发生变化时,生成一个新的列头集合。该参数只有第一次对某个对象的特定属性排序时才能生效
  • -Wrap:如果Shell需要把列的信息截断,会在列尾带上省略号(...)以便表示信息被截断。该参数使得Shell可以换行显示剩余信息,这使你的表变长,但会保留你期望显示的所有消息

有时候你所需要展示的信息过多无法适应表格宽度,这时候使用列表就很恰当。是时候使用“Format-List”了,其别名是:“Fl”。其也包含了-Property属性,实际上,Fl是另一个用于展示对象属性的方式,和Gm不同。

Get-Service | Fl *

最后一个Cmdlet是“Format-Wide”,别名是“Fw”,用于展示一个宽列表。它仅展示一个属性的值,所有它的“-Property”参数仅接受一个属性名称,而不是接受列表,并不接受通配符。

默认情况下,“Format-Wide”会查找对象的“Name”属性,因为“Name”是广泛使用的属性并且通常包含有用信息,该命令默认输出结果只有两列,但是“-Columns”参数可以用于指定输出更多列。

在这里插入图片描述

Format-Table”和“Format-List”都能使用通用的结构创建自定义列或自定义表条目。可以通过提供与属性名称不同的列头创建自定义列。

Get-Service | Format-Table @{name="ServiceName";expression={$_.Name}},Status,DisplayName

甚至使用更加复杂的数学表达式。

Get-Process | Format-Table Name, @{name="VM(MB)";expression={$_.VM / 1mb -as [int]}} -AutoSize
  • PowerShell中的斜线是除法操作,另外其能够识别KBMBGBTBPB等缩写
  • -as操作符可以帮助我们将数据结果从浮点型转换成整型(如指定[int]

一旦格式化完成某些对象,你就必须决它的去向。

如果命令最后是Format-开头的Cmdlet,其会传递给Out-Default,然后将结果传递给Out-Host,最后显示结果到屏幕上。当然也可以通过管道输出到以Out-开头的Cmdlet,即Out-FileOut-Printer。只有这三个以Out-开头的Cmdlet才可以跟在以Format-开头的Cmdlet后面。

请记住,Out-FileOut-Printer都有默认的输出列宽,可以通过-Width参数控制宽度输出。

Out-GridView”提供另一种形式的输出结果。但是从技术角度来说,这并不是真正意义上的格式化。实际上,“Out-GridView”完全绕过了格式化子系统。它不需要调用以“Format-”开头的Cmdlet,不生产格式化指令,不会在控制台窗口输出文本结果。“Out-GridView”不接受“Format-Cmdlet输出,仅接受其他Cmdlets输出的对象。“Out-GridView”可能无法在非Windows系统中生效。

在这里插入图片描述

过滤和比较

Shell提供了两种方式缩小结果集,它们都被归结为过滤。第一种方式:尝试指定Cmdlet命令值检索指定的内容。第二种方式:采用迭代的方法,通过第一个Cmdlet获取所有结果,并使用第二个Cmdlet过滤掉不想要的东西。

按道理,应该使用第一种方式:我们称之为尽可能提前过滤,也可称之为“左过滤”。“左过滤”意味着尽可能把过滤条件放置在左侧或者靠近命令的开始部分。越早过滤不需要的对象,就越能减轻其他Cmdlets命令的工作,并且能减少不必要的信息通过网络传递到你的电脑。

左过滤的缺点是每个Cmdlet都可以通过自己的方式指定过过滤,并且每个Cmdlet都会有不同的过滤方式。例如Get-Service,你只能通过Name属性过滤服务。但是使用Get-ADComputer,你可以根据computer对象可能存在的任何活动目录属性进行过滤。

当无法通过要给Cmdlet就可以完成你所需要的所有过滤时,你可以使用一个叫做Where-Object(它的别名是Where)的核心PowerShell命令。而这就可能会使用到PowerShell中的比较操作符。

  • -eq——相等
  • -ne——不等于
  • -ge——大于等于
  • -le——小于等于
  • -gt——大于
  • -lt——小于

对于字符串的比较,如果需要区分大小写,可以使用下面的集合:-ceq-cne-cgt-clt-cge-cle

如果想一次比较多个对象,可以使用布尔运算符-and-or。通常在每个子表达式两边加上括号,使得表达式更容易阅读的。

另一种布尔运算发-nottruefalse取反。PowerShell中对于了$False$True表似falsetrue的布尔值。例如,需要测试要给进程是否没有响应,可以这样(使用$_作为当前进程的容器):

-not $_.Responding

上面的运行返回True,这就按时这该进程 “没有响应”

当你需要比较文本字符串时,还有其他几个有用的比较运算符。

  • -like接收*作为通配符,所以可以比较:"Hello" -like "*ll*"(返回true)。它的反义运算符是-notlike。它们不区分大小写。区分大小写可以使用-clike-cnotlike
  • -match用于文本字符串与正则表达式进行比较。-notmatch是个逻辑上的反义词。并且-cmatch-cnotmatch提供了区分大小写的语法
Get-Service | Where-Object -filter { $_.Status -dq 'Running' }
Get-Service | Where { $_.Status -dq 'Running' }

-filter参数是一个位置参数,这意味着你经常看到很多命令没有显示指定该参数

我们现在想为你简单介绍PowerShell迭代命令行模型或者称为PSICLMPSICLM的核心思想在于你不需要一开始就创建一个大而复杂的命令行,而是从简单的开始。

比方说,你想计算正在使用虚拟内容排名前十的进程所占用的虚拟内存总和。如果排名前十的进程种包含PowerShell进程,而又不想在结果种包含PowerShell进程,快速罗列出几个需要的步骤。

  • 获取进程列表
  • 排除PowerShell进程
  • 按照虚拟内存进行排序
  • 只保存前10或者最后10个,这取决于我们的排序方式
  • 把剩下进程的虚拟内存相加

可以按照如下命令方式逐步添加:

Get-Process | Where-Object -FilterScript { $_.Name -notlike 'powerShell*' }

Get-Process | Where-Object -FilterScript { $_.Name -notlike 'powershell*' } | Sort-Object VM -descending 

Get-Process | Where-Object -FilterScript { $_.Name -notlike 'powershell*' } | Sort-Object VM -descending | Select-Object -First 10

Get-Process | Where-Object -FilterScript { $_.Name -notlike 'powershell*' } | Sort-Object VM -descending | Select-Object -First 10 | Measure-Object -Property VM -Sum

变量:一个存放资料的地方

介绍

PowerShell并没有对变量有太多的限制。比如,你不需要在使用变量前对其进行显示声明或定义,你也可以更改变量值的类型。PowerShell中所有的东西都被认为是对象,即使是一个简单的字符串。

$var = "SERVER-R2"

需要注意的是,美元符($)并不是变量名称的一部分,其只是告诉Shell接下来的是一个变量名,并且将要赋值给这个变量。

下面我们看看关于变量及其名称的一些注意事项。

  • 变量名通常包含字母、数字和下划线,最常见的形式是以字母或下划线开头
  • 变量名称可以包含空格,但是名称必须被花括号包住。比如${My Variable}表示一个变量名称“My Variable”,个人不建议使用空格的变量名
  • 变量不会驻留在Shell会话之间。当关闭Shell时,所有你创建的变量都会被清除
  • 变量名称可以很长——长到你可以不用考虑它到底多长。但是请确保变量名称的可读性
  • PowerShell用户通常不需要使用前缀名来表示变量存放的是什么

如果需要查看变量内容,可以使用美元符加上变量名称。你可以在几乎所有地方使用变量来替代值。

Get-WmiObject Win32_ComputerSystem -ComputerName SERVER-R2
Get-WmiObject Win32_ComputerSystem -ComputerName $var

使用变量:关于引号有趣的技巧

PowerShell会把所有包在单引号中的东西认为是一个文本字符串。如下面的例子。

$var = 'Whate does $var contain?'
$var
# 输出:Whate does $var contain?

但是在双引号中又是另一番情景。

$computername = 'Server-R2'
$phrase = "The computer name is $computername"
$phrase
# 输出:The computer name is Server-R2

PowerShell自动在双引号中搜索美元符,然后用变量的值替代所有被找到的变量。这种替代操作仅发生在Shell初次解析字符串时。如果后面变量的值改变了,之前的$phrase变量的值不变。

关于PowerShell双引号的另一个窍门是转义字符,这个字符是重音符(`)。看下面的例子,它消除了任何在转义符之后又特殊意义字符的含义,或者在某些情况下增加了字符的特殊意义。

# 消除特殊含义
$computername = 'Server-R2'
$phrase = "`$computername contains $computername"
$phrase
# 输出:$computername contains Server-R2

# 增加特殊意义 ,这里`n的意义是回车换行
$phrase = "`$computername `ncontains `n$computername"
$phrase
# 输出:
# $computername
# contains
# Server-R2

在一个变量中存储多个对象

一种方式是用逗号分隔符列表,PowerShell认为这些列表是对象的集合

$computername = 'Server-R2','server1','localhost'
$computername
# 输出:
# Server-R2
# server1
# localhost

注意:逗号是在单引号外面,如果是在里面就是一个包含3个计算机名称的单一变量了

你可以在某个时刻访问多值单一变量(一个变量存储多个值)的独立元素。只需要在中括号中指定你要访问的对象的索引号即可。可以从0开始,第二个值的索引号是1,以此类推。也可以从-1开始访问对的最后一个值,-2为倒数第二个值等。

$computername[0]
# 输出:Server-R2
$computername[1]
# 输出:server1
$computername[-1]
# 输出:localhost
$computername[-2]
# 输出:server1
$computername.count
# 输出:3

你同样可以访问变量内部对象的属性和方法,就像变量自身的属性和方法一样。首先看下单一对象的变量。

$computer ='Server-R2'
$computer.length
# 输出:9
$computer.toupper()
# 输出:SERVER-R2
$computer.tolower()
# 输出:server-r2
$computer.replace('R2','2008')
# 输出:server-2008
$computer
# 输出:Server-R2

而当一个变量包含多个值时,如果相应访问其属性和方法,可以参考下面的例子。

$computername[0].toupper()
# 输出:SERVER-R2

再次提醒,方法会产生新的字符串结果,不会更改变量中的原有值。如果要更改,则需要重新赋值。

$computername[1].replace('server','client')
# 输出:client1
$computername[1] = $computername[1].replace('server','client')
$computername
# 输出:
# Server-R2
# client1
# localhost

在与多个对象交互的时候,还可以考虑使用ForEach-Object命令。下面的列子的效果和上面的一样。

$computername = $computername | ForEach-Object { $_.ToLower() }

同样也可以将其通过管道传递给Select-Object对属性做类似的事情。

在这里插入图片描述

PowerShell v3及之后的版本中对对象的方法和属性的访问做了一些调整。看下面的例子。

$service = Get-Service
$service.name
# 上面的写法,等价于下面的方式实现
Get-Service | ForEach-Object { Write-Output $_.Name }
Get-Service | Select-Object -ExpandProperty Name

这里可以延申一下双引号的技巧使用,比如上面的$service变量,如何你只想要得到第一个服务名称,该怎么办?可以将命令放入一个表达式中。

$service = Get-Service
$firstname = "The first name is $($service[0].name)"
$firstname
# 输出:The first name is AelookupSvc

而在Powershell v3及以后的版本中也有一个很酷的功能,可参考下图理解。

在这里插入图片描述

声明变量类型

假设你像在变量中放入一个数字,并对其进行计算,该怎么办?这里我们就要在声明变量的时候同时告诉Shell变量的类型。通过在变量首次使用前使用[],明确定义一个数据类型“int”。

[int] $number = Read-Host "Enter a number"
Enter a number: 100
$number = $number * 10

通过在声明的时候约束变量的类型,也可以避免不必要的麻烦。比如你定义了要给int类型的变量,如果你输入的字符串,则Shell会报错。

下面看一下最常用的数据类型清单。

  • [int]——整型数字
  • [single][double]——单精度和多精度浮点型数字
  • [string]——字符串
  • [char]——仅单个字符
  • [xml]——一个XML文档。不管你如何解析里面的值,都要确保它包含有效的XML标记(比如[xml] $doc = Get-Content MyXml.xml)
  • [adsi]——一个活动目录服务接口(ADSI)查询。Shell会执行查询并把结果对象存入变量(如[adsi] $user="WinNT:\\MYDOMAIN\Administrator,user")

和变量相关的命令

  • New-Variable
  • Set-Variable
  • Remove-Variable
  • Get-Variable
  • Clear-Variable

除了Remove-Variable之外,其他命令可能都用不上。该命令对需要删除的变量很有用(也可以使用del删除变量)。基本不建议使用这些Cmdlet命令,如果需要使用,请提取查询好相关的帮助文档信息。

$LASTEXITCODE变量

PowerShell允许调用外部可执行程序,比如ping.exe。外部程序允许结束后返回一个退出码(或者返回码),通常,0表示成功,其他数字表示失败。使用方式参考下面代码。

ping.exe www.baidu.com
$LASTEXITCODE
# 输出: 0

总结

以上是对PowerShell基本知识的介绍,如果需要更多的知识,可以进入下一篇的知识深入部分进行了解。

  • 22
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值