7Z.psm1
#region New-7ZFile Function New-7ZFile { Param ( [CmdletBinding()] [Parameter(Position = 0, Mandatory = $true)] [string]$Path, [Parameter(Position = 1, Mandatory = $false )] [string]$FilePath, [Parameter(Position = 2, Mandatory = $false )] [ValidateSet(“7z”,”Zip”,”Tar”, "GZip", "BZip2", "Exe")] [string]$FileType = "7Z", [int]$Threads, [string]$Split, [switch]$Encrypt, [switch]$EncryptFileNames, [System.Security.SecureString]$Password ) # Get the path to the 7Z.exe $7ZPath = Get-7ZPath # Test the 7Z files Test-7ZInstallation # Test if source path exists if(-Not (Test-Path $Path)) { Write-Output "Could not find path $Path!" return } # Get the full path to the source $sourcePath = (Resolve-Path $Path).Path # Check if the FilePath is null and create a path if(-Not $FilePath) { $base = (Get-Location).Path + "\" $filename = (Get-Item -Path $Path).Name + "." + $FileType.ToLower() $FilePath = $base + $filename } else { $FilePath = (Resolve-NonExistentPath -Path $FilePath).Fullname } # Check the extension of the file path if( -Not ($FilePath.ToLower().EndsWith("."+$FileType.ToLower()))) { # Find the last . on the file name $index = $FilePath.LastIndexOf('.') $FilePath = $FilePath.Substring(0, $index + 1) + $FileType.ToLower() } # Form the arguments $arguments = @() $arguments += "a" if($Threads) { $arguments += "-mmt=$Threads" } if( $FileType.ToLower() -eq "exe" ) { $arguments += "-sfx7z.sfx" } if($Split) { # Get the size to split the files switch ($split.ToLower().Substring($split.length - 2, 2)) { 'mb' {$SplitSize = 'm'; $Size = $Split.Substring(0, $Split.Length - 2)} 'kb' {$SplitSize = 'k'; $Size = $Split.Substring(0, $Split.Length - 2)} 'gb' {$SplitSize = 'g'; $Size = $Split.Substring(0, $Split.Length - 2)} 'b' {$SplitSize = 'b'; $Size = $Split.Substring(0, $Split.Length - 1)} Default {$SplitSize = "b"; $Size = $Split.Substring(0, $Split.Length - 1)} } $arguments += "-v$Size$SplitSize" } # Check if we should encrypt the file if($Encrypt) { if($FileType -ne "7z") { Throw "Encryption is only supported with the 7z file format." } # Chech if the password was provided if(!$Password) { # Read the password from the console $Password = Read-Host -Prompt "Enter the password for the archive: " -AsSecureString } # Get the plain text password $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Password) $PlainPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) $arguments += "-p$PlainPassword" if($EncryptFileNames) { $arguments += "-mhe=on" } } $arguments += '"' + $FilePath + '"' $arguments += '"' + $sourcePath + '"' # Start 7z $pinfo = New-Object System.Diagnostics.ProcessStartInfo $pinfo.FileName = $7ZPath $pinfo.RedirectStandardError = $true $pinfo.RedirectStandardOutput = $true $pinfo.CreateNoWindow = $true $pinfo.UseShellExecute = $false $pinfo.Arguments = $arguments $p = New-Object System.Diagnostics.Process $p.StartInfo = $pinfo $p.Start() | Out-Null $p.WaitForExit() $stdout = $p.StandardOutput.ReadToEnd() $stderr = $p.StandardError.ReadToEnd() Write-Verbose $stdout if($p.ExitCode -ne 0) { Write-Error $stderr } } #endregion #region Get-7ZFile Function Get-7ZFile { Param ( [CmdletBinding()] [Parameter(Position = 0, Mandatory = $true)] [string]$Path ) # Get the path to the 7Z.exe $7ZPath = Get-7ZPath # Test the 7Z files Test-7ZInstallation # Test if source path exists if(-Not (Test-Path $Path)) { Write-Output "Could not find path $Path!" return } # Get the full path to the source $sourcePath = (Resolve-Path $Path).Path # Form the arguments $arguments = @() $arguments += "l" $arguments += "-ba" $arguments += "-slt" $arguments += '"' + $sourcePath + '"' # Start 7z $pinfo = New-Object System.Diagnostics.ProcessStartInfo $pinfo.FileName = $7ZPath $pinfo.RedirectStandardError = $true $pinfo.RedirectStandardOutput = $true $pinfo.CreateNoWindow = $true $pinfo.UseShellExecute = $false $pinfo.Arguments = $arguments $p = New-Object System.Diagnostics.Process $p.StartInfo = $pinfo $p.Start() | Out-Null $p.WaitForExit() $stdout = $p.StandardOutput.ReadToEnd() $stderr = $p.StandardError.ReadToEnd() #Process output $output = $stdout.Split("`n`r") | Where-Object {$_ -ne ""} $currentLine = 0 $propertyCounter = 0 foreach($l in $output) { if($propertyCounter -gt 8) { $propertyCounter = 0 } if($propertyCounter -eq 0) { $obj = New-Object psobject } $items = $l.Split("=") $propertyName = $items[0].Trim() $propertyValue = $items[1].Trim() if($propertyName -eq "Modified") { $propertyName = "Date" $propertyValue = [datetime]$items[1].Trim() } if($propertyName -eq "Size") { $propertyName = "Size (MB)" try { $propertyValue = [int]::Parse($propertyValue) } catch { $propertyValue = 0 } if($propertyValue -gt 0) { $propertyValue = $propertyValue / 1MB $propertyValue = [Math]::Round($propertyValue,2) } } if($propertyName -eq "Packed Size") { $propertyName = "Compressed Size (MB)" try { $propertyValue = [int]::Parse($propertyValue) } catch { $propertyValue = 0 } if($propertyValue -gt 0) { $propertyValue = $propertyValue / 1MB $propertyValue = [Math]::Round($propertyValue,2) } } if($propertyName -eq "Block") { try { $propertyValue = [int]::Parse($propertyValue) } catch { $propertyValue = 0 } } if($propertyName -eq "Attributes") { $propertyName = "Type" if($propertyValue -eq "A") { $propertyValue = "File" } else { $propertyValue = "Directory" } } # Add the property to the object $obj | Add-Member -MemberType NoteProperty -Name $propertyName -Value $propertyValue # Reset if needed if($propertyCounter -eq 8) { Write-Output $obj } $propertyCounter++ } <# $start = 0 foreach($l in $output) { if( $l.Length -le 1 ) { continue } if( ($l.StartsWith("--------")) -and ($start -gt 0)) { break } if($l.StartsWith("--------")) { $start = 1 continue } if( $start -gt 0 ) { $line = $l $obj = New-Object psobject $date = [datetime]$line.Substring(0,20) $obj | Add-Member -MemberType NoteProperty -Name Date -Value $date $line = $line.Substring(20) $itemtype = $line.Substring(0,5) $type = "" if($itemtype.Equals("....A")) { $type = "File" } else { $type = "Directory" } $obj | Add-Member -MemberType NoteProperty -Name "Type" -Value $type $line = $line.Substring(5) Write-Host $line $items = $line.Split() | Where-Object {$_.Length -gt 0} Write-Host $items $size = 0; $compsize = 0; $itemname = "" <# if( $items.Count -eq 3) { $size = $items[0] $compsize = $items[1] $itemname = $items[2] } else { $size = $items[0] $compsize = $null $itemname = $items[1] } if($size -ne $null) { $size = [int]::Parse($size) / 1MB $size = [Math]::Round($size,2) } if($compsize -ne $null) { $compsize = [int]::Parse($compsize) / 1MB $compsize = [Math]::Round($compsize,2) } Write-Host "Size: $size" Write-Host "CSize: $compsize" $obj | Add-Member -MemberType NoteProperty -Name "Size (MB)" -Value $size $obj | Add-Member -MemberType NoteProperty -Name "Compressed Size (MB)" -Value $compsize $obj | Add-Member -MemberType NoteProperty -Name "Name" -Value $itemname Write-Output $obj } } #> # Write-OutPut $stdout if($p.ExitCode -ne 0) { Write-Error $stderr } } #endregion #region Test-7ZFile Function Test-7ZFile { Param ( [CmdletBinding()] [Parameter(Position = 0, Mandatory = $true)] [string]$Path, [switch]$Recurse, [int]$Threads ) # Get the path to the 7Z.exe $7ZPath = Get-7ZPath # Test the 7Z files Test-7ZInstallation # Test if source path exists if(-Not (Test-Path $Path)) { Write-Output "Could not find path $Path!" return } # Get the full path to the source $sourcePath = (Resolve-Path $Path).Path # Form the arguments $arguments = @() $arguments += "t" if($Threads) { $arguments += "-mmt=$Threads" } $arguments += '"' + $sourcePath + '"' if( $Recurse ) { $arguments += "-r" } # Start 7z $pinfo = New-Object System.Diagnostics.ProcessStartInfo $pinfo.FileName = $7ZPath $pinfo.RedirectStandardError = $true $pinfo.RedirectStandardOutput = $true $pinfo.CreateNoWindow = $true $pinfo.UseShellExecute = $false $pinfo.Arguments = $arguments $p = New-Object System.Diagnostics.Process $p.StartInfo = $pinfo $p.Start() | Out-Null $p.WaitForExit() $stdout = $p.StandardOutput.ReadToEnd() $stderr = $p.StandardError.ReadToEnd() Write-Verbose $stdout if($p.ExitCode -ne 0) { Write-Error $stderr } } #endregion #region Extract-7ZFile Function Extract-7ZFile { Param ( [CmdletBinding()] [Parameter(Position = 0, Mandatory = $true)] [string]$Path, [Parameter(Position = 1, Mandatory = $false )] [string]$Destination, [int]$Threads ) # Get the path to the 7Z.exe $7ZPath = Get-7ZPath # Test the 7Z files Test-7ZInstallation # Test if source path exists if(-Not (Test-Path $Path)) { Write-Output "Could not find path $Path!" return } # Get the full path to the source $sourcePath = (Resolve-Path $Path).Path # Get the full path to the destination directory $destinationpath = (Resolve-NonExistentPath $Destination).Fullname # Form the arguments $arguments = @() $arguments += "x" $arguments += "-y" if($Threads) { $arguments += "-mmt=$Threads" } $arguments += '"' + $sourcePath + '"' $arguments += '"' + "-o" + $destinationpath + '"' # Start 7z $pinfo = New-Object System.Diagnostics.ProcessStartInfo $pinfo.FileName = $7ZPath $pinfo.RedirectStandardError = $true $pinfo.RedirectStandardOutput = $true $pinfo.CreateNoWindow = $true $pinfo.UseShellExecute = $false $pinfo.Arguments = $arguments $p = New-Object System.Diagnostics.Process $p.StartInfo = $pinfo $p.Start() | Out-Null $p.WaitForExit() $stdout = $p.StandardOutput.ReadToEnd() $stderr = $p.StandardError.ReadToEnd() Write-Verbose $stdout if($p.ExitCode -ne 0) { Write-Error $stderr } } #endregion #region Update-7ZFile Function Update-7ZFile { Param ( [CmdletBinding()] [Parameter(Position = 0, Mandatory = $true)] [string]$Path, [string]$ItemPath, [Parameter(ParameterSetName=’add’)] [switch]$Remove, [Parameter(ParameterSetName=’remove’)] [switch]$Add, [int]$Threads ) # Get the path to the 7Z.exe $7ZPath = Get-7ZPath # Test the 7Z files Test-7ZInstallation # Test if archive path exists if(-Not (Test-Path $Path)) { Write-Output "Could not find path $Path!" return } # Get the full path to the archive $sourcePath = (Resolve-Path $Path).Path # In case we're adding items to the archive, check if the items exist if($Add) { if(-Not (Test-Path $ItemPath)) { Write-Error "Could not find path $ItemPath!" return } } # Form the arguments $arguments = @() if($Remove) { $arguments += "d" if($Threads) { $arguments += "-mmt=$Threads" } $arguments += '"' + $sourcePath + '"' $arguments += '"' + $ItemPath + '"' } else { $arguments += "a" if($Threads) { $arguments += "-mmt=$Threads" } $arguments += '"' + $sourcePath + '"' $ItemPathFull = (Resolve-Path $ItemPath).Path $arguments += '"' + $ItemPathFull + '"' } # Start 7z $pinfo = New-Object System.Diagnostics.ProcessStartInfo $pinfo.FileName = $7ZPath $pinfo.RedirectStandardError = $true $pinfo.RedirectStandardOutput = $true $pinfo.CreateNoWindow = $true $pinfo.UseShellExecute = $false $pinfo.Arguments = $arguments $p = New-Object System.Diagnostics.Process $p.StartInfo = $pinfo $p.Start() | Out-Null $p.WaitForExit() $stdout = $p.StandardOutput.ReadToEnd() $stderr = $p.StandardError.ReadToEnd() Write-Verbose $stdout if($p.ExitCode -ne 0) { Write-Error $stderr } } #endregion #region Get-7ZVersion Function Get-7ZVersion { Param ( ) # Get the path to the 7Z.exe $7ZPath = Get-7ZPath # Form the arguments $arguments = @("/?") # Start 7z $pinfo = New-Object System.Diagnostics.ProcessStartInfo $pinfo.FileName = $7ZPath $pinfo.RedirectStandardError = $true $pinfo.RedirectStandardOutput = $true $pinfo.CreateNoWindow = $true $pinfo.UseShellExecute = $false $pinfo.Arguments = $arguments $p = New-Object System.Diagnostics.Process $p.StartInfo = $pinfo $p.Start() | Out-Null $p.WaitForExit() $stdout = $p.StandardOutput.ReadToEnd() $stderr = $p.StandardError.ReadToEnd() # Return the output $stdout | Where-Object {$_.length -gt 0} } #endregion #region Helper Functions #region Get-7ZPath Function Get-7ZPath { # Get the system architecture since it affects the path if([System.Environment]::Is64BitOperatingSystem) { $arch = "x64" } else { $arch = "x86" } # Get the path to the 7Z.exe $7ZPath = (Get-Module -Name CPolydorou.7Z).Path $7ZPath = $7Zpath.Substring(0, $7ZPath.Length - 19) + "\7Zip\" + $arch + "\7za.exe" return $7ZPath } #endregion #region Test-7ZInstallation Function Test-7ZInstallation { $7ZPath = Get-7ZPath # Test if 7Zip binaries exist if( -Not (Test-Path ($7ZPath))) { Write-Error "Could not locate 7za.exe!" return } if( -Not (Test-Path ($7ZPath.Replace(".exe",".dll")))) { Write-Error "Could not locate 7z.dll!" return } if( -Not (Test-Path ($7ZPath.Replace("7za.exe","7zxa.dll")))) { Write-Error "Could not locate 7zxa.dll!" return } } #endregion #endregion |