---
title: "How to Find Every Unsigned PowerShell Script on a File Share"
description: "Use Get-AuthenticodeSignature to find unsigned or edited PowerShell scripts on a file share, then export every failed check to a CSV."
canonical: "https://adamtheautomator.com/find-unsigned-powershell-scripts/"
---

# How to Find Every Unsigned PowerShell Script on a File Share

> Use Get-AuthenticodeSignature to find unsigned or edited PowerShell scripts on a file share, then export every failed check to a CSV.

Source: https://adamtheautomator.com/find-unsigned-powershell-scripts/

---

ATA Learning

Tap to hide

[

ATA Learning

](/)

*   [Home](/)
*   [Tutorials](/tutorials/)
*   [Instructors](/author/)
*   [Advertising](/advertising/)
*   [Recommended Resources](/resources/)
*   [About Adam](/about-adam/)

Search for:  

*   [](https://twitter.com/adbertram)
*   [](https://github.com/Adam-the-Automator)
*   [](https://www.linkedin.com/company/adam-the-automator-llc)
*   [](/feed/)

![How to Find Every Unsigned PowerShell Script on a File Share](https://adamtheautomator.com/wp-content/uploads/publisher/3f95d9c85b2b8194adeee658911c3d7a/7f6a2f144374610925efe230aa9b7df588fbe316342ea3599805d58d8ef3616c.jpg)

# How to Find Every Unsigned PowerShell Script on a File Share

[![](https://secure.gravatar.com/avatar/d0b9d42e21e5622713f8b693aa5c0f9244d5f7dd200ed29b8398f52dee5de337?s=192&d=mm&r=g)Adam Bertram](https://adamtheautomator.com/author/adam-bertram/)20 October 20263 min. read

Categories: [Information Security](/category/infosec/)

Tags:[PowerShell](/tag/powershell/)[Windows](/tag/windows/)[Security](/tag/security/)

Table of Contents

*   [Prerequisites](#prerequisites)
*   [What the Status Values Tell You](#what-the-status-values-tell-you)
*   [Find Unsigned PowerShell Scripts with Get-AuthenticodeSignature](#find-unsigned-powershell-scripts-with-get-authenticodesignature)
*   [Read the Flags](#read-the-flags)
*   [Why There Is No ForEach-Object](#why-there-is-no-foreach-object)
*   [Catch the Statuses the Pipeline Misses](#catch-the-statuses-the-pipeline-misses)
*   [Act on the Results](#act-on-the-results)

You there, the admin who just inherited `\\fileserver\IT_Scripts`: you suspect nobody ever signed what lives in it. When someone asks which unsigned PowerShell scripts sit on that share, and whether anyone edited a signed one afterward, you need an answer faster than opening files one at a time.

You’ll run one `Get-ChildItem | Get-AuthenticodeSignature` pipeline against the share and filter the results down to the `NotSigned` and `HashMismatch` statuses. Then you’ll add the statuses that pipeline misses and export a CSV for whoever owns the scripts.

## Prerequisites

Three things need to be in place before you run anything:

*   A Windows host, even when the share lives on a NAS you reach over SMB. The [Get-AuthenticodeSignature reference](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.security/get-authenticodesignature?view=powershell-7.6) says “This cmdlet is only available on the Windows platform.”
    
*   PowerShell 7.6 or Windows PowerShell 5.1. The commands below follow the 7.6 reference.
    
*   Read access to every folder on the share. With the [default `-ErrorAction Continue`](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_commonparameters?view=powershell-7.6), `Get-ChildItem` reports an error for a folder it can’t open and keeps going, so the scripts in one denied folder never reach your results.
    

## What the Status Values Tell You

The [SignatureStatus enumeration](https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.signaturestatus?view=powershellsdk-7.6.0) defines seven `Status` values that `Get-AuthenticodeSignature` can return for a file. The first pipeline below catches two.

| Status | Microsoft’s meaning | First pipeline flags it | What you do |
| --- | --- | --- | --- |
| `Valid` | Signature is syntactically valid | No | Check the signer separately |
| `NotSigned` | The file has no signature | Yes | Sign it or retire it |
| `HashMismatch` | Content no longer matches the stored hash | Yes | Find out who edited it |
| `UnknownError` | The file has an invalid signature | No | Read `StatusMessage` |
| `NotTrusted` | Signed by a publisher not trusted on the system | No | Trust the publisher or re-sign |
| `NotSupportedFileFormat` | File type cannot be signed or verified | No | Fix your file filter |
| `Incompatible` | Signature cannot be verified on this system | No | Re-check from another host |

Microsoft’s definition of `Valid` says “This means only that the signature is syntactically valid. It does not imply trust in any way.” To see who signed the files that pass, change the first pipeline’s filter to `Where-Object Status -eq 'Valid'` and add `SignerCertificate` to `Select-Object`.

## Find Unsigned PowerShell Scripts with Get-AuthenticodeSignature

Point the pipeline at the share and let it list every unsigned or modified script. Replace the path with your own:

```powershell
Get-ChildItem -LiteralPath '\\fileserver\IT_Scripts' -Filter *.ps1 -Recurse -File |
    Get-AuthenticodeSignature |
    Where-Object Status -in 'NotSigned', 'HashMismatch' |
    Select-Object Status, Path
```

The output is a two-column table of status and path, as shown below.

![Audit pipeline results](https://adamtheautomator.com/wp-content/uploads/publisher/a0e8e23f461b5e103fec14685b8d0b01b8deb78f2eece90b5dbdfdafa2bb9b6d.jpg)

Read the `HashMismatch` rows first. A `NotSigned` file may never have been signed. But a `HashMismatch` file was signed and then changed, and that’s the row someone should explain.

* * *

_**Pro Tip: Compare a HashMismatch file against its copy in source control before you re-sign it. Signing whatever sits on disk gives the unreviewed edit a valid signature.**_

* * *

### Read the Flags

Each option in the audit pipeline controls what gets scanned or what reaches the output:

*   `-LiteralPath` names the share root. The [Get-ChildItem reference](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-childitem?view=powershell-7.6) warns “You should avoid using the Path parameter with the Recurse parameter.”
    
*   `-Filter *.ps1` is applied by the FileSystem provider while it enumerates. The same page says “Filters are more efficient than other parameters,” which matters when every listing crosses the network.
    
*   `-File` keeps folders out of the signature check.
    
*   `Where-Object Status -in` keeps the two statuses you care about and drops the rest.
    

### Why There Is No ForEach-Object

The file objects `Get-ChildItem` returns carry a `PSPath` property, which binds by property name to `-LiteralPath`.

That is how they pipe straight in without the `ForEach-Object {Get-AuthenticodeSignature $_}` wrapper Microsoft’s own example uses. The binding is literal, so a `[` or `]` in a file name never counts as a wildcard.

## Catch the Statuses the Pipeline Misses

The first pipeline ignores `UnknownError`, `NotTrusted`, and `Incompatible`, so a file with a broken or untrusted signature passes unflagged. This version flags everything that isn’t `Valid`, adds module and manifest files, and writes a CSV:

```powershell
Get-ChildItem -LiteralPath '\\fileserver\IT_Scripts' -Include *.ps1, *.psm1, *.psd1 -Recurse -File |
    Get-AuthenticodeSignature |
    Where-Object Status -ne 'Valid' |
    Sort-Object Status, Path |
    Select-Object Status, StatusMessage, Path |
    Export-Csv -Path .\unsigned-script-audit.csv -NoTypeInformation
```

`-Include` replaces `-Filter` here because `-Filter` accepts a single string and you need three patterns.

But the cost is speed, because PowerShell applies `-Include` after the provider has enumerated every file. `-NoTypeInformation` keeps [Export-Csv](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/export-csv?view=powershell-7.6) from writing the `#TYPE` header line on Windows PowerShell 5.1.

The `StatusMessage` column gives the script owner the reason in Microsoft’s words. Opened in a spreadsheet, the file looks like the one below.

![Audit CSV in a spreadsheet](https://adamtheautomator.com/wp-content/uploads/publisher/c4635484ba9e5604c2cdcc76d576036244def675f4a12668d7495f7341f5e6d6.jpg)

* * *

_**Warning: Don’t widen the pattern to ******`*.*`****** to be thorough. It matches file types the system can’t sign or verify, which return ******`NotSupportedFileFormat`****** and fill your CSV with rows that aren’t script findings.**_

* * *

## Act on the Results

Send the CSV to the script owners and ask them to [sign or retire what’s listed](https://adamtheautomator.com/how-to-sign-powershell-script/). Owners sign with [Set-AuthenticodeSignature](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-authenticodesignature?view=powershell-7.6); [about\_Signing](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_signing?view=powershell-7.6) covers the certificate requirements.

Every row in your CSV is also a script that an [`AllSigned` execution policy](https://adamtheautomator.com/set-executionpolicy/) would stop from running.

After the signing round, re-run the second pipeline without its `Export-Csv` line. No output means every script, module, and manifest on the share returns `Valid`, and the signer check is the only review left.

Share this article

[Share on X](https://twitter.com/intent/tweet?url=https%3A%2F%2Fadamtheautomator.com%2Ffind-unsigned-powershell-scripts%2F&text=How%20to%20Find%20Every%20Unsigned%20PowerShell%20Script%20on%20a%20File%20Share)[Share on Facebook](https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fadamtheautomator.com%2Ffind-unsigned-powershell-scripts%2F)[Share on LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fadamtheautomator.com%2Ffind-unsigned-powershell-scripts%2F)

## Related Posts

![](https://adamtheautomator.com/wp-content/uploads/publisher/3ec5d9c85b2b8198b651eec70c447ee1/bc27e65fd261774769a0da850c0fe0f594bb2c6ba5bfcf317eadea5471382804.jpg)

### [Find Expired Windows Certificates Instantly via PowerShell](/find-expired-certificates-powershell/)

Use PowerShell to scan every certificate store across a Windows fleet, report expired and expiring certificates, and alert before authentication breaks.

![](https://adamtheautomator.com/wp-content/uploads/publisher/3ec5d9c85b2b81c8a7f8e65f33231fa4/606223a2505919db35cb97858e8eafa9a96eb8d297bab790394df6d592d2af99.webp)

### [Sysmon: Detect Hidden Malware in Windows Event Logs](/sysmon-detect-hidden-malware/)

Deploy Sysinternals Sysmon with a tuned config, then use Get-WinEvent and Sysmon event IDs to catch process injection and C2 beaconing.

![](https://adamtheautomator.com/wp-content/uploads/publisher/3f35d9c85b2b8157af67cfe805737c4c/d87a8e3ffd5988406606bd14f49a16ebbed72206f31a33a1f24372061a22b0e9.webp)

### [Troubleshoot Missing AI Prompts in Purview Activity Explorer](/purview-missing-ai-prompts/)

Find why Purview records AI activity without prompt text. Check audit settings, capture policies, and viewer permissions in a scoped test.

## Categories

*   [IT Ops](/category/it-ops/)
*   [Cloud](/category/cloud/)
*   [DevOps](/category/devops/)
*   [Home Ops](/category/home-ops/)
*   [Information Security](/category/infosec/)
*   [Software Development](/category/software-development/)

## Site

*   [Home](/)
*   [Tutorials](/tutorials/)
*   [Instructors](/author/)
*   [Advertising](/advertising/)
*   [Recommended Resources](/resources/)
*   [About Adam](/about-adam/)

Copyright 2026© ATA Learning | [Privacy Policy](/privacy/)
