Get-CmsMessage

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\My to view certs available to the current user.
  • Use secure storage practices – combine Get-CmsMessage with 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

Your email address will not be published. Required fields are marked *