PowerShell 技能连载 - AI 集成技巧

在 PowerShell 中集成 AI 功能是一项前沿任务,本文将介绍一些实用的 AI 集成技巧。

首先,让我们看看如何与 OpenAI API 进行交互:

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
27
28
29
30
31
32
33
34
35
36
# 创建 OpenAI 交互函数
function Invoke-OpenAIAPI {
param(
[string]$ApiKey,
[string]$Prompt,
[ValidateSet('gpt-4', 'gpt-3.5-turbo')]
[string]$Model = 'gpt-3.5-turbo',
[float]$Temperature = 0.7,
[int]$MaxTokens = 500
)

try {
$headers = @{
'Content-Type' = 'application/json'
'Authorization' = "Bearer $ApiKey"
}

$body = @{
model = $Model
messages = @(
@{
role = "user"
content = $Prompt
}
)
temperature = $Temperature
max_tokens = $MaxTokens
} | ConvertTo-Json

$response = Invoke-RestMethod -Uri "https://api.openai.com/v1/chat/completions" -Method Post -Headers $headers -Body $body
return $response.choices[0].message.content
}
catch {
Write-Host "OpenAI API 调用失败:$_"
}
}

使用 AI 生成 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
26
27
28
29
30
31
32
# 创建 AI 脚本生成函数
function New-AIScript {
param(
[string]$ApiKey,
[string]$Description,
[string]$OutputPath
)

try {
$prompt = @"
生成一个 PowerShell 脚本,完成以下功能:$Description

要求:
1. 脚本应包含详细的注释
2. 包含适当的错误处理
3. 遵循 PowerShell 最佳实践
4. 只返回脚本代码,不要额外的解释
"@

$script = Invoke-OpenAIAPI -ApiKey $ApiKey -Prompt $prompt -MaxTokens 2000

if ($OutputPath) {
$script | Out-File -FilePath $OutputPath -Encoding UTF8
Write-Host "脚本已保存至:$OutputPath"
}

return $script
}
catch {
Write-Host "AI 脚本生成失败:$_"
}
}

利用 AI 进行日志分析:

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# 创建 AI 日志分析函数
function Analyze-LogsWithAI {
param(
[string]$ApiKey,
[string]$LogFilePath,
[string]$OutputPath,
[switch]$IncludeRecommendations
)

try {
$logs = Get-Content -Path $LogFilePath -Raw

# 将日志截断到合理的大小
if ($logs.Length -gt 4000) {
$logs = $logs.Substring(0, 4000) + "... [日志截断]"
}

$promptSuffix = ""
if ($IncludeRecommendations) {
$promptSuffix = "并提供解决方案建议。"
}

$prompt = @"
分析以下系统日志,识别可能的错误、警告和问题模式$promptSuffix

日志内容:
$logs
"@

$analysis = Invoke-OpenAIAPI -ApiKey $ApiKey -Prompt $prompt -MaxTokens 1500

if ($OutputPath) {
$analysis | Out-File -FilePath $OutputPath -Encoding UTF8
Write-Host "分析结果已保存至:$OutputPath"
}

return $analysis
}
catch {
Write-Host "AI 日志分析失败:$_"
}
}

AI 辅助的自动化故障排除:

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# 创建 AI 故障排除函数
function Start-AITroubleshooting {
param(
[string]$ApiKey,
[string]$Issue,
[switch]$RunDiagnostics
)

try {
$systemInfo = Get-ComputerInfo | ConvertTo-Json

if ($RunDiagnostics) {
$eventLogs = Get-WinEvent -LogName Application -MaxEvents 20 | Select-Object TimeCreated, LevelDisplayName, Message | ConvertTo-Json
$services = Get-Service | Where-Object { $_.Status -eq 'Stopped' -and $_.StartType -eq 'Automatic' } | ConvertTo-Json

$diagnosticInfo = @"
系统信息:
$systemInfo

最近事件日志:
$eventLogs

已停止的自动启动服务:
$services
"@
} else {
$diagnosticInfo = "系统信息:$systemInfo"
}

$prompt = @"
我有以下系统问题:$Issue

基于以下系统信息,提供排查步骤和可能的解决方案:

$diagnosticInfo
"@

$troubleshooting = Invoke-OpenAIAPI -ApiKey $ApiKey -Prompt $prompt -MaxTokens 2000 -Model 'gpt-4'

return $troubleshooting
}
catch {
Write-Host "AI 故障排除失败:$_"
}
}

