In this guide, you will learn how to encrypt and decrypt files on a Windows computer with the help of PowerShell and PGP (Pretty Good Privacy).

File encryption is commonplace these days. You can encrypt files in many ways with a lot of different tools. One way to do this is through an open-source encryption system called Pretty Good Privacy. PGP has been around a long time, and we can encrypt just about any form of data by using it. For now, we’re going to focus on encryption files using PGP and PowerShell.

To encrypt and decrypt files on Windows with PGP, we must download the GNU Privacy Guard for Windows utility. This free, open-source utility uses the OpenPGP Standard to bring PGP to Windows. We first need to download and install this.

We could go out to the website and do this manually, but we’re using PowerShell! Let’s stick to the command line. We could also figure out how to build a PowerShell tool around GnuPG for Windows ourselves, but why do that when a community module already exists?

Let’s save some time; downloading a PowerShell module from GitHub will expedite this process dramatically. To do that, I’ll reach out to GitHub and download a module called GnuPG and place it in a module path on my system.

$uri = ''
$moduleFolderPath = 'C:\Program Files\WindowsPowerShell\Modules\GnuPg'
$null = New-Item -Path $moduleFolderPath -Type Directory
Invoke-WebRequest -Uri $uri -OutFile (Join-Path -Path $moduleFolderPath -ChildPath 'GnuPg.psm1')

Once I download the module, I can see I’ve got a few commands available to me.

Get-Command -Module GnuPg | ft -a
Commands in the GnuPG PowerShell module

Commands in the GnuPG PowerShell module

One of those commands is Install-GnuPG. Let’s run that and see what happens.

PS> Install-GnuPG -DownloadFolderPath 'C:\'

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName
-------  ------    -----      -----     ------     --  -- -----------
     30       2      476        940       0.00   4460   2 gpg4win-2.2.5

This command went out to the GnuPG website, downloaded the installer, and then silently installed it. That saved some time!

Next, I need to encrypt a bunch of important files in a folder with a password only a few other people and I know. To do that, I can use the Add-Encryption command that comes with this module by simply using the Add-Encryption command specifying the folder of files I’d like to encrypt as well as the password I’d like use to secure them.

You can see below that I have a folder with a single file in it. I’m using the Add-Encryption command, which calls the GnuPG utility under the covers to encrypt this file using the password I’m specifying. It returns a GPG file that is the contents of the file encrypted. At this point, I could just remove the original file if I desired.

 Add-Encryption -FolderPath C:\ImportantFiles\ -Password 'secret'
Encrypting a file with PowerShell

Encrypting a file with PowerShell

Now that the file is encrypted in the GPG file, it can’t be read unless decrypted. This GnuPG utility processes the file by first decrypting it, then creating a file of the same name with the unencrypted contents.

You can see below that I’m using the Remove-Encryption command and passing the path of the folder and the secret. The GnuPG utility is creating a keyring if it doesn’t exist yet, decrypting the file, and the Remove-Encryption function is returning the path to the folder that I passed in.

