PowerShell变量作用域深度解析

作用域层级原理

1
2
3
4
5
6
7
8
9
10
11
12
13
# 全局作用域示例
$global:config = 'Server1'

function Show-Config {
# 局部作用域访问全局变量
Write-Host $global:config

# 声明私有变量
$private:connection = 'Active'
}

Show-Config
# $connection 在此不可访问

作用域穿透技巧

修饰符 作用范围 生命周期
global 全局可见 永久
script 脚本文件内 脚本周期
private 当前代码块 瞬时
local 默认作用域 瞬时

典型应用场景

  1. 模块开发时使用script作用域封装内部状态
  2. 函数间通信通过reference参数传递对象
  3. 避免使用$global污染全局命名空间
  4. 调试时通过Get-Variable -Scope追踪变量值

常见误区分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 错误的作用域继承示例
function Set-Value {
$value = 100
}

Set-Value
Write-Host $value # 输出为空

# 正确的作用域传递方式
function Get-Value {
$script:value = 200
}

Get-Value
Write-Host $script:value # 输出200

PowerShell 技能连载 - 错误处理机制

异常处理基础结构

1
2
3
4
5
6
7
8
9
10
11
12
try {
Get-Content -Path '不存在的文件.txt' -ErrorAction Stop
}
catch [System.IO.FileNotFoundException] {
Write-Warning "文件未找到: $($_.Exception.Message)"
}
catch {
Write-Error "未知错误: $_"
}
finally {
Write-Output "清理操作完成"
}

错误类型识别

  1. 终止错误:必须使用-ErrorAction Stop
  2. 非终止错误:通过$Error自动变量捕获

高级处理技巧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 自定义错误记录
$ErrorActionPreference = 'Continue'
$ErrorView = 'NormalView'

function Invoke-SafeOperation {
[CmdletBinding()]
param([scriptblock]$ScriptBlock)

try {
& $ScriptBlock
}
catch {
[PSCustomObject]@{
Timestamp = Get-Date
ErrorType = $_.Exception.GetType().Name
Message = $_.Exception.Message
ScriptLine = $_.InvocationInfo.ScriptLineNumber
} | Export-Csv -Path 'errors.log' -Append
}
}

最佳实践

  1. 区分可恢复与不可恢复错误
  2. 使用ErrorRecord对象获取完整信息
  3. 通过$ErrorActionPreference控制默认行为
  4. 定期清理$Error自动变量
1
2
3
4
# 错误信息增强处理
$Error[0] | Select-Object *
$Error[0].InvocationInfo | Format-List *
$Error[0].Exception | Format-List *

PowerShell blog post collection (2023-04 ~ 2024-03)

2023 年 04 月

2023 年 05 月

2023 年 06 月

2023 年 07 月

2023 年 08 月

2023 年 09 月

2023 年 10 月

2023 年 11 月

2024 年

2024 年 01 月

2024 年 02 月

2024 年 03 月

PowerShell 技术互动社区发展状况(2023 年 3 月)

至 2024 年 3 月,“PowerShell 技术互动”社区人数已达到 1976 人,十分接近社区最大容量(2000 人),保持 PowerShell 最大中文社区的位置。根据腾讯社交平台的策略,社区人数的上限为 2000 人,我们会尽可能保留机会给活跃用户。

QQ Group

如您遇到 PowerShell 方面的技术问题,或有好的资源希望分享,请加入我们。QQ 群号:271143343

或者用手机 QQ 扫描二维码:

QR

PowerShell 技能连载 - PowerShell函数的手把手指南

为了在多个脚本中重复使用相同的代码,我们使用PowerShell函数。

PowerShell函数是一组已经被命名的PowerShell语句。每当我们想要运行一个函数时,我们需要输入它的名称。

函数可以像cmdlet一样具有参数。可以通过管道或命令行访问函数参数。
它们返回一个值,该值可以赋给变量或作为命令行参数或函数参数传递。为了指定返回值,我们可以使用关键字return

函数语法

以下是用于Function的语法。

1
2
3
4
5
6
7
8
function [<scope:>]<name> [([type]$parameter1[,[type]$parameter2])]
{
param([type]$parameter1 [,[type]$parameter2])
dynamicparam {<statement list>}
begin {<statement list>}
process {<statement list>}
end {<statement list>}
}

以上语法中包括以下术语:

  1. 一个函数关键短语
  2. 您选择的名称
  3. 功能范围(可选)
  4. 可以有任意数量的命名参数。
  5. 一个或多个 PowerShell 命令被大括号括起来。

