PowerShell
本文大量参考: 官方教程 zhuanlan powershell
正文
快捷键
先来了解一下功能键和快捷键 ALT+F7
清除命令的历史记录 PgUp PgDn
显示当前会话的第一个命令和最后一个命令 Enter
执行当前命令 End
将光标移至当前命令的末尾 Del
从右开始删除输入的命令字符 Esc
清空当前命令行 F2
自动补充历史命令至指定字符 (例如历史记录中存在Get-Process,按F2,提示"Enter char to copy up to",键入 S,自动补齐命令:Get-Proce) F4
删除命令行至光标右边指定字符处 F7
对话框显示命令行历史记录 F8
检索包含指定字符的命令行历史记录 F9
根据命令行的历史记录编号选择命令,历史记录编号可以通过F7查看 ←/→
左右移动光标↑/↓ 切换命令行的历史记录 Home
光标移至命令行最左端 Backspace
从右删除命令行字符 Ctrl+C
取消正在执行的命令 Ctrl+←/→
在单词之间移动光标 Ctrl+Home
删除光标最左端的所有字符 Tab
自动补齐命令或者文件名
前置知识
换行符
`n
什么是Cmdlets
- 可执行命令/PowerShell中的函数
- [<动词>-<名词>] [-<参数> <值>] 例如:
-Get-Content -Path 'C:'
详细动词列表
常用的
意思 | 动词 | 意思 |动词 | 意思 |动词 ------- | ------- | ------- | ------- | ------- | ------- 搜索 | Search | 得到 | Get | 打开 | Open | 添加 | Add 选择 | Select | 隐藏 | Hide | 优化 | Optimize | 清除 | Clear 设置 | Set | 加入 | Join | 弹出 | Pop | 关闭 | Close 显示 | Show | 锁 | Lock | 推动 | Push | 复制 | Copy 跳过 | Skip | 移动 | Move | 重做 | Redo | 进入 | Enter 分裂 | Split | 新的 | New | 删除 | Remove | 出口 | Exit 解锁 | Unlock | 开关 | Switch | 重命名 | Rename | 查找 | Find 监视 | Watch | 撤消 | Undo | 重置 | Reset | 格式 | Format
什么是PoweShell Pipeline
就是管道|
在自己的脚本里实现
Begin
, Process
, End
是管道语句块
get-process | select -last 5 | & {
begin {
"开始准备环境"
}
process
{
$_.Name
}
end {
"开始清理环境"
}
}
#输出结果为:
开始准备环境
wlcommsvc
WLIDSVC
WLIDSVCM
WmiPrvSE
XDict
开始清理环境
在脚本上使用管道
低速顺序模式
如果你在脚本中使用管道,脚本收集上一个语句的执行结果,默认保存在$input
自动变量中。但是直到上一条语句完全执行完,管道脚本才会执行。所以实际就是传递一个对象的数组进来,获取之后通过foreach
遍历数组
pipeline.ps1
# 效果,如果后缀是exe则输出红色的字体,否则是绿色
foreach ($element in $input)
{
if($element.Extension -eq ".exe")
{
Write-Host -fore "red" $element.Name
}
else
{
Write-Host -fore "Green" $element.Name
}
}
执行脚本:
PS E:> ls $env:windir | .pipeline.ps1
注:$env:windir
:从环境变量中获取系统目录 (绝对路径) 这个$env
就是环境变量的意思,例如$env:Path
就是返回这个Path的值
如果这样执行:
PS E:> ls $env:windir -Recurse | .pipeline.ps1
控制台会被冻结,因为存储的中间结果在玩命的吃内存(没有释放内存)。这个也是低速顺序模式的缺点。
高速流模式
在Powershell脚本的处理中,绝大多数情况下遇到的都是集合,一旦上一条命令产生一个中间结果,下一条命令就对这个中间结果及时处理,及时释放资源。这样可以节省内存,也减少了用户的等待时间。在处理大量数据时,尤其值得推荐。高速流模式的管道定义包括三部分:begin,process,end。上面的描述中提到了中间结果,中间结果保存在$_
自动化变量中。
begin
{
Write-Host "管道脚本环境初始化"
}
process
{
$ele=$_
if($_.Extension -ne "")
{
switch($_.Extension.tolower())
{
".ps1" {"脚本文件:"+ $ele.name}
".txt" {"文本文件:"+ $ele.Name}
".gz" {"压缩文件:"+ $ele.Name}
}
}
}
end
{
Write-Host "管道脚本环境恢复"
}
执行脚本文件:
PS E:> ls | .pipeline.ps1
管道脚本环境初始化
文本文件:a.txt
压缩文件:Metrol.tar.gz
脚本文件:MyScript.ps1
脚本文件:pipeline.ps1
脚本文件:PSLib.ps1
管道脚本环境恢复
执行策略限制
PowerShell 一般初始化情况下都会禁止脚本执行。脚本能否执行取决于PowerShell的执行策略。 只有管理员才有权限更改这个策略。非管理员会报错。 查看脚本执行策略,可以通过在 PowerShell 控制台直接输入: Get-ExecutionPolicy 更改脚本执行策略,可以管理员启动PowerShell,在控制台输入: Set-ExecutionPolicy <策略>
如果要使用脚本功能又要兼顾安全性,我们就选择RemoteSigned
即在以管理员身份允许的 PowerShell 输入 Set-ExecutionPolicy RemoteSigned
常用工具
也可以用PowerShell打开一些系统工具 notepad:记事本 calc:计算器 mspaint:画图
帮助系统
查找命令(通配符的使用): gal te :就可以找到后面是te的命令 同理:gal a :就可以找到a开头的命令 gal gservice gal 是get-alias的简称
get-help 命令 -online
可以自动打开一个外部文档 get-help 命令 -ShowWindow
可以自动打开一个本地文档 例如: Get-Help Write-Output -ShowWindow
get-help *关键字*
也可以用来查找命令
cmdlet get-alias:获取别名,就是把cmd之前的类似cd
,cls
这类命令与 cmdlet
命令对应
常用命令
常用的cmdlet
输入&输出
输入输出函数
PowerShell提供了 Read-Host 命令,可以接收返回用户在控制台输入的字符
$name=read-host "请输入你的名字"
#会把提示信息打印到PS控制台,也可以不写提示信息
<#执行+输入 结果:
请输入你的名字: Nougat
#>
$name
=>Nougat
有两种输出命令 Write-Host和Write-Output 若输出字符串不包含空白字符可以不加引号Write-Host当需要展示一个特定信息,比如使用其他颜色来吸引人们的注意力的时候,可使用 Write-Host 命令 Write-Host 和其他Cmdlets一样使用管道,但是它不放置任何数据道管道中。反而会直接写到宿主应用程序的界面。正如此,可以使用-ForegroundColor 和 -BackgroundColor 参数将前景和背景设置为其他颜色:
write-host "啊哈" -ForegroundColor White -BackgroundColor Red
=>啊哈
注:不是每个使用PowerShell的应用程序都支持其他颜色,也并不是每个应用程序都支持所有颜色。 该输出方法不适用于常规的输出结果,因为 Write-Host 命令输出到屏幕的任何东西都无法被捕捉。若执行远程命令或无人值守命令(纯自动化), Write-Host 可能不会按照你的预期工作。因此,此命令仅仅用于与人进行直接交互。
输出到文件里
$str|Out-File -FilePath .yxh.txt -Encoding utf8
ForEach-Object
迭代对象 对输入对象集合中的每个项目执行操作 $_表示当前处理对象 常用参数:-Begin ,-Process, -End
# 例1:循环打印字符
'You','Me'| ForEach-Object{"Say $_"}
=>Say You
Say Me
# 例2:把日志信息输出到Events.txt
# 这里用了-Begin ,-Process, -End参数,-Begin和-End分别输出开头时间,完成时间(-Begin和-End只执行一次)
$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}
Where-Object
筛选对象
'You','Me'| Where-Object{$_ -match 'u'}
=> You
Select-Object
选择对象/属性 常用参数: -First 选择的数量(从开头开始数) -Last 选择的数量(从结尾开始数) -Skip 跳过的数量 -SkipLast 从结尾开始跳过的数量 -Property 作用是输出对象的属性值,输出的为属性名加属性值(输入对象的属性名字,可以是数组用,
分隔) -Unique 当多个对象的属性值相同时只处理一个 -ExpandProperty 只输出属性值
# -Property 输出的为属性名加属性值
Get-ComputerInfo | Select-Object -Property OsName
=>OsName
------
Microsoft Windows 10 专业版
# -ExpandProperty 只输出属性值
Get-ComputerInfo | Select-Object -ExpandProperty OsName
=> Microsoft Windows 10 专业版
# -First 2 选择前2个对象
Get-ChildItem | Select-Object -First 2
=>
目录: C:UsersalsritterDesktoptmp
Mode LastWriteTime Length Name
---- ------------- ------ ----
da---- 2020/4/18 15:03 MarkDown文本
-a---- 2020/4/19 0:50 176272 Events.txt
-Replace
搜索或替换字符串中的文本 支持正则表达式
'i like tea' -Replace 'tea','coffee'
=> i like coffee
'i like tea' -Replace 's','_'
=> i_like_tea
-Join
连接字符串 支持插入分隔符
-join('a','b','c')
=>abc
# 用.做连接
'127','a','b','c' -join '.'
=> 127.0.0.1
Out-File
输出到指定目录 例:把所有的md文件传到一个文件上的命令
Get-ChildItem *.md -Recurse|Get-Content -Encoding UTF8 |Out-File ./tep.txt -Encoding UTF8
-whatif
可以告诉用户这个命令执行后会发生什么
get-module
查看当前加载的模块 -ListAvailable
:查看可用模块
get-process
查看进程
Get-Member
获取对象的属性和方法,对象 使用例:Get-Service | Get-Member
Get-Member
简称gm
语法
PowerShell变量名也对大小写不敏感
- 行注释:
#
- 块注释:
<#
和#>
代码块
PowerShell 是一种块结构的语言,这些块用 { 和 } 来界定,代码块可以包含任意多条语句
{
<#代码行1#>
<#代码行2#>
{
<#代码行3#>
<#代码行4#>
}
# 每条语句如果在一行则以`;`分隔开
<#代码行5#>;<#代码行6#>;
}
PS E:> @'
>> Get-Date
>> $Env:CommonProgramFiles
>> #Script End
>> "files count"
>> (ls).Count
>> #Script Really End
>>
>> '@ > myscript.ps1
param(
# 这里定义变量
)
Begin{
# 开始前操作,可以省略(只执行一次)
}
Process{
# 这里执行主要的操作
}
End{
# 结束操作,可以省略(只执行一次)
}
# 创建一个Learn1.ps1,里面输入
Process{
# 这里执行主要的操作
$_
}
# 控制台输入
PS C:UsersalsritterDesktoptmp> "hello","Shell"| .Learn1.ps1
# 输出为
hello
Shell
数据类型
变量
运行时数据的存储 计算结果,字符串等
PowerShell是动态类型
$<变量名> = <值>
#例如 $surname = "john"
# $length = 32
预定义变量
$null 空值 $true 真 $false 假 $_ 当前处理的元素 $Home 用户的主目录 $? 前一命令执行状态,成功(Ture) 或者 失败(False)
删除变量
如果不想继续使用自定义的变量,可以使用del variable:
变量名的方法删除变量,注意此处无$
符号
$a=0
$a -eq $null
False
del variable:a
$a -eq $null
True
静态类型
一般对 PowerShell 变量重新赋值时,变量类型会自动改变,这是动态语言的特点; 而 PowerShell 的亲兄弟C#是静态强类型的,所以 PowerShell 也可以使用静态强类型,静态类型语言带来的严谨性能避免不必要的错误。 可以在变量前添加类型限定符使该变量变为静态类型,可以确保变量的类型不会随着赋值而改变
[int]$num=123 #正确
[int]$num=ls <#错误
无法将“System.Object[]”类型的“System.Object[]”值转换为“System.Int32”类型。
所在位置 行:1 字符: 1
+ [int]$num=ls
+ ~~~~~~~~~~~~
+ CategoryInfo : MetadataError: (:) [], ArgumentTransformationMetadataException
+ FullyQualifiedErrorId : RuntimeException
#>
数组
创建 --> @(<元素>,<元素>,<元素>,...)
索引 --> <数组>[<索引>]
# 例如:
$temp = @(<1>,<"元素">,<"元素">)
$temp[0]
#因为是动态类型,所以数组里面可以是任意类型
哈希表
创建 --> @{<键>=<值>;...}
索引 --> <哈希表>[<键>]
枚举
例:
enum VersionType{
SoftwareVersion = 1
HardwareVersion = 2
}
# 使用
[VersionType]::SoftwareVersion
运算符
逻辑运算符
!
不等于 -not
非 -and
且 -or
或
比较运算符
Powershell 中的比较运算符 -eq
:等于 -ne
:不等于 -gt
:大于 -ge
:大于等于 -lt
:小于 -le
:小于等于 -contains
:包含 -notcontains
:不包含
调用运算符
&
可用于调用脚本块或者命令/函数的名称 用法如下:
$a = { Get-Process | Select -First 2} #获取处理器信息排名前二的两条记录
&$a
.
可用于方法调用 用法如下:
$a = "这是字符串"
$a.substring(0,3)
::
用于静态方法调用
用法如下:
[DateTime]::IsLeapYear(2008)
结果:True
[DateTime]::Now #返回当前时间
字符串运算符
+
连接两个字符串 *
按指定次数重复字符串 -f
设置字符串格式 -replace
替换运算符 用法:"abcd" -replace "bc","TEST"
返回结果:aTESTd -match
正则表达式匹配 -like
通配符匹配
流程控制
- if-else分支
If(<条件>){
<语句>
}
ElseIf(<条件>){
<语句>
}
Else{
<语句>
}
- switch分支
Switch(<条件>){
<测试值>{<语句>;break}
...
Default{<语句>}
}
循环
也支持break
,continue
For循环
For(<开始值>;<循环条件>;<迭代步骤>){
<语句>
}
# 例子
$sum=0
for($i=1;$i -le 100;$i++)
{
$sum+=$i
}
$sum
ForEach(<元素> in <集合> ){
<语句>
}
# 例:
# 打印出windows目录下大于1mb的文件名
foreach($file in dir c:windows)
{
if($file.Length -gt 1mb)
{
$File.Name
}
}
While循环
While(<循环条件>){
<语句>
}
Do{
<语句>
}While(<循环条件>)
函数
函数是自定义的 Powershell 代码,有三个原则: 简短:函数名简短,并且显而易见。 聚合:函数可以完成多个操作。 * 封装和扩展:将一批 Powershell 语句进行封装,实现全新的功能需求。 函数的结构由三部分组成:函数名,参数,函数体
function FuncName(args[]) #括号可省略
{
<#代码段#>
}
$args 万能参数
给一个函数定义参数最简单的是使用$args
这个内置的参数。它可以识别任意个参数。尤其适用那些参数可有可无的函数。
function sayHello
{
if($args.Count -eq 0)
{
"No argument!"
}
else
{
$args | foreach {"Hello,$($_)"}
}
}
#无参调用
sayhello
#输出
No argument!
#一参调用
sayhello "World!" #也可以写成sayhello("World!")
#输出
Hello,World!
#多参数调用
$str="it's me."
sayhello 123 "aha" $str #如果字符串不包含空白字符(比如空格),引号可以不写,参数之间用空格隔开
<#输出
Hello,123
Hello,aha
Hello,it's me.
#>
$arg
是一个数组,可以用它很方便的写出求和函数
function Add
{
$sum=0
$args | foreach {$sum=$sum+$_}
$sum
}
Add 10 7 3 100
#120
使用固定参数
function StringContact($str1,$str2)
{
return $str1+$str2
}
<!-- @import "[TOC]" {cmd="toc" depthFrom=1 depthTo=6 orderedList=false} -->
StringContact LN P
#StringContact -str1 word -str2 press
#StringContact("word","press")
LNP
wordpress
- 给参数定义默认值
function stringContact($str1="LN",$str2="P")
{
return $str1+$str2
}
stringContact
LNP
面向对象
完全访问.Net框架
创建对象
-New-Object <类型名><构造函数-参数>
# 例
$version = New-Object System.Version
# 创建时添加构造函数
$version = New-Object System.Version 3,6
访问态的静态元素
- 访问类通过
[<类型名>]
- 类型转换 例如:
[System.Version] "1.0.3.4"
-类方法,枚举,... -例如:
[System.Version]::New()
[System.ConsoleColor]::Red
创建类
# 语法
class <类名>{
<hidden|static>
[<类型名>]$<属性名>
<hidden|static>
<构造函数名>(<参数>,..){
...
}
<hidden|static>
[<返回类型>]<方法名>(<参数>,..){
...
}
}
# 例如
class MyVersion{
[Int]$Major
[Int]$Minor
[Int]$Build
[Int]$Rev
MyVersion(){
$this.Major,$this.Minor,$this.Build,$this.Rev = 0
}
MyVersion($Major,$Minor,$Build,$Rev){
$this.Major = $Major
$this.Minor = $Minor
$this.Build = $Build
$this.Rev = $Rev
}
[String]ToString(){
return ($this.Major,$this.Minor,$this.Build,$this.Rev) -join "."
}
[System.Version]Convert(){
return [System.Version]$this.ToString()
}
}
# 使用
$MyVersionA = New-Object MyVersion
$MyVersionB = New-Object MyVersion 1,2,3,4
$MyVersionA.Minor
$MyVersionB.ToString()
自定义形参输入
[CmdletBinding()] :它的主要功能是让PowerShell脚本或者函数能够有cmdlet样式的参数绑定功能。 一般放在PowerShell的脚本或者函数中的第一行
使用例
[CmdletBinding()]
# 这个正则表达式检查输入是否是由三个.分隔的数字组成
Param Block(
[validatePattern('^(d+.)(3}d+$)')]
[Parameter(Mandatory = $true)]
[String]
$VersionString
)
参数配置 [Parameter()]
属性 [<Type>]
期望的类型 $<Name>
参数名
// 例
[Parameter(Position = 0, Mandatory = true)]
public string UserName
{
get { return userName; }
set { userName = value; }
}
private string userName;
# Mandatory 设定方法的参数是否是必须的
# $false 可选的
# $true 必须的
[Parameter(Mandatory = <$false|$true>)]
# 参数验证
[validateSet(<元素>,<元素>,...)]
[validateLength(<最小值>,<最大值>)]
[validateRange(<最小值>,<最大值>)]
[validateScript({<表达式>})]
[validatePattern({<正则表达式>})]
模块
PowerShell中包括两种模块——脚本模块和二进制模块 脚本模块:它完全由PowerShell语法和环境编写,不需要切换到其他编译语言或者开发环境。
通过get-module
可以查看模块里面的Function 本质这个模块就是一个之前写好的Function,调用时就像调用普通的Cmdlet那样
创建一个模块
拓展名为psm1
待更新...
导入模块
待更新...