PS C:\> Remove-Encryption -FolderPath C:\ImportantFiles\ -Password secret
gpg: keyring `C:/Users/adam/AppData/Roaming/gnupg/secring.gpg' created
gpg: CAST5 encrypted data
gpg: encrypted with 1 passphrase
gpg: WARNING: message was not integrity protected

    Directory: C:\ImportantFiles

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        2/24/2018   9:36 PM              0 NuclearLaunchCode.txt
-a----        2/24/2018   9:33 PM             60 NuclearLaunchCode.txt.gpg

We can now read that original file like normal!

Subscribe to 4sysops newsletter!

By using the GnuPG utility along with the GnuPG PowerShell module, we can quickly create a handy little tool that can apply encryption to any number of files on the fly. This is an excellent solution for times when you don’t need anything fancy but need a quick way to encrypt files securely with a password.

  1. Avatar
    Indra A 6 years ago


    I have used your code for encryption and decryption for PGP files in file server. But when I am decrypting, it is asking for password even though Im using the same code

    #[ValidateScript({ Test-Path -Path $_ -PathType Container })]


    [string]$GpgPath = ‘C:\Program Files (x86)\GnuPG\bin\gpg.exe’
    Get-ChildItem -Path $FolderPath -Filter ‘*.pgp’ | foreach {
    $decryptFilePath = $_.FullName.TrimEnd(‘.pgp’)
    Write-Verbose -Message “Decrypting [$($_.FullName)] to [$($decryptFilePath)]”
    $startProcParams = @{
    ‘FilePath’ = $GpgPath
    ‘ArgumentList’ = “–batch –yes –passphrase $Password -o $decryptFilePath -d $($_.FullName)”
    ‘Wait’ = $true
    ‘NoNewWindow’ = $true
    $null = Start-Process @startProcParams
    Get-ChildItem -Path $FolderPath | where {$_.Extension -ne ‘pgp’}
    Write-Error $_.Exception.Message

    But it is opening a window pinquery -qt

    asking for passphrase


    • Avatar
      JB 4 years ago

      Hi Indra,

      I also have this issue & wondered if you found a way to disable the additional password prompt?



  2. Avatar
    Adam 5 years ago

    Keep getting error:

    Add-Encryption : This command cannot be run due to the error: The system cannot find the file specified.
    At line:1 char:1
    + Add-Encryption -FolderPath c:\pgptest -Password dellwatts1
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Add-Encryption

    At my wits end. There are files in that directory. I’ve reached the end of google. I’ve tried single and double quotes. Tried run as admin. Any help would be much appreciated thank you. And thank you for the great tutorial. I wouldn’t even get this far without it.

    • Avatar
      Adam 5 years ago

      nevermind got it. installation issue.

      • Avatar
        Ravit Kumar 5 years ago

        Hey Adam,

        I am facing the same issue here with powershell unable to find the file specified.

        How did resolve this?

        • Avatar


          You must first execute the 4 lines at the beginning of this article in order to install the function.

  3. Avatar
    New 5 years ago

    Has anyone been able to get Remove-Encryption to actual work via Powershell?


    Remove-Encryption : Cannot validate argument on parameter ‘FolderPath’. The ” Test-Path -Path $_ -PathType Container ” validation script for the argument with value
    “\\NDH2CPRW2FSR001\ftp\Tallahassee\Hold\*gpg” did not return a result of True. Determine why the validation script failed, and then try the command again.


    • Avatar

      That’s because you used a wildcard.
      If you have several folders to uncypher, use the Foreach statement.
      For example:

      Get-ChildItem -Path '\\NDH2CPRW2FSR001\ftp\Tallahassee\Hold\*gpg' | ForEach-Object -Process {Remove-Encryption -FolderPath $PSItem.FullName -Password secret}

      • Avatar
        John C Brenner 4 years ago

        Nope same error even with your script block.  

        I have a working script that functions interactively but not as a scheduled task 

        $list = gci '\\someuncpath\'

        foreach ($file in $
        {$out = $File -replace ".pgp", ""

        & gpg2 –batch –passphrase "secret" –armor –output $out –decrypt $file 2> $null}

  4. Avatar
    Crow 5 years ago

    Running this script on A LOT of files and ran into a rather strange issue. the files are [filename].zip.gpg. When I run this script, it renames the files to .zi, removing the P in .zip.

    • Avatar

      Hi Crow,

      Script just has below trim code to remove the gpg extension. 

      Is this behaviour just specific to zip files?
      Is the decryption-renaming working fine for other files?

  5. Avatar
    Martin 4 years ago

    This method fails if the filename contains any spaces… 🙁

    • Avatar

      Please use below block for Remove-Encryption function within gnupg module for a workaround on space in the filename error.

      process {
      		try {
      			Get-ChildItem -Path $FolderPath -Filter '*.gpg' | foreach {
      				$decryptFilePath = $_.FullName.TrimEnd('.gpg')
      				Write-Verbose -Message "Decrypting [$($_.FullName)] to [$($decryptFilePath)]"
      			    & $GpgPath --batch --yes --passphrase $Password -o $decryptFilePath -d $_.FullName
      			Get-ChildItem -Path $FolderPath | where {$_.Extension -ne 'gpg'}
      		} catch {
      			Write-Error $_.Exception.Message

      • Avatar

        Also, don't forget to unload the 'gnupg' module using remove-module and re-load the module using import-module cmdlets one you make above changes.

  6. Avatar
    Nemo 4 years ago

    As mentioned above, the "Remove-Encryption" function was converting my ".zip.gpg" files to ".zi" using the "TrimEnd(".gpg") method. To get around it, I changed the code to use the "Substring" method instead and now it correctly converts my ".zip.gpg" files to ".zip". Here's my code snippet :

    #region Edited by 'Me' to fix a bug for renaming .gpg to .zip
                    $gpgFilename = $_.FullName
                    $len = $gpgFilename.Length
    				#$decryptFilePath = $_.FullName.TrimEnd('.gpg')
                    $decryptFilePath = $_.FullName.Substring(0,$len-4)
    #endregion Edited by 'Me' to fix a bug for renaming .gpg to .zip

  7. Avatar
    Frank 4 years ago

    If you cannot get it to work you nee to use "Install-GnuPG -DownloadFolderPath 'C:\'" which will get you gpg4win-2.2.5.exe, gpg4win-3.1.10.exe will not work.

  8. Avatar
    Shreyas 4 years ago

    Hi All,

    I am trying to decrypt a file with command line using gpg4win-3.1.10.exe.

    I am facing with a run time error on gpg4win while executing the script available in below link


    –batch –yes –passphrase $Password -o $decryptFilePath -d $($_.FullName) unrecognized command.

    I am totally new to powershell, could someone please help with the issue.




  9. Avatar

    PowerShell is made of .NET and the .NET Framework has very good build in Classes to encrypt / decrypt.

    If you do not need PGP i recommend this module which do not need a third party tool:

    Encrypt / Decrypt files with PowerShell using symmetrical encryption

        #Create Key 
        $key = New-CryptographyKey -Algorithm AES -AsPlainText
        # now you can save the key as text elsewhere!
        #Encrypt the file 
        Protect-File '.\secrets.txt' -Algorithm AES -KeyAsPlainText $key -RemoveSource 
        #Decrypt the file 
        Unprotect-File '.\secrets.txt.AES' -Algorithm AES -KeyAsPlainText $key -RemoveSource


  10. Avatar
    Nemo 4 years ago

    Thanks Peter Kriegel for pointing to this excellent source. I have been looking for something like this do to file encryption and decryption using native .NET classes and Powershell commands. This works great !!

  11. Avatar
    Jeff S 4 years ago

    I'll echo that. Thanks Peter Kriegel. I've successfully been using GnuPG to decrypt with powershell for years but recent installations have been nothing but trouble (plus missing/poor documentation.)

    Currently I get prompted for a password even if it's passed in a parameter where that used to work in older versions of GnuPG. I'm going to move to the native libs.

  12. Avatar
    KP 4 years ago

    Hello Sir,

    Can I use this module to PGP encrypt files in a folder using a public key provided by the client, as opposed to using  a password? The public key provided is in .asc format and the client holds the private key used for decrypting the files.

    Thank you!

  13. Avatar
    Sam 3 years ago

    Do you have to use this software, can't you just powershell this script?

  14. Avatar
    Jeff Reddy 3 years ago

    This example is confusing. Why are we downloading and installing software in step 1, then downloading a PS script library in step 2 that has a command that downloads and installs software in step 3? Is this really all necessary? Care to explain exactly what’s happening? This seems fraught with risk.

    Then, after installing 3 different third party software bundles, you give no instruction on how to use them beyond a simple password encryption example. What about support for these three libraries? Is there any? Is there any documentation for these? How do we use an asc key instead of a password? This would be great information.

    • Avatar
      Brian Aborg Weje 3 years ago

      Hi Jeff,
      Did you find a solution?
      I have the exact same. I have recieved an .asc from a partner, and supposed to encrypt the file with .asc file before uploading with SFTP.
      I have done all but the encryption in Powershell (with Posh-SSH module)

      • Avatar
        Jeff Reddy 3 years ago

        I ended up using a .Net solution,
        I then called the .Net code from my powershell script. This allowed me to do the PGP encryption and I didn’t have to install any applications. I need to run my PS script on a server via Task Scheduler. This unattended execution meant that a Public Key could not be used from a user’s KeyRing. My solution required no install, the public key file simply had to exist on disk, and everything worked without issue.

        • Avatar
          Brian Aborg Weje 3 years ago

          Hi Jeff

          Great. I have the exact same situation. need to be able to run the powershell from a SSIS package.
          I’ve downloaded the ChoPGP as a zip.
          If you have a tip/code snippet on how to execute it from Powershell, it would much appreciated.

          • Avatar
            Jeff Reddy 3 years ago


            $publicKeyFile = “C:\PHPEncryption\Concur\concursolutionsrotate.asc”
            $workingPath = “C:\PHPEncryption\TestWorkingPath\”
            $destination = “$($workingPath)Encrypted\”

            # simple gpg wrapper
            function Encrypt-File {
            Process {
            $nameGen = New-Object -TypeName EncryptedFileNameGenerator
            $encrypteFileName = $($destination) + “encryptedFile.gpg”

            Write-Host “Encrypting file ” + $fileToEncrypt + ” as ” $encrypteFileName
            $choPgpEncryptDecrypt = new-object Cinchoo.PGP.ChoPGPEncryptDecrypt

            $choPgpEncryptDecrypt.EncryptFile($fileToEncrypt, $encrypteFileName, $publicKeyFile, $true, $false)

            Write-Host “File encrypted”

            Encrypt-File -fileToEncrypt “C:\PHPEncryption\testfile.txt”

  15. Avatar
    Guilherme Matheus 3 years ago

    How do I decrypt a message that is in the CSV file, instead of decrypt a file itselft?

    And then, save the decrypted message to another CSV.

    • Avatar
      Leos Marek (Rank 4) 3 years ago

      Do you mean to store a secure string in a CSV/TXT file and then recall it somewher else?

  16. Avatar
    Alex 3 years ago

    Hi Jeff,

    Hopeing you can help ,  I've tried your code example above and I can't get it to work, the error suggested the assemblies aren't loaded but I have confirmed that they are.  Is there something obviousl I could be missing?


    I have tried multipl ecombinations of chopgp and bouncycastle versions but no joy


    Error below if it helps


     Encrypt-File -fileToEncrypt "C:\Users\me\Downloads\chopgp.\lib\test.pdf"
    Line |
       5 |  $nameGen = New-Object -TypeName EncryptedFileNameGenerator
         |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         | Cannot find type [EncryptedFileNameGenerator]: verify that the assembly containing this type is loaded.
    Encrypting file  + C:\Users\me\Downloads\chopgp.\lib\test.pdf +  as  C:\Users\me\Downloads\chopgp.\libencryptedFile.gpg
    Line |
      11 |  $choPgpEncryptDecrypt.EncryptFile($fileToEncrypt, $encrypteFileName,  …
         |  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         | Exception calling "EncryptFile" with "5" argument(s): "Could not load file or assembly 'BouncyCastle.Crypto, Version=, Culture=neutral, PublicKeyToken=0e99375e54769942'. The system cannot find the file specified."

  17. Avatar
    Deepu 3 years ago



    How can we use the public key to encrypt and decrypt the file using PGP

    • Avatar
      Jeff Reddy 3 years ago

      The Encrypt has already been posted. Decrypt is another function of ChoPgp, so it's pretty simple.


  18. Avatar
    Rohar 1 year ago

    This took me a lot of time to understand this, when I was simply looking to pass my passphare in to a Powershell script only to find it saying ‘ Not an option”

    So I though I share my findings and steps for any one new or just could ‘nt work this outlike me this site provided the core help So thanks to all above for the post.

    There seems to be fragmented versions of GPG
    iI you happen to get a newer version of GPG say 2.3 then the –passpharse is no longer an option its only in an older version of gpg.exe have a look at the version and hellp to check the commands

    1. gpg.exe –version

    2. Have a look at the help for commands
    gpg,exe –help (If you dont see the option –passphrase this version doesnt support it try gpg2.exe instead)

    There is a work around Echo | gpg.exe –batch–yes -o “Loc.txt” -o “Loc”
    but try and do this in Powershell mixed results hit and miss and btw the command need to be lowercase something we windows peps are not used to!

    Using this version ‘’ version 2.25 which is still in supported 2.2 2024-12-31 (Long term support) from install GPG and GPG2

    ** Important Step **
    I think this is part is kinda not said! and is required to get the module working

    Install and that you select a Key manager I decided to use GNU Priviacy Assistance (Perfered Choice) the install includes another

    Launched GPA Imported my Private and Public keys ,Run a test

    Ensure the GnuPg.psm1 was loadded using the command posted on the very beging
    confirm you can see the commands

    It all worked wonderfully , So it looks like the key here is to use gpa2.exe as it supports the –passphrase if wanting to create your own function/wrapper

    I hope this saves someome the time if using Powershell and PGP in General

    #pgpwithpowershell #pgppasspharse

Leave a reply to John C Brenner Click here to cancel the reply

Please enclose code in pre tags

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


© 4sysops 2006 - 2023


Please ask IT administration questions in the forums. Any other messages are welcome.


Log in with your credentials


Forgot your details?

Create Account