Every script download on this blog shows a SHA256 hash next to it. The hash is computed when the site is built, from the exact file that is served. Checking it takes ten seconds. Do it.
The short version
Run Get-FileHash .\Script-Name.ps1 and compare the Hash value with the one shown on the post. SHA256 is the default algorithm, so -Algorithm SHA256 is optional.
Details
Get-FileHashreturns an object withAlgorithm,HashandPath. The hash is upper-case hex; the blog may show it in lower case. That does not matter: PowerShell’s-eqcompares strings case-insensitively, so(Get-FileHash .\Script-Name.ps1).Hash -eq '<hash from the post>'returnsTruefor a match.- A matching hash proves the file was not changed in transit or on your disk after download. It does not prove who wrote it — the hash comes from the same website as the file. That is what code signing is for, and these scripts are not signed yet.
- Only after you have read the script and the hash matches: if your execution policy is
RemoteSigned, remove the “downloaded from the internet” mark withUnblock-File .\Script-Name.ps1. It deletes the file’sZone.Identifieralternate data stream — the same thing as the Unblock checkbox in the file’s Properties dialog. - Do not “fix” a blocked script by setting the execution policy to
UnrestrictedorBypassmachine-wide. If you need it for a single session,-Scope Processlimits the change to the current PowerShell process. - Avoid MD5 and SHA1 for this. Microsoft’s own documentation says they should only be used for simple change validation.