I have a PowerShell script function that creates a text file and then creates a zip file and encrypts it. The code that I have written is as below.
function Zip-File([String]$Name, [String]$getRandomPass, [String]$EncryptionKey) {
try {
$7ZipPath = "C:\Program Files\7-Zip\7z.exe";
$Filepath = "C:\Scripts\$Name.txt";
$ZipPath = "C:\Scripts\$Name.zip";
Set-Content -Path $Filepath -Value $getRandomPass -Force;
$arguments = "a -tzip ""$ZipPath"" ""$Filepath"" -mx9 -p$EncryptionKey";
$windowstyle = "Normal";
$p = Start-Process $7ZipPath -ArgumentList $arguments -Wait -Passthru -WindowStyle $windowstyle;
} catch {
Write-Host "Error is: $($_.Exception.GetType().FullName)"
Write-Host "Error is: $($_.Exception.Message)"
} finally {}
}
This code creates the zip folder $Name.zip with the file $Name.txt. However, only the file $Name.txt is encrypted with the encryption key. The zip archive $Name.zip is not encrypted.
I am not sure how to encrypt the $Name.zip zip archive. Could someone point out how to encrypt the $Name.zip zip archive?
If you want to protect your filenames, you can double archive it. Basically, you can again zip the .zip file. This should work.
Related
I am trying to encrypt multiple files in the folder, however it will not working if more than one files the filepath folder. If it only one file exist in the folder, it will encrypt without any issue. The following if the code that I have so far. Any advise what did I missed. Thanks
#region Encrypt
function Encrypt()
{
$pgp_program = "${env:ProgramFiles(x86)}" + "\GnuPG\bin\gpg.exe"
$recipient = "PROD_20"
$filepath = "C:\filesToEncypt\"
$files = Get-ChildItem -Path $filepath -recurse
try
{
foreach ($item in $files)
{
try
{
write-host $item
Start-Process $pgp_program -ArgumentList "--always-trust -r $recipient -e $item"
}
finally
{
}
}
}
catch [Exception]
{
Write-Host $_.Exception.Message
exit 1
}
}
Encrypt
I am using the following script to copy files from my local folder to SFTP. Once I upload the file I then want to move the file to a subfolder. I want to upload only files in the C:\Users\Administrator\Desktop\ftp folder, and not files in the other subfolders.
param (
$backupPath = "C:\Users\Administrator\Desktop\ftp\moved"
)
# Load the Assembly and setup the session properties
try
{
# Load WinSCP .NET assembly
Add-Type -Path "C:\Program Files (x86)\WinSCP\WinSCPnet.dll"
$session = New-Object WinSCP.Session
$filelist = Get-ChildItem C:\Users\Administrator\Desktop\ftp
# Connect And send files, then close session
try
{
# Connect
$session.Open($sessionOptions)
$transferOptions = New-Object WinSCP.TransferOptions
$transferOptions.TransferMode = [WinSCP.TransferMode]::Binary
foreach ($file in $filelist)
{
$transferResult = $session.PutFiles("C:\Users\Administrator\Desktop\ftp\$file", "/", $False, $transferOptions)
foreach ($transfer in $transferResult.Transfers)
{
Write-Host "Upload of $($transfer.FileName) succeeded"
Move-Item $transfer.FileName $backupPath
}
}
}
finally
{
# Disconnect, clean up
$session.Dispose()
}
exit 0
}
# Catch any errors
catch
{
Write-Host "Error: $($_.Exception.Message)"
exit 1
}
At this moment, if I run the script all files under the moved folder will also get uploaded through SFTP folder, and I just need to upload the files in the root directory of the ftp folder.
I guess I will need to change this line here, but not sure on how to change it.
$filelist = Get-ChildItem C:\Users\Administrator\Desktop\ftp
To skip the folders add -File switch to the Get-ChildItem (as already commented by #Scepticalist):
$filelist = Get-ChildItem -File C:\Users\Administrator\Desktop\ftp
Though you can achieve the same with less code, if you let WinSCP iterate the files (and skip the folders):
$transferOptions = New-Object WinSCP.TransferOptions
$transferOptions.TransferMode = [WinSCP.TransferMode]::Binary
$transferOptions.FileMask = "|*/" # Exclude the folders
$transferResult = $session.PutFiles(
"C:\Users\Administrator\Desktop\ftp\*", "/", $False, $transferOptions)
foreach ($transfer in $transferResult.Transfers)
{
Write-Host "Upload of $($transfer.FileName) succeeded"
Move-Item $transfer.FileName $backupPath
}
And you do not need any Get-ChildItem call.
The above is basically the code from WinSCP article Moving local files to different location after successful upload, just with an exclusion of subfolders.
Though note that your code (contrary to the article) does not have a test for a successful upload. So you will move even files that fail to upload. Make sure you add the $transfer.Error -eq $Null test.
foreach ($transfer in $transferResult.Transfers)
{
# Success or error?
if ($transfer.Error -eq $Null)
{
Write-Host "Upload of $($transfer.FileName) succeeded, moving to backup"
# Upload succeeded, move source file to backup
Move-Item $transfer.FileName $backupPath
}
else
{
Write-Host "Upload of $($transfer.FileName) failed: $($transfer.Error.Message)"
}
}
try to use
Get-Item C:\Users\Administrator\Desktop\ftp -include *.*
this should not get into subfolders.
I have a .zip containing an installer (setup.exe and associated files).
How can I run setup.exe in a PowerShell script without extracting the zip?
Also, I need to pass command line parameters to setup.exe.
I tried
& 'C:\myzip.zip\setup.exe'
but I get an error
... not recognized as the name of a cmdlet, function, script file, or operable program.
This opens the exe:
explorer 'C:\myzip.zip\setup.exe'
but I cannot pass parameters.
What you're asking is not possible. You must extract the zip file in order to be able to run the executable. The explorer statement only works because the Windows Explorer does the extraction transparently in the background.
What you can do is write a custom function to encapsulate extraction, invocation, and cleanup.
function Invoke-Installer {
Param(
[Parameter(Mandatory=$true)]
[ValidateScript({Test-Path -LiteralPath $_})]
[string[]]$Path,
[Parameter(Manatory=$false)]
[string[]]$ArgumentList = #()
)
Begin {
Add-Type -Assembly System.IO.Compression.FileSystem
}
Process {
$Path | ForEach-Object {
$zip, $exe = $_ -split '(?<=\.zip)\\+', 2
if (-not $exe) { throw "Invalid installer path: ${_}" }
$tempdir = Join-Path $env:TEMP [IO.File]::GetFileName($zip)
[IO.Compression.ZipFile]::ExtractToDirectory($zip, $tempdir)
$installer = Join-Path $tempdir $exe
& $installer #ArgumentList
Remove-Item $tempdir -Recurse -Force
}
}
}
Invoke-Installer 'C:\myzip.zip\setup.exe' 'arg1', 'arg2', ...
Note that this requires .Net Framework v4.5 or newer.
I'm in the process of learning Powershell, and am working on a little script that will upload a group of files to an FTPS server nightly. The files are located on a network share in a sub-directory containing the date in the name. The files themselves will all begin with the same string, let's say "JONES_". I have this script working for FTP, but I don't quite get what I need to do to get it to work for FTPS:
# Set yesterday's date (since uploads will happen at 2am)
$YDate = (Get-Date).AddDays(-1).ToString('MM-dd-yyyy')
#Create Log File
$Logfile = "C:\powershell\$YDate.log"
Function LogWrite
{
Param ([string]$logstring)
Add-Content $Logfile -value $logstring
}
# Find Directory w/ Yesterday's Date in name
$YesterdayFolder = Get-ChildItem -Path "\\network\storage\location" | Where-Object {$_.FullName.contains($YDate)}
If ($YesterdayFolder) {
#we specify the directory where all files that we want to upload are contained
$Dir= $YesterdayFolder
#ftp server
$ftp = "ftp://ftps.site.com"
$user = "USERNAME"
$pass = "PASSWORD"
$webclient = New-Object System.Net.WebClient
$webclient.Credentials = New-Object System.Net.NetworkCredential($user,$pass)
$FilesToUpload = Get-ChildItem -Path (Join-Path $YesterdayFolder.FullName "Report") | Where-Object {$_.Name.StartsWith("JONES","CurrentCultureIgnoreCase")}
foreach($item in ($FilesToUpload))
{
LogWrite "Uploading file: $YesterdayFolder\Report\$item"
$uri = New-Object System.Uri($ftp+$item.Name)
$webclient.UploadFile($uri, $item.FullName)
}
} Else {
LogWrite "No files to upload"
}
I'd rather not have to deal with a 3rd party software solution, if at all possible.
Using psftp didn't work for me. I couldn't get it to connect to the FTP over SSL. I ended up (reluctantly?) using WinSCP with this code:
$PutCommand = '& "C:\Program Files (x86)\WinSCP\winscp.com" /command "open ftp://USER:PASS#ftps.hostname.com:21/directory/ -explicitssl" "put """"' + $Item.FullName + '""""" "exit"'
Invoke-Expression $PutCommand
In the foreach loop.
I'm not sure if you would consider this as "3rd party software" or not, but you can run PSFTP from within Powershell. Here is an example of how you could do that (source):
$outfile=$YesterdayFolder"\Report\"$item.Name
"rm $outfile`nput $outfile`nbye" | out-file batch.psftp -force -Encoding ASCII
$user = "USERNAME"
$pass = "PASSWORD"
&.\psftp.exe -l $user -pw $pass $ftp -b batch.psftp -be
So I am trying to process files in to separate backup files, however the this craetes a single archive named as the last file in the array. I am not sure what I am missing here.
$process = "C:\Program Files (x86)\7-Zip\7z.exe"
$destinationdir = "M:\WIP\OUT\"
$sourcedir = "M:\WIP\ZIP\"
$password = "password"
$ziplist = get-childitem $sourcedir
foreach ($zip in $ziplist)
{$destinationfile= $zip+".zip"
Start-Process $process -ArgumentList "a $destinationfile $zip -o$destinationdir -p$password"-NoNewWindow -Wait
}
Change
$destinationfile= $zip+".zip"
to
$destinationfile= $zip.FullName+".zip"