Microsoft’s November 10, 2026 Windows security updates changed how PowerShell checks signed scripts, and some scripts that validated a week ago now report as unsigned. The company confirmed the change in a post on X, saying “We introduced stricter PowerShell script signature validation,” and pointed administrators to new guidance published as KB 5135999, which includes a repair script.
The change targets files containing malformed UTF-8, the text encoding most modern editors use. Before the update, Windows quietly swapped invalid bytes for replacement characters while decoding a script, so signing and verification still went through. After it, the same file fails. Microsoft describes this as intentional security hardening and lists no CVE, registry switch or opt-out for it.
It applies to Windows 11 versions 23H2, 24H2, 25H2, 26H1, and 26H2; Windows 10 Enterprise LTSC 2021; and Windows Server 2016, 2019, 2022, and 2025. The relevant updates include KB5132061 for Windows 11 24H2 through 26H2, KB5131087 for 23H2, KB5131096 for Windows 10 and KB5131090 for Windows Server 2022.
What breaks, and why untouched scripts are affected
Microsoft lists three symptoms. Get-AuthenticodeSignature returns Status : NotSigned for a script that carries a signature. Set-AuthenticodeSignature fails with UnknownError and the message “No mapping for the Unicode character exists in the target multi-byte code page.” On machines using App Control for Business (formerly WDAC), affected scripts may drop into ConstrainedLanguage mode, a restricted mode that blocks many .NET and COM calls.
When the execution policy is AllSigned, a script that reads as unsigned will not run. That puts scheduled tasks, logon scripts and deployment pipelines at risk in exactly the environments that enforce signing most strictly.
The update did not change how Windows picks an encoding, only how strictly it validates the result. Windows first looks for a byte order mark (BOM), a short marker at the start of a file that declares its encoding. Without one, it checks the first 32 bytes for UTF-8 or UTF-16 patterns; if nothing matches, it falls back to the system code page and decodes the whole file that way.
That 32-byte window is where many scripts will be caught. Visual Studio Code and PowerShell 7 both save UTF-8 without a BOM by default, so a script that opens with plain ASCII and contains a single accented name, a smart quote, or a non-English comment further down can be read with the wrong encoding. Microsoft groups the failures into three cases: files read as UTF-8 that contain invalid data; UTF-8 files without a BOM read through a system code page, such as 932 on Japanese systems; and files in a legacy encoding, such as Shift-JIS, mistaken for UTF-8.
The signature exists to prove that a script is byte-for-byte identical to what the publisher signed. A check that tolerated substituted characters was vouching for text that did not exactly match the file on disk.
How to find affected scripts
Microsoft’s guidance includes a script, Repair-SignedPowerShellUtf8.ps1, published in the appendix of the KB article. Its default Scan mode changes nothing and reports each file’s likely problem:
.\Repair-SignedPowerShellUtf8.ps1 -Mode Scan -Path C:\Scripts -Recurse |
Format-Table Path, Issue, SignatureStatus, Action -Wrap
The Issue column returns MalformedUtf8, Utf8WithoutBom, CodePageTextReadAsUtf8, NotValidInCodePage or None. Microsoft cautions that these labels are hints rather than proof of the original encoding, and that a NotSigned status alone is not a reason to run a repair, since the symptoms can have other causes. The tool requires Windows PowerShell 5.1 running in FullLanguage mode.
The fix: convert and re-sign, or a temporary repair
The recommended route is to convert the file to UTF-8 with a BOM and sign it again. Adding a BOM to a file that still contains invalid bytes does not fix it, so the text has to be reviewed after conversion:
.\Repair-SignedPowerShellUtf8.ps1 -Mode ConvertToUtf8Bom -Path C:\Scripts\Deploy.ps1
Set-AuthenticodeSignature -FilePath C:\Scripts\Deploy.utf8bom.ps1 -Certificate $cert
Get-AuthenticodeSignature -FilePath C:\Scripts\Deploy.utf8bom.ps1 |
Format-List Status, StatusMessage
The conversion writes a new file, Deploy.utf8bom.ps1, strips the old signature and never overwrites the original. For legacy-encoded files, add -SourceCodePage with the original code page, for example 932 for Shift-JIS. Deploy only after the status reads Valid.
Teams that do not hold the signing certificate can try -Mode Repair, which attempts to produce a copy whose existing signature still validates. Microsoft calls this temporary and says it is not guaranteed: it covers only the first two cases, refuses some BOM-less files, and, for those, it should be run on a machine with the same system code page as the original signer. If it fails, the only route left is a corrected, signed copy from the script’s publisher.
Microsoft has not said what prompted the hardening or whether a specific attack technique is behind it. It also has not said whether third-party vendors shipping signed scripts were notified before the update went out.
Community Discussion
Join the conversation. Ask questions, share solutions, and help others.
Be the first to start the discussion!
