plugins/languages/powershell/skills/modules/SKILL.md
PowerShell module authoring and distribution: .psd1 manifest, .psm1 root module, function/cmdlet/variable/alias export rules, scope (Script/Private/Global), PSResourceGet (Install-PSResource) replacing the legacy PowerShellGet v2, PSGallery publish workflow, semantic versioning, module layout (Public/Private folders + dot-source loader), binary modules basics, RequiredModules and CompatiblePSEditions. Use proactively when the user asks to "写 PowerShell 模块 / ps 模块发布 / Publish-PSResource / psgallery / module manifest". Also triggers on "psd1", "psm1", "Export-ModuleMember", "PSResourceGet", "Install-PSResource", "PowerShellGet", "PSGallery".
npx skillsauth add lazygophers/ccplugin powershell-modulesInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
| 类型 | 扩展 | 用途 |
|------|------|------|
| 脚本模块 | .psm1 | 纯 PowerShell 函数,最常见 |
| 清单模块 | .psd1 | 元数据 + 指向 .psm1 / .dll,发布必备 |
| 二进制模块 | .dll | C# 编译的 cmdlet |
| manifest 模块 | .psd1 only | 聚合多个模块 |
MyModule/
├── MyModule.psd1 # 清单(版本/作者/导出列表)
├── MyModule.psm1 # 根模块,仅做加载
├── Public/ # 公开函数(自动导出)
│ ├── Get-Foo.ps1
│ └── Set-Foo.ps1
├── Private/ # 内部函数(不导出)
│ └── Get-Internal.ps1
├── Classes/
│ └── MyType.ps1
├── Tests/
│ └── MyModule.Tests.ps1 # Pester
├── en-US/
│ └── MyModule-help.xml # MAML 帮助(可选)
├── README.md
└── LICENSE
.psm1(dot-source loader)#Requires -Version 7.4
Set-StrictMode -Version 3.0
$publicFunctions = @(Get-ChildItem -Path "$PSScriptRoot/Public" -Filter '*.ps1' -ErrorAction SilentlyContinue)
$privateFunctions = @(Get-ChildItem -Path "$PSScriptRoot/Private" -Filter '*.ps1' -ErrorAction SilentlyContinue)
foreach ($file in @($privateFunctions) + @($publicFunctions)) {
try {
. $file.FullName
} catch {
Write-Error "Failed to import $($file.FullName): $_"
}
}
Export-ModuleMember -Function $publicFunctions.BaseName
.psd1@{
RootModule = 'MyModule.psm1'
ModuleVersion = '1.2.0'
GUID = 'a1b2c3d4-...' # New-Guid 生成一次
Author = 'Your Name'
CompanyName = 'Acme'
Copyright = '(c) 2026 Acme. All rights reserved.'
Description = 'One-line description'
PowerShellVersion = '7.4'
CompatiblePSEditions = @('Core') # Desktop = WinPS 5.1
RequiredModules = @(
@{ ModuleName = 'Microsoft.PowerShell.SecretManagement'; ModuleVersion = '1.1.2' }
)
FunctionsToExport = @('Get-Foo', 'Set-Foo') # 显式列出,不要 '*'
CmdletsToExport = @()
VariablesToExport = @()
AliasesToExport = @()
PrivateData = @{
PSData = @{
Tags = @('automation', 'devops')
LicenseUri = 'https://example.com/license'
ProjectUri = 'https://github.com/owner/repo'
ReleaseNotes = 'See CHANGELOG.md'
}
}
}
关键准则:
FunctionsToExport 显式枚举,禁 '*'(影响自动发现性能 + 安全)。PowerShellVersion 与 CompatiblePSEditions 必填,CI 据此选 runner。RequiredModules 写最小版本约束,让 Install-PSResource 自动拉。| 作用域 | 语法 | 含义 |
|--------|------|------|
| $script:var | 模块内全局 | .psm1 内函数共享 |
| $local:var | 当前作用域 | 函数内默认 |
| $private:var | 仅当前作用域 | 子作用域不可见 |
| $global:var | session 全局 | 慎用,污染调用者 |
| $using:var | -Parallel / Invoke-Command | 跨边界引入 |
模块函数默认无法直接读写调用者的变量;需要时显式
param()传入。
PowerShellGet v2 已废弃;PSResourceGet 提供更快、独立的资源管理。
# 安装 PSResourceGet(Win 11 / pwsh 7.4 已内置)
Install-Module Microsoft.PowerShell.PSResourceGet -Scope CurrentUser
# 配置仓库
Register-PSResourceRepository -Name PSGallery -Uri https://www.powershellgallery.com/api/v3 -Trusted
Get-PSResourceRepository
# 安装 / 卸载
Install-PSResource -Name Pester -Version '5.5.0' -Scope CurrentUser
Update-PSResource -Name Pester
Uninstall-PSResource -Name Pester
# 搜索
Find-PSResource -Name 'PSScriptAnalyzer'
# 1. 在 https://www.powershellgallery.com/account/apikeys 创建 API key
$env:NUGET_API_KEY = '...' # 或用 SecretManagement
# 2. 本地校验清单
Test-ModuleManifest -Path ./MyModule.psd1
# 3. 静态分析
Invoke-ScriptAnalyzer -Path . -Recurse -Severity Warning
# 4. 跑测试
Invoke-Pester ./Tests -Output Detailed
# 5. 发布
Publish-PSResource -Path ./MyModule -ApiKey $env:NUGET_API_KEY -Repository PSGallery
CI 模板(GitHub Actions):
- uses: PowerShell/PSResourceGet@v1
- shell: pwsh
run: |
Test-ModuleManifest ./MyModule.psd1
Invoke-ScriptAnalyzer -Path . -Recurse -Severity Warning -EnableExit
Invoke-Pester -CI
if ($env:GITHUB_REF -like 'refs/tags/v*') {
Publish-PSResource -Path ./MyModule -ApiKey $env:PSGALLERY_KEY
}
ModuleVersion 走 SemVer MAJOR.MINOR.PATCH。Prerelease 字段(PrivateData.PSData.Prerelease = 'beta1')→ 显示 1.2.0-beta1。Update-ModuleManifest -ModuleVersion ...。Import-Module ./MyModule.psd1 -Force -Verbose
Get-Module MyModule | Remove-Module
Get-Command -Module MyModule
-Force强制重载,开发期常用。生产代码禁用-Force隐藏的副作用。
[Cmdlet(VerbsCommon.Get, "Greeting")]
public class GetGreetingCommand : PSCmdlet {
[Parameter(Mandatory = true)]
public string Name { get; set; } = "";
protected override void ProcessRecord() {
WriteObject($"Hello, {Name}!");
}
}
.csproj 引用 Microsoft.PowerShell.SDK,build 产物 .dll 在 .psd1 的 RootModule 引用。
.psd1 通过 Test-ModuleManifestFunctionsToExport 显式列出CompatiblePSEditions 与 PowerShellVersion 与目标匹配development
Go 数据库规范——GORM Model 命名 ModelXxx、表名单数、枚举 uint8 + 常量、索引 idx_ 前缀 + deleted_at leading column、禁 time.Time 统一 int64 unix、禁指针/nullable 字段、TEXT/BLOB/JSON 禁 default、AutoMigrate 禁改主键。设计 DB model、写 GORM tag、建索引、做 migration 审查时触发。
development
Go HTTP API 规范——响应始终 200 + body code 字段、路由 /api/* 全 POST 单段 <Action><Model>、中间件逐路由注册禁 Group(prefix,mw...)、handler 仅返回 (rsp,error)、认证走 header。设计 HTTP API、写路由/handler/中间件时触发。
development
Go 项目结构规范——三层架构(API → Impl → State)、全局状态模式、internal/ 私有包、cmd/ 仅 main.go、go.work 多模块、禁止 Repository 接口和 DI 容器、struct 公共字段开头全 omitempty、handler var rsp 顶声明、禁 legacy migration。设计项目骨架、新建目录、组织包、做架构评审时触发。
development
Go 命名规范——Id/Uid 字段(非 ID)、IsActive/HasMFA 布尔前缀、CreatedAt 时间字段、接收者统一用 p、包名全小写无下划线、泛型类型参数描述性命名、集合字段 xxx_list 禁 xxxs 复数、Enum 0 值 XxxNil 禁 Unknown、禁 Status 统一 State、Set/Update 语义区分。定义结构体字段、函数、变量、包、接收者名、泛型、枚举时触发。