powershell-security

安装量: 52
排名: #14344

安装

npx skills add https://github.com/josiahsiegel/claude-plugin-marketplace --skill powershell-security

PowerShell Security Best Practices (2025)

Modern security practices for PowerShell scripts and automation, including credential management, SecretManagement module, and hardening techniques.

SecretManagement Module (Recommended 2025 Standard) Overview

Microsoft.PowerShell.SecretManagement is the official solution for secure credential storage in PowerShell.

Why use SecretManagement:

Never store plaintext credentials in scripts Cross-platform secret storage Multiple vault provider support Integration with Azure Key Vault, 1Password, KeePass, etc. Installation

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

Basic Usage

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

Azure Key Vault Integration

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

Automation Scripts with SecretManagement <# .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() } }

Credential Management Best Practices Never Hardcode Credentials

❌ 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

Service Principal Authentication (Azure)

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 (JEA) What is JEA?

Just Enough Administration restricts PowerShell remoting sessions to specific cmdlets and parameters.

Use Cases Delegate admin tasks without full admin rights Compliance requirements (SOC 2, HIPAA, PCI-DSS) Production environment hardening Audit trail for privileged operations Creating a JEA Endpoint

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)

JEA Audit Logging

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

Windows Defender Application Control (WDAC) PowerShell Script Control

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

Code Signing Why Sign Scripts? Verify script integrity Meet organizational security policies Enable WDAC enforcement Prevent tampering Signing a Script

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"

Execution Policy

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"

Constrained Language Mode What is Constrained Language Mode?

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

Script Block Logging Enable Logging

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

Review Logs

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

Input Validation Prevent Injection Attacks

❌ 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" }

Security Checklist Script Development Never hardcode credentials (use SecretManagement) Use parameterized queries for SQL operations Validate all user input with [ValidatePattern], [ValidateSet], etc. Enable Set-StrictMode -Version Latest Use try/catch for error handling Avoid Invoke-Expression with user input Sign production scripts Enable Script Block Logging Automation Use Managed Identity or Service Principal (never passwords) Store secrets in SecretManagement or Azure Key Vault Implement JEA for delegated admin tasks Enable audit logging for all privileged operations Use least privilege principle Rotate credentials regularly Monitor failed authentication attempts Production Environments Implement WDAC policies for script control Use Constrained Language Mode for non-admin users Enable PowerShell logging (Script Block + Transcription) Require signed scripts (via execution policy) Regular security audits Keep PowerShell updated (7.5+) Use JEA for remote administration Resources SecretManagement Documentation JEA Documentation WDAC Documentation PowerShell Security Best Practices Azure Key Vault

返回排行榜