简介

简单来说,变量就是在内存中的一个带有名字的“盒子”。你可以把所有你想存放的东西都放入这个“盒子”中:一个计算机名称、一系列服务的集合、XML文档等。然后通过名字去访问这个盒子。在访问过程中,可以存放、添加或者从里面检索东西。
PowerShell并没有对变量有太多限制。比如,你不需要在使用变量前对其进行显式声明或定义。你也可以更改变量值的类型:某个时刻你可能只存储了一个进程在里面,下一时刻又可能存储一系列的计算机名进去。

赋值给变量

PowerShell中的所有东西,都被认为是一个对象。即使一个简单的字符串,比如计算机名,都被当作对象对待。把一个字符串用管道传输到Get-Member(或者它的别名Gm),可以看到对象的类型是“System.String

PowerShell允许在一个变量中存储简单的值。你需要定义一个变量,然后使用等号符(=),用于赋值操作。
image.png
如果需要查询变量的内容,可以使用美元符号加上变量名称:
image.png

关于变量及其名称的一些注意事项:

  • 变量名称通常包含字母、数字和下划线,最常见的形式是以字母或下划线开头。
  • 变量名称可以包含空格,但是名字必须被花括号包住。
    • 比如${My Variable},表示一个变量名“My Variable”。
  • 变量不会驻留在Shell会话之间。当关闭Shell时,所有创建的变量都会被清除。
  • 变量名称可以很长。但是请确保变量名称的可读性。
    • 比如,如果想要把计算机名存入变量,可以使用“computername”作为变量名称。

      关于引号的技巧

      PowerShell会把所有包在单引号中的东西,认为是一个文本字符串。
      image.png
      而双引号则不会:
      image.png
      这种变量赋值替代操作,仅发生在Shell初次解析字符串时
      image.png
      可以看到,$phrase变量依旧保存原有的值。

      转义字符

      关于PowerShell双引号的另外一个窍门是转义字符。这个字符是重音符(```),在美式键盘左上角的部分,通常在Esc键的下方,与波浪符(~)在同一个键上。
      转义字符的作用:它消除了任何在转义符之后有特殊意义字符的含义,或在某些情况下增加了字符的特殊意义。
      image.png
      当把字符串赋给$phrase时,我们使用了两次$computername。第一次,在美元符前使用了重音符。这样去除了美元符在变量中的特殊意义,并把它当作字符中的美元符。在第二次时,没有使用重音符,所以$computername被变量值替换掉。

下面来看一个第二种使用重音符的例子:
image.png
一般来说,“n”是一个字母,但是在前面带有重音符之后,它就变成了一个回车与换行符(n是new line的意思)。
运行“help about_escape”可以获得更多的信息,它包含了其他关于特殊转义符的列表。你可以尝试使用转义后的“t”实现tab功能,或者使用转义后的“a”使机器发出响声(a是alert,警报的意思)。

一个变量中存储多个对象

现在我们尝试把一堆对象放入一个单一变量中。其中一种方式是使用逗号分隔符列表,因为PowerShell认为这些列表是对象的集合。
image.png
通过以上的方法,可以得到3个独立对象,它们的类型均为字符串类型。当检查变量的内容时,PowerShell会把每个对象分别以单行展示。

使用索引

在某一时刻访问多值单一变量(一个变量存储多个值)的独立元素,只需在中括号中指定要访问的对象的索引号即可。该编号从0开始,第二个值的索引号为1,以此类推。使用-1这个索引号来访问对象的最后一个值,-2为倒数第二个值,以此类推。
image.png
变量本身有一个count属性,可以查看其中包含多少个对象。
image.png

与单一对象进行交互

同样可以访问变量内部对象的属性和方法,就像变量自身的属性和方法一样。首先,针对只有单一对象的变量。
(此处,使用前面创建的变量$computername
image.png

与多个对象进行交互

当一个变量包含了多个对象,处理步骤变得稍微有点麻烦。即使变量中的每个对象都像前面例子中的$computers变量那样具有相同的类型,PowerShell v2也不允许你同时针对多个对象调用一个方法或者访问一个属性。如果你非要尝试,会收到报错信息。
image.png
替代方案是,必须指定变量中要操作的那个对象,然后访问它的属性或执行一个方法。
image.png
这些方法不会更改变量中的原有值。如果要修改变量中的内容,必须为现有对象赋予新值。
image.png

与多个对象交互的其他方式

如果想要变量中的每个对象都执行ToLower()方法,并把结果存储回去,可以像这样执行。
image.png
$computers =与管道相连,意味着管道的输出将会被存储在变量中。这些结果将会覆盖以前变量的所有值。
image.png

双引号的其他技巧

范例:把第一个服务名称放入一个字符串
以下范例没有达到预期效果:
image.png
解决方法是将上述命令放入一个表达式:
image.png
$()中的所有内容都会被当成普通的PowerShell命令,结果也被放入字符串中,替代原有的所有内容。同样,该操作仅在双引号中有效这种$()结构称为子表达式

有时,需要把更复杂的内容放入一个变量,然后在引号中显示变量的内容。在PowerShell v3及后续版本中,Shell能更智能地枚举集合中的所有对象。即使你仅引用一个属性或方法,作用域集合中所有相同类型的对象中也没问题。比如,我们查询服务的清单并把它们放入$service变量中,然后使用双引号仅包含服务名称。
image.png

声明变量类型

PowerShell不在乎放入变量中的对象是什么类型。
假设有一个变量希望用于存储一个数值,准备用于一些算术运算,并期待用户输入一个数值。请看下面的例子,你可以直接在命令行中输入数值。
image.png
可以发现,PowerShell并没有把我们的输入当作数值,而是把它当作字符串。PowerShell只是把100这个字符串重复了10次,而不是把100乘以10。所以结果就是把字符串100在一行中列了10次。
image.png
可以看出Shell把它视为System.String,而不是System.Int32。

首先,应该告诉Shell知道$number变量应该存储一个整型,强制Shell把值转换成一个整型。如下面的例子,通过在变量首次使用前使用[],明确定义一个数据类型“int”实现。
image.png
此处,使用了[int]强制$number仅包含整数❶。在输入以后,我们把$number用管道传输到Gm,验证它的确已经是整型而不是字符串❷。最后可以看到,变量的值被认为是数值型并进行了实际乘法运算❸。

使用该技术的另外一个优势是,在Shell无法把数据的值转换成数字时,使得Shell可以抛出错误,因为$number仅仅是存储数值的一个容器。
image.png

其他常用类型

除了[int]之外,还有很多其他的选择。下面是最常用的一些类型清单:

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

明确指定变量的对象类型,可以避免在复杂脚本中出现一些严重的逻辑错误。正如下面的示例,一旦指定了对象类型,PowerShell会强制它使用该类型,直到重新显式定义变量的类型。
image.png
在上例中,首先声明$x变量为整型❶,并把一个整型值放入变量。当准备把一个字符串放入变量时❷, PowerShell抛出错误,因为它不能把字符串转换成整型数值。在后续把变量类型重新声明为字符串后,就可以把字符串放入其中❸。通过管道把变量传输到Gm,可以查看变量的类型名称❹。

与变量相关的命令

PowerShell不建议使用高级的变量声明,并且不能强制声明。
Shell包含了下面与变量有关的命令:

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

“Remove-Variable”命令对需要删除的变量很有用(也可以使用Del命令,使其删除该变量)。

使用这些Cmdlets,需要把变量名称授予对应Cmdlets的-name参数。这里仅需要变量名称——不需要包含美元符。通常只有在操作超出作用域(out-of-scope)变量时,才可能用到这些Cmdlets。使用这种变量不是好习惯,但是可以使用“help about_scope”来获取更详细的信息。