- Create a certificate-signed RDP shortcut via Group Policy - Fri, Aug 9 2019
- Monitor web server uptime with a PowerShell script - Tue, Aug 6 2019
- How to build a PowerShell inventory script for Windows Servers - Fri, Aug 2 2019
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 = 'https://raw.githubusercontent.com/adbertram/Random-PowerShell-Work/master/Security/GnuPg.psm1' $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
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'
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.
Sir,
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
param
(
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
#[ValidateScript({ Test-Path -Path $_ -PathType Container })]
[string]$FolderPath,
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string]$Password,
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$GpgPath = ‘C:\Program Files (x86)\GnuPG\bin\gpg.exe’
)
process
{
try
{
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’}
}
catch
{
Write-Error $_.Exception.Message
}
}
But it is opening a window pinquery -qt
asking for passphrase
Hi Indra,
I also have this issue & wondered if you found a way to disable the additional password prompt?
Thanks,
JB
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.
nevermind got it. installation issue.
Hey Adam,
I am facing the same issue here with powershell unable to find the file specified.
How did resolve this?
@ravit
You must first execute the 4 lines at the beginning of this article in order to install the function.
Has anyone been able to get Remove-Encryption to actual work via Powershell?
Error:
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.
@New
That’s because you used a wildcard.
If you have several folders to uncypher, use the Foreach statement.
For example:
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 $list.name)
{$out = $File -replace ".pgp", ""
& gpg2 –batch –passphrase "secret" –armor –output $out –decrypt $file 2> $null}
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.
Hi Crow,
Script just has below trim code to remove the gpg extension.
$_.FullName.TrimEnd('.gpg')
Is this behaviour just specific to zip files?
Is the decryption-renaming working fine for other files?
This method fails if the filename contains any spaces… 🙁
Please use below block for Remove-Encryption function within gnupg module for a workaround on space in the filename error.
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.
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 :
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.
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
https://gallery.technet.microsoft.com/scriptcenter/Encrypt-and-Decrypt-Files-214db670
Error:
–batch –yes –passphrase $Password -o $decryptFilePath -d $($_.FullName) unrecognized command.
I am totally new to powershell, could someone please help with the issue.
Thanks,
Shreyas
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
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 !!
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.
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!
KP
Do you have to use this software, can't you just powershell this script?
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.
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)
/Brian
I ended up using a .Net solution, https://github.com/Cinchoo/ChoPGP
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.
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.
[Reflection.Assembly]::LoadFile(“C:\PHPEncryption\ChoPGP.dll”)
[Reflection.Assembly]::LoadFile(“C:\PHPEncryption\BouncyCastle.Crypto.dll”)
$publicKeyFile = “C:\PHPEncryption\Concur\concursolutionsrotate.asc”
$workingPath = “C:\PHPEncryption\TestWorkingPath\”
$destination = “$($workingPath)Encrypted\”
# simple gpg wrapper
function Encrypt-File {
[cmdletbinding()]
Param([string]$fileToEncrypt)
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”
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.
Do you mean to store a secure string in a CSV/TXT file and then recall it somewher else?
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
Hi,
How can we use the public key to encrypt and decrypt the file using PGP
The Encrypt has already been posted. Decrypt is another function of ChoPgp, so it's pretty simple.
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 ‘http://files.gpg4win.org/gpg4win-2.2.5.exe’ version 2.25 which is still in supported 2.2 2024-12-31 (Long term support) from https://gnupg.org/download/ 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