[TOC]
描述: 当我第一次开始学习 PowerShell 时,如果无法使用 PowerShell 单行命令完成任务我会回到 GUI 找寻帮助。然后着时间的推移,我逐渐掌握了编写脚本、函数和模块的技能。
描述: Powershell调用入口的优先级(由上到下):
别名:控制台首先会寻找输入是否为一个别名,如果是执行别名所指的命令。因此我们可以通过别名覆盖任意powershell命令,因为别名的优先级最高。函数:如果没有找到别名会继续寻找函数,函数类似别名,只不过它包含了更多的powershell命令。因此可以自定义函数扩充cmdlet 把常用的参数给固化进去。命令:如果没有找到函数,控制台会继续寻找命令,即cmdlet,powershell的内部命令。脚本:没有找到命令,继续寻找扩展名为“.ps1”的Powershell脚本。文件:没有找到脚本,会继续寻找文件,如果没有可用的文件,控制台会抛出异常。Alias > Function > Command > Script > File
示例演示:
# -1.符号使用对比 PS C:UsersWeiyiGeek> $a=8; $b='$a is 8'; $b $a is 8 PS C:UsersWeiyiGeek> $a=8; $b="$a is 8"; $b 8 is 8 PS C:UsersWeiyiGeek> $a=8; $b="`$a is 8"; $b $a is 8 PS C:UsersWeiyiGeek> $json = [String]@" >> { >> "test": 'json', >> "name": "WeiyiGeek", >> "age": 1024 >> } >> "@ PS C:UsersWeiyiGeek> $json { "test": 'json', "name": "WeiyiGeek", "age": 1024 } # -2.转义字符进行命令执行换行使用以及字符串输出换行 PS C:UsersWeiyiGeek> Get-WmiObject -Class win32_bios ` | select serialnumber # serialnumber # ------------ # 8QVY862 "This is `nnewLine" # This is # newLine
Tips :PowerShell的正则表达式中可能出现的字符(实际上大致与Perl差不多)
(1) 字符串的匹配符(占位符PlaceHolder):
. 这是一个点儿,表示换行符之外的任意一个字符(Any character except newline (Equivalent: [^ ])) [^abc] 指定的字符(abc)之外的任意一个字符,可以把abc换成其它字符组。(All characters except the ones specified) [^a-z] 任意一个非小写字母的字符(All characters except those in the region specified) [abc] 指定的字符集中的任意一个,即abc中的任意一个(One of the characters) [a-z] 指定的字符范围中的任意一个,即任意一个小写字母。One of the characters in the region a 响呤(Bell (ASCII 7)) c Any character allowed in XML names cA-cZ Control+A to Control+Z, ASCII 1 to ASCII 26 d 任意一个数字,等同于[0-9](Any number (Equivalent: [0-9])) D 任意一个非数字。Any non-number e ESC键(Escape (ASCII 27)) f Form Feed, (ASCII 12) 换行Line break 回车Carriage return s 任意一个空白键(空白键如tab,换行)Any whitespace (space, tab, new line) S 任意一个非空白字符(Any non-whitespace) tab键 w 字母,数字和下划线(Letter, number or underline) W w的补集(Non-letter, number, or underline)
(2) 匹配次数(量词Quantifier)
* 出现零次、1次、多次(Any (no occurrence, once, many times)) ? 出现零次、1次(No occurrence or one occurrence) {n,} 出现至少n次(At least n occurrences) {n,m} 出现至少n次,最多m次(At least n occurrences, maximum m occurrences) {n} 出现n次(Exactly n occurrences) + 出现1次、多次(One or many occurrences) 所有的匹配次数的符号,默认情况下都是贪婪的,即它将最大长度的进行匹配。如果想要得到最短的匹配,那就要在上面这组符号之后加一个问号(?)。
(3) 匹配边界
$ 字符串结束(End of text) ^ 字符串开始(Start of text) Word boundary B No word boundary G After last match (no overlaps)
描述: 我们可以通过打开powershell.exe应用windows窗口来进行交互式命令行的输入
PS C:UsersWeiyiGeek> (512*2)/2+512 1024 PS C:UsersWeiyiGeek> 1gb / 1mb 1024 PS C:UsersWeiyiGeek> 0x3389 13193
描述: PS 能够像CMD一样很好的执行外部命令, 即在 windows Cmd 中运行的基本都可以在PS中运行。
# 通过netstat查看网络端口状态 netstat # 通过IPConfig查看自己的网络配置 ipconfig # 启动CMD控制台键入cmd或者cmd.exe, 而退出cmd可以通过命令exit。 cmd
Q: 为什么可以通过notpad打开记事本,不能通过wordpad打开写字板?
答: 因为Notepad++.exe位于C:Windowssystem32 这个目录,而这个目录已经默认被包含在Powershell的环境变量$env:Path中。而wordpad.exe 所在的“%ProgramFiles%Windows NTAccessorieswordpad.exe“目录却没有包含;
C:WINDOWSsystem32;C:WINDOWS;C:WINDOWSSystem32Wbem;C:WINDOWSSystem32WindowsPowerShellv1.0;C:Program Files (x
86)Windows Kits8.1Windows Performance Toolkit;C:Program FilesMicrosoft SQL Server110ToolsBinn;C:Program File
s (x86)Microsoft SDKsTypeScript1.0;C:Program FilesMicrosoftWeb Platform Installer
# 解决办法:可以先进入这个目录,再运行wordpad,或者将wordpad所在的目录加入到环境变量中,$env:Path=$env:Path+”%ProgramFiles%Windows NTAccessories”。
描述: 与Linux的Alias命令一样Windows PS中也支持自定义别名,其别名的两个作用是继承unix-shell和windows-cmd和方便用户使用。
基础实例:
# 1.查询别名所指的真实cmdlet命令。 Get-Alias -name ls # 2.查看可用的别名 Get-Alias # 查看所有别名和指向cmdlet的别名的个数 ls alias: | Group-Object definition | sort -Descending Count # 3.创建自己的别名 PS C:PS> Set-Alias -Name Edit -Value notepad PS C:PS> Edit PS C:PS> $alias:Edit notepad # 4.删除自己的别名 # 自定义的别名在powershell退出时会自动清除(前提是没有导入系统中),而内置别名需要手工进行删除别名 del alias:Edit # 5.保存自己的别名(导出与导入) Export-Alias alias.ps1 Import-Alias -Force alias.ps1 # 6.通过函数扩展别名(当简单的别名无法完成复制的工作时需要采用此方法),这样定义别名会变得更加灵活; PS C:PS> function test-conn { Test-Connection -Count 2 -ComputerName $args} PS C:PS> Set-Alias tc test-conn PS C:PS> tc localhost # 有了函数牵线别名可以完成更高级更强大的功能,其中$args为参数的占位符。 Source Destination IPV4Address IPV6Address Bytes Time(ms) ------ ----------- ----------- ----------- ----- -------- WeiyiGeek localhost 127.0.0.1 ::1 32 0
描述: 我们可以直接在PS命令行中运行文件和脚本,但是必须使用绝对路径或者相对路径,或者要运行的文件必须定义在可受信任的环境变量中。
PowerShell 中可执行Bat批处理、VB脚本问号、以及PS1脚本文件。
Tips: 脚本和批处理都属于伪可执行文件,它们只是包含了若干命令行解释器能够解释和执行的命令行代码。
示例1.在PS中执行ping.bat批处理
# ping.bat @echo off echo #batch File Test# echo %1% %1% pause
演示效果:
PS C:UsersWeiyiGeek> ./ping whoami #batch File Test# whoami weiyigeekweiyigeek 请按任意键继续. . . PS C:UsersWeiyiGeek> ./ping hostname #batch File Test# hostname WeiyiGeek 请按任意键继续. . .
WeiyiGeek.ping
Tips : 在cmd输入ping执行的不是ping命令而是直接运行ping.bat(即.bat覆盖了cmd命令),而在PS上面运行ping批处理文件必须是以./ping的格式, 所以说命令与脚本的混淆不会发生在powershell中,因为powershell有更安全的机制。
示例2.在PS中执行VB脚本文件
# 执行 . est.vbs 会遍历当前Win32进程,并把每个进程的详细信息通过窗口显示出来。 # test.vbs Set wmi = GetObject("winmgmts:") Set collection = wmi.ExecQuery("select * from Win32_Process") For Each process in collection WScript.Echo process.getObjectText_ Next # 在powershell中执行VB脚本 PS C:PS> cscript.exe .test.vbs instance of Win32_Process { Caption = "System Idle Process"; CreationClassName = "Win32_Process"; CSCreationClassName = "Win32_ComputerSystem"; .... }
Tips : 怎样让VB脚本的通过控制台输出呢? Wscript //H:CScript Tips : 怎样还原VB脚本通过窗口输出呢?WScript //H:WScript
示例3.在PS中执行ps1脚本文件 描述: Powershell拥有自己的脚本扩展名为”.ps1”
PS C:PS> echo "dir;Get-PSProvider;help dir" >test.ps1 PS C:PS> Get-Content ./test.ps1 dir;Get-PSProvider;help dir PS C:PS> ./test.ps1
Q:什么是管道?
答: 管道的行为就像一系列连接的管道段一样,沿着管道移动的项会通过每个管道段;
描述:在 PS 中创建管道请使用管道运算符“|”将命令连接在一起,每个命令的输出都将被用作下一命令的输入,与Linux中Shell使用类似, 但是不同的是它传递的数据不是文本而是对象;
管道的处理模式:
1.顺序模式(较慢):在顺序模式中管道中同一时间只执行一条命令,只有当前一条命令的所有执行完毕,才会把所有结果交付给下一条命令。优缺点:速度慢并且耗内存,因为需要很多次分配空间存储中间结果。2.流模式(较快):流模式会立即执行所有命令,同一时间可能在执行多条命令。优缺点: 比较节省内存,可能管道的某个任务还在执行,但是已经有部分结果输出了,减少了中间结果的保存。Tips : 管道命令也是存在的阻塞,比如在对递归的文件进行排序的时候,需要获取全部文件后才能进行排序; (Dir C: -recurse | Sort-Object)
Tips : 管道中的每个命令(称为管道元素)将其输出逐项传递到管道中的下一个命令
1.传统的Cmd管道是基于文本的,但是Powershell是基于对象2.管道中传递是对象可以作为下一个cmdlet的参数3.它可以减少使用复杂命令的工作量,更轻松地查看命令的工作流程4.少了资源消耗并且能够立即开始获取输出提高执行效率常用需要使用管道的命令:
Compare-Object: 比较两组对象。ConvertTo-Html: 将 Microsoft .NET Framework 对象转换为可在 Web 浏览器中显示的 HTML。Export-Clixml: 创建对象的基于 XML 的表示形式并将其存储在文件中。Export-Csv: 将 Microsoft .NET Framework 对象转换为一系列以逗号分隔的、长度可变的 (CSV) 字符串,并将这些字符串保存到一个 CSV 文件中。ForEach-Object: 针对每一组输入对象执行操作。Format-List: 将输出的格式设置为属性列表,其中每个属性均各占一行显示。Format-Table: 将输出的格式设置为表。Format-Wide: 将对象的格式设置为只能显示每个对象的一个属性的宽表。Get-Unique: 从排序列表返回唯一项目。Group-Object: 指定的属性包含相同值的组对象。Import-Clixml: 导入 CLIXML 文件,并在 Windows PowerShell 中创建相应的对象。Measure-Object: 计算对象的数字属性以及字符串对象(如文本文件)中的字符数、单词数和行数。more: 对结果分屏显示。Out-File: 将输出发送到文件。Out-Null: 删除输出,不将其发送到控制台。Out-Printer: 将输出发送到打印机。Out-String: 将对象作为一列字符串发送到主机。Select-Object: 选择一个对象或一组对象的指定属性。它还可以从对象的数组中选择唯一对象,也可以从对象数组的开头或末尾选择指定个数的对象。Sort-Object: 按属性值对象进行排序。Tee-Object: 将命令输出保存在文件或变量中,并将其显示在控制台中。Where-Object: 创建控制哪些对象沿着命令管道传递的筛选器。描述: PowerShell one 命令是一种连续管道,不一定是一条物理线路上的命令, 但又并非一个物理行上的所有命令都是单行命令。
Tips : 管道符号是 PowerShell 中允许自然换行处的某个字符,包括逗号 (,) 和方左括号 ([)、大括号 ({) 和圆括号 (()。
Tips : 其他不太常见的字符包括分号 (;)、等于号 (=) 以及左单引号和双引号(’、”)
示例1: 即使以下命令位于多个物理行上,它也是 PowerShell 单行命令,因为它是一个连续管道。
# 1) 系统服务获取与属性查看 Get-Service | Where-Object CanPauseAndContinue -eq $true | Select-Object -Property * # 2) 输出当前目录中的文件并通过管道进行排序 ls | sort -Descending Name | Format-Table Name,Mode
示例2.将反引号 (`) 或重音符用作续行符是一个有争议的话题(建议尽量避免这样做),因为上面和下面示例中所示的命令在 PowerShell 控制台中正常工作。 但如果尝试在 PowerShell ISE 的控制台窗格中运行它们,则会出现错误。
# PS (执行OK) Get-Service -Name w32time | >> Select-Object -Property * # PS ISE : PowerShell ISE 的控制台窗格不会等待命令的其余部分在下一行(如 PowerShell 控制台)中输入。 Get-Service -Name w32time | 不允许使用空管道元素。 + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordEx ception + FullyQualifiedErrorId : EmptyPipeElement
WeiyiGeek.PowerShell与ISE
解决办法: 要避免 PowerShell ISE 的控制台窗格中出现此问题,请使用 Shift+Enter,而不是只是在继续执行另一行上的命令时按 Enter。
# PS ISE PS C:UsersWeiyiGeek> Get-Service -Name w32time | # Select-Object -Property * # Name : w32time # RequiredServices : {} # CanPauseAndContinue : False # CanShutdown : True # CanStop : True # DisplayName : Windows Time # DependentServices : {} # MachineName : . # ServiceName : w32time # ServicesDependedOn : {} # ServiceHandle : # Status : Running # ServiceType : Win32OwnProcess, Win32ShareProcess # StartType : Manual # Site : # Container :
示例3.下一个示例不是 PowerShell 单行命令,因为它不是一个连续管道,它是一行上的两个单独命令,用分号(;)分隔。
$Service = 'w32time'; Get-Service -Name $Service # Status Name DisplayName # ------ ---- ----------- # Running w32time Windows Time
示例4.格式化管道文本输出 描述: PS 可以通过管道将对象结果转换成文本并显示在控制台上。
# 实例1.事实上Out-Default会首先调用Format-Table,将更多的属性默认隐藏,再调用Out-Host将结果输出在控制台上。 ls | Out-Default ls | Format-Table | Out-Host ls | Format-Table * -Wrap # 显示隐藏的对象属性
描述: 我们可以通过重定向符将命令输出保存到文件之中 ‘>’ 为覆盖 ’>>’ 追加;
重定向标识:
1 > stdio.out2 > errorout6 > infoout基础示例:
# 示例1.简单实例 PS C:PS> "Powershell Routing" >.txt PS C:PS> "Powershell Routing1" >>.txt PS C:PS> Get-Content ..txt Powershell Routing Powershell Routing1 # 示例2.错误输出重定向 Get-Command Get-Acl 1> out.txt 2> error.txt 6> info.txt
描述: 扩展类型系统Extended Type System (ETS),ETS会对管道中对象转换成文本的机制进行宏观调控。
ETS由两部分组成:
一部分控制对象的版式: 需要创建一个.ps1xml的配置文件一部分控制对象的属性: 在管道中将对象结果转换成文本后,不能再将文本转换成对象,因为ETS不能处理文本。Tip : ETS配置中包含的类型对象会以最佳的方式转换成文本,我们可以ETS配置中包含的类型对象会以最佳的方式转换成文本。
# 1.首先确定命令返回结果的对象类型 PS > $object = Get-WmiObject Win32_Processor | Select-Object -first 1 PS > $object.GetType().FullName System.Management.ManagementObject #发现目标类型为:System.Management.ManagementObject # 2.其次创建一个配置文件:Win32_Processor.format.ps1xml System.Management.ManagementObject <label>Name</label> <label>Description</label> <label>ID</label> PS > Update-FormatData .Win32_Processor.format.ps1xml #加载进ETS PS > Get-WmiObject win32_processor # Name Description ID # ---- ----------- -- # CPU0 x64 Family 6 Model 15 Stepp... BFEBFBFF000006FD
补充: 这样的定义可能有个缺点,当我们获取其它WMI对象时,也会根据我们定义的规则显示。
基础实例
# 0.键入以下内容看到可读形式的完整列表,通过管道符号传递给其他cmdlet并进行使用 Get-Command -Noun Variable | Format-Table -Property Name,Definition -AutoSize -Wrap # Clear-Variable [-Name] <string[]> [-Include <string[]>] [-Exclude <string[]>] [-Force] [-PassThru] [-Scope <string>] [-WhatIf] [-Confirm] [<CommonParameters>] # 1.例如如果使用 Out-Host 来强制逐页显示来自于另一个命令的输出(看起是传递的文本) Get-ChildItem -Path F: | Out-Host -Paging Get-ChildItem F: | Out-Host -Paging <SPACE> next page; <CR> next line; Q quit # 目录: F: # Mode LastWriteTime Length Name # ---- ------------- ------ ---- # d----- 2019/7/11 12:29 BadUSB-code # 2.如果运行 Get-Location,而当前位置是 C 驱动器的根路径 PS C:UsersWeiyiGeek> gl # Path #文本输出是信息摘要,而非 Get-Location 返回的对象的完整表示形式 # ---- # C:UsersWeiyiGeek #输出中的标题通过格式化屏幕显示数据的过程添加,可以获取有关 Get-Location 返回的对象信息。 Get-Location | Get-Member -MemberType Property Get-Location | Get-Member -Name Path # TypeName: System.Management.Automation.PathInfo # Name MemberType Definition # ---- ---------- ---------- # Equals Method bool Equals(System.Object obj) # 3.如果要执行一些大型查询,可查询一次并将结果存储在变量中以后便使用变量的内容,而无需重复使用一些开销较高的查询。property - 英 [ˈprɒpəti] $TimeService = Get-Service -Name W32Time $TimeService | Select-Object -Property Name,Status,ServiceType # Name Status ServiceType # ---- ------ ----------- # W32Time Running Win32OwnProcess, Win32ShareProcess # 4.通过管道停止服务和查看哪些参数接收管道符 # Stop-Service 的 InputObject 参数通过管道按值(按类型)接受 ServiceController 对象 。 Get-Service -Name w32time | Stop-Service # 通过管道将 w32time 传递到 Get-Member,以确认它是一个字符串。 'w32time' | Get-Member # TypeName: System.String # 5.在 PowerShell 中,应始终使用单引号而不是双引号,除非带引号的字符串的内容包含需要扩展为其实际值的变量。通过使用单引号,PowerShell 不必分析引号中包含的内容,因此可稍微加快代码运行速度。 'w32time' | Get-Service # Status Name DisplayName # ------ ---- ----------- # Running w32time Windows Time # 通过管道将 w32time 传递到 Stop-Service,以进行测试 'w32time' | Stop-Service # 6.按 Stop-Service 的 Name 参数的属性名称创建自定义对象,以测试管道输入。 $CustomObject = [pscustomobject]@{ Name = 'w32time' } # CustomObject 变量的内容是 PSCustomObject 对象类型,并且它包含名为 Name 的属性 。 # 如果要在 $CustomObject 变量两边使用引号,则需要使用双引号。 否则,如果使用单引号,则会将文本字符串 $CustomObject 通过管道传递到 Get-Member,而不是传递变量包含的值。 $CustomObject | Get-Member # 尽管将 $CustomObject 的内容通过管道传递到 Stop-Service cmdlet 会将该内容绑定到 Name 参数,但这次它会按属性名称绑定,而不是按值,因为 $CustomObject 的内容是一个具有名为 Name 的属性的对象 。 # 尝试通过管道将 $CustomObject 传递到 Stop-Service 时会产生错误,因为它不会生成 ServiceController 或 String 对象,并且没有名为 Name 的属性 。 $CustomObject | Stop-Service # 如果一个命令的输出与另一个命令的管道输入选项不相符,则可以使用 Select-Object 重命名属性,以便正确地配置属性。 # 使用 Select-Object 将 Service 属性重命名为名为 Name 的属性 。 $CustomObject | Select-Object -Property @{name='Name';expression={$_.Service}} | Stop-Service # 7.用一个命令的输出作为另一个命令的输入。 # 首先将几个 Windows 服务的显示名称保存到一个文本文件中。 'Background Intelligent Transfer Service', 'Windows Time' | Out-File -FilePath $env:TEMPservices.txt # 可以运行命令,在括号中提供所需输出,作为需要输入的命令的参数值。 Stop-Service -DisplayName (Get-Content -Path $env:TEMPservices.txt) # 8.使用 PowerShellGet 模块中包含的 Find-Module cmdlet,在 PowerShell 库中查找名为 MrToolkit 的模块。并进行安装 Find-Module -Name MrToolkit | Install-Module
备注:
1.分页还会降低 CPU 利用率,因为准备好显示完整页面时,会转为处理 Out-Host 管道中位于前面的 cmdlet 暂停执行,直到输出的下一页可用。
2.并非所有的PS主机都支持 Paging 参数 例如当你尝试在 PowerShell ISE 中使用 Paging 参数时,会看到以下错误:
3.查找管道输入的简单方法安装MrToolkit 模块包含一个名为 Get-MrPipelineInput 的函数;
# 此 cmdlet 可用于轻松确定接受管道输入的命令参数、接受的对象类型,以及是按值还是按属性名称接受管道输入 。 Find-Module -Name MrToolkit | Install-Module Get-MrPipelineInput -Name Stop-Service # ParameterName ParameterType ValueFromPipeline ValueFromPipelineByPropertyName # ------------- ------------- ----------------- --------------- # InputObject System.ServiceProcess.ServiceController[] True False # Name System.String[] True True
描述:变量Variable在任何一门脚本语言或者说是编程语言中都是存在的,其本质是不相上下的;
PS可以创建称为”变量”的命名对象,变量名称可以包含下划线字符和任何字母数字字符,且变量名大小写不敏感(a和A 是同一个变量)使用变量名称后跟的字符调用指定变量(与世界上最好的语言相似-你懂的),或者采用{变量名}进行赋值调用,还可以将某些特殊的字符作为变量但是在实际开发中不推荐; 赋值操作符不仅能给一个变量赋值,还可以同时给多个变量赋相同的值,交换变量的值PS只需要两步变量可以自动存储任何Powershell能够识别的类型信息采用`或者’’包含变量的都不能进行解析调用变量,只会原样进行输出;变量会在PS退出或关闭时自动清除PS变量类型:
自定义变量自动化变量环境变量: env:驱动器变量: varaible:创建变量
# 0.创建不同类型的变量(int/String/Boolen/float) PS > $var=1;$var;$var="String";$var;$var='TRUE';$var;$var=3.14159267;$var # 1 # String # TRUE # 3.14159267 # 1.将当前位置存储在变量 $loc 中 PS > $loc = Get-Location PS > $loc #键入 $loc 将显示当前位置: # 2.防止变量名与其他字符串混淆使用${} PS > $var=" variable" PS > $var variable PS > ${var} variable # 3.某些特殊的字符在PS中有特殊的用途,一般不推荐使用这些字符作为变量名。 PS C:> ${"I"like $}="mossfly" #请把整个变量名后缀用花括号括起来 PS C:> ${"I"like $} mossfly # 4.PS给多个变量同时赋值 PS C:> $a=$b=$c=123 # 5.交换两个变量的值 PS C:> $value1=10 PS C:> $value2=20 PS C:> $value1,$value2=$value2,$value1 # 6.采用cmdlet声明变量 New-Variable number -Value 100 -Force -Option readonly #变量写保护 New-Variable NUMBER -Value 100 -Force -Option constant -Description "This is my name" #声明常量并且进行描述 # 7.变量不解析 PS C:> Write-Host the '$HOME' is $home PS C:> Write-Host the `$HOME is $home the $HOME is C:UsersWeiyiGeek
操作变量
# 1.显示使用驱动器变量和环境变量: Get-ChildItem variable: #PS将变量的相关信息的记录存放在名为variable:的驱动中 Get-ChildItem variable:value* #查找变量 Get-ChildItem env: #使用任何 Windows 进程可用的相同环境变量,其中包括 cmd.exe # 2.用 env: 驱动器前缀访问环境变量,由于用 env: 驱动器前缀访问环境变量 #例如,cmd.exe 中的 %SystemRoot% 变量包含操作系统的根目录名称 PS > $env:SystemRoot C:Windows PS > $env:JAVA_HOME Programsjavajdk # 3.示例创建一个新的环境变量 $env:LIB_PATH='/usr/local/lib' PS > $env:WEIYIGEEK=$env:PATH PS > $env:WEIYIGEEK # C:Python27;C:Python27Scripts; # 4.示例或者改变更新变量PS中是 + 作为评卷符号 PS > $env:WEIYIGEEK=$env:PATH + ";c:" PS > $env:WEIYIGEEK # C:Python27;C:Python27Scripts;c: # 5.验证一个变量是否存在,仍然可以象验证文件系统那样 PS C:> -Path variable:value1 True PS C:> -Path variable:valueUnkonw False # 6.删除变量 PS C:> -Path variable:value1 True PS C:> Remove-Item variable:value1 -Force # 强制删除 del -> Remove-Item PS C:> -Path variable:value1 False
WeiyiGeek.环境变量获取显示
描述:一旦打开Powershell就会自动加载的变量,并且某些自动化变量只读不能写,一般存放的内容包括:
用户信息:例如用户的根目录$home配置信息:例如powershell控制台的大小,颜色,背景等。运行时信息:例如一个函数由谁调用,一个脚本运行的目录等。PS> $HOME C:Users PS> $currentProcessID=$pid;$currentProcessID 5356 PS> Get-Process -Id $pid # Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName # ------- ------ ----- ----- ----- ------ -- ----------- # 390 10 30604 33100 172 1.11 5356 powershell PS> $PROFILE C:UsersDocumentsWindowsPowerShellMicrosoft.PowerShell_profile.ps1
详细说明-自动变量的列表:
$$ : 包含会话所收到的最后一行中的最后一个令牌。 $? : 包含最后一个操作的执行状态。如果最后一个操作成功,则包含 TRUE,失败则包含 FALSE。 $^ : 包含会话所收到的最后一行中的第一个令牌。 $_ : 包含管道对象中的当前对象。在对管道中的每个对象或所选对象执行操作的命令中,可以使用此变量。 $Args : 包含由未声明参数和/或传递给函数、脚本或脚本块的参数值组成的数组。 在创建函数时可以声明参数,方法是使用 param 关键字或在函数名称后添加以圆括号括起、逗号 分隔的参数列表。 $ConsoleFileName : 包含在会话中最近使用的控制台文件 (.psc1) 的路径。在通过 PSConsoleFile 参数启动 Windows PowerShell 或使用 Export-Console cmdlet 将管理单元名称导出到控制台文件 时,将填充此变量。 在使用不带参数的 Export-Console cmdlet 时,它自动更新在会话中最近使用的控制台文件。 可以使用此自动变量确定要更新的文件。 $Error : 包含错误对象的数组,这些对象表示最近的一些错误。最近的错误是该数组中的第一个错误对象 ($Error[0])。 $Event :包含一个 PSEventArgs 对象,该对象表示一个正在被处理的事件。 此变量只在事件注册命令(例如 Register-ObjectEvent)的 Action 块内填充。 此变量的值是 Get-Event cmdlet 返回的同一个对象。 因此,可以在 Action 脚本块中使用 $Event 变量的属性(例如 $Event.TimeGenerated)。 $EventSubscriber : 包含一个 PSEventSubscriber 对象,该对象表示正在被处理的事件的事件订阅者。 此变量只在事件注册命令的 Action 块内填充。此变量的值 是 Get-EventSubscriber cmdlet 返回的同一个对象。 $ExecutionContext : 包含一个 EngineIntrinsics 对象,该对象表示 Windows PowerShell 主机的执行上下文。 可以使用此变量来查找可用于 cmdlet 的执行对象。 $False : 包含 FALSE。可以使用此变量在命令和脚本中表示 FALSE,而不是使用字符串”false”。如果 该字符串转换为非空字符串或非零整数,则可将该字符串解释为 TRUE。 $ForEach : 包含 ForEach-Object 循环的枚举数。可以对 $ForEach 变量的值使用枚举数的属性和方法。 此变量仅在运行 For 循环时存在,循环完成即会删除。 $Home : 包含用户的主目录的完整路径。此变量等效于 %homedrive%%homepath% 环境变量。 $Host : 包含一个对象,该对象表示 Windows PowerShell 的当前主机应用程序。可以使用此变量在命 令中表示当前主机,或者显示或更改主机的属性,如 $Host.version、$Host.CurrentCulture 或 $host.ui.rawui.setbackgroundcolor(“Red”)。 $Input : 一个枚举数,它包含传递给函数的输入。$Input 变量区分大小写,只能用于函数和脚本块。(脚本块本质上是未命名的函数。)在函数的 Process 块中,$Input 变量包含当前位于管道中的对象。在 Process 块完成后,$Input 的值为 NULL。如果函数没有 Process 块,则 $Input的值可用于 End 块,它包含函数的所有输入。 $LastExitCode : 包含运行的最后一个基于 Windows 的程序的退出代码。 $Matches : $Matches 变量与 -match 和 -not match 运算符一起使用。 将标量输入提交给 -match 或 -notmatch 运算符时,如果检测到匹配,则会返回一个布尔值,并使用由所有匹配字符串值组成的哈希表填充 $Matches 自动变量。 $MyInvocation : 包含一个对象,该对象具有有关当前命令(如脚本、函数或脚本块)的信息。可以使用该对象中的信息(如脚本的路径和文件名 ($myinvocation.mycommand.path) 或函数的名称 ($myinvocation.mycommand.name))来标识当前命令。对于查找正在运行的脚本的名称,这非常有用。 $NestedPromptLevel : 包含当前提示级别。值 0 指示原始提示级别。该值在进入嵌套级别时递增,在退出嵌套级别时递减。 例如,在使用 $Host.EnterNestedPrompt 方法时,Windows PowerShell 会出现嵌套命令提示符。在 Windows PowerShell 调试程序中到达断点时,Windows PowerShell 也会出现嵌套命令提示符。在进入嵌套提示时,Windows PowerShell 暂停当前命令,保存执行上下文,并递增 $NestedPromptLevel 变量的值。要创建更多嵌套命令提示符(最多 128 级)或返回到原始命令提示符,请完成命令,或键入”exit”。 $NestedPromptLevel 变量有助于跟踪提示级别。可以创建包含此值的备用 WindowsPowerShell 命令提示符,以使此值始终可见。 $NULL: 包含 NULL 或空值。可以在命令和脚本中使用此变量表示 NULL,而不是使用字符串”NULL”。 如果该字符串转换为非空字符串或非零整数,则可将该字符串解释为 TRUE。 $PID : 包含承载当前 Windows PowerShell 会话的进程的进程标识符 (PID)。 $Profile : 包含当前用户和当前主机应用程序的 Windows PowerShell 配置文件的完整路径。可以在命令 中使用此变量表示配置文件。例如,可以在命令中使用此变量确定是否已创建某个配置文件: 也可以在命令中使用此变量创建配置文件: new-item -type file -path $pshome -force 此外,还可以在命令中使用此变量在记事本中打开配置文件: notepad $profile $PSBoundParameters 包含活动参数及其当前值的字典。只有在声明参数的作用域(如脚本或函数)中, 此变量才有值。可以使用此变量显示或更改参数的当前值,也可以将参数值传递给 其他脚本或函数。 基础示例: function { param($a, $b) # Display the parameters in dictionary format. $psboundparameters # Call the 1 function with $a and $b. 1 @psboundparameters } $PsCmdlet : 包含一个对象,该对象表示正在运行的 cmdlet 或高级函数。 可以在 cmdlet 或函数代码中使用该对象的属性和方法来响应使用的条件。例如,ParameterSetName 属性包含正在使用的参数集的名称,而 ShouldProcess 方法将 WhatIf和 Confirm 参数动态添加到 cmdlet。 有关 $PSCmdlet 自动变量的详细信息,请参阅 about_Functions_Advanced。 $PsCulture : 包含操作系统中当前所用的区域性的名称。区域性确定数字、货币和日期等项的显示格式。这是系统的System.Globalization.CultureInfo.CurrentCulture.Name 属性的值。要获取系统的 System.Globalization.CultureInfo 对象,请使用 Get-Culture cmdlet。 $PSDebugContext : 在调试期间,此变量包含有关调试环境的信息 在其他时间,此变量包含 NULL 值。因此,可以使用此变量指示调试程序是否拥有控制权。填充之后,此变量包含一个具有 Breakpoints 和InvocationInfo 属性的 PsDebugContext 对象。InvocationInfo 属性有多个十分有用的属性,包括 Location 属性。Location 属性指示正在调试的脚本的路径。 $PsHome 包含 Windows PowerShell 的安装目录的完整路径(通常为%windir%System32WindowsPowerShellv1.0)。可以在 Windows PowerShell 文件的路径中使用此变量。例如,下面的命令在概念性帮助主题中搜索”variable”一词: select-string -pattern variable -path $pshome*.txt $PSScriptRoot :包含要从中执行脚本模块的目录。通过此变量,脚本可以使用模块路径来访问其他资源。 $PsUICulture 包含操作系统中当前所用的用户界面 (UI) 区域性的名称。UI 区域性确定哪些文本字符串用于用户 界面元素(如菜单和消息)。这是系统的 System.Globalization.CultureInfo.CurrentUICulture.Name 属性的值。要获取系统 的 System.Globalization.CultureInfo 对象,请使用 Get-UICulture cmdlet。 $PsVersionTable 包含一个只读哈希表,该哈希表显示有关在当前会话中运行的 Windows PowerShell 版本的详 细信息。 该表包括下列项: * CLRVersion: 公共语言运行时 (CLR) 的版本 * BuildVersion: 当前版本的内部版本号 * PSVersion: Windows PowerShell 版本号 * WSManStackVersion: WS-Management 堆栈的版本号 * PSCompatibleVersions: 与当前版本兼容的 Windows PowerShell 版本 * SerializationVersion :序列化方法的版本 * PSRemotingProtocolVersion:Windows PowerShell 远程管理协议的版本 $Pwd : 包含一个路径对象,该对象表示当前目录的完整路径。 $Sender : 包含生成此事件的对象。此变量只在事件注册命令的 Action 块内填充。 此变量的值也可在 Get-Event 返回的 PSEventArgs (System.Management.Automation.PSEventArgs) 对象的 Sender 属性中找到。 $ShellID : 包含当前 shell 的标识符。 $SourceArgs : 包含表示正在被处理的事件的事件参数的对象。此变量只在事件注册命令的 Action 块内填充。此变量的值也可在 Get-Event 返回的 PSEventArgs (System.Management.Automation.PSEventArgs) 对象的 SourceArgs 属性中找到。 $SourceEventArgs : 包含一个对象,该对象表示从正在被处理的事件的 EventArgs 中派生出的 第一个事件参数。此变量只在事件注册命令的 Action 块内填充。 此变量的值也可在 Get-Event 返回的 PSEventArgs (System.Management.Automation.PSEventArgs) 对象的 SourceArgs 属性中找到。 $This : 在定义脚本属性或脚本方法的脚本块中,$This 变量引用要扩展的对象。 $True : 包含 TRUE。可以在命令和脚本中使用此变量表示 TRUE。
描述: 内置变量包括了PS中的默认的环境变量、以及命令行控制显示变量、以及函数参数的变量。
1) 环境变量: 存在于操作系统之中但是如果环境变量被更新了其它程序也可以更新调用它。内置变量一览表
# 1.环境变量 $env # 2.消息控制变量 $DebugPreference #显示Debug输出: 可选值 [Continue | SilentlyContinue] $ErrorActionPreference #显示Error输出: 可选值 [Continue | SilentlyContinue] # 3.函数及参数变量 $global $local $function $input # 管道数据中转变量 $arg # 万能参数变量 # 4.其它变量 $Host # 例如$host.UI.Rawui
基础实例:
#1.读取特殊的环境变量 PS> ls $env: PS> $env:windir C:Windows PS> $env:ProgramFiles C:Program Files #2.为了和其它变量保持一致,你可以把它插入到文本中。 PS> "My computer name $env:COMPUTERNAME" My computer name MYHome--01 #3.创建新的环境变量 PS> $env:Var1="This is my environment variable" PS> $env:Var2="Hollow, environment variable" PS> $env:Path+=";C:python" #4.环境变量更新生效 # .NET方法[environment]::SetEnvironmentvariable操作可以立刻生效。 PS> [environment]::SetEnvironmentvariable("Path", ";c:WeiyiGeek", "User") PS> [environment]::GetEnvironmentvariable("Path", "User") ;c:WeiyiGeek
备注:
尽管没有要求,但环境变量名称通常使用全部大写字母。描述:PS中所有不是我们自己的定义的变量都属于驱动器变量(比如环境变量),它的前缀只是提供给我们一个可以访问信息的虚拟驱动器.。
基础实例:
#0.查看你PS支持的驱动器 PS > Get-PSDrive # Name Used (GB) Free (GB) Provider Root CurrentLocation # ---- --------- --------- -------- ---- --------------- # C 58.24 91.76 FileSystem C: UsersWeiyiGeek # Cert Certificate # D 11.76 249.24 FileSystem D: # E 19.07 240.93 FileSystem E: # Env Environment # F 88.83 171.46 FileSystem F: # Function Function # G FileSystem G: # HKCU Registry HKEY_CURRENT_USER # HKLM Registry HKEY_LOCAL_MACHINE # I FileSystem I: # Variable Variable # WSMan WSMan #1.$后花括号中的路径必须是具体的路径,而不能带返回值。 PS> Invoke-Expression "`${$env:HOMEDRIVE/Powershell/ping.bat}" #反引号"`"放在$前,会把$解析成普通字符,解释器会继续去解析第二个$ #参数=${C:/Powershell/ping.bat}
描述: PS所有的变量都有一个决定变量是否可用的作用域,有了作用域就可以限制变量的可见性了,尤其是在函数和脚本中。 PS支持四个作用域:全局、当前、私有和脚本。
设置单个变量的作用域:
$global 全局变量: 在所有的作用域中有效,如果你在脚本或者函数中设置了全局变量,即使脚本和函数都运行结束这个变量也任然有效。$script 脚本变量: 只会在脚本内部有效,包括脚本中的函数,一旦脚本运行结束变量就会被回收。$private 私有变量: 只会在当前作用域有效,不能贯穿到其他作用域。$local 默认变量: 可以省略修饰符,在当前作用域有效,其它作用域只对它有只读权限。Tips : 利用"."来更改变量的可见性,加强变量可见性限制的优点清空初始化环境,但如果定义的是一个自读的常量的时候这个是不能操作和删除的;
Tips : 本地变量会从全局变量继承值,但是本地变量的更改不会影响全局变量,除非显示制定global;
基础示例:
1) 变量在交换影响
# 1.在脚本里面的变量不影响交互式环境中的变量 PS E:WeiyiGeek> $DemoVar="This is a Demo" PS E:WeiyiGeek> .Demo1.ps1 # D:Programsjavajdk PS E:WeiyiGeek> $DemoVar # This is a Demo # 2.点"."来运行脚本该符号域Linux中的source命令有异曲同工之妙; PS E:WeiyiGeek> . .Demo1.ps1 # D:Programsjavajdk PS E:WeiyiGeek> $DemoVar # 脚本中的变量覆盖了$DemoVar变量(关键点) # D:Programsjavajdk
2) 单个变量作用域实例
# 1.在当前控制台只存在一个作用域,通过修饰符访问,其实访问的是同一个变量: PS C:UsersWeiyiGeek> $var="WeiyiGeek" PS C:UsersWeiyiGeek> $private:var # WeiyiGeek PS C:UsersWeiyiGeek> $script:var # WeiyiGeek PS C:UsersWeiyiGeek> $global:var # WeiyiGeek PS C:UsersWeiyiGeek> $local:var="WeiyiGeek" # WeiyiGeek # 2.普通变量与Global修饰符之间的区别(在函数中利用Global修饰符来更改普通变量之中) $var = "WeiyiGeek" function demo1() { echo "Function => $($Var)";$Var = "Function Change";echo "-----$($Var)-----"} $var; demo1; $var # Function => WeiyiGeek # WeiyiGeek # -----Function Change----- # WeiyiGeek function demo2() { $Global:Var = "Function Change $var 变量";$var} $var; demo2; $var # WeiyiGeek # Function Change WeiyiGeek 变量 # Function Change WeiyiGeek 变量 # 3.Private修饰符在控制台中的变量保护起来,不让它在函数和脚本中被访问,但他可以被Global修饰符修改; function fun() { echo "DemoVar=$($DemoVar)"; $global:DemoVar="This is Function Inner"; $DemoVar; } $Private:DemoVar="This is private variable" fun; $DemoVar # 执行结果 (此处是关键点私有变量在函数中不能获取) # DemoVar= # This is Function Inner # This is Function Inner $Global:DemoVar="This is global variable" fun; $DemoVar $Private:DemoVar # 执行结果 (全局变量可被内部全局变量更改) # DemoVar=This is global variable # This is Function Inner # This is Function Inner # This is Function Inner # 4.Global修饰符中验证对private修饰符的影响 function fun() {"DemoVar=$DemoVar";$Global:DemoVar="This is Global";$DemoVar;} $Private:DemoVar="this is private" $DemoVar fun #对后续变量存在影响 $DemoVar # 执行结果 # this is private # DemoVar=this is private # This is Global # This is Global # 5.Local修饰符可以通过$global修饰符修饰的变量 function fun() {"DemoVar=$DemoVar";$Global:DemoVar="This is Global";$DemoVar;} $Local:DemoVar="this is Local" $DemoVar fun $Local:DemoVar # 执行结果 # this is Local # DemoVar=this is Local # This is Global # This is Global
描述: Powershell 默认支持的.NET类型如下:
[Byte] [sbyte][Char][Bool][Int] [Int16] [Int32] [Int64][uint16] [uint32] [uint64][float][double][array][string][long][Decimal][timespan][DateTime][type][switch][guid][nullable][hashtable][psobject][regex][scriptblock][single][Xml]PS弱类型和强类型 描述: PS给数据分配一个最佳的数据类型也称作“弱类型”,如果一个整数超出了32位整数的上限([int32]::MaxValue),它就会分配一个64位整数的数据类型;同样如果是小数,字符串,日期时间也会分配成为该对应的数据类型,使用时候非常的方便;
1.弱类型的缺点:有一个变量要存储的是即将拷贝文件的个数,可是在赋值时付了一个字符串,Powershell不会去做过多的判断,它会更新这个变量的类型,并且存储新的数据。2.强类型的优点:严谨防止程序异常,不会根据数据进行转换数据类型,手动地定义类型的一个重要原因是每个特殊的数据类型都有自己的特殊命令和特殊方法,PS中使用它的另一个原因是每一个数据类型都有属于自己的函数;变量类型查看
PS C:UsersWeiyiGeek> $var=1024; $var -is [int] True PS C:UsersWeiyiGeek> $var=1024; $var -is [int32] True PS C:UsersWeiyiGeek> $string="weiyigeek"; $string -is [string] True # (1) 类型获取 $string.gettype() # IsPublic IsSerial Name BaseType # -------- -------- ---- -------- # True True String System.Object # (2) 对象类型全称 $string.gettype().fullname # System.String
通过$variable的GetType().Name查看和验证PS分配给变量的数据类型。
PS C:UsersWeiyiGeek> $var=1024;$var is Int Int32 PS C:UsersWeiyiGeek> $var=1024;$var.GetType().name Int32 PS C:UsersWeiyiGeek> (999999999999999).GetType().name Int64 PS C:UsersWeiyiGeek> (99999999999999999999).GetType().name Decimal PS C:UsersWeiyiGeek> (3.14).GetType().name Double PS C:UsersWeiyiGeek> (3.14d).GetType().name Decimal PS C:UsersWeiyiGeek> ("String").GetType().name String PS C:UsersWeiyiGeek> (date).GetType().name DateTime PS C:UsersWeiyiGeek> (get-date).GetType().name DateTime
指定类型定义变量:
#1.例如定义一个Byte类型的变量,因为Byte的定义域为[0,255],一旦尝试使用一个不在定义域中的值赋给该变量就会显示一条错误信息。 PS C:UsersWeiyiGeek> [byte]$b=254 PS C:UsersWeiyiGeek> $b.gettype() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Byte System.ValueType #2.DateTime类型对象的属性的使用 PS C:UsersWeiyiGeek> [DateTime]$date="2019-11-27 09:19:20" PS C:UsersWeiyiGeek> $date 2019年11月27日 9:19:20 PS C:UsersWeiyiGeek> $date.DayOfWeek Wednesday PS C:UsersWeiyiGeek> $date.DayOfyear 331 PS C:UsersWeiyiGeek> $date.AddDays(-10) 2019年11月17日 9:19:20 #3.XML类型对象的使用查询.exe 和 .dll结点 PS > [XML]$xml=(Get-Content .Demo2.xml) PS > $xml # logo # -------- # logo PS > $xml.FirstChild # extensions unextensions # ---------- ------------ # extensions unextensions PS > $xml.logo.extensions.e # .exe # .dll
变量强弱类型转换 描述:每个变量的都有自己的类型,这个具体的类型存放在PsVariable对象的Attributes[System.Management.Automation.PSVariableAttributeCollection]属性,如果这个Attributes为空,可以给这个变量存放任何类型的数据,PS会自己选择合适的类型。
一旦Attribute属性确定下来就不能随意存储其他类型的数据;
例如给var存放一个整数,属于弱类型,所以Attributes属性为空,这时还可以给它赋值一个字符串。但是如果给var增加强类型,存放一个整数,再给它赋值一个其它类型,解释器会自动尝试转换,如果不能转换就会抛出异常。解决办法:使用 (Get-Variable var).Attributes.Clear() 清空 Attributes此时强类型又转变成为弱类型了;
#1.默认申明的变量是弱类型 PS C:UsersWeiyiGeek> $var=1024 PS C:UsersWeiyiGeek> (Get-variable var).Attributes PS C:UsersWeiyiGeek> $var.gettype() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Int32 System.ValueType PS C:UsersWeiyiGeek> $var=3.14 PS C:UsersWeiyiGeek> $var.gettype() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Double System.ValueType #2.强类型转弱类型 PS C:UsersWeiyiGeek> [Int]$var=1024 PS C:UsersWeiyiGeek> (Get-variable var).Attributes TransformNullOptionalParameters TypeId ------------------------------- ------ True System.Management.Automation.ArgumentTypeConverterAttribute PS C:UsersWeiyiGeek> $var=3.14;$var 3 PS C:UsersWeiyiGeek> $var="2019 IS END" #无法将值“2019 IS END”转换为类型“System.Int32”。错误:“输入字符串的格式不正确。” PS C:UsersWeiyiGeek> (Get-variable var).Attributes.clear() # 关键点-强类型清除 PS C:UsersWeiyiGeek> $var="2019 IS END";$var 2019 IS END
描述:变量PSVariable对象的Attributes属性能够存储一些附件条件, 常用的变量内容验证分别为:
ValidateLengthAttribute:限制变量的长度ValidateNotNullAttribute:限制变量不能为空ValidateNotNullOrEmptyAttribute:限制变量不等为空,不能为空字符串,不能为空集合ValidatePatternAttribute:限制变量要满足制定的正则表达式ValidateRangeAttribute:限制变量的取值范围ValidateSetAttribute:限制变量的取值集合基础实例:
#1.ValidateLengthAttribute 限制一个字符串变量的长度为位于2-5之间 PS> $var="限制变量" PS> $condition = New-Object System.Management.Automation.ValidateLengthAttribute -ArgumentList 2,5 #关键点 PS> (Get-Variable var).Attributes.Add($condition) PS> $var="射雕英雄传" #变量长度位于2-5之间 #2.ValidateNotNullAttribute 例子 PS> $a=123 PS> $con=New-Object System.Management.Automation.ValidateNotNullAttribute PS> (Get-Variable a).Attributes.Add($con) PS> $a=$null #无法验证此变量,因为值不是变量 a 的有效值。 #3.ValidateNotNullOrEmptyAttribute 例子 注意@()为一个空数组。 PS> $con=New-Object System.Management.Automation.ValidateNotNullOrEmptyAttribute PS> (Get-Variable a).Attributes.clear() PS> (Get-Variable a).Attributes.add($con) PS> $a=$null #4.ValidatePatternAttribute 例子利用正则表达式验证Email格式 PS> $email="@mossfly.com" PS> $con=New-Object System.Management.Automation.ValidatePatternAttribute "[A-Z0-9._%+-]+@[A-Z0-9.-]+.[A-Z]{2,4}" PS> (Get-Variable email).Attributes.Add($con) PS> $email="abc@abc.com" #5.ValidateRangeAttribute 例子验证月份1-12 PS> $month=1 PS> (Get-Variable month).Attributes.Add($(New-Object System.Management.Automation.ValidateRangeAttribute -ArgumentList 1,12)) PS> $month=10
描述: 我们可以把 PS 看作是一个非常强大的计算器,除了支持数学表达式运算符还支持计算机容量单位和HEX进制转换;
计算机容量常用单位: Bit - B - KB - MB - GB - TB - PB
参考地址: https://docs.microsoft.com/zh-cn/powershell/module/microsoft.powershell.core/about/about_arithmetic_operators?view=powershell-7.1
1) 基础运算符: PowerShell 包含了我们常规使用的基础运算符,用于算数运算等
- () - + - - - * - / - %
2) 比较运算符: PowerShell 包含许多比较运算符,用于比较值或查找与特定模式匹配的值。
# 值 & 字符串 -eq 等于 -ne 不等于 -gt 大于 -ge 大于或等于 -lt 小于 -le 小于或等于 -Like 使用 * 通配符进行匹配 -NotLike 不使用 * 通配符进行匹配 -Match 匹配指定的正则表达式 -NotMatch 不匹配指定的正则表达式 -Contains 确定集合中是否包含指定的值 -NotContains 确定集合是否不包含特定值 -In 确定指定的值是否在集合中 -NotIn 确定指定的值是否不在集合中 -Replace 替换指定的值
Tips: 上述列出的所有运算符都不区分大小写,将 c 放置在上次表中列出的运算符之前使其区分大小写。 Tips: -Like 和 -Match 运算符也可能会造成混淆, 其两者的区别是前者与通配符 * 和 ? 结合使用 而后者与正则表达式结合使用。 Tips: PowerShell 版本 3.0 首次引入了“in”比较运算符。换言 -in 执行与 contains 比较运算符相同的测试,不过方向相反。 Tips: 还有一些可用于替换内容的方法如 Replace(),其工作原理类似于替换运算符。但是默认情况下,-Replace 运算符不区分大小写,而 Replace() 方法区分大小写。 Tips: 字符串比较时是模仿忽略大小写并且大小写敏感比较时小写字母小于大写字母。如果需要大小写敏感比较可以使用操作符-ceq, -clt, -cle, -cge,如果要明确的大小写不敏感比较操作符是在默认操作符前加前缀i,即-ieq,-ilt,-ile,-igt,-ige。
3) 逻辑运算符: 顾名思义进行逻辑判断(位运算符仅适用于整数类型)
-and :和 -or :或 -xor :异或 -not | ! :逆 -band 位与 5 -band 3 # 1 -bnot 按位“非” -bnot 5 # -6 -bor 按位“或” 5 -bor 0x03 # 7 -bxor 按位“异或” 5 -bxor 3 # 6 -shl 将位向左移动 3 -shl 2 # 12 -shr 将位向右移动 16 -shr 2 # 4
4) 布尔转换: 包括位操作符在内的多个操作符返回数字类型的值,PowerShell可以自动将其转换为布尔类型的值,转换规则如下:
1) 任何非零值将会被转换为$true 2) 非零长度的字符串将会被转换为$true 3) 至少有一项的集合会返回$true 4) 其他对象将会被转换成$true,除非它们为$null
5) 运算符优先级
- PowerShell 按以下顺序处理算术运算符: # 优先级 运算符 说明 # 1 () 括号 # 2 - 对于负数或一元运算符 # 3 *, /, % 用于乘法和除法 # 4 +, - 加法和减法 # 5 -band, -bnot 对于位运算 # 5 -bor, -bxor 对于位运算 # 5 -shr, -shl 对于位运算 - PowerShell 根据优先规则从左到右处理表达式。 # 表达式 结果 # 3+6/3*4 11 # 3+6/(3*4) 3.5 # (3+6)/3*4 12 - PowerShell 计算表达式的顺序可能不同于你使用的其他编程和脚本语言 在此示例中,对表达式 $a++ 进行计算 $b[$a] 。在 $a++ $a 语句中使用之后,计算更改的值, $c[$a++] 但在中使用它之前 $b[$a] 。 中的 $a 变量 $b[$a] 等于 1 ,而不是 0 ; 因此,语句将值赋给 $b[1] ,而不是 $b[0] 。 $a = 0 $b = @(1,2) $c = @(-1,-2) $b[$a] = $c[$a++] # $b[1] = $c[0] ==> -1
# 1.四则运算(交换式) PS > 3.14*10*10 314 PS > 1+3-(2.4-5)*(7.899-4.444) 12.983 #由 $+圆括号+表达式 构成的变量属于子表达式变量,这样的变量会先计算表达式,然后把表达式的值返回。 PS C:UsersWeiyiGeek> $((3+9)/3) 4 #2.十六进制转换 PS > 0xA 10 PS > 0xB 11 PS > 0xff 255 #3.自动识别计算机容量单位 PS > 1kb 1024 PS > 1GB 1073741824 PS > 1gb 1073741824 PS > 1gb/1kb 1048576 PS > 1gb/20mb*10kb 524288 PS C:ps> 80kb*800*30/1gb # 假如一个网站每个页面大小为80kb,统计显示每天的PV操作为800,1个月下来占用的带宽 1.8310546875
基础示例:
# 1.首字母大写的“PowerShell”等效于使用等于比较运算符的小写的“powershell”。 'PowerShell' -eq 'powershell' # True 'PowerShell' -ceq 'powershell' # False 区别大小写 # 2.不等于比较运算符反转条件。 'PowerShell' -ne 'powershell' # 3.大于、大于或等于、小于和小于或等于均可用于字符串或数值。 5 -gt 5 # False 5 -ge 5 # True # 针对于计算机容量进行比较 PS > 1gb -lt 1gb+1 True PS > 1gb -lt 1gb-1 False # 4.执行"like"匹配 -Like 与通配符 * 和 ? 结合使用 'PowerShell' -like '*shell' # True 'PowerShell' -notLike 'weiyigeek' # True # 5.使用正则表达式执行匹配 -Match 'PowerShell' -match '^*.shell$' 'master@weiyigeek.top' -match '@' # 貌似只要有一个字符串匹配即返回True # True 'master@weiyigeek.top' -match 'ji' # False 'master@weiyigeek.top' -notMatch 'weiye' # True # 6.列表包含或者不包含指定`$Numbers`变量,-NotContains 反转逻辑以查看 $Numbers 变量是否不包含值。 (3,4,5) -contains 2 $Numbers = 1..10 # 使用范围运算符将数字 1 到 10 存储在变量中 $Numbers -contains 15 # False $Numbers -notcontains 15 # True # 7.它用于确定某个值是否“位于”数组中。 # $Numbers 变量是数组,因为它包含多个值。 # 与 -contains 运算符一样,not 反转 -in 运算符的逻辑。 15 -in $Numbers # False 10 -in $Numbers # True 10 -notin $Numbers # False # 8.-replace 运算符 它用于替换内容 # 如果指定一个值,则会将该值替换为空值。 'PowerShell' -replace 'Shell' # Power # 如果要将值替换为其他值,请在要替换的模式之后指定新值。 'my website address is hTTp://wwww.weiyigeek.top' -replace 'http','https' my website address is https://wwww.weiyigeek.top # 如果要区分大小写进行替换请采用 Replace() 方法。 'my website address is hTTp://wwww.weiyigeek.top'.Replace('http','https') my website address is hTTp://wwww.weiyigeek.top # 9.比较数组和集合 PS WeiyiGeek> 1,2,3,4,3,2,1 -eq 3 3 3
基础示例:
# 1.求反运算符为-not 但是像高级语言一样”! “ 也支持求反 PS > $a= 2 -eq 3 PS > $a False PS > -not $a True PS > !($a) True PS > $true -xor $false True PS > $true -xor $true False