Jenkins + PowerShell - 将Zip文件转换为字节,传输字节,然后重建字节以压缩

时间:2017-09-07 13:39:52

标签: powershell jenkins converter file-transfer

由于这个复杂的问题现在有一个可行的解决方案,我想更新它以适应解决方案,以便其他人可以从中受益。

问题

我正在与Jenkins和PowerShell合作执行一系列操作。其中一个操作是将所有关联日志文件收集并合并到一个相应名称的文件夹中,以将其与原始计算机/服务器关联,将文件夹压缩,然后以某种方式将其传输回Jenkins工作区环境,将拉链存储到单个文件夹中主文件夹,并将所述主文件夹转换为工件,可以在以后的时间/日期下载以进行调试。但是,由于此操作往往涉及两跳交换,因此我遇到了许多阻碍我执行简单文件传输的墙壁。所以我转向社区寻求那些希望有更多经验做这种事情的人的帮助。

我执行许多操作的唯一方法(我到目前为止找到的)是通过Invoke-Command连接到目标机器;然而,我花了很长时间才开始撞墙。一个这样的墙是Jenkins和目标机器之间的文件传输问题。我发现通过创建一个等于被调用命令的对象(例如:$returnMe = Invoke-Command {}),我能够从动作中返回要存储在变量中的对象。这让我可以解决通过会议将项目退回Jenkins的问题......但是现在提出了一个问题:

问题

  1. 使用PowerShell,可以将文件夹压缩,然后转换 将zip文件转换为要传递的对象,然后重构该文件 zip文件使用对象的内容?如果是这样,怎么样?
  2. 分辨率:

    特别向@ArcSet大喊,以帮助其正常工作。

    好吧,所以极有可能这样做;然而,它需要一系列关键步骤才能实现。这是一个四到五步的过程:

    1)将文件收集到目标文件夹中并压缩文件夹 2)将zip文件转换为可以轻松传输的字节 3)通过特殊的自定义对象传递这些字节 4)解析对象以确保多余的字节没有进入文件。 5)将字节转换回Jenkins上的zip文件

    以下是显示如何实现这一目标的代码(带注释):

    # Parse Through Each Server One By One
    ForEach ($server in $servers) {
        # Create a Variable to Take in the Invoke-Command and Receive what is Returned
        $packet = Invoke-Command -ComputerName $server -ArgumentList $server -Credential $creds -ScriptBlock {
            # Function for Creating a Zip File
            Function Create-ZipFromFolder ([string]$Source, [string]$SaveAs) {
                Add-Type -Assembly "System.IO.Compression.FileSystem"
                [IO.Compression.ZipFile]::CreateFromDirectory($Source, $SaveAs)
            }
    
            # Function for Converting Zip to Bytes For File Transfer
            Function Get-BytesFromFile($Path) {
                return [System.IO.File]::ReadAllBytes($Path)
            }
    
            # Absorb and Maske Server IP for the Server to Use For Logging Purposes and FileNaming
            $maskedAddress = $args[0] -Replace ('.+(?=\.\d+$)', 'XX.XX.XX')
    
            # Construct the Path For Consolidated Log Files
            $masterLogFolderPath = ("C:\Logs\RemoteLogs\$maskedAddress")
    
            # Series of Code to Create Log Folder, Consolidate Files, And Delete Unnecessary Data For Cleanup
    
            # Establish what to Save the Zip As. You Will Want The Path Included to Prevent it From Finding Path of Least Resistance Upon Saving
            $zipFile = ($masterLogFolderPath + ".zip")
    
            Try {
               # Here is Where We Call Our Compression Function
               Create-ZipFromFolder -Source $masterLogFolderPath -SaveAs ZipFile
    
               # Next We Convert the Zip to Bytes
               [byte[]]$FileAsBytes = Get-BytesFromFile -Path $zipFile
            }
            Catch {
                Write-Error $_.Exception.Message
            }
    
            # Now We Return the New Object to Jenkins
            return New-Object -TypeName PSCustomObject -Property @{Response=$FileAsBytes}
        }
    
        # Function to Convert the Bytes Back Into a Zip File
        Function Create-FileFromBytes([byte[]]$Bytes, [string]$SaveAs) {
            # It was Discovered that Depending Upon the Environment, Extra Bytes Were Sometimes Added
            # These Next Lines Will Help to Remove Those
            For (($k = 0), ($kill = 0); $kill -lt 1; $k++) {
                If ($Bytes[$k] -gt 0) {
                    $kill = 1
                    # Truncate the Excess Bytes
                    $newByteArray = ($Bytes)[$k..(($Bytes).Length -1)]
                }
            }
    
            # Reconstruct the Zip File
            [System.IO.File]::WriteAllBytes($SaveAs, $NewByteArray)
        }
    
        Try {
            # Call the Function to Begin Reconstruction
            Create-FileFromBytes -SaveAs "$env:Workspace\MasterLog\$maskedAddress.zip" -Bytes $packet.response
        }
        Catch {
            Write-Error $_.Exception.Message
        }
    

    现在这只是一个没有所有重物的基础骨架,但这些是将所有东西放在一起的关键部分。在大多数情况下,遵循此公式将返回所需的结果。我希望这可以帮助那些发现自己处于类似情况的人。

    再次感谢大家的帮助

1 个答案:

答案 0 :(得分:2)

首先,您需要创建一个zip文件。 您需要先使用添加类型加载装配系统。 使用 CreateFromDirectory 方法构建并保存zip文件。 使用 System.IO.File 类从zip读取所有字节。此时,您可以将此数据发送到另一台计算机。最后使用 System.IO.File 类将字节数组转换回文件

function Create-ZipFromFrolder([string]$Source,[string]$SaveAs){
    Add-Type -assembly "system.io.compression.filesystem"
    [io.compression.zipfile]::CreateFromDirectory($Source, $SaveAs)
    return $SaveAs
}

function Get-BytesFromFile([string]$File){
    return [byte[]]$ZipFileBytes = [System.IO.File]::ReadAllBytes($File)
}

function Create-FileFromBytes([byte[]]$Bytes, [string]$SaveAs){
    return [System.IO.File]::WriteAllBytes($SaveAs, $Bytes)
}

[byte[]]$FileAsBytes = Get-BytesFromFile -File (Create-ZipFromFrolder -Source "C:\ZipFolder" -SaveAs "C:\Test\test.zip")

Create-FileFromBytes -SaveAs "C:\ZipFolder\Test.zip" -Bytes $FileAsBytes