From 79b21b9772e2c2f07180ffb5f63441484c23ac62 Mon Sep 17 00:00:00 2001 From: Tom Peltonen Date: Sun, 8 Aug 2021 21:36:16 +1000 Subject: [PATCH] Improved documentation Minor bug fixes --- PeterDocs/PeterDocs.psd1 | Bin 8574 -> 8574 bytes PeterDocs/PeterDocs.psm1 | 75 ++++++++++++++++++++++++++++++++------- PeterDocs/PeterExif.ps1 | 10 ++++-- PeterTask.ps1 | 12 +++++-- QuickStart.md | 28 ++++++++++++++- README.md | 6 ++-- 6 files changed, 110 insertions(+), 21 deletions(-) diff --git a/PeterDocs/PeterDocs.psd1 b/PeterDocs/PeterDocs.psd1 index 17afca179e72efc434ef8344c32103e60fd5afac..9debeb6526090beed5e1786a71e3fe48e9b8c918 100644 GIT binary patch delta 14 Vcmez8^v`L78zZC9W_Lz&1pqI{1pNR2 delta 14 Vcmez8^v`L78zZCPW_Lz&1pqI>1pEL1 diff --git a/PeterDocs/PeterDocs.psm1 b/PeterDocs/PeterDocs.psm1 index 0fbb886..0a47ef6 100644 --- a/PeterDocs/PeterDocs.psm1 +++ b/PeterDocs/PeterDocs.psm1 @@ -35,7 +35,7 @@ $global:default_exifFile = "##peter_exif##.csv" $global:default_metaFile = "##peter##.json" $global:LogPathName = "" $global:MetadataPathName = Join-Path -Path ".\" -ChildPath ".peter-metadata" -$global:Version = "0.0.1" +$global:Version = "0.2" function Open-Log { @@ -241,8 +241,10 @@ function Get-ConvenientFileSize function New-PeterReconcile { Param( - [Parameter(Mandatory)][String] $SourceFolder, - [Parameter(Mandatory)][String] $ReconcileFile, + [Parameter(Mandatory)] + [String] $SourceFolder, + [Parameter(Mandatory)] + [String] $ReconcileFile, [String] $RootFolder, [String] $FileFilter, [int] $ProcessFileCount, @@ -275,7 +277,10 @@ Param( if ($ReconcileFile -eq "") { - $ReconcileFile = $default_reconcileFile + if (!(Test-Path -Path $global:MetadataPathName )) { + $null = New-Item -Path $global:MetadataPathName -ItemType Directory + } + $ReconcileFile = Join-Path -Path $global:MetadataPathName -ChildPath $global:default_reconcileFile } if ($SourceFolder.StartsWith("@")) { @@ -298,10 +303,11 @@ Param( Write-Host "Generating reconciliation file '$ReconcileFile'" if ($IncludeExif) { - if (!(Test-Path -Path $global:MetadataPathName )) { - $null = New-Item -Path $global:MetadataPathName -ItemType Directory + $dirPath = Split-Path -Path $ReconcileFile -Parent + if (!(Test-Path -Path $dirpath )) { + $null = New-Item -Path $dirpath -ItemType Directory } - $ExifFile = Join-Path -Path $global:MetadataPathName -ChildPath $global:default_exifFile + $ExifFile = Join-Path -Path $dirpath -ChildPath $global:default_exifFile Write-Log "Generating Exif file '$ExifFile'" Set-Content -Encoding utf8 -Path $ExifFile -Value $(Set-ExifCsvHeader) } @@ -361,7 +367,9 @@ Param( if ($IncludeExif) { $exifData = Get-ImageFileExif -ImageFile $($_.FullName) - Add-Content -Path $ExifFile -Value (Set-ExifCsvRecord -ExifData $exifData) + if ($null -ne $exifData) { + Add-Content -Path $ExifFile -Value (Set-ExifCsvRecord -ExifData $exifData) + } } } @@ -397,7 +405,9 @@ Param( if ($IncludeExif) { $exifData = Get-ImageFileExif -ImageFile $($_.FullName) - Add-Content -Path $ExifFile -Value (Set-ExifCsvRecord -ExifData $exifData ) + if ($null -ne $exifData) { + Add-Content -Path $ExifFile -Value (Set-ExifCsvRecord -ExifData $exifData ) + } } } @@ -566,6 +576,7 @@ function Invoke-SinglePack The following environment variables are supported: - PETERDOCS_RECIPIENTKEY + - PETERDOCS_SECRETKEY - PETERDOCS_LOGPATH .Example @@ -641,6 +652,13 @@ Param( } } + if ($SecretKey -eq "") { + $getEnvName = $(Get-SoftwareName) + "_SECRETKEY" + if ([System.Environment]::GetEnvironmentVariable($getEnvName) -ne "" -and $null -ne [System.Environment]::GetEnvironmentVariable($getEnvName)) { + $SecretKey = [System.Environment]::GetEnvironmentVariable($getEnvName) + } + } + if (($RecipientKey -eq "") -and ($SecretKey -eq "")) { Write-Log "Recipient Key or Secret Key required for packing" Write-Host "Recipient Key or Secret Key required for packing" -ForegroundColor Red @@ -775,6 +793,12 @@ Param( $null = $items.Add($dataItem) } + $dataItem = @{"SecretFile"="$SecretFile";"Caption"="File used for complex password storage with asymmetric key";} + $null = $items.Add($dataItem) + + $dataItem = @{"FileFilter"="$FileFilter";"Caption"="File filter used with Compress";} + $null = $items.Add($dataItem) + $jsonData.Add("Links",$items) $jsonData | ConvertTo-Json -Depth 10 | Out-File $jsonFile @@ -782,7 +806,7 @@ Param( $fullMetadatName = (Get-Item $global:MetadataPathName).FullName $fullZipName = (Get-Item $ArchiveFile).FullName Compress-7Zip -Path $fullMetadatName -ArchiveFileName $fullZipName -PreserveDirectoryRoot -Format SevenZip -Append -Password $secret -EncryptFilenames -# Remove-Item $fullMetadatName -Recurse + Remove-Item $fullMetadatName -Recurse Write-Log "Archive file '$ArchiveFile' created from folder '$SourceFolder'" Write-Host "Archive file '$ArchiveFile' created from folder '$SourceFolder'" -ForegroundColor Green @@ -869,7 +893,8 @@ Param( is not accessible and you want to reconcile, then this tool is appropriate. The following environment variables are supported: - - PETERDOCS_RECIPIENTKEY + - PETERDOCS_PROFILE + - PETERDOCS_ACCOUNTKEY - PETERDOCS_LOGPATH .Example @@ -1385,6 +1410,7 @@ Param( The following environment variables are supported: - PETERDOCS_RECIPIENTKEY + - PETERDOCS_SECRETKEY - PETERDOCS_LOGPATH @@ -1447,6 +1473,13 @@ Param( } } + if ($SecretKey -eq "") { + $getEnvName = $(Get-SoftwareName) + "_SECRETKEY" + if ([System.Environment]::GetEnvironmentVariable($getEnvName) -ne "" -and $null -ne [System.Environment]::GetEnvironmentVariable($getEnvName)) { + $SecretKey = [System.Environment]::GetEnvironmentVariable($getEnvName) + } + } + if (($RecipientKey -eq "") -and ($SecretKey -eq "")) { Write-Log "Recipient Key name or Secret Key required for unpacking" Write-Host "Recipient Key name or Secret Key required for unpacking" -ForegroundColor Red @@ -1576,8 +1609,8 @@ Param( # Check for metadata $jsonFile = Join-Path -Path (Join-Path -Path $RestoreFolder -ChildPath $global:MetadataPathName ) -ChildPath $global:default_metaFile - Write-Host "Checking $jsonFile" - if (Test-FilesExist $jsonFile) { + Write-Host "Checking for $jsonFile" + if (Test-Path -Path $jsonFile -PathType Leaf ) { $jsonData = Get-Content -Raw -Path $jsonFile | ConvertFrom-Json $software = $jsonData.Software.Name @@ -1607,6 +1640,7 @@ Param( } } } + If (!(Test-Path -Path $ReconcileFile )) { Write-Log "Reconciliation file '$ReconcileFile' does not exist" Write-Host "Reconciliation file '$ReconcileFile' does not exist" -ForegroundColor Red @@ -1619,6 +1653,8 @@ Param( Write-Log "Using reconciliation file '$ReconcileFile'" + Write-Progress -Activity "Comparing reconciliation entries in file $ReconcileFile" -Status "Start" + $totalFileCount = 0 $totalFileSize = 0 $errorCount = 0 @@ -1626,6 +1662,11 @@ Param( $missingFileCount = 0 $missingHash = $false + $ProcessFileCount = 0 + Import-Csv $ReconcileFile | ForEach-Object { + $ProcessFileCount += 1 + } + Import-Csv $ReconcileFile | ForEach-Object { $totalFileCount = $totalFileCount +1 if ($RootFolder -ne "") { @@ -1696,7 +1737,15 @@ Param( $errorCount = $errorCount + 1 Write-Log "Non existant target file '$restoreFileName'" } + + if ( $ProcessFileCount -gt 0) { + Write-Progress -Activity "Comparing reconciliation entries in file $ReconcileFile" -Status "Read $totalFileCount files and size $(Get-ConvenientFileSize -Size $totalFileSize ). Currently at folder '$restoreFileName'" -PercentComplete (($totalFileCount / $ProcessFileCount) * 100) + } else { + Write-Progress -Activity "Comparing reconciliation entries in file $ReconcileFile" -Status "Read $totalFileCount files and size $(Get-ConvenientFileSize -Size $totalFileSize ). Currently at folder '$restoreFileName'" -PercentComplete -1 + } } + + Write-Progress -Activity "Comparing reconciliation entries in file $ReconcileFile" -Completed Write-Log "Total file storage size is $(Get-ConvenientFileSize -Size $totalFileSize ) ($totalFileSize)" Write-Host "Total file storage size is $(Get-ConvenientFileSize -Size $totalFileSize )" diff --git a/PeterDocs/PeterExif.ps1 b/PeterDocs/PeterExif.ps1 index deb95c0..abbf632 100644 --- a/PeterDocs/PeterExif.ps1 +++ b/PeterDocs/PeterExif.ps1 @@ -168,8 +168,13 @@ function Get-ImageFileExif { [System.IO.FileOptions]::SequentialScan ) - $fs = New-Object System.IO.FileStream -ArgumentList $fileStreamArgs - $image = [System.Drawing.Image]::FromStream($fs) + Try { + $fs = New-Object System.IO.FileStream -ArgumentList $fileStreamArgs + $image = [System.Drawing.Image]::FromStream($fs) + } Catch { + # Error likely because not an image file + return $null + } $val = Get-ExifContents -ImageStream $image -ExifCode 37378 -Numeric -Size 8 -Parts 2 if ($null -eq $val -or $val -eq "") { @@ -284,7 +289,6 @@ function Get-ImageFileExif { if ($fs) { $fs.close() } - break return $null } } diff --git a/PeterTask.ps1 b/PeterTask.ps1 index b34a9e3..6a33b4c 100644 --- a/PeterTask.ps1 +++ b/PeterTask.ps1 @@ -90,6 +90,9 @@ uses a symmetric cryptographic key exchange which is less secure then the RecipientKey approach. + SecretKey can also be specifed with Environment variable + "PETERDOCS_SECRETKEY" + Note: Currently the script does not user Secure Strings .Parameter ArchiveFile @@ -165,6 +168,7 @@ The following environment variables are supported: - PETERDOCS_RECIPIENTKEY + - PETERDOCS_SECRETKEY - PETERDOCS_PROFILE - PETERDOCS_ACCOUNTKEY - PETERDOCS_LOGPATH @@ -270,7 +274,11 @@ Import-Module .\PeterDocs if ($task -eq "NewReconcile") { $actioned = $true - New-PeterReconcile -ReconcileFile $reconcileFile -SourceFolder $path -Feedback -RootFolder $rootFolder -FileFilter $fileFilter -LogPath LogPath -ExcludeHash:$ExcludeHash -IncludeExif:$IncludeExif + if ($null -eq $reconcileFile -or $reconcileFile -eq "") { + Write-Error "Reconcile file name required (-ReconcileFile)" + return + } + New-PeterReconcile -ReconcileFile $reconcileFile -SourceFolder $path -Feedback -RootFolder $rootFolder -FileFilter $fileFilter -LogPath $LogPath -ExcludeHash:$ExcludeHash -IncludeExif:$IncludeExif } @@ -282,7 +290,7 @@ Import-Module .\PeterDocs if ($task -eq "ArchiveInformation") { $actioned = $true if (($RecipientKey -eq "") -and ($SecretKey -eq "")) { - Write-Host "Recipient Key or Secret Key required for 7Zip information" -ForegroundColor Red + Write-Error "Recipient Key or Secret Key required for 7Zip information" return } diff --git a/QuickStart.md b/QuickStart.md index 98d046a..97e2510 100644 --- a/QuickStart.md +++ b/QuickStart.md @@ -3,7 +3,7 @@ If you are in a hurry, comfortable to use ``PeterTask.ps1`` and want to accept the defaults then this is what you need to do. -1. Download PowerShell file [PeterTask.ps1](https://raw.github.com/) to a lcoal directory. +1. Download PowerShell file [PeterTask.ps1](https://raw.githubusercontent.com/meerkat-manor/PeterDocs/main/PeterTask.ps1) to a local directory. 2. Open a PowerShell terminal where the above file is stored locally and execute command ```powershell @@ -29,6 +29,32 @@ then this is what you need to do. .\PeterTask.ps1 -Task Compare -Path ``` +## Just Compare + +If your interest is in the reconciliation function of PeterDocs, then assuming you +have two directories, source and target, then the steps to just reconcile are: + + +1. Download PowerShell file [PeterTask.ps1](https://raw.githubusercontent.com/meerkat-manor/PeterDocs/main/PeterTask.ps1) to a local directory. +2. Open a PowerShell terminal where the above file is stored locally and execute command + + ```powershell + Install-Module -Name PeterDocs -Scope CurrentUser + ``` + +3. Run command below substituting the names as applicable + + ```powershell + .\PeterTask.ps1 -Task NewReconcile -ReconcileFile .\myfiles.csv -Path + ``` + +4. Send, if required, the generated CSV file to your destination (target) +5. Now compare the destination. Don't forget to run steps 1. and 2. above on your destination + + ```powershell + .\PeterTask.ps1 -Task Compare -ReconcileFke .\myfiles.csv -Path + ``` + ## Advanced security If you are sending the documents and only want the recipient to be able to unpack the contents then diff --git a/README.md b/README.md index cdd4f4d..995e8cc 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,8 @@ transfer the archive file to your target, where the content are unpacked using t key. After archive contents are restored you can execute the reconcile function to veriy that the contents are transferred, unaltered. +See [Quick Start](QuickStart.md) if you are ready to start and don't need the details. + If you have access to both source and target folders, then you should consider using tools such as: @@ -37,7 +39,7 @@ folders and can be large in number and size because of the increased resolution of digital cameras. The backup also required to be secure from accidental distribution. The backup is not secured -from accidental or malicious deletion, which are require different controls. +from accidental or malicious deletion, which require different controls. ## Usage @@ -56,7 +58,7 @@ Expand-Peter -RestoreFolder "c:\backup\pictures" -Secret "c0mpleX%S3cret" -Archi Compare-Peter -RestoreFolder "c:\backup\pictures" ``` -The above commands are using the default settings for certain options +The above commands are using the default settings for certain options. Packages source folder contents into a 7ZIP file, adding a reconciliation file to the 7ZIP file and then encrypting the contents. Send