PowerShell/Scripts/encrypt-file.ps1

160 lines
5.7 KiB
PowerShell
Raw Normal View History

2021-08-26 10:46:12 +02:00
<#
2021-07-13 21:10:02 +02:00
.SYNOPSIS
encrypt-file.ps1 [<path>] [<password>]
.DESCRIPTION
2021-08-29 17:50:03 +02:00
Encrypts the given file.
2021-07-13 21:10:02 +02:00
.EXAMPLE
PS> .\encrypt-file.ps1 C:\MyFile.txt "123"
2021-08-29 17:50:03 +02:00
.NOTES
Author: Markus Fleschutz · License: CC0
2021-07-13 21:10:02 +02:00
.LINK
https://github.com/fleschutz/PowerShell
#>
2021-07-15 15:51:22 +02:00
param([string]$Path = "", [string]$Password = "")
2021-01-27 15:12:17 +01:00
function EncryptFile {
<#
.SYNOPSIS
Encrypts a file using a symmetrical algorithm.
.DESCRIPTION
Encrypts a file using a symmetrical algorithm.
.PARAMETER FileName
File(s) to be encrypted.
.PARAMETER Key
Cryptography key as a SecureString to be used for encryption.
.PARAMETER KeyAsPlainText
Cryptography key as a String to be used for encryption.
.PARAMETER CipherMode
Specifies the block cipher mode to use for encryption.
.PARAMETER PaddingMode
Specifies the type of padding to apply when the message data block is shorter than the full number of bytes needed for a cryptographic operation.
.PARAMETER Suffix
Suffix of the encrypted file to be removed.
.PARAMETER RemoveSource
Removes the source (decrypted) file after encrypting.
.OUTPUTS
System.IO.FileInfo. Protect-File will return FileInfo with the SourceFile, Algorithm, Key, CipherMode, and PaddingMode as added NoteProperties
#>
[CmdletBinding(DefaultParameterSetName='SecureString')]
[OutputType([System.IO.FileInfo[]])]
Param(
[Parameter(Mandatory=$true, Position=1, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
[Alias('PSPath','LiteralPath')]
[string[]]$FileName,
[Parameter(Mandatory=$false, Position=2)]
[ValidateSet('AES','DES','RC2','Rijndael','TripleDES')]
[String]$Algorithm = 'AES',
[Parameter(Mandatory=$false, Position=3, ParameterSetName='SecureString')]
[System.Security.SecureString]$Key = (New-CryptographyKey -Algorithm $Algorithm),
[Parameter(Mandatory=$true, Position=3, ParameterSetName='PlainText')]
[String]$KeyAsPlainText,
[Parameter(Mandatory=$false, Position=4)]
[System.Security.Cryptography.CipherMode]$CipherMode,
[Parameter(Mandatory=$false, Position=5)]
[System.Security.Cryptography.PaddingMode]$PaddingMode,
[Parameter(Mandatory=$false, Position=6)]
[String]$Suffix = ".$Algorithm",
[Parameter()]
[Switch]$RemoveSource
)
2021-01-04 10:37:14 +01:00
begin {
try {
if ($PSCmdlet.ParameterSetName -eq 'PlainText') {
$Key = $KeyAsPlainText | ConvertTo-SecureString -AsPlainText -Force
}
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Key)
$EncryptionKey = [System.Convert]::FromBase64String([System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR))
$Crypto = [System.Security.Cryptography.SymmetricAlgorithm]::Create($Algorithm)
2021-01-04 10:37:14 +01:00
if ($PSBoundParameters.ContainsKey('CipherMode')) {
$Crypto.Mode = $CipherMode
}
2021-01-04 10:37:14 +01:00
if ($PSBoundParameters.ContainsKey('PaddingMode')) {
$Crypto.Padding = $PaddingMode
}
$Crypto.KeySize = $EncryptionKey.Length*8
$Crypto.Key = $EncryptionKey
2021-01-04 10:37:14 +01:00
} catch {
Write-Error $_ -ErrorAction Stop
}
}
2021-01-04 10:37:14 +01:00
process {
$Files = Get-Item -LiteralPath $FileName
2021-01-04 10:37:14 +01:00
foreach($File in $Files) {
$DestinationFile = $File.FullName + $Suffix
2021-01-04 10:37:14 +01:00
try {
$FileStreamReader = New-Object System.IO.FileStream($File.FullName, [System.IO.FileMode]::Open)
$FileStreamWriter = New-Object System.IO.FileStream($DestinationFile, [System.IO.FileMode]::Create)
$Crypto.GenerateIV()
$FileStreamWriter.Write([System.BitConverter]::GetBytes($Crypto.IV.Length), 0, 4)
$FileStreamWriter.Write($Crypto.IV, 0, $Crypto.IV.Length)
$Transform = $Crypto.CreateEncryptor()
$CryptoStream = New-Object System.Security.Cryptography.CryptoStream($FileStreamWriter, $Transform, [System.Security.Cryptography.CryptoStreamMode]::Write)
$FileStreamReader.CopyTo($CryptoStream)
$CryptoStream.FlushFinalBlock()
$CryptoStream.Close()
$FileStreamReader.Close()
$FileStreamWriter.Close()
2021-01-04 10:37:14 +01:00
if ($RemoveSource) {
Remove-Item -LiteralPath $File.FullName
}
$result = Get-Item $DestinationFile
$result | Add-Member MemberType NoteProperty Name SourceFile Value $File.FullName
$result | Add-Member MemberType NoteProperty Name Algorithm Value $Algorithm
$result | Add-Member MemberType NoteProperty Name Key Value $Key
$result | Add-Member MemberType NoteProperty Name CipherMode Value $Crypto.Mode
$result | Add-Member MemberType NoteProperty Name PaddingMode Value $Crypto.Padding
$result
2021-01-04 10:37:14 +01:00
} catch {
Write-Error $_
2021-01-04 10:37:14 +01:00
if ($FileStreamWriter) {
$FileStreamWriter.Close()
Remove-Item -LiteralPath $DestinationFile -Force
}
2021-01-04 10:37:14 +01:00
continue
} finally {
if($CryptoStream){$CryptoStream.Close()}
if($FileStreamReader){$FileStreamReader.Close()}
if($FileStreamWriter){$FileStreamWriter.Close()}
}
}
}
}
try {
if ($Path -eq "" ) {
$Path = read-host "Enter path to file"
}
if ($Password -eq "" ) {
$Password = read-host "Enter password"
}
$PasswordBase64 = [System.Convert]::ToBase64String($Password)
2021-01-04 10:37:14 +01:00
EnryptFile "$Path" -Algorithm AES -KeyAsPlainText $PasswordBase64 -RemoveSource
2021-02-10 19:25:48 +01:00
2021-08-24 20:46:03 +02:00
"✔️ Done."
exit 0
} catch {
2021-05-02 21:30:48 +02:00
write-error "⚠️ Error in line $($_.InvocationInfo.ScriptLineNumber): $($Error[0])"
exit 1
}