函数示例:

1
2
3
4
5
6
7
8
9
function Operation{
$num1 = 8
$num2 = 2
Write-Host "Multiply : $($num1*$num2)"
Write-Host "Addition : $($num1+$num2)"
Write-Host "Subtraction : $($num1-$num2)"
Write-Host "Divide : $($num1 / $num2)"
}
Operation

结果:

1
2
3
4
Multiply : 16
Addition : 10
Subtraction : 6
Divide : 4

函数范围

  • 在 PowerShell 中,函数存在于创建它的范围内。
  • 如果一个函数包含在脚本中,那么它只能在该脚本中的语句中使用。
  • 当我们在全局范围指定一个函数时,我们可以在其他函数、脚本和命令中使用它。

PowerShell 中的高级功能

高级功能是可以执行类似于 cmdlet 执行的操作的功能。当用户想要编写一个不必编写已编译 cmdlet 的函数时,他们可以使用这些功能。

使用已编译 cmdlet 和高级功能之间主要区别是已编译 cmdlet 是.NET Framework 类,必须用.NET Framework 语言编写。此外,高级功能是用 PowerShell 脚本语言编写的。

以下示例展示了如何使用 PowerShell 的高级功能:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function show-Message
{
[CmdletBinding()]
Param (
[ Parameter (Mandatory = $true)]

[string] $Name
)
Process
{
Write-Host ("Hi $Name !")
write-host $Name "today is $(Get-Date)"
}
}

show-message

结果:

1
2
3
4
5
cmdlet show-Message at command pipeline position 1
Supply values for the following parameters:
Name: Dhrub
Hi Dhrub !
Dhrub today is 09/01/2021 13:41:12

结论

我们在每种语言中都使用函数,通常会减少代码的行数。如果您的代码有1000行,那么借助函数的帮助,您可以将计数降至500。希望您喜欢这篇文章,我们下一篇文章再见。

PowerShell 技能连载 - 轻松掌握PowerShell中的ErrorAction

PowerShell 是一种强大的脚本语言,允许用户轻松自动化任务和管理系统。PowerShell 的一个关键特性是 ErrorAction 参数,它允许用户控制脚本或命令中如何处理错误。

理解 PowerShell 中的 ErrorAction

ErrorAction 是一个参数,可用于任何 PowerShell 命令或脚本块,用于指定如何处理错误。可以为 ErrorAction 参数分配几个值,例如 Continue、SilentlyContinue、Stop 和 Inquire。

示例:使用 ErrorAction

在 PowerShell 中,-ErrorAction 参数允许您指定如何处理特定命令或脚本的错误。您可以使用此参数与多个可能值,包括 ContinueSilentlyContinueStopInquire。以下是如何使用这些值的示例:

  1. Continue: 此选项告诉 PowerShell 在发生错误时继续执行脚本或命令,并显示错误消息后继续执行剩余代码。
1
Get-ChildItem -Path “C:\\NonexistentFolder” -ErrorAction Continue**
  1. SilentlyContinue: 此选项告诉 PowerShell 抑制错误消息并继续执行脚本或命令。不会显示错误消息。
1
Get-Item -Path “C:\\NonexistentFile” -ErrorAction SilentlyContinue**
  1. Stop: 此选项告诉 PowerShell 如果发生错误,则停止执行脚本或命令。它将终止该脚本并显示错误消息。
1
Remove-Item -Path “C:\\ImportantFile” -ErrorAction Stop**
  1. Inquire:这个选项与其他选项有些不同。当发生错误时,它会提示用户输入,让他们决定是继续执行还是停止。通常与trycatch块一起用于交互式错误处理。

请注意,这些错误操作的实际行为可能会因您使用的特定 cmdlet 或脚本而异,因为并非所有 cmdlet 都支持所有错误操作首选项。但根据您的需求,在 PowerShell 中处理错误的常见方法如下。

使用 ErrorAction 的最佳实践

在使用 ErrorAction 参数时,请记住以下一些最佳实践:

  • 始终明确指定 ErrorAction 参数以确保一致的错误处理。
  • 如果要确保捕获并显示任何错误,请考虑使用 Stop 值。
  • 使用 Try-Catch-Finally 结构来处理特定错误并执行清理操作。

结论

