PowerShell学习笔记[分享]
数组其实在任何语言里都是一个比较头疼的学习对象,在学习PowerShell的空余时间,做了以下简单整理:
1. 在PowerShell中,只要把不同的对象用逗号“,”连接起来,就可以构造出数组对象。
例如:520,'abc',2MB,0xFFFE
520
abc
2097152
65534
上面的小例子输出了4个对象:数值“520”、字符串“abc”、数值“2MB”和十六进制数值“0xFFFE”。
2. 关于数组对象更多的特性:
$array = 1,2,3,4,5
$int = 1
$array.count
5
"$array"
1 2 3 4 5
$int.count
"$int"
1
以上$int是一个整数,而不是数组。
3. PowerShell是基于对象的shell,现在让我们来看看数组究竟是什么对象:
$array.GetType().FullName
System.Object[]
其实Powershell实际操作的对象还是.Net类库中的对象。使用数组时,需要大家记住数组的第一个元素的下标是“0”、数组的最后一个元素下标是数组长度减去1。例如:
$array = 1,2,3
$array.Length
3
$array[0]
1
$array[2]
3
实际上,当数组访问越界时,PowerShell是不会给出任何错误信息的,只会得到一个$null对象,如$array[4] 。
3. 如何向这个数组中添加新的元素呢:
$a = " I ", " am "
$a[0]
I
$a[1]
am
$a[2] = " Lihua "
Array assignment failed because index '2' was out of range.
At line:1 char:4
+ $a[2 <<<< ]=" Lihua "
虽然如此,但PowerShell可以通过$a[0]="we"来修改数组元素值。另外添加则需要:
$a = $a + " Lihua "
$a
I am Lihua
最后补充一下学习PowerShell中的系统cmdlets技巧:
我写了一个批量输出帮助文件,并只输出Examples的例子,希望对你学习有帮助。
"Total:" + $d.Count
$i = 0
$d | ForEach-Object -process{
$i++
"Printing" + $i
$cmdlet = $_.Name
$path = ".\EXAMPLE\"+$cmdlet + ".ps1"
Get-Help -Examples $cmdlet > $path
}
"Successfully"
#test
然后我们打开其中一个文件看一下:
NAME
ForEach-Object
SYNOPSIS
Performs an operation against each of a set of input objects.
-------------------------- EXAMPLE 1 --------------------------
C:\PS>30000,56798,12432 | foreach-object -process {$_/1024}
This command accepts an array of integers, divides each one of them by 1024, and displays the r
esults.
-------------------------- EXAMPLE 2 --------------------------
C:\PS>get-childitem C:\ | foreach-object -process { $_.length / 1024 }
This command retrieves the files and directories in the root of the C: drive and returns and di
splays the size of each of them. The zeroes represent directories where no file size was availa
ble.
-------------------------- EXAMPLE 3 --------------------------
C:\PS>$events = get-eventlog -logname system -newest 1000
$events |
foreach-object -begin {get-date}
-process {out-file -filepath events.txt -append -inputobject $_.message}
-end {get-date}
This command retrieves the 1000 most recent events from the system log and stores them in the $
events variable. It then pipes the events to the ForEach-Object cmdlet. The Begin parameter dis
plays the current date and time. Next, the Process parameter uses the Out-File cmdlet to create
a text file named events.txt and stores the message property of each of the events in that fil
e. Last, the End parameter is used to display the date and time after all of the processing has
completed.
-------------------------- EXAMPLE 4 --------------------------
C:\PS>get-itemproperty -path hkcu:\Network\* |
foreach-object {set-itemproperty -path $_.pspath -name RemotePath
-value $_.RemotePath.ToUpper();}
This command updates a set of registry entries by using the Set-ItemProperty cmdlet. The regist
ry entries specify the UNC path of mapped network drives on the computer. This command changes
the characters in the UNC path to uppercase. In a real scenario, you might need to change the s
erver name or another component of the path.
Because the Set-ItemProperty cmdlet acts on a single property, the ForEach-Object cmdlet is use
d to call Set-ItemProperty for each property (registry entries in this case) being changed. The
name of the registry entries is RemotePath and they are located in HKCU\Network\<mapped drive
letter>. The entries are retrieved by using the Get-ItemProperty cmdlet and piped as input to F
orEach-Object. In the call to Set-ItemProperty within ForEach-Object, the $_ variable holds a r
eference to the current registry entry being processed. The value of the PSPath property is the
registry key containing the current entry. The RemotePath property is of type System.String, w
hich includes the ToUpper method used to change the value of the entry to uppercase.
你会发现这对我们学习陌生的cmdlets非常实用。 由于我的系统是英文的,Powershell也是英文版的,所以例子与解说都是英文的。
另外,如果你需要对自定义的cmdlets作以上的输出,而不需要输出系统的cmdlets,可以做如下改进:
$d = Get-Command -PSSnapin Zivsoft.PowerShell.Cmdlets
"Total:" + $d.Count
$i = 0
$d | ForEach-Object -process{
$i++
"Printing" + $i
$cmdlet = $_.Name
$path = ".\CmdletsUsage\"+$cmdlet + ".ps1"
Get-Help -Examples $cmdlet > $path
}
"Successfully"
执行后,会将系统的过滤掉不输出。
最后,细心人可以看出我的脚本还是有很多漏洞,比如直接用"successfully"判断成功,其实不对的,但我想不到其它好的办法,由于不影响大局,代码没做过多改进。