用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/Asymmetric-al/Compass --skill powershell-security命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
Maia theme design system for Compass. Read this skill BEFORE creating or modifying any UI component, page layout, or styling. Covers tokens, typography, color, spacing, component standards, states, motion, and accessibility. Applies whenever working on .tsx files, CSS, or anything visual.
Comprehensive Azure Data Factory knowledge base with official documentation sources, CI/CD methods, deployment patterns, and troubleshooting resources
Comprehensive Azure Data Factory validation rules, activity nesting limitations, linked service requirements, and edge-case handling guidance
基于 SOC 职业分类
正在显示 SKILL.md
| name | powershell-security |
| description | Modern PowerShell security practices including SecretManagement, JEA, WDAC, and credential protection |
Modern security practices for PowerShell scripts and automation, including credential management, SecretManagement module, and hardening techniques.
Microsoft.PowerShell.SecretManagement is the official solution for secure credential storage in PowerShell.
Why use SecretManagement:
# Install SecretManagement module
Install-Module -Name Microsoft.PowerShell.SecretManagement -Scope CurrentUser
# Install vault provider (choose one or more)
Install-Module -Name Microsoft.PowerShell.SecretStore # Local encrypted vault
Install-Module -Name Az.KeyVault # Azure Key Vault
Install-Module -Name SecretManagement.KeePass # KeePass integration
# Register a vault
Register-SecretVault -Name LocalVault -ModuleName Microsoft.PowerShell.SecretStore
# Store a secret
$password = Read-Host -AsSecureString -Prompt "Enter password"
Set-Secret -Name "DatabasePassword" -Secret $password -Vault LocalVault
# Retrieve a secret
$dbPassword = Get-Secret -Name "DatabasePassword" -Vault LocalVault -AsPlainText
# Or as SecureString
$dbPasswordSecure = Get-Secret -Name "DatabasePassword" -Vault LocalVault
# List secrets
Get-SecretInfo
# Remove a secret
Remove-Secret -Name "DatabasePassword" -Vault LocalVault
# Install and import Az.KeyVault
Install-Module -Name Az.KeyVault -Scope CurrentUser
Import-Module Az.KeyVault
# Authenticate to Azure
Connect-AzAccount
# Register Azure Key Vault as secret vault
Register-SecretVault -Name AzureKV `
-ModuleName Az.KeyVault `
-VaultParameters @{
AZKVaultName = 'MyKeyVault'
SubscriptionId = 'your-subscription-id'
}
# Store secret in Azure Key Vault
Set-Secret -Name "ApiKey" -Secret "your-api-key" -Vault AzureKV
# Retrieve from Azure Key Vault
$apiKey = Get-Secret -Name "ApiKey" -Vault AzureKV -AsPlainText
<#
.SYNOPSIS
Secure automation script using SecretManagement
.DESCRIPTION
Demonstrates secure credential handling without hardcoded secrets
#>
#Requires -Modules Microsoft.PowerShell.SecretManagement
[CmdletBinding()]
param()
# Retrieve credentials from vault
$dbConnectionString = Get-Secret -Name "SQLConnectionString" -AsPlainText
$apiToken = Get-Secret -Name "APIToken" -AsPlainText
# Use credentials securely
try {
# Database operation
$connection = New-Object System.Data.SqlClient.SqlConnection($dbConnectionString)
$connection.Open()
# API call with token
$headers = @{ Authorization = "Bearer $apiToken" }
$response = Invoke-RestMethod -Uri "https://api.example.com/data" -Headers $headers
# Process results
Write-Host "Operation completed successfully"
}
catch {
Write-Error "Operation failed: $_"
}
finally {
if ($connection) { $connection.Close() }
}
# ❌ WRONG - Hardcoded credentials
$password = "MyPassword123"
$username = "admin"
# ❌ WRONG - Plaintext in script
$cred = New-Object System.Management.Automation.PSCredential("admin", "password")
# ✅ CORRECT - SecretManagement
$password = Get-Secret -Name "AdminPassword" -AsPlainText
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential("admin", $securePassword)
# ✅ CORRECT - Interactive prompt (for manual runs)
$cred = Get-Credential -Message "Enter admin credentials"
# ✅ CORRECT - Managed Identity (Azure automation)
Connect-AzAccount -Identity
# Store service principal credentials in vault
Set-Secret -Name "AzureAppId" -Secret "app-id-guid"
Set-Secret -Name "AzureAppSecret" -Secret "app-secret-value"
Set-Secret -Name "AzureTenantId" -Secret "tenant-id-guid"
# Retrieve and authenticate
$appId = Get-Secret -Name "AzureAppId" -AsPlainText
$appSecret = Get-Secret -Name "AzureAppSecret" -AsPlainText
$tenantId = Get-Secret -Name "AzureTenantId" -AsPlainText
$secureSecret = ConvertTo-SecureString $appSecret -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($appId, $secureSecret)
Connect-AzAccount -ServicePrincipal -Credential $credential -Tenant $tenantId
Just Enough Administration restricts PowerShell remoting sessions to specific cmdlets and parameters.
# 1. Create role capability file
New-PSRoleCapabilityFile -Path "C:\JEA\RestartServices.psrc" `
-VisibleCmdlets @{
Name = 'Restart-Service'
Parameters = @{
Name = 'Name'
ValidateSet = 'Spooler', 'W32Time', 'WinRM'
}
}, 'Get-Service'
# 2. Create session configuration file
New-PSSessionConfigurationFile -Path "C:\JEA\RestartServices.pssc" `
-SessionType RestrictedRemoteServer `
-RoleDefinitions @{
'DOMAIN\ServiceAdmins' = @{ RoleCapabilities = 'RestartServices' }
} `
-LanguageMode NoLanguage
# 3. Register JEA endpoint
Register-PSSessionConfiguration -Name RestartServices `
-Path "C:\JEA\RestartServices.pssc" `
-Force
# 4. Connect to JEA endpoint (as delegated user)
Enter-PSSession -ComputerName Server01 -ConfigurationName RestartServices
# User can ONLY run allowed commands
Restart-Service -Name Spooler # ✅ Allowed
Restart-Service -Name DNS # ❌ Denied (not in ValidateSet)
Get-Process # ❌ Denied (not visible)
# Enable transcription and logging
New-PSSessionConfigurationFile -Path "C:\JEA\AuditedSession.pssc" `
-SessionType RestrictedRemoteServer `
-TranscriptDirectory "C:\JEA\Transcripts" `
-RunAsVirtualAccount
# All JEA sessions are transcribed to C:\JEA\Transcripts
# Review audit logs
Get-ChildItem "C:\JEA\Transcripts" | Get-Content
WDAC replaces AppLocker for controlling which PowerShell scripts can execute.
# Create WDAC policy for signed scripts only
New-CIPolicy -FilePath "C:\WDAC\PowerShellPolicy.xml" `
-ScanPath "C:\Scripts" `
-Level FilePublisher `
-Fallback Hash `
-UserPEs
# Allow only signed scripts
Set-RuleOption -FilePath "C:\WDAC\PowerShellPolicy.xml" `
-Option 3 # Required WHQL
# Convert to binary policy
ConvertFrom-CIPolicy -XmlFilePath "C:\WDAC\PowerShellPolicy.xml" `
-BinaryFilePath "C:\Windows\System32\CodeIntegrity\SIPolicy.p7b"
# Reboot to apply policy
Restart-Computer
# Get code signing certificate
$cert = Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert
# Sign script
Set-AuthenticodeSignature -FilePath "C:\Scripts\MyScript.ps1" -Certificate $cert
# Verify signature
$signature = Get-AuthenticodeSignature -FilePath "C:\Scripts\MyScript.ps1"
$signature.Status # Should be "Valid"
# Check current execution policy
Get-ExecutionPolicy
# Set execution policy (requires admin)
Set-ExecutionPolicy RemoteSigned -Scope LocalMachine
# Bypass for single script (testing only)
PowerShell.exe -ExecutionPolicy Bypass -File "script.ps1"
Restricts PowerShell language features to prevent malicious code execution.
# Check current language mode
$ExecutionContext.SessionState.LanguageMode
# Output: FullLanguage (admin) or ConstrainedLanguage (standard user)
# Set system-wide constrained language mode
# Via Environment Variable or Group Policy
# Set: __PSLockdownPolicy = 4
# Test constrained mode behavior
# FullLanguage allows:
[System.Net.WebClient]::new() # ✅ Allowed
# ConstrainedLanguage blocks:
[System.Net.WebClient]::new() # ❌ Blocked
Add-Type -TypeDefinition "..." # ❌ Blocked
# Enable via Group Policy or Registry
# HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging
New-ItemProperty -Path "HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" `
-Name "EnableScriptBlockLogging" -Value 1 -PropertyType DWord
# Log location: Windows Event Log
# Event Viewer > Applications and Services Logs > Microsoft > Windows > PowerShell > Operational
# Query script block logs
Get-WinEvent -LogName "Microsoft-Windows-PowerShell/Operational" |
Where-Object { $_.Id -eq 4104 } | # Script Block Logging event
Select-Object TimeCreated, Message |
Out-GridView
# ❌ WRONG - No validation
function Get-UserData {
param($Username)
Invoke-Sqlcmd -Query "SELECT * FROM Users WHERE Username = '$Username'"
}
# Vulnerable to SQL injection
# ✅ CORRECT - Parameterized queries
function Get-UserData {
param(
[ValidatePattern('^[a-zA-Z0-9_-]+$')]
[string]$Username
)
Invoke-Sqlcmd -Query "SELECT * FROM Users WHERE Username = @Username" `
-Variable @{Username=$Username}
}
# ✅ CORRECT - ValidateSet for known values
function Restart-AppService {
param(
[ValidateSet('Web', 'API', 'Worker')]
[string]$ServiceName
)
Restart-Service -Name "App${ServiceName}Service"
}
[ValidatePattern], [ValidateSet], etc.Set-StrictMode -Version Latesttry/catch for error handlingInvoke-Expression with user input