Search This Blog

Monday, July 04, 2016

Powershell: Start multiple parallel 7zip archives jobs

Had an automated job that would loop through folders and archive the folders into encrypted archives using 7zip. The final script is rushed and should be tidied…. But its enough for my purposes at the moment.

Every now and then one of the folders would fail to archive. Not really sure why and I am guessing either a network issue or internal 7zip issue. But on the next run it would work. So I was running the archive manually for each of the failed archives.

Decided to put together a script to help me, I can now add the failed folders to an array and this script will fire off the archives to run in parallel.

Had real issues getting start-job to accept the parameters due to the inclusion of spaces and quotes. For some reason the command using $args would wrap the –p parameter in an additional quotes and this would throw the 7zip command. In the end I had to create a string and then use invoke-expression in the script block. I spent a while trying to get the –p parameter to work normally (using the $args array but in the end had to cut it short due to time. So the script works but would love to fully understand why it wants to wrap that one parameter in additional quotes….

function Get-ScriptDirectory
{
    #Determine the folder in which the script lives.
    $Invocation = (Get-Variable MyInvocation -Scope 1).Value
    Split-Path $Invocation.MyCommand.Path
}

$scriptPath = Get-ScriptDirectory

[String]$scriptCurrentDateTime = Get-Date -format "yyyyMMddHHmmss";
[String]$computerName = $env:computername;
[string]$7zipX64Path = 'C:\7zipPath\7z.exe';
[string]$WorkingFolder = '\\UNC\path\path';
[string]$WorkingFolderWithQuotes = '-w"\\UNC\path\path"';
[string]$passwordWithQuotes = '-p"ThePassword"';
[string]$sourceFolder = '\\UNC\path\path';
[string]$password = '"ThePassword"'

$failedClients = @(
'clientfolder1',
'clientfolder2',
'clientfolder3',
'clientfolder4',
'clientfolder5',
'clientfolder6',
'clientfolder7'
)

    
Foreach ($failedClient IN $failedClients) {
    
    
    $sZipFilesArchive=$scriptCurrentDateTime + '_' + $computerName + '_FilesArchiveAdditonalText_' + $failedClient + '_X64.7z';
    $SFfaileClientWithQuotes = '"' + $sourceFolder + '\' + $failedClient + '"';
    $WFzipArchiveWithQuotes = '"' + $WorkingFolder + '\' + $sZipFilesArchive + '"';
    
    $debugblock = {
        #Have to implement am unusual way to do this as using $args
        #it wraps an additional "" aroudn the -p parameter, not sure why but it screws up the command.
        #& 'C:\7zipPath\7z.exe' $args;
        $commandToRun = 'C:\7zipPath\7z.exe';
        $commandToRun = "`"$commandToRun`" $($args[0]) $($args[1]) $($args[2]) $($args[3]) $($args[4]) $($args[5]) $($args[6]) $($args[7]) $($args[8]) $($args[9]) $($args[10])";
        #debug
        #$commandToRun | Add-Content -Path 'e:\test.txt';
        Invoke-Expression "& $commandToRun";
        
    }

    try 
    {
        start-job -ScriptBlock $debugblock -ArgumentList  "a", "-t7z", "-mx=5", "-m0=LZMA2", "-mmt", "-mhe=on", "-mhc=on", $passwordWithQuotes, $WorkingFolderWithQuotes, $WFzipArchiveWithQuotes, $SFfaileClientWithQuotes;
    }
    catch
    {
        $MyError = $_
        Throw $MyError
    }
}

trap
    {
        #$CRLF added because usual `r`n in string doesnot work within trap.
        [string]$CRLF = [char]13 + [char]10
        $script:errorMessage += '"' + $smtpserver + '" : Error: {0}' -f $_.Exception.Message + $CRLF;
        $Error.Clear();
        continue;
    }
    
    

 

Share/Bookmark

No comments:

Post a Comment