Catch the Hardcoded Credential and the Invoke-Expression Before an Attacker Does — Security Review for Privileged PowerShell
An AI-assisted workflow to find the credential leaks, injection paths, and excessive privileges in any PowerShell script — before it runs as domain admin at scale.
Executive Brief
Your Challenge
Your PowerShell automation runs as a domain administrator, retrieves credentials, modifies Active Directory, and executes remotely across every endpoint — and it probably received less security review than the smallest application in your environment. A script can function perfectly while embedding a plain-text password, converting caller input into executable code, or disabling certificate validation to make a connection work. The convenience that made it useful is the same thing that makes it a pathway to credential theft, privilege escalation, and lateral movement.
Common Obstacles
Security review of scripts is inconsistent because they're shared informally, run without code review, and executed under privileged accounts nobody audits. Reviewers who do look often review only the script and miss the deployment context — the writable script directory, the stored task credential, the unpinned module — that is frequently the largest risk. And the tempting shortcuts make it worse: SecureString treated as secret management, execution policy treated as a security boundary, a valid code signature treated as proof the code is safe. None of those hold.
The ABME Approach
This workflow runs the review in the right order: establish the script's purpose, trust boundaries, identities, and data before reading a single line, then work the review domains — credentials, input validation, dynamic execution, remote content, privilege, files, network, logging, persistence, supply chain. The prompt pack produces findings ranked by severity and confidence, each with evidence, an exploitation scenario, remediation, and safer code. A 30-point validation checklist and a Pester security-test pattern turn the findings into an acceptance gate, so Critical and High issues are resolved or formally accepted before the script ships.
Insight Summary
Administrative automation is privileged software. A PowerShell script that can manage the environment must be secured with the same care as any other production system — informal sharing and no code review is how a useful script becomes an attack path.
Deployment context is often the largest risk. The identity, the scheduler, the file permissions, and the secret storage can defeat a perfectly written script — review them as carefully as the code.
Converting caller-controlled text into executable PowerShell is remote-code execution waiting for an attacker. Replace free-form commands with approved actions and validated parameters, not with more validation on the free-form command.
SecureString does not make an embedded password secure — the plain-text secret still exists in the script. Treating the conversion as a fix is how a Critical finding gets marked resolved without being resolved.
Disabling certificate validation to fix a connection problem converts a certificate error into a man-in-the-middle vulnerability. Fix the trust chain, never the validation.
Search repository history, not only the current file — a rotated secret still lives in source control, backups, and deployment packages until you go looking for it.
The Journey
Three phases; each lists the tools you'll use there.
Map the Trust Boundaries and Assets
- Gather the complete script or module and its deployment details
- Summarize the script's purpose and execution context
- Identify the identities, roles, permissions, and API scopes involved
- Inventory the assets, data, and external dependencies
- Classify every input source by trust level and map trust boundaries
Run the AI Security Review
- Run the primary prompt with the script and its deployment context
- Work the review domains — credentials, input, dynamic execution, remote content, privilege, files, network, logging, persistence, supply chain
- Apply targeted follow-ups for secret handling, injection, least privilege, and dependencies
- Rank each finding by severity and confidence against the severity model
- Produce a hardened version remediating confirmed Critical and High findings
Validate and Approve
- Run static analysis, secret scanning, and AST-based review
- Execute input-fuzzing, permission, logging, and dependency tests
- Write Pester tests verifying the remediated security controls
- Work the 30-point validation checklist
- Resolve or formally accept every Critical and High finding
What's Inside the Execution Layer
Numbered deliverables grouped by phase. Membership unlocks every tool.
Prerequisites Checklist
- Collect execution identity, privileges, and deployment method up front
- Surface data classification and organizational standards early
- Confirm no real secrets will be placed in the AI prompt
Before using this workflow, gather:
Do not include
PowerShell Security Review Prompt Pack
- Produce severity- and confidence-ranked findings with evidence and remediation
- Run focused reviews of secrets, injection, privilege, and supply chain
- Generate a hardened version and Pester security tests
Primary Prompt
Start here with the full script or module and its deployment context.You are a senior PowerShell security engineer performing a defensive code review of enterprise automation.I will provide a PowerShell script or module and information about how it is deployed.Your task is to identify security vulnerabilities, unsafe assumptions, excessive privileges, insecure data handling, and missing controls without changing the script’s intended business purpose.Before reviewing individual lines:1. Summarize the script’s purpose.2. Identify the execution context: • Interactive • Scheduled task • Service account • Azure Automation • CI/CD agent • Endpoint-management platform • RMM platform • Remote session • Other3. Identify the identities, roles, permissions, and API scopes involved.4. Identify assets the script can access or modify.5. Identify sensitive data processed, stored, transmitted, or logged.6. Identify all input sources and classify each as: • Trusted • Partially trusted • Untrusted • Unknown7. Identify trust boundaries.8. Identify all external dependencies, modules, endpoints, files, and downloaded content.9. Identify all state-changing and security-sensitive operations.10. Identify all persistence mechanisms created or modified.Then review the script for:• Hardcoded credentials or secrets• Plain-text secret handling• Insecure credential storage• Excessive privileges• Overly broad API scopes• Command injection• Argument injection• Path traversal• Unsafe dynamic code execution• Invoke-Expression usage• Unsafe script-block creation• Untrusted remote content• Missing hash or signature verification• Insecure module installation• Module-path hijacking• DLL or executable search-path issues• Insecure temporary files• Weak file permissions• Unsafe shared-folder use• Unquoted native-command arguments• Sensitive data in command lines• Insecure HTTP use• Disabled certificate validation• Weak TLS behavior• Authentication-token exposure• Sensitive data in URLs• Unsafe deserialization• Unvalidated JSON, XML, CSV, or API input• LDAP-filter injection• SQL injection• REST request manipulation• Registry manipulation• Scheduled-task abuse• Service creation or modification• Defender or firewall weakening• Security logging gaps• Sensitive data in logs• Error-message disclosure• Unsafe retry or rollback behavior• Uncontrolled parallel execution• Cross-tenant data leakage• Insufficient tenant isolation• Weak cleanup• Insecure deletion• Missing auditability• Missing code-signing or integrity controlsFor each finding, provide:1. Finding ID.2. Title.3. Severity: • Critical • High • Medium • Low • Informational4. Confidence: • Confirmed • Likely • Possible • Requires environment validation5. Affected code.6. Evidence.7. Exploitation or failure scenario.8. Business and technical impact.9. Recommended remediation.10. Safer code example where appropriate.11. Verification steps.12. Compensating controls if immediate remediation is not possible.Requirements:• Do not invent vulnerabilities without evidence.• Clearly distinguish confirmed findings from assumptions.• Do not recommend weakening authentication, TLS, certificate validation, logging, or access controls.• Apply least-privilege principles.• Do not expose or reproduce secrets.• Do not recommend Invoke-Expression when a safer alternative exists.• Do not treat SecureString as complete secret protection.• Consider Windows PowerShell 5.1 and PowerShell 7 differences.• Consider both script code and deployment context.• Preserve operational requirements in recommended changes.• Rank remediation by risk reduction and implementation effort.After the findings, provide:1. Executive summary.2. Overall risk rating.3. Immediate actions required before deployment.4. Remediation roadmap.5. Least-privilege recommendations.6. Secret-management recommendations.7. Dependency and supply-chain recommendations.8. Logging and audit recommendations.9. Deployment-hardening recommendations.10. Security-test plan.11. Remaining accepted or unresolved risks.
Review Secret Handling
For a focused pass on credentials and secrets.Perform a focused review of how credentials, tokens, certificates, API keys, connection strings, and other secrets are obtained, stored, passed, cached, logged, and destroyed.Recommend secure alternatives appropriate for the deployment platform.Do not reproduce any secret values.
Review for Command Injection
To trace untrusted input into command surfaces.Trace every value that can influence:• Commands• Script blocks• Native executable arguments• File paths• URLs• Registry paths• SQL statements• LDAP filters• Remote commandsIdentify whether untrusted input can alter execution and provide safer parameterized alternatives.
Remove Invoke-Expression
To eliminate dynamic execution where possible.Identify every use of Invoke-Expression or dynamically created code.Explain the intended purpose and replace it with safer PowerShell constructs where possible.Preserve required behavior and identify any case where dynamic execution cannot yet be removed.
Apply Least Privilege
To reduce the execution identity to the minimum viable.Identify every permission, role, administrative membership, API scope, and filesystem right required by the script.Separate:• Required permissions• Conditionally required permissions• Excessive permissions• Unknown permissions requiring validationRecommend the minimum viable execution identity.
Review Downloaded Content
For scripts that download scripts, binaries, or modules.Review all downloaded scripts, binaries, modules, templates, and configuration files.Recommend controls for:• Source trust• HTTPS• Certificate validation• Version pinning• Hash verification• Signature verification• Controlled storage• Approval• Update management
Review Scheduled Task Security
When the script is deployed as a scheduled task.Review the script’s scheduled-task deployment.Assess:• Run-as identity• Stored credentials• Highest-privilege setting• Task-file permissions• Script-file permissions• Working directory• Arguments• Logging• Trigger abuse• Task modification rights• Interactive logon dependencies
Review Module Supply Chain
To assess imported and installed module trust.Review all imported and installed PowerShell modules.Identify:• Source repository• Publisher• Version• Installation scope• Automatic updates• Dependency chain• Signature status• Hash or integrity controls• Module-path precedence risks• Whether the module is actually required
Review Logging for Sensitive Data
To confirm secrets never reach logs.Review every log, verbose, debug, warning, error, transcript, and console-output statement.Identify values that could expose credentials, tokens, personal data, customer data, internal infrastructure, or sensitive command arguments.Provide sanitized alternatives.
Create a Hardened Version
After findings, to remediate confirmed Critical and High issues.Create a hardened version of the script that remediates confirmed Critical and High findings.Preserve the intended business behavior.For each change, reference the corresponding finding ID and explain any deployment requirement.
Create Security Pester Tests
To verify remediated controls with automated tests.Create Pester tests that verify the remediated security controls.Include tests for:• Input validation• Rejection of unsafe paths• Rejection of unsafe URLs• No Invoke-Expression usage• Secret redaction• Least-privilege assumptions where testable• Secure temporary-file behavior• Dependency validation• Hash or signature checks• Logging exclusions
Least-Privilege Review
- Compare required permissions against granted permissions for each operation
- Identify and rank excess privilege
- Justify a reduced execution identity
| Operation | Required Permission | Current Permission | Excess |
|---|---|---|---|
| Read user attributes | Directory read | Domain Admin | High |
| Update department field | Scoped user-write permission | Domain Admin | High |
| Write local report | Modify approved report folder | Local Admin | Medium |
| Read secret | Access to one vault secret | Vault administrator | High |
Risk Register
- Log each finding with severity, confidence, and status
- Assign an owner and target date to each item
- Track remediation to closure or formal acceptance
Finding ID
Severity
Title
Confidence
Status
Owner
Target Date
Remediation Priority Matrix
- Sort findings into Immediate, Near Term, and Planned Hardening
- Gate deployment on the Immediate list
- Feed Planned Hardening items into platform standards
Immediate — address before deployment
Near Term — address in the next controlled release
Planned Hardening — address through platform standards
Security Validation Checklist
- Approve or reject a script against a complete security gate
- Confirm secrets, privileges, and dependencies are controlled
- Verify Critical and High findings are resolved or formally accepted
Before approving the script:
Security Test Plan
- Test security controls independently from business logic
- Confirm inputs remain data and secrets never reach logs
- Verify dependency and integrity controls fail safely
Run each pass and record results:
Static Analysis
Secret Scanning — search repositories and deployment packages for
Input-Fuzzing Tests — test values containing
Permission Tests — run the script using
Logging Tests — inject synthetic secrets and confirm they do not appear in
Dependency Tests — verify
Pester Example
🔒 The full execution layer — every checklist, matrix, and the prompt pack — is included with ABME membership.
Unlock Full BlueprintFull Playbook
Overviewpublic
PowerShell scripts frequently operate with elevated permissions, access sensitive systems, retrieve credentials, modify accounts, execute remote commands, and process confidential data.
A script may function correctly while still creating serious security exposure.
Common risks include:
- Hardcoded credentials
- Insecure secret storage
- Excessive privileges
- Unsafe dynamic code execution
- Unvalidated user input
- Command injection
- Disabled certificate validation
- Sensitive data written to logs
- Untrusted downloads
- Insecure temporary files
- Overly broad permissions
- Weak authentication patterns
- Unsafe remote execution
- Dependency tampering
- Missing audit records
This workflow uses AI to perform a structured security review of an existing PowerShell script. It identifies potential vulnerabilities, explains their operational impact, recommends practical remediation, and distinguishes confirmed findings from assumptions requiring validation.
The goal is to reduce the security risk of PowerShell automation without disrupting its intended operational purpose.
Business Problempublic
PowerShell automation often receives less security review than traditional application code even though it may:
- Run as a domain administrator
- Execute under a service account
- Modify Active Directory
- Control Microsoft 365 tenants
- Manage Azure subscriptions
- Access security tools
- Process customer data
- Install software
- Change firewall rules
- Create scheduled tasks
- Download and execute remote content
- Run on many endpoints simultaneously
A vulnerable administrative script can provide an attacker with:
- Credential access
- Privilege escalation
- Remote-code execution
- Persistence
- Lateral movement
- Data exfiltration
- Security-control bypass
- Destructive administrative capability
The risk is amplified when scripts are shared informally, run without code review, or executed using privileged automation accounts.
Typical Use Casespublic
Use this workflow when:
- Preparing a script for production use
- Reviewing inherited automation
- Accepting a script from a third party
- Publishing an internal PowerShell module
- Deploying scripts through RMM or endpoint-management platforms
- Running scripts with elevated privileges
- Managing Active Directory or Microsoft Entra ID
- Handling credentials, secrets, or certificates
- Calling external APIs
- Downloading files or code
- Creating scheduled tasks or services
- Executing commands remotely
- Preparing for an audit
- Responding to a security incident
- Standardizing scripts across an MSP
Do NOT Use This Workflow Whenpublic
This workflow is not intended to:
- Certify a script as completely secure
- Replace penetration testing
- Replace malware analysis
- Replace code signing and release controls
- Replace identity and access reviews
- Replace threat modeling
- Approve unknown third-party code automatically
- Run suspicious code for inspection
- Remove security controls to improve compatibility
- Guarantee regulatory compliance
AI-assisted review should supplement human security review, testing, and organizational controls.
Expected Outcomepublic
After completing this workflow, you should have:
- A script-purpose and trust-boundary summary
- An asset and data inventory
- An identity and privilege review
- A vulnerability inventory
- Findings ranked by severity
- Evidence supporting each finding
- A remediation plan
- A revised or hardened script where appropriate
- Secure alternatives for dangerous patterns
- Logging and auditing recommendations
- Dependency and supply-chain guidance
- Verification tests
- Remaining risks and assumptions
🔒 The complete playbook — reference models, worked examples, and operational guidance — is included with ABME membership.
Unlock Full BlueprintSecurity Review Objectivesprotected
A complete review should answer:
- What privileges does the script require?
- What systems can it access?
- What data does it process?
- Where do inputs originate?
- Which inputs are trusted?
- Does the script execute dynamic or remote content?
- How are credentials and secrets handled?
- Are communications encrypted and validated?
- Can an attacker influence commands, paths, or arguments?
- Can the script modify security-sensitive settings?
- Are logs protected and sanitized?
- Can dependencies or downloaded files be tampered with?
- Are temporary files handled securely?
- Can the script be safely rerun?
- Is activity attributable and auditable?
- What happens if the script is compromised?
Security Severity Modelprotected
Critical
- Arbitrary code execution
- Credential disclosure
- Domain or tenant compromise
- Unrestricted privilege escalation
- Destructive actions at scale
- Security-control bypass
- Execution of untrusted remote code
High
- Excessive privileged access
- Unsafe secret handling
- Writable privileged script location
- Insecure scheduled-task configuration
- Unvalidated administrative input
- Missing certificate validation
- Dangerous command construction
Medium
- Overly detailed errors
- Weak temporary-file handling
- Missing integrity verification
- Unrestricted log access
- Unnecessary permissions
- Insufficient audit records
Low
- Missing version metadata
- Unclear security assumptions
- Weak comments around privileged behavior
- Limited validation on low-risk inputs
Informational
- Platform-specific security dependency
- Expected administrative requirement
- Compensating control
- Accepted operational risk
Review Domainsprotected
Credential and Secret Handling
Review for:
- Hardcoded passwords
- Plain-text API keys
- Embedded access tokens
- Credentials stored in files
- Secrets passed through command-line arguments
- Weak secure-string usage
- Secrets exposed in process listings
- Credentials written to logs
- Long-lived tokens
- Shared service-account passwords
- Exported credential objects
- Insecure environment variables
Input Validation
Review all input sources:
- Parameters
- CSV files
- JSON files
- XML files
- Environment variables
- Registry values
- API responses
- User prompts
- Database records
- File names
- Network paths
- Webhook payloads
- Pipeline input
Determine whether input can influence:
- Commands
- Script blocks
- File paths
- URLs
- SQL queries
- LDAP filters
- API requests
- Registry paths
- Scheduled-task arguments
- Remote commands
Dynamic Code Execution
Pay particular attention to:
Invoke-Expression[scriptblock]::Create()& $userControlledCommandpowershell.exe -Command $dynamicTextInvoke-Command -ScriptBlock $dynamicScriptBlock
Dynamic execution is not always malicious, but it requires strict input control and justification.
Remote Content
Review patterns such as:
Invoke-WebRequest $Url | Invoke-Expressioniex (New-Object Net.WebClient).DownloadString($Url)Invoke-RestMethod $Url | Invoke-Expression
Remote content should not be executed without:
- Trusted source validation
- TLS validation
- Integrity verification
- Version control
- Signature verification where applicable
- Controlled staging and review
Privilege and Identity
Review:
- Required execution identity
- Administrative group membership
- Domain permissions
- Cloud roles
- API scopes
- Local administrator requirements
- Service-account rights
- Delegated versus application permissions
- Just-in-time privilege options
- Whether all requested access is necessary
File and Path Security
Review:
- Writable script directories
- Relative paths
- Search-path hijacking
- DLL or module loading paths
- Temporary files
- Shared folders
- Inherited permissions
- Log directories
- Configuration files
- Backup files
- Output-file replacement
- Symbolic links and reparse points where relevant
Network Security
Review:
- HTTP instead of HTTPS
- Certificate validation
- TLS versions
- Proxy handling
- DNS assumptions
- Endpoint allowlisting
- Authentication headers
- Session reuse
- Sensitive data in URLs
- Untrusted redirects
- Download integrity
- Credential delegation
Logging and Error Handling
Review whether the script logs:
- Passwords
- Tokens
- Authentication headers
- Customer data
- Full API responses
- Connection strings
- Credential objects
- Sensitive command lines
- Personal information
Also determine whether security-relevant actions are logged at all.
Persistence and System Modification
Review actions involving:
- Scheduled tasks
- Services
- Run keys
- Startup folders
- PowerShell profiles
- WMI event subscriptions
- Registry autoruns
- Module installation
- Firewall rules
- Defender exclusions
- User and group changes
- Remote-management settings
These may be legitimate but require clear justification and auditing.
Supply Chain and Dependencies
Review:
- Module sources
- Unpinned module versions
- Public repositories
- Package trust
- Automatic module installation
- Downloaded binaries
- External scripts
- NuGet dependencies
- GitHub release downloads
- Hash verification
- Code signing
- Module-path precedence
- Dependency update behavior
Example Inputprotected
param(
[string]$ComputerName,
[string]$Command
)
$username = 'Administrator'
$password = 'P@ssw0rd123'
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
$credential = New-Object `
System.Management.Automation.PSCredential(
$username,
$securePassword
)
Invoke-Command `
-ComputerName $ComputerName `
-Credential $credential `
-ScriptBlock (
[scriptblock]::Create($Command)
)Example Findingsprotected
PSSEC-001 — Hardcoded Administrative Credential
Severity: Critical
Confidence: Confirmed
Affected Code:
$username = 'Administrator'
$password = 'P@ssw0rd123'Evidence: A privileged username and password are embedded directly in the script.
Risk Scenario: Anyone who can read the script, a backup, a repository copy, an editor history, or a deployment package can recover the credential.
The credential may also remain available through:
- Source control history
- Endpoint-management packages
- Backups
- Email attachments
- Temporary files
- Screen sharing
- AI prompt history
Impact: Potential remote administrative access to every system where the credential is valid.
Remediation: Remove the embedded secret immediately. Rotate the exposed password and review authentication logs. Retrieve credentials from an approved secret-management system or use an identity mechanism that does not require a stored password.
Possible alternatives include:
- Managed identity
- Group Managed Service Account
- Windows integrated authentication
- Certificate-based application authentication
- Azure Key Vault
- Approved enterprise password vault
- Secret variables provided by the automation platform
Verification:
- Search current and historical repositories for the password.
- Rotate the credential.
- Confirm the script works using the approved identity mechanism.
- Verify the secret is absent from logs and deployment packages.
PSSEC-002 — Execution of Untrusted Dynamic Code
Severity: Critical
Confidence: Confirmed
Affected Code:
[scriptblock]::Create($Command)Evidence: Caller-controlled text is converted directly into executable PowerShell.
Risk Scenario: An attacker who controls the Command parameter can execute arbitrary commands under the supplied administrative credential.
Impact: Potential remote-code execution and full compromise of the target system.
Remediation: Do not accept arbitrary PowerShell commands. Replace the free-form command parameter with a constrained action and validated parameters.
PSSEC-003 — Excessive Privilege
Severity: High
Confidence: Likely
Affected Code:
$username = 'Administrator'Evidence: The script uses the built-in administrator account regardless of the specific operation required.
Risk Scenario: If the script or credential is compromised, the attacker receives broader access than the task requires.
Remediation: Create a dedicated automation identity with only the rights required for approved operations.
Example Hardened Designprotected
Instead of accepting arbitrary command text, define approved actions.
[CmdletBinding(SupportsShouldProcess)]
param(
[Parameter(Mandatory)]
[ValidatePattern(
'^[A-Za-z0-9][A-Za-z0-9.-]{0,62}$'
)]
[string]$ComputerName,
[Parameter(Mandatory)]
[ValidateSet(
'GetServiceStatus',
'RestartApprovedService'
)]
[string]$Action,
[Parameter()]
[ValidateSet(
'Spooler',
'W32Time'
)]
[string]$ServiceName
)
$sessionParameters = @{
ComputerName = $ComputerName
ErrorAction = 'Stop'
}
$session = $null
try {
$session = New-PSSession @sessionParameters
switch ($Action) {
'GetServiceStatus' {
Invoke-Command `
-Session $session `
-ScriptBlock {
param($Name)
Get-Service `
-Name $Name `
-ErrorAction Stop
} `
-ArgumentList $ServiceName `
-ErrorAction Stop
}
'RestartApprovedService' {
if (
$PSCmdlet.ShouldProcess(
"$ComputerName\$ServiceName",
'Restart service'
)
) {
Invoke-Command `
-Session $session `
-ScriptBlock {
param($Name)
Restart-Service `
-Name $Name `
-ErrorAction Stop
Get-Service `
-Name $Name `
-ErrorAction Stop
} `
-ArgumentList $ServiceName `
-ErrorAction Stop
}
}
}
}
finally {
if ($session) {
Remove-PSSession -Session $session
}
}This version:
- Removes the embedded credential
- Uses the caller's approved authentication context
- Rejects arbitrary command text
- Restricts available actions
- Restricts service names
- Validates the computer name
- Supports -WhatIf
- Uses argument passing rather than dynamic code construction
- Cleans up the remote session
The actual authentication model should be selected based on the deployment environment.
Credential and Secret Guidanceprotected
Plain-Text Variables
Unsafe:
$password = 'Secret123!'The value may be exposed through:
- Source code
- Memory
- Debug output
- Logging
- Error handling
- Repository history
Command-Line Arguments
Unsafe:
tool.exe --password $PasswordCommand-line arguments may be visible through process inspection and logging. Use a safer supported input method when available.
SecureString
SecureString may reduce accidental exposure in some situations, but it should not be treated as complete secret protection.
This:
ConvertTo-SecureString `
'Secret123!' `
-AsPlainText `
-Forcedoes not make an embedded password secure. The plain-text secret still exists in the script.
Export-Clixml Credentials
Example:
$credential |
Export-Clixml -Path '.\credential.xml'On Windows, this typically protects the credential using the current user and machine context. However, consider:
- File permissions
- Account compromise
- Machine compromise
- Portability
- Backup exposure
- Rotation
- Shared-account use
- Non-Windows behavior
Use an enterprise secret-management platform for important automation.
Input Validation Guidanceprotected
Validate Sets
[ValidateSet('Start', 'Stop', 'Restart')]
[string]$ActionUseful when only known actions are allowed.
Validate Patterns
[ValidatePattern(
'^[A-Za-z0-9][A-Za-z0-9.-]{0,62}$'
)]
[string]$ComputerNamePatterns should be designed for the actual valid input format.
Validate Paths
Do not rely only on Test-Path. Also consider:
- Approved root directories
- Path normalization
- UNC paths
- Reparse points
- Symbolic links
- File type
- Extension
- Access permissions
- Whether the path is writable by untrusted users
Example:
$approvedRoot = [System.IO.Path]::GetFullPath(
'C:\ApprovedImports')
$candidatePath = [System.IO.Path]::GetFullPath(
$InputPath)
if (
-not $candidatePath.StartsWith(
$approvedRoot,
[System.StringComparison]::OrdinalIgnoreCase
)
) {
throw 'The input path is outside the approved directory.'
}Boundary handling should be reviewed carefully to avoid prefix-matching errors.
Avoid Shell Command Construction
Unsafe:
cmd.exe /c "ping $ComputerName"Prefer direct parameter passing:
Test-Connection `
-ComputerName $ComputerName `
-Count 1For native executables, pass arguments separately and validate values.
Remote Content Guidanceprotected
Unsafe:
Invoke-WebRequest -Uri $Url |
Invoke-ExpressionSafer process:
- Restrict approved domains.
- Use HTTPS.
- Download to a controlled location.
- Verify the expected hash or signature.
- Inspect the file.
- Execute a version-controlled approved copy.
- Record source and version.
Example hash verification:
$expectedHash = 'APPROVED_SHA256_VALUE'
Invoke-WebRequest `
-Uri $Uri `
-OutFile $downloadPath `
-UseBasicParsing `
-ErrorAction Stop
$actualHash = (
Get-FileHash `
-LiteralPath $downloadPath `
-Algorithm SHA256).Hash
if ($actualHash -ne $expectedHash) {
Remove-Item `
-LiteralPath $downloadPath `
-Force `
-ErrorAction SilentlyContinue
throw 'Downloaded file failed integrity verification.'
}The expected hash must come from a trusted, independently controlled source.
TLS and Certificate Validationprotected
Do not disable certificate validation to resolve connection problems.
Unsafe patterns may include:
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {
$true
}or custom handlers that accept every certificate.
Disabling validation enables interception and impersonation.
Correct the underlying issue:
- Trust the correct certificate authority
- Repair the certificate chain
- Use the correct hostname
- Renew expired certificates
- Update the operating-system trust store
- Configure approved proxy inspection properly
Module Securityprotected
Unpinned Installation
Risky:
Install-Module SomeModule -ForceA future version may behave differently or become compromised. Consider:
Install-Module `
-Name SomeModule `
-RequiredVersion '1.2.3' `
-Repository 'PSGallery' `
-Scope AllUsersVersion pinning alone does not guarantee trust, but it improves repeatability.
Automatic Trust
Avoid automatically trusting unknown repositories. Review:
- Repository ownership
- TLS
- Package signing
- Publisher identity
- Package contents
- Dependencies
- Release process
- Update behavior
Module-Path Hijacking
PowerShell may import a module by name from the first matching location in $env:PSModulePath.
For sensitive automation:
- Control module paths
- Restrict directory permissions
- Validate loaded module paths
- Pin versions
- Consider explicit approved paths
- Record module hashes or signatures where appropriate
Example validation:
$module = Get-Module `
-ListAvailable `
-Name 'ApprovedModule' |
Sort-Object Version -Descending |
Select-Object -First 1
$approvedRoot = 'C:\Program Files\WindowsPowerShell\Modules'
if (
-not $module.Path.StartsWith(
$approvedRoot,
[System.StringComparison]::OrdinalIgnoreCase
)
) {
throw 'The module was not found in an approved location.'
}Native Command Securityprotected
PowerShell scripts often call native executables. Review:
- Executable path
- Search-path resolution
- Quoting
- Argument boundaries
- Input validation
- Exit code
- Standard error
- Command-line secret exposure
- Working directory
- Environment variables
Prefer an explicit executable path:
$executablePath = 'C:\Program Files\Vendor\Tool\tool.exe'rather than:
tool.exewhen path hijacking is a meaningful risk.
Temporary File Securityprotected
Avoid predictable temporary-file names.
Weak:
$tempPath = 'C:\Temp\data.txt'Better:
$tempPath = Join-Path `
-Path ([System.IO.Path]::GetTempPath()) `
-ChildPath (
[System.IO.Path]::GetRandomFileName()
)Also consider:
- Directory permissions
- File permissions
- Sensitive contents
- Secure cleanup
- Failure cleanup
- Race conditions
- Reparse-point attacks
- Whether a temporary file is necessary
Do not assume deletion guarantees secure erasure on modern storage systems.
Scheduled Task Securityprotected
Review scheduled tasks for:
- Highly privileged run-as accounts
- Stored passwords
- Writable script locations
- Writable argument files
- Unquoted executable paths
- Task modification permissions
- Interactive logon requirements
- Unnecessary RunLevel Highest
- Insecure working directories
- Missing logging
- Uncontrolled triggers
- Network-share dependencies
A low-privilege user who can modify the script executed by a privileged task may be able to escalate privileges.
Logging Securityprotected
Good security logging should record:
- Script name and version
- Run ID
- Execution identity
- Host
- Start and completion status
- Privileged operations
- Target resource
- Administrative changes
- Authentication failures
- Authorization failures
- Integrity-verification failures
- Dependency changes
- Security-sensitive configuration changes
Do not log:
- Passwords
- Tokens
- Credential objects
- Authentication headers
- Private keys
- Full connection strings
- Sensitive request bodies
- Entire user records without need
- Secret environment variables
Code Signing and Execution Controlsprotected
Code signing can support:
- Publisher verification
- Integrity checking
- Controlled release processes
- Application-control policies
Code signing does not prove that code is safe. It establishes origin and integrity based on the trust placed in the certificate and release process.
Review:
- Certificate protection
- Signing identity
- Timestamping
- Certificate expiration
- Revocation
- Build pipeline
- Who can publish signed code
- Whether signatures are verified at execution
Potential supporting controls include:
- AppLocker
- Windows Defender Application Control
- Constrained Language Mode
- Just Enough Administration
- Controlled administrative workstations
- Repository protections
- CI/CD approvals
AST-Based Reviewprotected
PowerShell's abstract syntax tree can help identify risky constructs.
Example:
$tokens = $null
$errors = $null
$ast = [System.Management.Automation.Language.Parser]::ParseFile(
$Path,
[ref]$tokens,
[ref]$errors)
$invokeExpressionCommands = $ast.FindAll(
{
param($node)
$node -is [
System.Management.Automation.Language.CommandAst
] -and
$node.GetCommandName() -eq 'Invoke-Expression'
},
$true)AST review is more reliable than simple regular expressions for many code patterns.
Deployment-Hardening Recommendationsprotected
Consider:
- Dedicated automation identity
- Least-privilege role
- Managed identity or gMSA
- Protected script directory
- Signed release artifacts
- Version-controlled deployment
- Approved module repository
- Version pinning
- Restricted outbound network access
- Centralized logging
- Alerting on failures and modifications
- Administrative workstation controls
- JEA endpoints
- AppLocker or WDAC
- Script integrity monitoring
- Periodic access review
- Credential rotation
- Emergency-disable procedure
Automation Opportunitiesprotected
- Pull-request reviews
- Secure coding pipelines
- PSScriptAnalyzer rules
- Secret-scanning tools
- Dependency scanning
- Code-signature verification
- GitHub Actions
- Azure DevOps pipelines
- Internal module publishing
- MSP script approval
- RMM deployment governance
- Compliance evidence collection
- Privileged-access reviews
- Security architecture reviews
- A mature PowerShell security gate could: parse the script AST, detect dangerous commands, scan for secrets, run PSScriptAnalyzer, validate module versions, verify signatures, run Pester security tests, compare required permissions, review deployment configuration, and require human approval for high-risk findings.
Pro Tipsprotected
- Review deployment context as carefully as script code.
- Never provide real secrets to an AI reviewer.
- Rotate any credential discovered in source code.
- Treat arbitrary dynamic code execution as a critical concern.
- Replace free-form commands with approved actions and validated parameters.
- Reduce privileges before optimizing convenience.
- Verify downloaded content before execution.
- Pin and govern dependencies.
- Protect script locations from modification by lower-privileged users.
- Search repository history, not only the current file.
- Test that synthetic secrets never appear in logs.
- Use AST analysis for risky PowerShell constructs.
- Review scheduled-task permissions and script-file permissions together.
- Document compensating controls when immediate remediation is impossible.
- Require formal acceptance for unresolved Critical or High risks.
- Repeat the review whenever privileges, dependencies, deployment methods, or trust boundaries change.
Common Mistakesprotected
- Treating SecureString as secret management — converting an embedded password to SecureString does not solve the exposure.
- Using Invoke-Expression for convenience — most uses can be replaced with direct cmdlet calls, script-block parameters, splatting, switch statements, argument lists, or approved action maps.
- Disabling TLS validation — this converts a certificate problem into a man-in-the-middle vulnerability.
- Logging entire exceptions and objects — exception records and objects may contain tokens, URLs, query parameters, paths, user data, request bodies, and command lines; sanitize before logging.
- Running everything as domain admin — administrative convenience is not a least-privilege design.
- Installing the latest module automatically — an unattended production script should not silently accept arbitrary future dependency changes.
- Trusting internal inputs automatically — internal files, shared folders, APIs, and users may still be compromised or misconfigured; treat trust as an explicit decision.
- Relying only on execution policy — PowerShell execution policy is not a complete security boundary; use layered controls.
- Signing vulnerable code — a valid signature proves source and integrity, not security quality.
- Reviewing only the script — deployment context (identity, scheduler, file permissions, repository, modules, host controls, secret storage, monitoring, update process) may be the largest risk.
Related Blueprints
⚠ Normalization Warnings — 14 for review
- RESTRUCTURE: 'Primary Prompt' and 'Follow-Up Prompts' (two source H1s) combined into one prompt_pack tool with 11 prompts; 'when' guidance lines are editorial additions, prompt text verbatim (including the source's run-together formatting where lines had no line breaks in extraction).
- CLASSIFICATION TO CONFIRM: 'Prerequisites' classified as a checklist TOOL (gather-before-start items are completable). The 'Do not include real secrets' warning was folded in as a second group. Alternative: body/prose.
- CLASSIFICATION TO CONFIRM: 'Least-Privilege Review' classified as a matrix TOOL built from the doc's per-operation permission table; the 'Review permissions at:' list placed in rubric. Alternative: body/reference. Confirm.
- CLASSIFICATION TO CONFIRM: 'Risk Register Template' classified as a template TOOL with sections derived from the table columns; the doc's rows are example content, not skeleton. Confirm template vs matrix — chose template because it is a fill-in record per finding, but the source is a table so matrix is a defensible alternative.
- CLASSIFICATION TO CONFIRM: 'Remediation Priority Matrix' classified as a template TOOL (three fill-in horizons: Immediate / Near Term / Planned Hardening) despite 'Matrix' in the title — it is not columnar; it is a labeled bucketing structure. Confirm.
- CLASSIFICATION TO CONFIRM: 'Testing Recommendations' classified as a checklist TOOL named 'Security Test Plan' (all items are runnable/verifiable across six passes). Display name changed from source heading. The Pester Example and AST-Based Review contain full code; the Pester code block was summarized into a checklist item rather than reproduced verbatim to fit the checklist shape — the AST-Based Review was kept as a body/example to preserve its code. Confirm whether the Pester Example code should also live as a body/example.
- CLASSIFICATION: 'Security Severity Model' classified as body/reference (tiered scheme the reviewer consults). 'Review Domains' classified as a body/group of prose subsections (review guidance the practitioner reads, not fills in).
- CLASSIFICATION: 'Security Validation Checklist' is the doc's own named checklist — classified as checklist TOOL verbatim (30 items).
- RESTRUCTURE: Credential and Secret Guidance, Input Validation Guidance, and Module Security kept as body GROUPS (subsection-rich with code examples) rather than flattening into playbook lists.
- RESTRUCTURE: 'Common Mistakes' mapped to playbook.common_mistakes as flat items (each subsection's title + explanation condensed to one line) since items are short guidance rather than code-heavy subsections. Confirm vs body/group.
- RESTRUCTURE: 'Automation Opportunities' list plus the 'mature security gate' numbered steps folded into playbook.automation_opportunities (the numbered gate as a single summarizing item). Confirm.
- AST-Based Review, Deployment-Hardening Recommendations, and the code-example sections placed in body; 'Deployment-Hardening Recommendations' is prose (list of considerations).
- STATS: prompts counted as 11 (1 primary + 10 follow-ups); deliverables counted as 7 tools; hours_saved '2–8' from front-matter.
- Extraction ran code blocks together without line breaks (SourceCode style not recognized by Mammoth); code in body/example and prompt text was re-lineated for readability where structure was unambiguous — verify no code semantics changed.
SEO Block
- Title tag: Security Review a PowerShell Script with AI | ABME (50 chars)
- Meta: Find the embedded secrets, command injection, and excessive privileges in any PowerShell script — with severity-ranked findings and a hardened rewrite. (151 chars)
- Schema: HowTo · noindex: false
- Related: ps-001, ps-002, ps-003, ps-004, ps-005, ps-006, ps-007, ps-008, ps-010
- Keywords: powershell security review, powershell code review security, invoke-expression vulnerability, powershell hardcoded credentials, powershell command injection, powershell least privilege, powershell module supply chain, powershell secret scanning, pester security tests, powershell ast analysis
