PowerShell/PowerShell · error · PSInvalidOperationException

The file could not be signed.

Error message

The file {0} could not be signed.

What it means

Thrown by Export-PSSession when signing the generated psm1 or format.ps1xml file fails for any reason. SignatureHelper.SignFile is wrapped in a try/catch that catches a generic Exception and re-throws it as PSInvalidOperationException with the failing filename, preserving the original exception as the inner exception.

Solutions

  1. Inspect the inner exception to find the underlying SignFile failure (e.g. CryptographicException) for the real cause
  2. Verify the certificate is a code-signing cert with HasPrivateKey and a Valid EnhanceKeyUsage (Code Signing), and is within its validity period
  3. Ensure the generated psm1/format.ps1xml files are writable and not locked by another process
  4. Re-run with a fresh cert issued specifically for code signing

Example fix

# before
Export-PSSession -Session $s -OutputModule MyMod -Certificate $tlsCert

# after
$signCert = Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert |
    Where-Object { $_.NotAfter -gt (Get-Date) -and $_.HasPrivateKey }
Export-PSSession -Session $s -OutputModule MyMod -Certificate $signCert
Defensive patterns

Strategy: try-catch

Validate before calling

$cert = Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert |
  Where-Object { $_.HasPrivateKey -and $_.NotAfter -gt (Get-Date) }
if (-not $cert) { throw 'No valid code-signing cert available.' }

Type guard

null

Try / catch

try { Export-PSSession -Certificate $cert @params } catch [System.Management.Automation.PSInvalidOperationException] { $inner = $_.Exception.InnerException; Write-Error "Signing failed: $($inner.Message)" }

Prevention

When it happens

Trigger: Passing a -Certificate that exists in the store but is not a valid code-signing certificate, is expired/revoked, lacks a private key, or cannot write the signature to the file (path locked, read-only, missing permissions).

Common situations: Selecting a non-code-signing cert (e.g. an SSL/TLS cert) from the store; expired or not-yet-valid certificates; files held open by antivirus or another process; the cert's private key is not exportable/accessible to the current user.

Related errors


AI-assisted analysis of PowerShell/PowerShell@3ff3c711bf (2026-08-13). Data as JSON: /api/errors/494e7b23534d9528. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.PowerShell.Commands.Utility/commands/utility/ImplicitRemotingCommands.cs:3103

            {
                if (certificate == null)
                {
                    string message = ImplicitRemotingStrings.CertificateNeeded;
                    throw new PSInvalidOperationException(message);
                }
                else
                {
                    string currentFile = baseName + ".psm1";
                    try
                    {
                        SignatureHelper.SignFile(SigningOption.Default, currentFile, certificate, string.Empty, null);
                        currentFile = baseName + ".format.ps1xml";
                        SignatureHelper.SignFile(SigningOption.Default, currentFile, certificate, string.Empty, null);
                    }
                    catch (Exception e)
                    {
                        string message = StringUtil.Format(ImplicitRemotingStrings.InvalidSigningOperation, currentFile);
                        throw new PSInvalidOperationException(message, e);
                    }
                }
            }

            result.Add(baseName + ".psd1");
            FileInfo manifestFile = new(baseName + ".psd1");
            FileStream psd1 = new(
                manifestFile.FullName,
                fileMode,
                FileAccess.Write,
                FileShare.None);
            using (TextWriter writer = new StreamWriter(psd1, encoding))
            {
                GenerateManifest(writer, baseName + ".psm1", baseName + ".format.ps1xml");
                psd1.SetLength(psd1.Position);
            }

            PSPrimitiveDictionary applicationArguments = GetApplicationArguments();

View on GitHub (pinned to 3ff3c711bf)