【速成】PowerShell快速学习教程

 ℹ️教程说明

PowerShell虽说功能比CMD强大,但在各种技术使用的广泛性上来说,并不比CMD广泛,而且其内容过于庞大,我擅自认为,太深入学习没太大必要,快速掌握其核心内容,遇到的时候查一下帮助,基本就够用了。

本教程,只涵盖核心内容,供大家快速了解掌握PowerShell的基本使用。

📒 参考资料

官方教程:Getting Started with PowerShell - PowerShell | Microsoft Learn

官方中文教程:如何使用 PowerShell 文档 - PowerShell | Microsoft Learn

windows PowerShell官方中文教程:https://learn.microsoft.com/zh-cn/powershell/scripting/developer/windows-powershell-reference

github:https://github.com/PowerShell/PowerShell


一、认识PowerShell及运行环境

1. PowerShell概述

1.1 PowerShell是什么?

2006年,微软推出PowerShell,功能远超CMD,成为微软推荐的“现代CLI”。

powershell是面向对象的命令行Shell和脚本语言环境。 传统 Shell 命令输出的是文本,比如CMD。PowerShell Cmdlet 输出的是.NET 对象

PowerShell与CMD的框架差异:

特性CMDPowerShell
输出类型纯文本对象流
可扩展性固定命令集支持自定义 Cmdlet
脚本能力批处理文件面向对象的脚本语言
错误处理简单退出码详细错误对象

1.2 版本体系

版本家族包括 Windows PowerShell 5.1(内置 Windows),PowerShell 7+(Core,跨平台)。Windows PowerShell 和 PowerShell 是两个独立的产品:

  • Windows PowerShell 是 Windows 中随附的 PowerShell 版本,不再更新,可执行文件名为 powershell.exe
  • PowerShell独立安装软件,在版本 6 及更高版本中,可执行文件命名 pwsh.exe

 核心区别

特性Windows PowerShell 5.1PowerShell 7(Core)
基础架构基于 .NET Framework基于 .NET Core / .NET 5+
跨平台支持仅限 Windows支持 Windows、Linux、macOS
开源与更新频率闭源,微软维护开源(GitHub),活跃更新
版本迭代停止功能更新(仅安全补丁)持续更新(PowerShell 7.x)
兼容性完全兼容传统 Windows 组件部分 .NET Framework 功能受限
默认安装位置系统内置(通常是:C:\Windows\System32\WindowsPowerShell)需单独安装(通过 Microsoft Store 或安装包,自行选择安装路径)

💡本教程,以PowerShell7为准,不过基本是核心内容,大部分也使用Windows PowerShell 5.1


2. 安装

2.1 Windows系统安装

 使用 WinGet 安装 PowerShell(推荐)

WinGet(Windows 包管理器)是一种命令行工具,允许用户在 Windows 客户端计算机上发现、安装、升级、删除和配置应用程序。 此工具是 Windows 程序包管理器服务的客户端接口。 默认情况下,winget 命令行工具作为应用安装程序与 Windows 11 和现代版本的 Windows 10 捆绑在一起。

搜索最新版本的 PowerShell

winget search Microsoft.PowerShell

 执行界面:

MSI 包安装

若要在 Windows 上安装 PowerShell,请使用以下链接从 GitHub 下载安装包。

下载后,双击安装程序文件并按照提示进行操作。

安装 ZIP 包

提供有 PowerShell 二进制 ZIP 存档,从而支持高级部署方案。下载以下 ZIP 存档之一,地址如下。

 将内容解压到你选择的位置,然后从该位置运行 pwsh.exe。 与安装 MSI 包不一样,安装 ZIP 存档不会检查先决条件。 

 2.2 linux系统安装

# Linux(Ubuntu)安装
sudo apt-get install -y powershell

3. 运行

 3.1 识别不同版本的PowerShell

在开始菜单,查找powershell,你可能看到本机的各种版本:

各版本说明:

  • PowerShell 7,独立安装的版本
  • Windows PowerShell是系统自带的
    •  64 位版本的 Windows PowerShell 控制台和 Windows PowerShell 集成脚本环境(ISE)
    •  快捷方式上用 (x86)标识的32 位版本
  • 基于不同开发环境的版本,如Developer PowerShell for VS2022

3.2 查看不同版本