ErrorAction 参数是 PowerShell 中一个强大的工具,允许用户控制如何处理错误。通过了解如何使用此参数并遵循最佳实践,您可以编写更健壮和可靠的脚本。所以,在下次在 PowerShell 脚本中遇到错误时,请记得利用 ErrorAction 参数来优雅地处理它!

PowerShell 技能连载 - 理解 PowerShell 执行策略:初学者指南

PowerShell 是一种强大的脚本语言和自动化框架,被广泛应用于IT专业人员和系统管理员。PowerShell 的一个重要方面是 PowerShell 执行策略,它确定了在系统上运行脚本的安全级别。

如果您是 PowerShell 新手,可能已经遇到过像“set-executionpolicy”和“get-executionpolicy”这样的术语。在本博客文章中,我们将探讨这些命令的作用以及它们为何重要。

什么是 PowerShell 执行策略?

执行策略是 PowerShell 中的一个安全功能,确定是否可以在系统上运行脚本。它有助于防止恶意脚本在用户不知情或未经同意的情况下被执行。

有不同级别的执行策略:

  • Restricted:不允许运行任何脚本。这是默认设置。
  • AllSigned:只有由受信任发布者签名的脚本才能运行。
  • RemoteSigned:从互联网下载的脚本需要签名,但可以无需签名地运行本地脚本。
  • Unrestricted:任何脚本都可以无限制地运行。

设置 PowerShell 执行策略

要设置执行策略,您可以使用‘set-executionpolicy’命令后跟所需的策略级别。例如,要将执行策略设置为‘RemoteSigned’,您可以运行:

1
set-executionpolicy RemoteSigned

请注意,在更改执行策略时需要具备管理权限。

获取执行策略

要检查当前执行策略,请使用‘get-executionpolicy’命令。这将显示当前策略等级。

1
get-executionpolicy

执行策略为什么重要?

执行策略对于维护系统安全至关重要。默认情况下,PowerShell具有受限的执行策略,这意味着无法运行任何脚本。这有助于防止意外运行恶意脚本。

然而,在某些情况下,您可能需要在系统上运行脚本。在这种情况下,您可以将执行策略更改为更宽松的级别,例如“RemoteSigned”或“Unrestricted”。

值得注意的是,将执行策略更改为更宽松的级别可能会增加运行恶意脚本的风险。因此,建议仅在必要时更改执行策略,并在从不受信任的来源运行脚本时保持谨慎。

结论

了解PowerShell执行策略对于任何IT专业人员或系统管理员都是至关重要的。它有助于维护系统安全性同时允许您在需要时运行脚本。

在这篇博客文章中,我们介绍了执行策略的基础知识、如何设置以及如何检查当前政策水平。请记住,在运行脚本时始终保持谨慎,并仅在必要时更改执行策略。

PowerShell 技能连载 - 获取法国假期

我看到了这篇博客文章,决定为法国发布这个。下面是一个获取所有法国假日的 PowerShell 函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function Get-FrenchHoliday
{
param
(
[int]
$Year = (Get-Date).Year,

[ValidateSet("alsace-moselle", "guadeloupe", "guyane", "la-reunion", "martinique", "mayotte", "metropole", "nouvelle-caledonie", "polynesie-francaise", "saint-barthelemy", "saint-martin", "saint-pierre-et-miquelon", "wallis-et-futuna")]
[string]
$Area = 'metropole',

[switch]
$NextOnly
)

$url = "https://calendrier.api.gouv.fr/jours-feries/$Area/$Year.json"

$holidays = Invoke-RestMethod -Uri $url -UseBasicParsing

foreach ($obj in $holidays.PSObject.Properties) {
if (-Not ($NextOnly.IsPresent) -or (((([DateTime]$obj.Name).Ticks) - (Get-Date).Ticks) -gt 0)) {
Write-Host "$($obj.Value) : $($obj.Name)"
}
}
}

运行上面的函数,然后运行这个命令:

1
Get-FrenchHoliday

或者,提交额外的参数以获取特定地区的特定假日:

1
Get-FrenchHoliday -NextOnly -Area guyane
1
Get-FrenchHoliday -Area "alsace-moselle" -Year 2024

PowerShell 技能连载 - 理解PowerShell中的错误处理

在编写代码时,错误管理是必须的。预期行为经常可以进行检查和验证。当发生意外情况时,我们使用异常处理。您可以轻松处理其他人代码抛出的异常,或者创建自己的异常供他人处理。

PowerShell 中的异常是什么?

