Get-CmsMessage – Decrypting Messages in PowerShell
Welcome back to Wahmans Powershell blog! Today we’re diving into a powerful cmdlet that allows you to decrypt and read messages secured using Cryptographic Message Syntax (CMS). That cmdlet is Get-CmsMessage. If you’ve ever received .p7m files or encrypted data via certificates in the enterprise world, this is how you handle them directly within PowerShell.
What is Get-CmsMessage?
Get-CmsMessage is used to decrypt content that has been encrypted using the Cryptographic Message Syntax format (CMS). This format is widely used for signing and encrypting messages via certificates.
This cmdlet pairs nicely with Protect-CmsMessage, which performs the encryption/signing. Get-CmsMessage is useful when you need to access encrypted strings, XML configurations, policy definitions, etc., and you’re in possession of the corresponding private key/certificate.
Example 1: Decrypt a basic CMS message
Here’s the simplest usage. If you’ve already got a message encrypted via Protect-CmsMessage, you can pass it directly as a string or read it from a file:
# Read encrypted content from a file
$encryptedMessage = Get-Content -Path "C:\Messages\secret.txt" -Raw
# Decrypt the message
$decrypted = Get-CmsMessage -Content $encryptedMessage
# Display the content
$decrypted
Example 2: Combine with Protect-CmsMessage
Showcasing round-trip encryption and decryption. Best for learning and test environments:
# Encrypt some content
$recipients = @("[email protected]")
$originalMessage = "This is a secret message."
$cms = Protect-CmsMessage -To $recipients -Content $originalMessage
# Simulate saving to file
Set-Content -Path "encrypted.txt" -Value $cms
# Later, decrypt it using Get-CmsMessage
$encrypted = Get-Content -Path "encrypted.txt" -Raw
$decrypted = Get-CmsMessage -Content $encrypted
$decrypted
Example 3: Decrypt CMS message in automation script
Imagine you’re automating deployment and get secrets via encrypted files. This shows you how to decrypt without user intervention:
param (
[string]$SecretPath = "C:\secrets\dbpassword.cms"
)
if (Test-Path $SecretPath) {
$cmsContent = Get-Content -Path $SecretPath -Raw
try {
$secret = Get-CmsMessage -Content $cmsContent
Write-Host "Decrypted DB password: $secret"
} catch {
Write-Error "Failed to decrypt CMS message: $_"
}
} else {
Write-Warning "Secret file not found at $SecretPath"
}
Example 4: Decrypt CMS message from a web service
Advanced use case: Assume a secure internal web API sends CMS-encrypted responses. Here’s how to decrypt them automatically:
# Get encrypted response (application/pkcs7-mime)
$response = Invoke-RestMethod -Uri "https://intranet/api/securedata" -UseDefaultCredentials
# Decrypt the CMS content
$plaintext = Get-CmsMessage -Content $response
# Output the result
Write-Output "Decrypted response: $plaintext"
Tips and Considerations
- Ensure the certificate with the private key exists in your personal store.
- Use
Get-ChildItem Cert:\CurrentUser\Myto view certs available to the current user. - Use secure storage practices – combine
Get-CmsMessagewith vaults like Azure Key Vault when possible.
That’s it for today’s deep dive into Get-CmsMessage. I hope these examples help you better secure and interact with encrypted content in your PowerShell workflows.
Happy scripting, and I will see you in the next post!
Leave a Reply