PowerShell 中有自动变量用于存储状态信息。 其中一个变量 $PSVersionTable包含有关 PowerShell 会话的版本信息。

运行不同的版本,返回对应的版本信息:

3.3 管理员运行权限

如果需要使用提升的权限运行 PowerShell, 选择“ 以管理员身份运行”:

二、PowerShell命令

1. cmdlet

cmdlet(读作 command-let)是本机 PowerShell 命令。  cmdlet 收集在 PowerShell 模块中,可按需加载。 可以用任何编译的 .NET 语言或 PowerShell 脚本语言本身来编写 cmdlet。除了 cmdlet 外,使用 PowerShell 还可以在系统上运行任何可用命令。

Cmdlet命令结构

PowerShell 使用“动词-名词”名称对来命名 cmdlet。动词标识 cmdlet 执行的操作,名词标识该 cmdlet 执行其操作的所在资源。 

基本结构:
<动词>-<名词> [-参数名] [参数值]

示例: 

Get-Command 命令,用于获取在命令行界面中注册的所有 cmdlet。


2. 几个基础命令

PowerShell 随附数百个预安装命令,不过有帮助我们了解PowerShell命令的命令。

 PowerShell 中核心cmdlet:

  • Get-Verb。 运行此命令时,将返回大多数命令遵循的动词的列表,和功能的说明。 
  • Get-Member。 它在基于对象的输出上运行,并且能够发现可用于命令的对象、属性和方法。
  • Get-Help。 以命令名称为参数调用此命令,将显示一个帮助页面,其中说明了命令的各个部分。

 2.1 Get-Verb

获取所有可用动词列表

Get-Verb

下面是前几行的输出:

Verb    AliasPrefix   Group     Description
----    -----------   -----     -----------
Add     a             Common    Adds a resource to a container, or attaches an item to another item
Clear   cl            Common    Removes all the resources from a container but does not delete the container
Close   cs            Common    Changes the state of a resource to make it inaccessible, unavailable, or unusab…
Copy    cp            Common    Copies a resource to another name or to another container
Enter   et            Common    Specifies an action that allows the user to move into a resource
Exit    ex            Common    Sets the current environment or context to the most recently used context
...

常用动词

动词含义示例
Get获取/检索数据Get-Process
Set修改/配置数据Set-Service
Start启动操作Start-Job
Stop停止操作Stop-Process
New创建新资源New-Item
Remove删除资源Remove-Item
Export导出数据Export-Csv
Import导入数据Import-Csv

2.2 Get-Command

 Get-Command 将返回系统上所有可用命令的列表。 当然,可以通过参数筛选,以及通配符。

几个常用参数,也可以组合使用

参数用途示例
-Name按名称查找命令,支持通配符 *Get-Command -Name "*Service*"
-CommandType (或 -Type)按特定类型查找命令。Get-Command -CommandType Cmdlet
-Verb查找具有特定动词的命令(如 Get, Set, New)。动词描述了命令执行的操作。Get-Command -Verb Get
-Noun查找具有特定名词的命令(如 Service, Process, Item)。名词描述了命令操作的对象。Get-Command -Noun Service
-ParameterName查找其参数中包含特定参数名的命令,用于探索具有相似功能或参数的命令。Get-Command -ParameterName LogLevel

示例:

# 列出所有可用的命令(Cmdlets, 函数, 别名等)
Get-Command

# 列出所有名为 Get-* 的命令
Get-Command -Name Get-*

# 查找所有处理进程的命令
Get-Command -Noun *Process*

# 查找所有执行“停止”操作的命令
Get-Command -Verb Stop

#组合使用
Get-Command -Verb Get -Noun U*

2.3 Get-Help

通过Get-Help ,查找命令,及获得其使用说明。

⚠️注意:从 PowerShell 版本 3.0 开始,帮助内容没有随操作系统预装。 首次运行 Get-Help 时,询问是否要将 PowerShell 帮助文件下载到计算机,如果没有类似提示,以管理员身份运行 PowerShell,再进行尝试。

基本语法

Get-Help [-Name] <字符串> [-Full] [-Detailed] [-Examples] [-Online] [-Parameter <字符串>]

常用参数:

