上午考完了马原和英语,接下来得抓紧学数据结构和数字逻辑了。
powershell作为windows系统默认shell之一,能运行cmd绝大部分命令,还能兼容linux一些命令,并且不光高效率地调用系统程序,还可以通过.net平台或者其他插件进行互联网和浏览器层面的操作,可以说是名副其实的具有很强的power。
ai放入powershell当插件的power
自定义命令
查看powershell的默认路径:
echo $profile
可能不止一条,我选择了这一条
C:\Program Files\WindowsPowerShell
在此目录下创建一个新文件夹,新建一个包含自定义命令的psm1文件放入文件夹下。
(在此路径下没有办法直接新建文件,所以要在外面创建了移进去)
文件名大概没有要求,或者直接命名为函数名也省去问题。
自定义函数
psm1文件中写如下内容
function my-func {
# 这里是函数体
}
这样可以直接在终端使用my-func
命令调用自定义函数,当然名字是自定义的。
自定义函数导出可用模板
Export-ModuleMember -Function <functionName> # 导出函数
它会对函数添加限制,使每次使用都需要导入才可访问。
不添加默认是全局可用。
powershell语法
变量
$var = "value"
内置变量
$PSScriptRoot # 当前脚本所在目录
$PSSenderInfo # 调用命令的用户信息
$PSBoundParameters # 调用命令的参数
$PSCommandPath # 当前脚本的完整路径
$PSScriptRoot # 当前脚本所在目录
$MyInvocation # 当前命令的详细信息
$HOME# 当前用户的主目录路径
$PWD# 当前工作目录。
$PSVersionTable# 包含有关当前PowerShell会话版本的信息。
# 对版本这个词要有敏感性,版本意味着变化,可能是更新,又或者是修补
$IsWindows # 判断当前系统是否为windows
$IsLinux # 判断当前系统是否为linux
$IsMacOS # 判断当前系统是否为macos
自动变量
$_ # 上一个命令的输出
$args # 传递给脚本或函数的参数
$input # 输入流
$lastexitcode # 上一个命令的退出代码
$Error # 存储错误信息
$true # 布尔值 true
$false # 布尔值 false
$null # 空值
注释
# 单行注释
<#
多行注释
#>
打印
直接输出结果:
"Hello, world!"# 输出字符串
@("apple", "banana", "orange")#·数组·
@{key1 = "value1"; key2 = "value2"}#·哈希表·
# 以上可以直接输出在终端
其他打印方式:
Write-Host "Hello, world!" # 输出字符串
Write-Output "Hello, world!" # 输出字符串
Write-Warning "Warning message" # 输出警告信息
Write-Error "Error message" # 输出错误信息
Write-Verbose "Verbose message" # 输出详细信息
Write-Debug "Debug message" # 输出调试信息
# 或者换为echo
条件判断
# if语句
if ($a -gt 0) {# -gt 大于
"a is greater than 0"
} elseif ($a -lt 0) {# -lt 小于
"a is less than 0"
} else {
"a is 0"
}
# switch语句
switch ($a) {
{$_ -gt 0} {"a is greater than 0"}
{$_ -lt 0} {"a is less than 0"}
Default {"a is 0"}
}
switch ($a) {
"apple" {
"这是一个苹果"
}
"banana" {
"这是一个香蕉"
}
"orange" {
"这是一个橙子"
}
default {
"未知水果"
}
}
运算符
# 算术运算符
+ # 加法
- # 减法
* # 乘法
/ # 除法
% # 取模
++ # 自增
-- # 自减
# 赋值运算符
= # 赋值
+= # 加法赋值
-= # 减法赋值
*= # 乘法赋值
/= # 除法赋值
%= # 取模赋值
# 比较运算符
-eq # 等于
-ne # 不等于
-gt # 大于
-lt # 小于
-ge # 大于等于
-le # 小于等于
# 逻辑运算符
-and # 与
-or # 或
-not # 非
字符串操作
# 字符串拼接
"Hello, " + "world!"
# 字符串重复
"Hello" * 3
# 字符串长度
"Hello, world!".Length
# 字符串查找
"Hello, world!".IndexOf("l")
# 字符串替换
"Hello, world!".Replace("l", "L")
# 字符串分割
"Hello, world!".Split(",")
# 字符串转换
"123".ToInt() # 转换为整数
"123".ToFloat() # 转换为浮点数
"123".ToString() # 转换为字符串
# 转化输入为字符串
[string]$input
$input.ToString()
$input.Trim() # 去除前后空格
$input.ToLower() # 转化为小写
$input.ToUpper() # 转化为大写
$input.Split(",") # 按逗号分割
$input.Length # 字符串长度
$input.IndexOf("l") # 字符串查找
$input.Replace("l", "L") # 字符串替换
$input.Split(",") # 按逗号分割
$input.ToInt() # 转换为整数
$input.ToFloat() # 转换为浮点数
$input.ToString() # 转换为字符串
数组操作
# 创建数组
$array = @("apple", "banana", "orange")
# 数组长度
$array.Length
# 数组索引
$array[0]
# 数组添加元素
$array += "grape"
# 数组删除元素
$array = $array[0..1]
# 数组合并
$array1 + $array2
# 数组排序
$array | Sort-Object
# 数组倒序排序
$array | Sort-Object -Descending
# 数组查找元素
$array -contains "banana"
# 数组遍历
foreach ($item in $array) {
# 这里是循环体
}
# 数组元素计数
$array.Count
# 数组元素唯一化
$array | Select-Object -Unique
# 数组元素分组
$array | Group-Object
# 数组元素分组并求和
$array | Group-Object | ForEach-Object { $_.Name + ": " + $_.Count }
# 数组元素分组并求最大值
$array | Group-Object | ForEach-Object { $_.Name + ": " + ($_.Group | Measure-Object -Maximum).Maximum }
# 数组元素分组并求最小值
$array | Group-Object | ForEach-Object { $_.Name + ": " + ($_.Group | Measure-Object -Minimum).Minimum }
# 数组元素分组并求平均值
$array | Group-Object | ForEach-Object { $_.Name + ": " + ($_.Group | Measure-Object -Average).Average }
# 数组元素分组并求总和
$array | Group-Object | ForEach-Object { $_.Name + ": " + ($_.Group | Measure-Object -Sum).Sum }
哈希表操作
# 创建哈希表
$hashTable = @{key1 = "value1"; key2 = "value2"}
# 哈希表长度
$hashTable.Count
# 哈希表索引
$hashTable["key1"]
# 哈希表添加元素
$hashTable.Add("key3", "value3")
# 哈希表删除元素
$hashTable.Remove("key2")
# 哈希表遍历
foreach ($key in $hashTable.Keys) {
$value = $hashTable[$key]
# 这里是循环体
}
# 哈希表元素计数
$hashTable.Count
# 哈希表元素唯一化
$hashTable.Values | Select-Object -Unique
# 哈希表元素分组
$hashTable | Group-Object -Property Value
# 哈希表元素分组并求和
$hashTable | Group-Object -Property Value | ForEach-Object { $_.Name + ": " + $_.Count }
# 哈希表元素分组并求最大值
$hashTable | Group-Object -Property Value | ForEach-Object { $_.Name + ": " + ($_.Group | Measure-Object -Maximum).Maximum }
# 哈希表元素分组并求最小值
$hashTable | Group-Object -Property Value | ForEach-Object { $_.Name + ": " + ($_.Group | Measure-Object -Minimum).Minimum }
# 哈希表元素分组并求平均值
$hashTable | Group-Object -Property Value | ForEach-Object { $_.Name + ": " + ($_.Group | Measure-Object -Average).Average }
模糊匹配
# 模糊匹配字符串
"hello world" -like "*world*"
# 模糊匹配数组
$array | Where-Object {$_ -like "*world*"}
# 模糊匹配哈希表
$hashTable | Where-Object {$_.Value -like "*value*"}
# 模糊匹配路径
Get-ChildItem c:\temp\*.txt
# 模糊匹配文件名
Get-ChildItem *.txt
# 模糊匹配文件内容
Get-Content *.txt | Select-String "hello"
循环
foreach ($item in $array) {
# 这里是循环体
}
for ($i = 0; $i -lt 10; $i++) {
# 这里是循环体
}
1..10 | foreach {
# 这里是循环体
}
筛选
# 筛选数组中长度大于5的元素
$array | Where-Object {$_.Length -gt 5}
# 筛选哈希表中 value 为 "value1" 的键值对
$hashTable | Where-Object {$_.Value -eq "value1"}
# 筛选数组中偶数元素
1..10 | Where-Object {$_ % 2 -eq 0}
# 筛选数组中大于5小于8的元素
1..10 | Where-Object {$_ -gt 5} | Where-Object {$_ -lt 8}
# 循环数组并乘以2
1..10 | ForEach-Object {$_ * 2}
# 筛选数组中大于10的元素并输出
1..20 | Where-Object {$_ -gt 10}
# 对数组中的每个元素进行平方处理
1..10 | ForEach-Object {$_ * $_}
# 筛选字符数组中为字母 'A' 的元素
$arrayOfChars | Where-Object {$_ -eq 'A'}
# 过滤出进程名以 "Powershell" 开头的所有进程
Get-Process | Where-Object {$_ -like "Powershell*"}
进程
# 获取所有进程
Get-Process
# 根据名称获取进程
Get-Process -Name "powershell"
# 获取特定进程的属性
Get-Process -Id 1234 | Select-Object Name, Id, CPU, Memory
# 停止进程
Stop-Process -Name "notepad" -Force # 强制停止
# 启动进程
Start-Process "notepad.exe"
# 管道获取进程信息并筛选
Get-Process | Where-Object { $_.CPU -gt 100 } | Select-Object Name, Id, CPU
# 获取进程的详细信息
Get-WmiObject Win32_Process | Where-Object { $_.Name -eq "notepad.exe" }
# 列出所有服务
Get-Service | Where-Object { $_.Status -eq "Running" }
管道
Get-Process | Where-Object {$_.Name -eq "powershell"} | Select-Object Name, Id
重定向
这个和linux较相似
# 重定向输出
echo 1 > output.txt
# 重定向错误输出
echo 1 2>&1 > output.txt
# 重定向输入
Get-Content input.txt > output.txt
# 重定向输入并处理
Get-Content input.txt | foreach {
# 这里是循环体
}
脚本
# 脚本模块的基本结构
<# 这前面都是模块的注释
.SYNOPSIS
Short description # 简要描述
.DESCRIPTION
Long description # 详细描述
.EXAMPLE
An example # 示例
.INPUTS
Inputs (if any) # 输入
.OUTPUTS
Outputs (if any)# 输出
.NOTES
General notes # 通用说明
.COMPONENT
Component (if any) # 组件
.ROLE
Role (if any) # 角色
.FUNCTIONALITY
Functionality (if any) # 功能
#>
# 定义函数
function my-func {
# 这里是函数体
# 接收参数并传递给函数
param(
[Parameter(Mandatory=$true)]
[string]$Param1,
[Parameter(Mandatory=$true)]
[string]$Param2
)
}# 一个脚本中可以定义多个函数
# 导出函数
Export-ModuleMember -Function my-func
# 调用模块
Import-Module "path\to\module.psm1"
# 调用模块中的函数
my-func -Param1 "value1" -Param2 "value2"
调用外部命令
## 调用外部命令
Start-Process "notepad.exe" #可简化为notepad
## 调用powershell脚本
. "path\to\script.ps1"
## 调用函数
my-func
## 调用模块
Import-Module "path\to\module.psm1"
## 调用环境变量
$env:PATH
## 调用历史命令
!10
## 调用历史命令参数
!!
## 调用历史命令参数和值并执行并输出
!10 * | foreach {
# 这里是循环体
} | Out-Host
# 调用内置命令
Get-Process # 直接调用并获取当前进程(所有)
# 查找特定命令的别名
Get-Alias -Name gci
# 调用 PowerShell 命令别名
gci # 别名 'Get-ChildItem'
补一个错误返回
错误返回
# 错误返回
$lastexitcode # 最后一个命令的退出代码
if ($lastexitcode -ne 0) {
# 这里是错误处理
}
$error[0] # 最后一个错误信息
catch {
# 这里是错误处理
}
catch [System.Exception] {
# 未被捕捉的所有类型的异常
}
System.IO.DirectoryNotFoundException # 目录不存在
System.IO.FileNotFoundException # 文件不存在
System.Management.Automation.CommandNotFoundException # 命令不存在
System.Management.Automation.ParameterBindingException # 参数绑定错误
System.Management.Automation.RuntimeException # 运行时错误
System.Management.Automation.PipelineStoppedException # 管道停止错误
System.Management.Automation.PipelineClosedException # 管道关闭错误
System.Management.Automation.ProviderNotFoundException # 未找到提供程序
System.Management.Automation.DriveNotFoundException # 未找到驱动器
System.Management.Automation.ItemNotFoundException # 未找到项目
System.Management.Automation.InvalidOperationException # 无效操作
System.Management.Automation.SessionStateUnauthorizedAccessException # 无权访问会话状态
System.Management.Automation.SessionStateException # 会话状态错误
System.Management.Automation.PSArgumentException # 参数错误
System.Management.Automation.PSArgumentNullException # 参数为空错误
System.Management.Automation.PSArgumentOutOfRangeException # 参数超出范围错误
可以看出shell语言之间功能趋向基本相似,只是语法不同。
命令行语言是最接近人类自然语言的程序语言了吧。代价就是封装函数过多,想要完全掌握的学习成本高,也许功能也局限于系统操作,不适于拓展。
可能因为本身就不是为了编写程序服务的。
但是很有power。
此方悬停