源代码下载: LearnPowershell-cn.ps1
PowerShell 是 Windows 平台下的脚本语言同时也是配置管理框架,它是建设在微软 .Net Framework 之上,Windows 7 以及之后版本都内置 Poweshell。上面的示例中都是 PoweShell 脚本的一部分或者间接可能在 Shell 交互窗口中执行。
与 Bash 最大的不同是你大部分操作的货色是对象而不是一般的文本。
延长浏览
如果你不确定你的环境,执行如下操作:
Get-ExecutionPolicy -ListSet-ExecutionPolicy AllSigned# Execution Policy 蕴含以下:# - Restricted: 不会运行脚本。# - RemoteSigned: 只会运行受信赖的发行商下载的脚本。# - AllSigned: 运行须要被信赖发行商签名的脚本。# - Unrestricted: 运行所有脚本help about_Execution_Policies # 查看更多信息# 以后 PowerShell 版本$PSVersionTable
获取帮忙
# 查找命令Get-Command about_* # 别名: gcmGet-Command -Verb AddGet-Alias psGet-Alias -Definition Get-ProcessGet-Help ps | less # 别名: helpps | Get-Member # 别名: gmShow-Command Get-EventLog # GUI 填充参数Update-Help # 管理员运行
接下来是教程
# 正如你看到的,每一行结尾是 # 都是正文# 简略的 Hello World 实例echo Hello world!# echo 是 Write-Output (cmdlet) 的别名# 大部分 cmdlet 和函数都遵循 "动词-名词" 命名规定。# 每个命令都从新的一行开始或者是一个分号echo 'This is the first line'; echo 'This is the second line'# 申明一个变量如下:$aString="Some string"# 或者像这样:$aNumber = 5 -as [double]$aList = 1,2,3,4,5$anEmptyList = @()$aString = $aList -join '--' # 也蕴含 join 办法$aHashtable = @{name1='val1'; name2='val2'}# 应用变量:echo $aStringecho "Interpolation: $aString"echo "$aString has length of $($aString.Length)"echo '$aString'echo @"This is a Here-String$aString"@# 留神 ' (单引号) 不是变量的一部分# 在这里字符串也能够是单引号# 内置变量:# 上面是一些有用的内置变量,比方:echo "Booleans: $TRUE and $FALSE"echo "Empty value: $NULL"echo "Last program's return value: $?"echo "Exit code of last run Windows-based program: $LastExitCode"echo "The last token in the last line received by the session: $$"echo "The first token: $^"echo "Script's PID: $PID"echo "Full path of current script directory: $PSScriptRoot"echo 'Full path of current script: ' + $MyInvocation.MyCommand.Pathecho "FUll path of current directory: $Pwd"echo "Bound arguments in a function, script or code block: $PSBoundParameters"echo "Unbound arguments: $($Args -join ', ')."# 更多的内置类型: `help about_Automatic_Variables`# 内联其余文件 (点操作符). .\otherScriptName.ps1### 控制流# 上面是条件判断构造if ($Age -is [string]) { echo 'But.. $Age cannot be a string!'} elseif ($Age -lt 12 -and $Age -gt 0) { echo 'Child (Less than 12. Greater than 0)'} else { echo 'Adult'}# Switch 语句比其余语言更弱小$val = "20"switch($val) { { $_ -eq 42 } { "The answer equals 42"; break } '20' { "Exactly 20"; break } { $_ -like 's*' } { "Case insensitive"; break } { $_ -clike 's*'} { "clike, ceq, cne for case sensitive"; break } { $_ -notmatch '^.*$'} { "Regex matching. cnotmatch, cnotlike, ..."; break } { 'x' -contains 'x'} { "FALSE! -contains is for lists!"; break } default { "Others" }}# 经典的 For 循环for($i = 1; $i -le 10; $i++) { "Loop number $i"}# 或者能够更简洁1..10 | % { "Loop number $_" }# PowerShell 还提供其余循环形式foreach ($var in 'val1','val2','val3') { echo $var }# while () {}# do {} while ()# do {} until ()# 异样解决try {} catch {} finally {}try {} catch [System.NullReferenceException] { echo $_.Exception | Format-List -Force}### Providers# 列出当前目录下的文件和子目录ls # 或者 `dir`cd ~ # 回到主目录Get-Alias ls # -> Get-ChildItem# 这些 cmdlet 有更加通用的名称,因为它不仅仅只操作当前目录,这一点和其余脚本语言不同。cd HKCU: # 跳转 HKEY_CURRENT_USER 注册表中的值# 获取以后会话中的提供者Get-PSProvider### 管道# Cmdlets 中的参数用来管制它们的行为:Get-ChildItem -Filter *.txt -Name # 获取所有 txt 文件名。# 须要输出足够多的参数来确保没有歧义。ls -fi *.txt -n # -f 是不能够的因为 -Force 同样存在。# 应用 `Get-Help Get-ChildItem -Full` 来查看全副参数。# 之前 cmdlet 获取的后果输入能够作为一下个输出。# `$_` 指代以后管道解决的对象。ls | Where-Object { $_.Name -match 'c' } | Export-CSV export.txtls | ? { $_.Name -match 'c' } | ConvertTo-HTML | Out-File export.html# 如果对管道的对象感到纳闷,应用 `Get-Member` 来查看该对象的可应用的办法和属性。ls | Get-MemberGet-Date | gm# ` 是行间断标识符,或者在每一行结尾增加一个 |Get-Process | Sort-Object ID -Descending | Select-Object -First 10 Name,ID,VM ` | Stop-Process -WhatIfGet-EventLog Application -After (Get-Date).AddHours(-2) | Format-List# 应用 % 作为 ForEach-Object 的简称。(a,b,c) | ForEach-Object ` -Begin { "Starting"; $counter = 0 } ` -Process { "Processing $_"; $counter++ } ` -End { "Finishing: $counter" }# Get-Process 返回蕴含三列的表# 第三列是应用 2 位精度数值示意 VM 属性# 计算出来的列也能够示意更多的信息:# `@{name='lbl';expression={$_}`ps | Format-Table ID,Name,@{n='VM(MB)';e={'{0:n2}' -f ($_.VM / 1MB)}} -autoSize### 函数# [string] 注记是可选的。function foo([string]$name) { echo "Hey $name, have a function"}# 调用你的函数foo "Say my name"# 函数能够蕴含命名参数、参数的注记和可解析的文档<#.SYNOPSISSetup a new website.DESCRIPTIONCreates everything your new website needs for much win.PARAMETER siteNameThe name for the new website.EXAMPLENew-Website -Name FancySite -Po 5000New-Website SiteWithDefaultPortNew-Website siteName 2000 # ERROR! Port argument could not be validated('name1','name2') | New-Website -Verbose#>function New-Website() { [CmdletBinding()] param ( [Parameter(ValueFromPipeline=$true, Mandatory=$true)] [Alias('name')] [string]$siteName, [ValidateSet(3000,5000,8000)] [int]$port = 3000 ) BEGIN { Write-Verbose 'Creating new website(s)' } PROCESS { echo "name: $siteName, port: $port" } END { Write-Verbose 'Website(s) created' }}### 都是 .NET# PS 中的字符串事实上就是 .NET 的 System.String 类型# 所有 .NET 办法和属性都可用'string'.ToUpper().Replace('G', 'ggg')# 或者更加 PowerShell 一点'string'.ToUpper() -replace 'G', 'ggg'# 不确定这样的话 .NET 办法如何调用'string' | gm# 调用动态 .NET 办法的语法:[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')# 留神 .NET 办法调用必须应用括号,然而 PS 函数调用不能应用括号;# 如果你调用 cmdlet/PS 函数应用了括号,就相当于传递了参数列表。$writer = New-Object System.IO.StreamWriter($path, $true)$writer.Write([Environment]::NewLine)$writer.Dispose()### IO# 从输出读入一个值$Name = Read-Host "What's your name?"echo "Hello, $Name!"[int]$Age = Read-Host "What's your age?"# Test-Path, Split-Path, Join-Path, Resolve-Path# Get-Content filename # 返回字符串数组 string[]# Set-Content, Add-Content, Clear-ContentGet-Command ConvertTo-*,ConvertFrom-*### 有用的货色# 更新 PATH$env:PATH = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")# 找到 Python 的 PATH$env:PATH.Split(";") | Where-Object { $_ -like "*python*"}# 扭转工作目录而不须要记住之前的门路Push-Location c:\temp # 扭转工作目录至 c:\tempPop-Location # 扭转到之前的工作目录# 别名: pushd 和 popd# 在下载之后解除目录阻塞Get-ChildItem -Recurse | Unblock-File# Windows 资源管理器关上当前目录ii .# 按任意键退出$host.UI.RawUI.ReadKey()return# 创立快捷方式$WshShell = New-Object -comObject WScript.Shell$Shortcut = $WshShell.CreateShortcut($link)$Shortcut.TargetPath = $file$Shortcut.WorkingDirectory = Split-Path $file$Shortcut.Save()
配置你的 PowerShell
# $Profile 是文件 `Microsoft.PowerShell_profile.ps1` 残缺门路# 上面所有的代码都在 PS 会话开始的时候执行if (-not (Test-Path $Profile)) { New-Item -Type file -Path $Profile -Force notepad $Profile}# 更多信息: `help about_profiles`# 更多对于 Shell 有用的信息,确保查看上面的 PSReadLine 我的项目。
更多我的项目
- Channel9 PowerShell 教程
- PSGet PowerShell NuGet 包
- PSReadLine 仿 bash 按行读取( Window10 默认蕴含)
- Posh-Git Git 命令提醒 (举荐!)
- PSake 主动构建工作
- Pester BDD 测试框架
- Jump-Location Poweshell 中
cd
来跳转目录 - PowerShell Community Extensions (废除)
尚未波及
- WMI: Windows 治理标准 (Get-CimInstance)
- 多任务: Start-Job -scriptBlock {...},
- 代码签名
- 近程 (Enter-PSSession/Exit-PSSession; Invoke-Command)
有倡议?或者发现什么谬误?在Github上开一个issue,或者发动pull request!
原著Wouter Van Schandevijl,并由0个好心人批改。
© 2022 Wouter Van Schandevijl
Translated by: Feng Gao
本作品采纳 CC BY-SA 3.0 协定进行许可。