powershel笔记

Day 1

1
$Psversiontable # 查看版本

powershell cmdlet 遵循 动词-名词 的命令格式,例如:

1
2
get-TimeZone
set-timezone

这里有一点说明,powershel无所谓大小写,作为PS新手,最有用的命令就是:

1
2
3
4
get-help some-command
get-command some-command
get-command some-command -online
get-command some-command -example

从此,基本上可以学习所有的命令了。如果有不会的直接寻找本地或者web文档说明即可。

我们知道ps总是获取对象,当我们想知道更多消息的时候。可以通过管道寻找更多信息

1
ls | get-member

获取到更多信息,了解得到的对象具有什么属性或者函数,是什么类型的等等。搜索command支持通配符,但是有时候类似名字的命令
不一定有效,其实也无所谓,随时可以Google搜索需要的命令。

powershell跟其他语言一样,通过扩展和模块支持更多功能,如果需要寻找某些功能,可以查找:

1
find-module -tag ssh

Day 2

管道,从命令中学习:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 按id排序,可以换为cpu等等
get-process | sort-object id

# 关闭process,管道传过去的也需要是process对象
get-process notepad | stop-process
# 如下则报错
get-service -Name BITS | stop
# stop=process不知道如何处理非process

# 遍历
get-process | foreach-object {$psitem}

# 通常大家会把遍历对象写为,$_是简写对象:
get-process | foreach-object {$_}

获取一个对象,可以有很多展示的方法,例如:

1
get-date | format-table / format-list

默认,显示最重要的信息,如果需要特殊格式,则需要指定。

更多:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# 展示所有数据
get-process notepad | format-list *

# 选择展示特定信息
PS C:\Users\44300> Get-Process *pwsh* | select name, id, CPU

Name Id CPU
---- -- ---
pwsh 7328 8.484375
pwsh 10816 6.203125


PS C:\Users\44300> Get-Process | Where-Object {$_.cpu -gt 70s}

NPM(K) PM(M) WS(M) CPU(s) Id SI ProcessName
------ ----- ----- ------ -- -- -----------
94 265.12 332.06 75.00 11108 3 chrome
56 443.16 213.44 151.95 11812 3 chrome
78 269.08 302.54 100.66 17168 3 chrome


PS C:\Users\44300> ls -file -Recurse | Where-Object {$_.length -gt 500mb}


Directory: C:\Users\44300\Documents

Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 2019/12/7 22:15 527339944 regedit.reg

Directory: C:\Users\44300\Downloads\Programs

Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 2019/12/2 9:04 567449424 VMware-workstation-full-15.5.1-15018445.exe


# 查看文件系统
PS C:\Users\44300> ls -file -Recurse | Measure-Object

Count : 28492
Average :
Sum :
Maximum :
Minimum :
StandardDeviation :
Property :

PS C:\Users\44300> ls -file -Recurse | Where-Object {$_.length -gt 100mb} | Measure-Object

Count : 10
Average :
Sum :
Maximum :
Minimum :
StandardDeviation :
Property :

多用tab键和gcm(get-command)

有趣的-whatif:

1
2
3
4
5
6
PS C:\Users\44300> Get-Process *ware*|Stop-Process -WhatIf
What if: Performing the operation "Stop-Process" on target "vmware-authd (5940)".
What if: Performing the operation "Stop-Process" on target "vmware-hostd (7932)".
What if: Performing the operation "Stop-Process" on target "vmware-tray (596)".
What if: Performing the operation "Stop-Process" on target "vmware-usbarbitrator64 (5956)".
PS C:\Users\44300>

Day 3

使用变量,powershell不是强类型的语言,举个例子:

1
2
3
$num = [int]$num = '1' # 转换为int

$num.tostring() # 转换为string

单引号和双引号也是有区别的,简单来说:

1
2
3
4
5
$foo = 'add: $(1 + 1)'	# output: add: $(1 + 1)

$foo = "add: $(1 + 1)" # output: add: 2

# 二者区别在于,类似单引号跟python中的raw字符串一致,不会对内部进行变量计算或者替换

一个简单例子:

1
2
3
4
5
$path = Read-Host -Prompt '输入路径,扫描top 10的最大文件'
$rawFiles = ls -file -Path $path -Recurse
$top10File = $rawFiles | Sort-Object -Top 10 Length -Descending
Write-Host 'top 10 大文件如下:'
write-host $top10File

接着,熟悉一下powershell的逻辑格式:

1
2
3
4
5
6
7
8
9
10

if (condition) {
# some
}
elseif (condition) {
# some
}
else {
# ok
}

上面的扫描大文件的例子有明显的bug,其中之一便是未对输入值进行检查。

1
2
3
4
5
6
7
8
9
10
11
$path = Read-Host -Prompt '输入路径,扫描top 10的最大文件'
$existPath = Test-Path $path
if ($existPath -eq $true) {
$rawFiles = ls -file -Path $path -Recurse
$top10File = $rawFiles | Sort-Object -Top 10 Length -Descending
Write-Host 'top 10 大文件如下:'
$top10File
}
elseif ($existPath -eq $false) {
Write-Host "$path is a verified path."
}

当然,还支持循环和switch等等

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

[int]$value = Read-Host "Enter a number"
switch ($value) {
1 {
Write-Host 'type in: 1'
}
Default {
Write-Host "type in $value"
}
}

for ($i = 0; $i -lt 10; $i++) {
Write-Host $i -ForegroundColor $($i % 7) # $(some code)
}

$path = 'C:\Users\44300'
[Int64]$totalSize = 0
$fileInfo = ls $path -file -Recurse

foreach ($file in $fileInfo) {
$totalSize += $file.Length
}

Write-Host "The total size of file in $path is $($totalSize / 1GB) GB"

do {
$path = Read-Host 'type in a path'
if (Test-Path $path){
Write-Host 'ok'
}
else {
Write-Host 'nonono'
}
} while ((Test-Path $path) -eq $true) # while是执行循环条件

$path = $true
while ($path -eq $true) {
[int]$in = Read-Host 'input 1'
if ($in -ne 1) {
$path = $false
Write-Host 'exit'
}
else {
Write-Host "input is $in"
}
}

$path = Read-Host 'type in your path'
$folderCount = 0
$fileCount = 0
$fileTotalLength = 0

$rawFileInfo = Get-ChildItem $path -Recurse

foreach ($item in $rawFileInfo) {
if ($item.PSIsContainer) {
# this is a folder
$folderCount++
}
else {
# this is a file, because it is not a PSIsContainer
$fileCount++
$fileTotalLength++
}
}

Write-Host "path is $path"
Write-Host "total folder is $folderCount"
Write-Host "total files $fileCount"
Write-Host "total size of files is $($fileTotalLength / 1Gb) GB"

Day4

今天学习一下powershell Input和Ouput,先从一个例子开始:
1
2
3
4
5
6
7
8
9
# 从网络获取数据

$webRequest = Invoke-WebRequest 'http://jandan.net/api/post/dot'
$rawJson = $webRequest.Content
$rawJson
$objJson = $rawJson | ConvertFrom-Json
$objJson
$admin_domain = $objJson.data.admin_domain
$admin_domain
似乎对网页处理得很不错的样子。看样子很方便从后端服务获取API的数据,再构建本地的数据集,或者做其他操作。
继续,从终端本地获取输入:
1
[int]$topSum = read-host -prompt "Enter the top sum of the folder"