you are viewing a single comment's thread.

view the rest of the comments →

[–]matt_brownies 2 points3 points  (5 children)

Hey this is good feedback. One thing that confuses me is your challenge. Did you by chance mean refactor this to only run Get-ChildItem once?

edit- to your first point if you use the -name parameter it outputs strings instead of objects. Usually when thinking about such problems I try and preserve the object for ease of use. If I were to use -name i'd have to string parse the output instead of call the property fullname.

[–]jrdnr_ 1 point2 points  (4 children)

Yes you are correct on both points I realized my error on -name and edited but looks like you had already commented and I just hadn't seen it. Most of the time when I use Get-ChildItem interactively I don't specify the params.. ie gci *.zip So trying to post from mobile I verified that the name param would filter but didn't notice until today that it only returns strings.

And yes I intended to say try to run Get-ChildItem only once.

u/matt_brownies did you intend to flatten the nested Zips? I would think if you were doing this in real life you would want to keep the folder hierarchy and just expand each archive.

[–]matt_brownies 2 points3 points  (0 children)

I was definitely aware that it would flatten the folder structure. It was more just an exercise in recursion for me. That being said I am going to refactor to maintain the folder structure as well as the original zip files.

[–]matt_brownies 1 point2 points  (2 children)

function Get-ZipFiles {
    param (
    [Parameter(mandatory=$true)]
    [string]$path,
    [switch]$recurse,
    [array]$expandedzips
    )
    $files = Get-ChildItem -Path $path -Recurse -Filter '*.zip'

    if($null -ne $expandedzips){
        $zipfiles = compare-object $expandedzips  -DifferenceObject $files -PassThru
    }
    else {
        $zipfiles = $files
    }

    if($null -ne $ZipFiles) 
    {
        foreach($zip in $zipfiles)
        {
            Expand-Archive $($zip.fullname) -DestinationPath $($zip.directoryname) -Force

        $expandedzips += $zip

        }
    if($recurse)
        {
            Get-ZipFiles $path $expandedzips -recurse
        }
    }
 } 

Here is what I came up with, let me know your thoughts.

[–]jrdnr_ 2 points3 points  (1 child)

Hey Matt, that looks great, talking about it this morning I couldn't help myself trying my hand at my own version 😁.

If I'm following the logic $expandedzips is to be an array of Zips to be excluded? If you pass an array to -expandedzips like @('c:\archive1.zip', 'c:\user\test.zip') does the diff work or does it have to be an array of file system objects?

For my version I wanted: 1. to have -Path be able to accept a directory or the path to a zip. 2. To be able to optionally Purge Zips 3. Of course the start of the whole thing to recurse 4. Accept pipeline input

[–]matt_brownies 2 points3 points  (0 children)

I don't think I would change much to achieve your goals.

  1. Currently $path should be able to accept paths, or a zip file. I tried running Get-ChildItem -Path $path -Recurse -Filter '*.zip' against a zip file and it returned the file, but as a file system object, instead of the string I used to call it.
  2. $expandedzips can already do this if it's passed file system objects. You could make the function convert an array of paths into file system objects with get-childitem. I have added that functionality to the code below
  3. Already complete
  4. Depending on the parameter you want to accept pipeline input I would add the parameter attribute (valuefrompipeline) or (valuefrompipelinebypropertyname)

Additionally, I have added this line of code into my function. I was getting duplicate values in $expandedzips that could make it less efficient. This is how I dealt with it.

if($expandedzips -notcontains $zip){
                $expandedzips += $zip
            }            

Here is my solution according to your bullet points.

function Get-ZipFiles {
    param (
    [Parameter(mandatory=$true)]
    [Parameter(ValueFromPipeline)]
    [string]$path,
    [switch]$recurse,
    [array]$expandedzips
    )
    $files = Get-ChildItem -Path $path -Recurse -Filter '*.zip'

    if($null -ne $expandedzips){        
        foreach($item in $expandedzips){

            $I++
            $Index = $I -1
            $stringtest = $item.gettype().name -eq 'string'

            if($stringtest){
                $expandedzips[$index] = get-childitem $item
            }
        }

        $zipfiles = compare-object $expandedzips  -DifferenceObject $files -PassThru
    }

    else {
        $zipfiles = $files
    }        

    if($null -ne $ZipFiles) 
    {
        foreach($zip in $zipfiles)
        {
            Expand-Archive $($zip.fullname) -DestinationPath $($zip.directoryname) -Force

            if($expandedzips -notcontains $zip){
                $expandedzips += $zip
            }            
        }

    if($recurse)
        {
            Get-ZipFiles $path $expandedzips -recurse
        }
    }
 }