使用 AI 优化 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
26
27
28
29
30
31
32
33
34
35
36
37
# 创建 AI 脚本优化函数
function Optimize-ScriptWithAI {
param(
[string]$ApiKey,
[string]$ScriptPath,
[string]$OutputPath,
[switch]$IncludeExplanation
)

try {
$script = Get-Content -Path $ScriptPath -Raw

$promptSuffix = ""
if ($IncludeExplanation) {
$promptSuffix = "并解释所做的改动和优化理由。"
}

$prompt = @"
优化以下 PowerShell 脚本的性能和代码质量$promptSuffix

脚本内容:
$script
"@

$optimizedScript = Invoke-OpenAIAPI -ApiKey $ApiKey -Prompt $prompt -MaxTokens 2000 -Model 'gpt-4'

if ($OutputPath) {
$optimizedScript | Out-File -FilePath $OutputPath -Encoding UTF8
Write-Host "优化后的脚本已保存至:$OutputPath"
}

return $optimizedScript
}
catch {
Write-Host "AI 脚本优化失败:$_"
}
}

这些技巧将帮助您更有效地在 PowerShell 中集成 AI 功能。记住,在处理 AI 相关任务时,始终要注意 API 密钥的安全性和成本控制。同时,建议使用适当的错误处理和日志记录机制来跟踪所有操作。

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
26
27
function Invoke-ModuleVulnerabilityScan {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string]$ModuleName
)

# 获取模块版本信息
$module = Get-InstalledModule -Name $ModuleName -ErrorAction Stop

# 调用漏洞数据库API
$response = Invoke-RestMethod -Uri "https://vulndb.example.com/api/modules/$($module.Name)/$($module.Version)"

# 生成安全报告
[PSCustomObject]@{
ModuleName = $module.Name
Version = $module.Version
Vulnerabilities = $response.vulns.Count
Critical = $response.vulns | Where-Object { $_.severity -eq 'Critical' } | Measure-Object | Select-Object -Expand Count
LastUpdated = $module.PublishedDate
} | Export-Csv -Path "$env:TEMP\ModuleSecurityScan_$(Get-Date -Format yyyyMMdd).csv" -Append
}

# 扫描常用模块
'PSReadLine', 'Pester', 'Az' | ForEach-Object {
Invoke-ModuleVulnerabilityScan -ModuleName $_ -Verbose
}

核心功能:

  1. 自动化检测已安装PowerShell模块版本
  2. 对接漏洞数据库API进行安全检查
  3. 生成包含严重性等级的安全报告

扩展方向:

  1. 集成软件物料清单(SBOM)生成
  2. 添加自动补丁更新功能
  3. 与CI/CD流水线集成实现预发布扫描

PowerShell循环结构深度解析

基础循环类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# ForEach循环示例
$services = Get-Service
$services | ForEach-Object {
if ($_.Status -eq 'Running') {
Write-Host $_.DisplayName
}
}

# While循环应用场景
$counter = 0
while ($counter -lt 5) {
Start-Process notepad
$counter++
}

性能对比测试

循环类型 10万次迭代耗时 内存占用
ForEach-Object 1.2s 85MB
For循环 0.8s 45MB
While循环 0.7s 40MB

最佳实践建议

  1. 管道数据优先使用ForEach-Object
  2. 已知次数迭代使用For循环
  3. 条件控制迭代使用While循环
  4. 避免在循环体内执行重复计算

调试技巧

1
2
3
4
5
6
7
8
9
10
11
12
13
# 设置循环断点
$i=0
1..10 | ForEach-Object {
$i++
if ($i -eq 5) { break }
$_
}

# 跟踪循环变量
Set-PSDebug -Trace 1
foreach ($file in (Get-ChildItem)) {
$file.Basename
}

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专业人员或系统管理员都是至关重要的。它有助于维护系统安全性同时允许您在需要时运行脚本。

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