This week, I was asked to create a PowerShell script that could find all EFS encrypted files on a Windows 7 computer and decrypt them to prepare the computer to be removed from the domain. As EFS encrypted files are encrypted using a private key that is stored in the user profile, they would otherwise be unreadable when using the new local user profile once the PC was removed from the domain.

Anyways, here is the script:

Windows includes the cipher utility to encrypt and decrypt files, but I wanted to use native PowerShell as much as possible to log all encrypted and decrypted files to a logfile. To decrypt a file using PowerShell, we can use the decrypt method found in the Get-Item cmdlet.

However, the folders aren’t actually encrypted: folders have a encrypted attribute, that encrypts all files that are being put inside it. I didn’t find an easy way to remove this attribute using PowerShell: other attributes like the archive were no problem, but removing the encrypt attribute seems to be a no-go. As a result, I had to use the cipher executable to actually remove this attribute.

Please note, if you want to run this script on a computer still running PowerShell v2, you will have to use the script below instead. There is only one small modification for running this script on v2, and that is that the Get-ChildItem cmdlet does not contain the -file or -directory switches, so you have to filter between files and folders using the PSIsContainer-property.

Here’s the version 2 script:

 

  1. I somehow encrypted some files without meaning to, and because of it I can’t backup my user folder to Mozy. Is there a way to remove the encryption from all the files or at least find out which one are encrypted?

  2. I somehow encrypted some files without meaning to, and because of it I can’t backup my user folder to Mozy. Is there a way to remove the encryption from all the files or at least find out which one are encrypted?

  3. You can use my script to quickly find all the encrypted files by just using this part of the script as a oneliner:

    Get-ChildItem -path ‘C:\’ -File -Recurse -Force -ErrorAction SilentlyContinue |
    Where-Object { $_.Attributes -match “Encrypted” } |
    Select-Object -ExpandProperty FullName

    You should change the path to the drive or folder that you want to start your scan

  4. Hi,
    I am trying to follow ur script but not able to as I am not educated in this.Can you tell me which are the commands I need to use to decrypt the files without any other dialogues.

    • Hi Munira,

      If you have only a couple of files or folders that need decrypting, you might be better off using the GUI. If not, please provide me with some more details of the parts your’re struggling with.

  5. Hi there,
    I only have 1 encrypted file that I encrypted years ago and I can’t even remember through which program I encrypted it. Now I can’t rename, delete or remove it,. Do you have a solution to my problem sir?

  6. Thanks Marco, saved my bacon with this script! Had written countless hours of my own trying to do just this, but couldn’t get it to recurse the different drives.

  7. Hi Munira

    Has this issue been resolved?

    @ admin, can you provide some Powershell scripts on how to decrypt .msg files on a server or a specific location on a server?

    Kind Regards

    Nivan

  8. This script is great – thanks for taking the time and sharing it. I have discovered a few bugs though.

    $logFile = "C:LogsEfsDecryptLog_$filename.log"
    Does not expand to a reasonable path – in my case it ends up dumping the log in C:\Windows\System32. Adding the path separators solves this:
    $logFile = $("C:\Logs\" + $filename + ".log")

    The second one is more severe – it seems the file name expansion is a bit sensitive, causing the script to fail on filenames with brackets – [ and ]. For example, these will throw “File Not Found”:

    archive_sync_sftp 2018-05-07 101702.491 [Stopped].log
    archive_sync_sftp 2018-05-10 105037.639 [Error].log

    It also fails with the hidden “.suo” file that Visual Studio generates. I’m pretty sure both cases will be solved by escaping or quoting the filename expansion somehow, but not sure how to go about it.

    Eg. I assume the problem is with (Get-Item $file).Decrypt() but I’m not sure how to make it more robust. Any ideas?

    Thanks!

Leave a Reply

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

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">