更新记录
转载请注明出处。
2022年8月21日 发布。
2022年8月18日 从笔记迁移到博客。
A variable may be of any .NET type or object instance
PowerShell并没有对变量有太多限制
不需要在使用变量前对其进行显式声明或定义
可以使用中更改变量值的类型
所有东西在PowerShell中都是对象
一个简单的字符串,比如计算机名,都被当作对象对待
变量的语法规则:
Variables in PowerShell are preceded by the dollar symbol ($)
The name of a variable may contain numbers, letters, and underscores
[类型]$变量名
实例:
字符串都是System.String类型
"Panda666.com" | Get-Member
支持的类型:
[int] 整型数字 [single][double] 单精度和多精度浮点型数值(小数位部分的数值) [string] 字符串 [char] 字符(如[char]$c='X') [xml] XML文档(比如[xml]$doc=Get-Content MyXML.xml) [adsi] 活动目录服务接口(ADSI)查询 Shell会执行查询并把结果对象存入变量 (如[adsi]$user="WinNT:\\MYDOMAIN\Administrator,user")
实例:
$panda = 666 $panda = "Panda666.com"
变量名称可以很长,长到可以不用考虑它到底能有多长
变量名称可以包含空格,但是名字必须被花括号包住
比如${My Variable},表示一个变量名“My Variable”
不建议这么用,容易出错且不易阅读
实例:
${Panda 666} = "Panda666.com"
注意:
变量不会驻留在Shell会话之间
当关闭Shell,所有创建的变量都会被清除
$panda
注意:
变量可以放在""双引号中,会被解析
变量可以放在''单引号中,不会被解析
读取不存在的变量不会报错
实例:
$panda = "Panda666.com" "My Website = $panda" #My Website = Panda666.com 'My Website = $panda' #My Website = $panda
Type conversion in PowerShell is used to switch between different types of a value
变量的类型可以是:.NET type, a class, or an enumeration
PowerShell支持以下类型的转换:
Direct assignment
Language-based conversion
Parse conversion
Static create conversion
Constructor conversion
Cast conversion
IConvertible conversion
IDictionary conversion
PSObject property conversion
TypeConverter conversion
实例:
定义字符串变量
[String]$thisString = "some value"
定义数值变量
[Int]$thisNumber = 2
定义日期DateTime变量
[DateTime]$date = '01/01/2016'
将变量赋值为$null将不会改变其类型
[string]$name = "Panda"; $name = $null; $name.GetType(); //String
字符串类型转为数值类型
[int]"123"
将日期类型转为字符串类型
[String](Get-Date)
字符串类型转为DateTime类型
[DateTime]"01/01/2016"
以下情况会被转为bool值的true
[Boolean]1 [Boolean]-1 [Boolean]2016 [Boolean]"Hello world"
以下情况会被转为bool值的false
[Boolean]0 [Boolean]"" [Boolean]$null
New-Variable
实例:
创建变量存放字符串
New-Variable –Name One –Value 'Hello'
创建变量存放数组
New-Variable -Name "Panda" -Value 1,2,3,4
创建变量存放哈希表
New-Variable -Name "Panda3" -Value @{ ID = 1; Shape = "Square"; Color = "Blue"}
创建变量存放日期
New-Variable -Name today -Value (Get-Date)
定义常量
New-Variable -Name startTime -Value (Get-Date) -Option Constant
Set-Variable
实例:
设置变量存放数值类型
Set-Variable -Name One -Value 123
设置变量存放数组
Set-Variable -Name "Panda" -Value 1,2,3,4,5,6
设置变量存放哈希表
Set-Variable -Name "Panda" -Value @{"Name"="Panda"}
设置变量的描述
Set-Variable objectCount -Description 'The number of objects in the queue'
删除变量的名和释放变量的值
Remove-Variable
实例:
移除指定变量
Remove-Variable -Name One
清除变量的值
Clear-Variable
实例:
移除指定名称的变量
Clear-Variable -Name "Panda2"
获得已定义的和预定义的变量
Get-Variable
实例:
获得用户定义的变量
$panda = 666; Get-Variable panda
获得所有已存在的变量
Get-Variable | Select-Object Name, Description
PowerShell includes a variable provider that can be queried as a filesystem
使用变量提供器,可以将文件系统使用的命令直接用在变量中
实例:
获得所有已经定义的变量
Get-ChildItem variable:
检测变量存在
Test-Path variable:\VerbosePreference
创建新的变量
Set-Item variable:\new -Value variable
获得变量的内容
Get-Content variable:\OutputEncoding
分割字符串进行解构赋值
$firstName, $lastName = "First Last" -split " " $firstName, $lastName = "First Last".Split(" ")
拆分数组进行解构赋值
$i, $j = 1, 2
最后一个变量获得数组最后的全部元素
$i, $j, $k = 1, 2, 3, 4, 5
最后一个变量没有被赋值
$i, $j, $k = 1, 2
Variables may be declared in a number of different scopes
The scopes are as follows:
全局作用域(Global Scope)
局部作用域(Local Scope)
脚本作用域(Script Scope)
私有作用域(Private Scope)
A numeric scope relative to the current scope
By default, variables are placed in local scope
Access to variables is hierarchical
Child (scopes created beneath a parent) can access variables created by the parent
Variables created in a child scope cannot be accessed from a parent scope
如果变量在本地作用域没有查到,则向上作用域继续查找
实例:
获得作用域的帮助信息
Get-Help about_scopes
When creating a variable in the console (outside of functions or script blocks), the local scope is global
实例:
定义局部作用域的变量
$Local:thisValue = "Some value"
定义全局作用域的变量
$global:thisValue = 123
访问全局作用域的变量
$Local:pandaOuter = "panda666" function Test-ThisScope { "From Local: $local:thisValue" # Does not exist "From Global: $global:pandaOuter" # Accessible } Test-ThisScope
Shell本身具有最高级的作用域,称为全局域(global scope)
当运行一个脚本时,会在脚本范围内创建一个新的作用域
脚本作用域是全局作用域的子集,也就是全局作用域的子作用域(child)
全局作用域是脚本作用域的父作用域(parent)
实例:
显式定义脚本作用域内的变量
[Version]$Script:Version = "0.1"
在函数内访问同名全局作用域需要使用全局修饰符
注意:如果非同名,可以直接使用变量名
function Set-Version { param( [Version]$version ) $Script:Version = $version }
函数还有其特有的私有作用域(private scope)
The private scope may be accessed using the private prefix
注意:私有作用域仅在自己的作用域内可用
实例:
定义私有作用域
$private:thisValue = "Some value"
私有作用域仅在自己的作用域内可用
$private:pandaPrivate = "panda666" "From global: $global:pandaPrivate" # Accessible function Test-ThisScope { "Without scope: $pandaPrivate" # Not accessible "From private: $private:pandaPrivate" # Not accessible "From global: $global:pandaPrivate" # Not accessible } Test-ThisScope
如果变量在当前作用域找到了匹配的变量,则不会向上查找
function bottom { $thisValue = "Bottom" Write-Host "Bottom: $thisValue" middle } function middle { # Hide thisValue from children $private:thisValue = "Middle" # Middle only Write-Host "Middle: $thisValue" top } function top { Write-Host "Top: $thisValue" # Original value } #调用 Bottom
如果尝试访问一个作用域元素,PowerShell在当前作用域内查找
如果不存在于当前作用域,PowerShell会查找其父作用域,依此类推
直到找到树形关系的顶端全局作用域
本质就是dotNet中的System.Array类型
Array类型支持的方法基本都支持
默认数组内的元素类是System.Object
Indexing in an array starts from 0
定义空数组
$myArray = @()
直接定义数组的元素,使用,分隔值即可
元素可以是任意类型(因为默认的元素类型是Object类型)
$A = 1, 2, 3, 4 $pandaArr = "Panda",666,"Dog",888 $myGreetings = "Hello world", "Hello sun", "Hello moon" $myGreetings = @("Hello world", "Hello sun", "Hello moon") $myThings = "Hello world", 2, 34.23, (Get-Date)
默认情况下数值的元素类型是System.Object,可以使用getType方法获得数组类型
$A.getType()
通过序列生成
$A = 1..4
还可以跨越多行
$myGreetings = "Hello world", "Hello sun", "Hello moon"
声明数组的类型
[int32[]]$intA = 1500,2230,3350,4000
创建指定类型的数组并指定数组长度
$myArray = New-Object Object[] 10 # 10 objects $byteArray = New-Object Byte[] 100 # 100 bytes $ipAddresses = New-Object IPAddress[] 5 # 5 IP addresses
当声明了类型后,如果赋值其他类型将会发生转换
如果无法进行转换,将会抛出异常
[Int32[]]$myNumbers = 1, 2, $null, 3.45
多维矩阵数组
$arrayOfArrays = @( @(1, 2, 3), @(4, 5, 6), @(7, 8, 9) )
多维锯齿数组(Jagged arrays)
$arrayOfArrays = @( @(1, 2), @(4, 5, 6, 7, 8, 9), @(10, 11, 12) )
索引从0开始
$pandaArr[0] #Panda $arrayOfArrays[0][1]
倒序开始访问
$myArray[-1]
访问倒数第二个元素
$myArray[-2]
选择一个范围
$myArray[2..4] $myArray[-1..-5]
选择多个范围
$myArray[0..2 + 6..8 + -1] $myArray[0..0 + 6..8 + -1]
获得数组中的部分元素组成新数组
$newArray = $oldArray[0..48] + $oldArray[50..99]
修改数组的单个元素
$myArray = 1, 2, 9, 4, 5 $myArray[2] = 3
遍历修改数组的元素
$myArray = 1, 2, 3, 4, 5 for ($i = 0; $i -lt $myArray.Count; $i++) { $myArray[$i] = 9 }
直接添加
$myArray = @() $myArray += "New value"
直接添加
$myArray = $myArray + "New value"
连接多个数组
$firstArray = 1, 2, 3 $secondArray = 4, 5, 6 $mergedArray = $firstArray + $secondArray
注意:以上操作如果是大数组会导致效率问题
直接将元素设置为null
$myArray = 1, 2, 3, 4, 5 $myArray[1] = $null
使用For循环筛选元素
$newArray = for ($i = 0; $i -lt $oldArray.Count; $i++) { if ($i -ne 49) { $oldArray[$i] } }
获得数组中的部分元素组成新数组
$newArray = $oldArray[0..48] + $oldArray[50..99]
使用Array.Copy方法
$newArray = New-Object Object[] ($oldArray.Count - 1) # Before the index #Array.Copy重载1 [Array]::Copy( $oldArray, # Source $newArray, # Destination 49 # Number of elements to copy ) # #Array.Copy重载2 [Array]::Copy( $oldArray, # Source 50, # Copy from index of Source $newArray, # Destination 49, # Copy to index of Destination 50 # Number of elements to copy )
通过Where-Object命令移除不需要的元素
$newArray = $oldArray | Where-Object { $_ -ne 50 }
$pandaArr.count
$pandaArr.IndexOf(666)
使用For-Each进行遍历
$myArray | ForEach-Object { Write-Host $_ }
使用for循环进行遍历
$arr = 1..3 for ($i = 0; $i -le ($arr.length - 1); $i += 1) { Write-Host $i; }
$newArray = 1, 2, 3, 4, 5 $newArray.Clear()
哈希表存储键值对(key/value pairs)
通常使用String或者 numbers作为键
A hashtable is an associative array or an indexed array
Individual elements in the array are created with a unique key
Keys cannot be duplicated within the hashtable
定义空哈希表
$hash = @{}
定义包含成员的哈希表
$hash = @{ ID = 1; Shape = "Square"; Color = "Blue"}
定义有序哈希表(Ordered dictionaries)
$hash = [ordered]@{ ID = 1; Shape = "Square"; Color = "Blue"}
将成员放置在多行,方便阅读代码
注意:多行方式,元素之间没有符号分隔
$hashtable = @{ Key1 = "Value1" Key2 = "Value2" }
$hash["ID"]
也可以使用属性的形式
$hashtable.Key1
数值键也可以直接使用方法的形式
$hashtable = @{1 = 'one'} $hashtable.1 $hashtable[1]
$hash["Updated"] = "Now" ### 获得哈希表的所有键 $hash.keys ### 获得哈希表的所有值 $hash.values ### 添加元素到哈希表
注意:添加前记得检测键是否已经存在,否则重复的键会造成抛出异常
$hash.Add("Created","Now")
或者使用方法的形式添加
$pandaHashTable = @{ "Name"="Panda666" }; $pandaHashTable.Hobby = 'Computer','Girl','CoCo'
还可以直接使用索引式添加
$pandaHashTable = @{ "Name"="Panda666" }; $pandaHashTable['Code'] = 666;
注意:如果Key不存在,不会报错
注意:不可以在遍历循环中移除元素
$hash.Remove("Code")
可以使用折中的方式进行循环删除元素
$pandaHashTable = @{ Name = "Panda666" Code = 666 Hobby = "Computer","PowerShell","Windows","Girl" }; [object[]] $keys = $pandaHashTable.Keys; foreach($key in $keys) { $pandaHashTable.Remove($key); }
$hashtable = @{one = 1; two = 2; three = 3} $hashtable.Clear()
$hash.GetEnumerator()
$pandaHashTable = @{ "Name"="Panda666" }; $pandaHashTable.ContainsKey("Name");
$pandaHashTable = @{ "Name"="Panda666" }; $pandaHashTable.ContainsValue("Panda666");
注意:这种方式的遍历不可以修改哈希表
$pandaHashTable = @{ "Name" = "Panda" "Code" = 666 }; foreach($key in $pandaHashTable.Keys) { Write-Host $pandaHashTable[$key]; }
可以使用折中的方式进行修改哈希表
$hashtable = @{ Key1 = 'Value1' Key2 = 'Value2' } [Object[]]$keys = $hashtable.Keys foreach ($key in $keys) { $hashtable[$key] = "NewValue" }