参数类型说明
-NameString指定命令或主题名称
-CategoryString[]筛选帮助类型(Cmdlet、Function、Script、Alias、Provider、General)
-ComponentString[]按组件筛选(如 Microsoft.PowerShell.Utility)
-FunctionalityString[]按功能域筛选(如 FileSystem)
-RoleString[]按角色筛选(如 Administrator)
-ParameterString[]查看指定参数的说明
-FullSwitch显示完整帮助内容
-DetailedSwitch显示中等详细度帮助
-ExamplesSwitch显示示例
-OnlineSwitch打开在线文档
-ShowWindowSwitchGUI 显示帮助(仅 Windows)

示例:

# 显示 Get-Process 命令的基本帮助
Get-Help -Name Get-Process

# 显示详细的帮助,包含参数说明和示例
Get-Help -Name Get-Process -Detailed

# 显示完整的帮助,包含技术细节
Get-Help -Name Get-Process -Full

# 显示帮助中的示例部分,非常实用!
Get-Help -Name Get-Process -Examples

# 更新帮助文档(需要管理员权限)
Update-Help

 3. 对象及相关命令

在 PowerShell 中,命令的输出是 .NET 对象。对象是一个结构化的数据实体,它包含:

  • 属性(Properties):描述对象的特征(例如,一个“文件”对象有 NameLength(大小)、LastWriteTime 等属性)。类似于Excel表格中的列。

  • 方法(Methods):对象可以执行的操作(例如,一个“文件”对象可以有 Delete()CopyTo() 等方法)。它们是动态的函数。

  • 事件(Events):对象可以触发的通知(较少在日常脚本中使用)。

示例:

Get-ChildItem -Name "somefile.txt"
# 输出不是一个字符串,而是一个 `System.IO.FileInfo` 类型的对象。
# 你可以直接访问它的 `Length` 属性:
$file = Get-ChildItem -Name "somefile.txt"
$file.Length # 直接返回数字 102400,你可以直接用它进行数学计算或比较。