异常是一种事件类型,在标准错误处理无法解决问题时会被触发。尝试将一个数字除以零或耗尽内存都属于异常情况。当特定问题出现时,您正在使用其代码的创建者可能会创建异常。

PowerShell 中的 Throw、Try 和 Catch

当发生异常时,我们称之为抛出了一个异常。您必须捕获抛出的异常才能对其进行管理。如果未通过任何方式捕获引发了一个未被捕获的异常,则脚本将停止运行。

同样地,我们有 Try 可以放置任何逻辑并使用 try 来捕获该异常。以下分别是 throw、try 和 catch 的一些示例。

我们使用 throw 关键字来生成自己的例外事件。

1
2
3
4
5
function hi
function hi
{
throw "hi all"
}

这会抛出一个运行时异常,这是一个致命错误。调用函数中的catch语句处理它,或者脚本以类似这样的通知离开。

1
2
3
4
5
6
7
8
hi

hi all
At line:3 char:1
+ throw "hi all"
+ ~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (hi all:String) [], RuntimeException
+ FullyQualifiedErrorId : hi all

在PowerShell(以及许多其他语言中),异常处理的工作方式是首先尝试一部分代码,然后在它抛出错误时捕获它。这里有一个示例来说明我的意思。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function hi
{
throw "hi all"

}
try hi
{

catch
{
Write-Output "Something threw an exception"
}

##Output:

Something threw an exception

PowerShell 中的 finally 块

在 PowerShell 中的最终块

您并不总是需要处理错误,但无论是否发生异常,都需要一些代码来运行。这正是 finally 块所做的。finally 中的代码最终会被执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
function hi
{
throw "hi all"

}

try
{
hi
}

catch
{
Write-Output "Something threw an exception"
}

Finally

{
"PowershellGuru"
}

## Output ##

Something threw an exception
PowershellGuru

Cmdlet -ErrorAction

当您在任何高级函数或 cmdlet 中使用 -ErrorAction Stop 选项时,它会将所有 Write-Error 语句转换为终止错误,从而停止执行或可以被捕获。

类似地,我们有 -ErrorAction SilentlyContinue 选项,如果出现错误,则不显示错误并继续执行而不中断。

让我向您展示如何在脚本中使用这些。

1
2
3
4
5
6
7
$ErrorActionPreference = "Stop"

script-start
'
'
'
script-end

我们可以使用“SilentlyContinue”来代替“Stop”。这样做的好处是我们不必在每一行都提到它所需的地方。

结论

在本文中,我们已经介绍了异常、try/catch/throw/finally以及示例。此外,我们还看到了-ErrorAction cmdlets 以及如何实际使用它们。现在应该知道Powershell中异常处理的重要性了。让我们在下一篇文章中见面。

PowerShell 技能连载 - Windows 系统的温度控制

Windows 笔记本电脑(以及服务器)可能会变得很热,尤其是在夏天。令人惊讶的是,在 Windows 中没有简单的内置方法来监控温度传感器。了解机器有多热实际上非常重要,可以改善操作条件等方面带来巨大好处。例如,将笔记本电脑抬起并允许足够的空气进入通风口对它们非常有益。

这里有一个 PowerShell 模块,使温度监控变得非常简单:

1
PS> Install-Module -Name PSTemperatureMonitor

要从PowerShell Gallery安装此模块,您需要本地管理员权限,这是有道理的,因为无论如何您都需要本地管理员权限来读取硬件状态。

安装完模块后,请使用管理员权限启动PowerShell,然后启动温度监控,即每5秒刷新一次。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
PS> Start-MonitorTemperature -Interval 5 | Format-Table -Wrap
WARNING: HardwareMonitor opened.

Time CPU Core #1 CPU Core #2 CPU Core #3 CPU Core #4 CPU Package HDD Temperature Average
---- ----------- ----------- ----------- ----------- ----------- --------------- -------
12:17:31 65 69 66 65 69 53 64
12:17:36 63 62 63 59 62 53 60
12:17:41 62 59 59 59 62 53 59
12:17:46 61 62 62 58 62 53 60
12:17:51 70 68 63 63 70 53 64
12:17:56 59 60 55 56 61 53 57
12:18:02 60 60 57 61 61 53 59
12:18:07 65 68 61 62 68 53 63
WARNING: HardwareMonitor closed.

按下 CTRL+C 中止监控。更多详细信息请访问此处:https://github.com/TobiasPSP/PSTemperatureMonitor