3.1. 发现对象(使用 Get-Member

当你不知道一个命令返回什么对象或对象有哪些属性/方法时,使用 Get-Member(别名 gm)。

示例:

Get-Process | Get-Member

这条命令会列出 Get-Process 输出的所有对象类型(如 System.Diagnostics.Process)以及该对象的所有属性和方法。这是学习 PowerShell 最重要的命令之一。

示例输出摘要:

TypeName: System.Diagnostics.Process
Name                       MemberType Definition
----                       ---------- ----------
Name                       Property   string Name {get;set;}
Id                         Property   int Id {get;}
CPU                        Property   double CPU {get;}
...
Kill                       Method     void Kill()
Start                      Method     bool Start()
...

 使用 MemberType 参数可以限制返回的信息,如下例:

Get-Process | Get-Member -MemberType Method

3.2 选择/过滤属性(使用 Select-Object

Select-Object(别名 select)允许你从对象中选择特定的属性,甚至可以创建计算属性。

示例:

# 只显示进程的名称和CPU占用
Get-Process | Select-Object Name, CPU

# 列出 Get-Process 输出的所有对象类型,仅显示 Name 和 Definition 信息列
Get-Process | Get-Member | Select-Object Name, Definition

# 选择前5个进程,只显示名称和ID,并按ID排序
Get-Process | Sort-Object ID | Select-Object -First 5 Name, Id

# 创建计算属性(例如,将字节转换为MB显示)
Get-ChildItem .\largefile.iso | Select-Object Name, @{Name="Size(MB)"; Expression={$_.Length / 1MB -as [int]}}

3.3 过滤对象(使用 Where-Object

Where-Object(别名 where 或 ?)允许你根据对象的属性值来筛选对象。这里 $_ 代表管道中的当前对象。

示例:

# 找到所有占用内存超过 100MB 的进程
Get-Process | Where-Object { $_.WorkingSet -gt 100MB }

# 找到所有名称以 "code" 开头的进程(不区分大小写)
Get-Process | Where-Object { $_.Name -like "code*" }

3.4 排序对象(使用 Sort-Object

Sort-Object(别名 sort)根据一个或多个属性对对象进行排序。

示例:

# 按CPU占用降序排序进程
Get-Process | Sort-Object CPU -Descending

# 先按公司名称排序,再按进程名称排序
Get-Process | Sort-Object Company, Name

3.5 将对象分组(使用 Group-Object

Group-Object(别名 group)根据属性值将对象分组。

示例:

# 按进程的公司名称分组
Get-Process | Group-Object Company

# 查看每个文件扩展名的数量
Get-ChildItem | Group-Object Extension -NoElement

3.6 调用对象的方法

既然输出是对象,你就可以直接调用它们的方法。

示例:

# 获取Notepad进程并调用Kill()方法结束它
$notepad = Get-Process -Name notepad
$notepad.Kill() # 调用方法

# 一次性结束所有Chrome进程
Get-Process -Name chrome | ForEach-Object { $_.Kill() }

⚠️警告: 像 .Kill() 这样的方法具有破坏性,使用前请务必确认!

4. 常用命令

让我们用新学的概念来完成一些常见任务。

任务命令说明
浏览文件系统Get-ChildItem (dirls)列出当前目录内容
Set-Location (cd)切换目录
Get-Location (pwd)显示当前目录
处理项目New-Item (ni)创建新文件或目录
Remove-Item (delrm)删除项目
Copy-Item (copycp)复制项目
Move-Item (movemv)移动项目
Get-Content (catgc)读取文件内容
Set-Content (sc)写入内容到文件
处理进程和服务Get-Process (ps)获取运行中的进程
Stop-Process (kill)停止进程
Get-Service获取系统服务状态
Start-Service启动服务
Stop-Service停止服务

示例

# 1. 找到所有大于 1MB 的 .log 文件并删除它们
Get-ChildItem -Path C:\Logs -Filter *.log | Where-Object {$_.Length -gt 1MB} | Remove-Item -WhatIf
# 注意:-WhatIf 参数是安全帽,它会预览执行结果而不实际操作。确认无误后去掉它。

# 2. 创建一个目录和一个新文件,并写入内容
New-Item -ItemType Directory -Path ./MyProject
New-Item -ItemType File -Path ./MyProject/script.ps1
Set-Content -Path ./MyProject/script.ps1 -Value “# My first script`nGet-Date”

# 3. 获取所有正在运行的服务,并导出为 CSV 文件
Get-Service | Where-Object {$_.Status -eq 'Running'} | Export-Csv -Path ./running_services.csv -NoTypeInformation

# 4. 排序和选择
Get-Process | Sort-Object -Property CPU -Descending | Select-Object -First 5 -Property Name, CPU, ID

三、脚本编程

1. 脚本结构

PowerShell 脚本文件后缀.ps1,可以使用任何文本编辑器创建它们。

1.1 创建脚本

创建第一个脚本 HelloWorld.ps1

# 这是一个注释
Write-Host "Hello, World!" -ForegroundColor Green
1.2 运行脚本

在运行脚本前,可能需要设置执行策略(以管理员身份运行),先跳过,后面详细介绍。

  1. 直接调用

    .\HelloWorld.ps1
  2. 使用 PowerShell 命令行

    powershell -File "C:\path\to\script.ps1"
  3. 带参数执行

    powershell -Command "& {C:\Scripts\MyScript.ps1 -Parameter1 value1}"
1.3注释
# 单行注释

<#
  多行注释
  可以跨越多行
#>
1.4 管道

管道 (|) 将一个命令的输出作为另一个命令的输入:

# 获取所有服务,然后只选择运行中的服务
Get-Service | Where-Object {$_.Status -eq "Running"}

# 获取进程,按CPU使用率排序,选择前5个
Get-Process | Sort-Object CPU -Descending | Select-Object -First 5
1.5 脚本通用结构

一个规范的脚本通常包含:

  1. Param 块 — 声明输入参数

  2. Begin / Process / End 块 — 处理逻辑

  3. 错误处理与退出码

  4. 日志输出

示例:

Param(
    [Parameter(Mandatory=$true)]
    [string]$SourcePath,

    [string]$DestinationPath = "C:\Backup"
)

Begin {
    Write-Host "Starting backup..." -ForegroundColor Green
}

Process {
    Copy-Item -Path $SourcePath -Destination $DestinationPath -Recurse -Force
}

End {
    Write-Host "Backup completed successfully." -ForegroundColor Green
}

脚本执行逻辑:

 ┌───────────┐
 │  解析参数 │
 └─────┬─────┘
       │
       ▼
 ┌───────────┐
 │   Begin   │ 初始化资源(日志、变量、连接)
 └─────┬─────┘
       │
       ▼
 ┌───────────┐
 │ Process   │ 主体逻辑,可多次执行(管道输入逐条处理)
 └─────┬─────┘
       │
       ▼
 ┌───────────┐
 │   End     │ 释放资源、汇总结果
 └───────────┘

💡原理说明:如果脚本或函数有管道输入,Process 会对每个输入对象执行一次;如果没有管道输入,则执行一次。


2. 基本语法

2.1 变量、数据类型与运算符
1. 变量 (Variables)

PowerShell 中的变量不需要显式声明类型(尽管可以),使用 $ 符号前缀来定义和引用。

# 创建变量并赋值
$myString = "Hello, World!"
$myNumber = 42
$myArray = 1, 2, 3, 4, 5
$myProcesses = Get-Process

# 使用变量
Write-Output $myString
$myNumber + 10

# 变量名可以包含空格,但不推荐,需用花括号包裹
${My Variable With Space} = "Strange but possible"
Write-Output ${My Variable With Space}
2. 数据类型

虽然 PowerShell 是动态类型的,但你有时需要强制类型转换以确保数据完整性。

# 自动类型推断
$var = "100" # 这是字符串
$var = 100   # 这是整数

# 强制类型转换
[int]$number = "100" # $number 被强制为整型
[string]$text = 100  # $text 被强制为字符串 "100"

# 常见类型
[string], [int], [double], [datetime], [bool]($true, $false), [array]
3. 运算符 (Operators)
  • 算术运算符+-*/% (取模)

  • 赋值运算符=+=-=*=/=

  • 比较运算符: (注意:与大多数语言不同!)

    • -eq (equal), -ne (not equal)

    • -gt (greater than), -ge (greater or equal)

    • -lt (less than), -le (less or equal)

    • -like-notlike (使用 * 通配符, e.g., "hello" -like "h*")

    • -match-notmatch (使用正则表达式)

  • 逻辑运算符-and-or-not or !

示例:

$result = 10 - 5 * 2 # 结果为 0 (遵循数学运算顺序)
$isAdmin = $false
$name = "PowerShell"

if ($name -like "Power*" -and !$isAdmin) {
    Write-Output "Name matches and user is not admin."
}
2.2 流程控制

这是编程逻辑的核心。

1. 条件语句: ifelseifelse
$time = Get-Date

if ($time.Hour -lt 12) {
    Write-Output "Good morning!"
} elseif ($time.Hour -lt 18) {
    Write-Output "Good afternoon!"
} else {
    Write-Output "Good evening!"
}
2. 循环语句
  • foreach: 遍历集合中的每个项目。

    $services = Get-Service
    foreach ($service in $services) {
        if ($service.Status -eq 'Running') {
            Write-Output "$($service.Name) is running."
        }
    }
  • For: 当你需要索引或计数器时。

    for ($i = 0; $i -lt 10; $i++) {
        Write-Output "Iteration number: $i"
    }
  • While: 当条件为真时持续循环。

    $counter = 0
    while ($counter -lt 5) {
        Write-Output "Counter is $counter"
        $counter++
    }
  • Do...While / Do...Until: 至少执行一次循环体。

    $inputValue = ""
    do {
        $inputValue = Read-Host -Prompt "Enter 'quit' to exit"
    } until ($inputValue -eq 'quit')

循环控制:

  • break: 立即退出整个循环。

  • continue: 立即跳到下一个迭代,跳过循环体内后续语句。

2.3 函数:创建可重用代码块

函数是脚本编程的基石,用于模块化和重用代码。

1. 基本函数
function Say-Hello {
    Write-Output "Hello, World!"
}

# 调用函数
Say-Hello
2. 带参数的函数

参数使函数变得灵活强大。

function Get-MyProcess {
    param(
        [string]$Name,
        [int]$Id
    )
    if ($Name) {
        Get-Process -Name $Name
    } elseif ($Id) {
        Get-Process -Id $Id
    } else {
        Get-Process
    }
}

# 调用方式 1: 按参数名
Get-MyProcess -Name "notepad"
# 调用方式 2: 按参数位置(如果定义了位置)
Get-MyProcess "notepad"
3. 返回值

PowerShell 函数不显式使用 return 语句。任何未捕获的输出都会成为返回值。

function Add-Numbers {
    param([int]$a, [int]$b)
    $a + $b # 这行输出就是返回值
    # Write-Output ($a + $b) # 效果同上
}

$sum = Add-Numbers 5 3
Write-Output "The sum is $sum" # The sum is 8

如果需要提前退出并返回值,可以使用 return


3. 脚本模块化

点源加载(Dot Sourcing)

创建通用函数文件 Utils.ps1

function Test-IsAdmin {
    $currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()
    $adminRole = [Security.Principal.WindowsBuiltInRole]::Administrator
    return (New-Object Security.Principal.WindowsPrincipal $currentUser).IsInRole($adminRole)
}

function Get-FileSize {
    param($Path)
    if (Test-Path $Path) {
        $file = Get-Item $Path
        return "$([math]::Round($file.Length / 1KB, 2)) KB"
    }
    return "文件不存在"
}

在主脚本中加载和使用:

# 点源加载(函数在当前会话中可用)
. .\Utils.ps1

# 使用加载的函数
if (Test-IsAdmin) {
    Write-Host "正在以管理员权限运行"
} else {
    Write-Host "需要管理员权限"
}

4. 错误处理

编写健壮的脚本必须处理错误。

1. $Error 自动变量

所有发生的错误都会记录在 $Error 数组中。

Get-Content -Path "nonexistentfile.txt" -ErrorAction SilentlyContinue
if ($Error.Count -gt 0) {
    Write-Output "The last error was: $($Error[0].Exception.Message)"
}
2. -ErrorAction 参数

控制 Cmdlet 对非终止错误的反应。

  • Stop: 将错误视为终止错误

  • SilentlyContinue: 静默失败,不显示错误。

  • Continue: 显示错误并继续(默认)。

  • Ignore: 静默失败,且错误不记录到 $Error

3. Try...Catch...Finally

处理终止错误的标准方式。

try {
    # 可能出错的代码
    Get-Content -Path "nonexistentfile.txt" -ErrorAction Stop # 注意这里必须是 Stop
    Write-Output "This will not execute if an error occurs."
}
catch [System.Management.Automation.ItemNotFoundException] {
    # 捕获特定类型的异常
    Write-Output "File was not found!"
    Write-Output $_.Exception.Message # $_ 包含错误详情
}
catch {
    # 捕获所有其他类型的异常
    Write-Output "An unexpected error occurred:"
    Write-Output $_.Exception.Message
}
finally {
    # 无论是否出错都会执行的代码,常用于资源清理
    Write-Output "Script block execution finished."
}

5. 脚本执行策略

PowerShell 的执行策略(Execution Policy) 是一种安全机制,用于控制 PowerShell 脚本的运行权限,以防止无意中执行恶意脚本。

📌 执行策略仅影响脚本中运行的命令,交互方式不受影响。 

5.1 执行策略级别

PowerShell 提供了多个执行策略级别,按限制强度从高到低排列:

策略名称描述
Restricted(受限)⛔ 默认策略(Windows 客户端)。不允许运行任何脚本,只能在命令行交互式输入命令。
AllSigned(全部签名)✅ 只允许运行由受信任的发布者签名的脚本。首次运行某发布者的脚本时会提示确认。
RemoteSigned(远程签名)✅ 本地脚本可直接运行;从互联网下载或远程获取的脚本必须由受信任的发布者签名。这是 Windows Server 的默认策略。
Unrestricted(无限制)⚠️ 允许运行所有脚本,但运行从互联网下载的脚本前会提示警告(需用户确认)。不推荐生产环境使用。
Bypass(绕过)🚫 不阻止、不提示、不限制。所有脚本均可静默运行。常用于自动化部署或 CI/CD 环境。⚠️ 高风险!
Undefined(未定义)表示当前作用域没有设置执行策略,将继承上层作用域的策略。如果是最高层(MachinePolicy/UserPolicy),则默认为 Restricted。

可视化对比:

安全性  ██████ Restricted
安全性  █████  AllSigned
安全性  ████   RemoteSigned
安全性  ███    Unrestricted
安全性  █      Bypass

💡 注意:Unrestricted 和 Bypass 有本质区别 —— 前者仍有提示,后者完全静默。

5.2 执行策略的作用范围(作用域)

执行策略可以针对不同“作用域”设置,优先级从高到低如下:

MachinePolicy       ← 组策略设置(计算机级别)
UserPolicy          ← 组策略设置(用户级别)
Process             ← 当前 PowerShell 进程(临时)
CurrentUser         ← 当前用户
LocalMachine        ← 本机所有用户(默认修改目标)

 ✅ 使用 Get-ExecutionPolicy 查看当前生效的策略:

Get-ExecutionPolicy

✅ 使用 Get-ExecutionPolicy -List 查看各作用域的策略:

Get-ExecutionPolicy -List

看到类似下面的输出,它清晰地展示了每个作用域的设置以及最终生效的策略(由优先级决定):

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser    RemoteSigned  <-- 当前用户设置了 RemoteSigned
 LocalMachine       AllSigned  <-- 整台机器设置了 AllSigned

在这个例子中,因为 CurrentUser 的优先级高于 LocalMachine,所以当前用户最终生效的策略是 RemoteSigned

5.3 设置执行策略

使用 Set-ExecutionPolicy 命令,需要管理员权限(除非设置 Process 或 CurrentUser)。

示例:        

  • 为当前用户设置 RemoteSigned:
  • Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
  • 仅对当前 PowerShell 会话有效(退出后失效):
  • Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process
  • 重置为默认(通常为 Restricted):
  • Set-ExecutionPolicy -ExecutionPolicy Restricted -Scope LocalMachine

🔐 设置策略时可能会要求确认,加 -Force 可跳过确认:

Set-ExecutionPolicy RemoteSigned -Force

5.4 临时绕过执行策略(非常实用)

临时运行一个脚本,不想永久更改系统的策略设置,使用参数-ExecutionPolicy Bypass:

powershell.exe -ExecutionPolicy Bypass -File "C:\Scripts\MyScript.ps1"

或者在当前会话中临时设为 Bypass:

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass

解释:

  • powershell.exe: 启动一个新的 PowerShell 进程。
  • -ExecutionPolicy Bypass: 告诉这个新进程使用 Bypass 策略。
  • -File "...": 指定要运行的脚本文件。

这个命令不会改变任何已保存的策略设置,仅在这一次运行时生效。它非常适合用在批处理文件 (.bat)、任务计划程序或CI/CD流水线中。

6.5 常见问题

  • 设置了策略却不起作用

检查是否有更高优先级的作用域(如组策略 MachinePolicy)覆盖了你的设置:

Get-ExecutionPolicy -List

组策略设置的策略优先级最高,普通用户无法修改。

  • 解除组策略设置的执行策略

需通过组策略编辑器(gpedit.msc)或联系域管理员修改:

路径:
计算机配置 → 管理模板 → Windows 组件 → Windows PowerShell

⚠️Windows家庭版默认不包含组策略编辑器,用户需要手动添加或升级到专业版。


四、示例

1. 系统信息查询脚本

<#
.SYNOPSIS
显示系统基本信息
#>

Write-Host "=== 系统信息 ===" -ForegroundColor Cyan

# 操作系统信息
$os = Get-CimInstance Win32_OperatingSystem
Write-Host "操作系统: $($os.Caption)"
Write-Host "版本: $($os.Version)"
Write-Host "安装日期: $($os.InstallDate.ToString('yyyy-MM-dd'))"

# 处理器信息
$cpu = Get-CimInstance Win32_Processor
Write-Host "`n处理器: $($cpu.Name)"

# 内存信息
$memory = Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property Capacity -Sum
$totalMemoryGB = [math]::Round($memory.Sum / 1GB, 2)
Write-Host "总内存: $totalMemoryGB GB"

Write-Host "`n=== 信息显示完毕 ===" -ForegroundColor Cyan

2. 文件备份脚本

<#
.SYNOPSIS
备份指定目录到目标位置
#>

param(
    [string]$sourcePath = "C:\Documents",
    [string]$backupPath = "D:\Backups"
)

# 检查源目录是否存在
if (-not (Test-Path $sourcePath)) {
    Write-Error "源目录不存在: $sourcePath"
    exit 1
}

# 创建备份目录(如果不存在)
$backupFolder = Join-Path $backupPath "Backup_$(Get-Date -Format 'yyyyMMdd_HHmmss')"
New-Item -ItemType Directory -Path $backupFolder | Out-Null

# 执行备份
try {
    Write-Host "开始备份... 源: $sourcePath 目标: $backupFolder"
    Copy-Item -Path $sourcePath -Destination $backupFolder -Recurse -Force
    Write-Host "备份完成!" -ForegroundColor Green
}
catch {
    Write-Error "备份失败: $_"
    exit 1
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

正经教主

有钱捧个钱场,没钱捧个人场👌

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值