CmdLets/Save-LibraryApplication.ps1

Function Save-LibraryApplication 
 {

    [CmdletBinding(SupportsShouldProcess=$true)]
    Param(
        [Parameter(Mandatory=$True,ValueFromPipeline=$True)]
            $Application,
        [Parameter(Mandatory=$True)]
            [System.IO.FileInfo]$Path,
        [Parameter(Mandatory=$False)]
            [Switch]$Force
    )
    Begin {
        Update-Evergreen -Force
    }
    Process {
        $ProgressPreference = 'SilentlyContinue'

        ForEach ($ScriptBlock in $Application.Source.PreScriptBlocks) {
            Write-Verbose "Executing: $ScriptBlock"
            Invoke-Command -ScriptBlock ([ScriptBlock]::Create($ScriptBlock)) -NoNewScope
        }
        
        $Destination = Join-Path -Path $Path -ChildPath $Application.Name
        Write-Verbose "Using Destination: $Destination"

        if (!(Test-Path $Destination)) { 
            Write-Verbose "Creating Destination"
            If ($PSCmdlet.ShouldProcess($Destination,"Creating Destination Folder")) {
                New-ItemWrapper -Path $Destination
            }
        }

        ForEach ($Item in $Application.Source.Copy) {
            ForEach ($ScriptBlock in $Item.PreScriptBlocks) {
                Write-Verbose "Executing: $ScriptBlock"
                Invoke-Command -ScriptBlock ([ScriptBlock]::Create($ScriptBlock)) -NoNewScope 
            }
            Write-Host "Copy: $($Application.Name)"
            
            If ($Item.Source -like "\\*") { 
                Connect-LibraryApplicationShare $Item
            }

            If ($Item.Source.EndsWith("\*")) {
                $Source = $Item.Source
            } elseif ($Item.Source.Endswith("\")) {
                $Source = $Item.Source + "*"
            } Else {
                $Source = $Item.Source + "\*"
            }
            
            Write-Verbose "Source: $Source"
            If ($PSCmdlet.ShouldProcess($Source,"Copying from")) {
                Copy-ItemWrapper -Path $Source -Destination $Destination
            } Else {
                Test-Path $Item.Source
            }

            ForEach ($ScriptBlock in $Item.PostScriptBlocks) { 
                Write-Verbose "Executing: $ScriptBlock"
                If ($PSCmdlet.ShouldProcess($ScriptBlock,"Execute")) {
                    Invoke-Command -ScriptBlock ([ScriptBlock]::Create($ScriptBlock)) -NoNewScope 
                }
            }
        }

        ForEach ($Item in $Application.Source.Download) {
            ForEach ($ScriptBlock in $Item.PreScriptBlocks) {
                Write-Verbose "Executing: $ScriptBlock"
                Invoke-Command -ScriptBlock ([ScriptBlock]::Create($ScriptBlock)) -NoNewScope 
            }
            
            Write-Host "Download: $($Application.Name)"

            if ($Item.FileName) {
                $OutFile = Join-Path $Destination $Item.FileName
            } else {
                $OutFile = Join-Path $Destination (Split-Path $Item.URI -Leaf)
            }
            Write-Verbose "OutFile: $OutFile"

            If (!(Test-Path $OutFile) -or $Force.IsPresent ) {
                Write-Verbose "URI: $($Item.URI)"
                If ($PSCmdlet.ShouldProcess($OutFile,"Download")) {
                    If ($Item.BITSTransfer) {
                        Start-BitsTransfer -Source $Item.URI -Destination $OutFile
                    } else {
                        Invoke-WebRequest -UseBasicParsing -Uri $Item.URI -OutFile $OutFile
                    }
                    If (!(Test-Path $OutFile)) {
                        Throw "File Not Found: $Outfile"
                    }
                } else {
                    Write-Host "From" $Item.URI
                }
            }

            ForEach ($ScriptBlock in $Item.PostScriptBlocks) { 
                Write-Verbose "Executing: $ScriptBlock"
                If ($PSCmdlet.ShouldProcess($ScriptBlock,"Execute")) {
                    Invoke-Command -ScriptBlock ([ScriptBlock]::Create($ScriptBlock)) -NoNewScope
                }
            }
        }

        ForEach ($Item in $Application.Source.Evergreen) {
            ForEach ($ScriptBlock in $Item.PreScriptBlocks) {
                Write-Verbose "Executing: $ScriptBlock"
                Invoke-Command -ScriptBlock ([ScriptBlock]::Create($ScriptBlock)) -NoNewScope 
            }
            Write-Host "Evergreen: $($Item.Name)"

            $EvergreenApp = Get-EvergreenApp -Name $Item.Name
            If ($Item.Filter -ne "") {
                Write-Verbose "Filtering: $($Item.Filter)"
                $Filter = [ScriptBlock]::Create($Item.Filter)
                $EvergreenApp = ($EvergreenApp | Where-Object -FilterScript $Filter)[0]
            }

            ForEach ($App in $EvergreenApp) {
                If ($Item.FileName){
                    $File = $Item.Filename
                } Else {
                    $File = [system.uri]::UnescapeDataString((Split-Path -Path $App.Uri -Leaf))
                }

                Write-Verbose "File: $File"
                $OutFile = Join-Path -Path $Destination -ChildPath ($File)
                Write-Verbose "OutFile: $OutFile"

                if (!(Test-Path $OutFile) -or $Force.IsPresent) {
                    Write-Verbose "Downloading: $($App.URI)"
                    If ($PSCmdlet.ShouldProcess($OutFile,"Download")) {
                        If ($Item.BITSTransfer) {
                            Start-BitsTransfer -Source $App.URI -Destination $OutFile
                        } else {
                            Invoke-WebRequest -UseBasicParsing -Uri $App.uri -OutFile $OutFile
                        }
                        If (!(Test-Path $OutFile)) {
                            Throw "Failed to download $Outfile"
                        }
                    } Else {
                        Write-Host "From" $App.URI
                    }
                }
            }

            ForEach ($ScriptBlock in $Item.PostScriptBlocks) { 
                Write-Verbose "Executing: $ScriptBlock"
                If ($PSCmdlet.ShouldProcess($ScriptBlock,"Execute")) {
                    Invoke-Command -ScriptBlock ([ScriptBlock]::Create($ScriptBlock)) -NoNewScope 
                }
            }
        }

        ForEach ($Item in $application.Source.WinGet) {
            ForEach ($ScriptBlock in $Item.PreScriptBlocks) {
                Write-Verbose "Executing: $ScriptBlock"
                Invoke-Command -ScriptBlock ([ScriptBlock]::Create($ScriptBlock)) -NoNewScope 
            }

            $WinGet = Get-Item (Join-Path $env:LOCALAPPDATA "Microsoft\WindowsApps\WinGet.exe")
            If ($PSCmdlet.ShouldProcess($Item.Name,"WinGet")) {
                $Process = Start-Process -FilePath $WinGet.FullName -ArgumentList "download $($Item.Name) --download-directory `"$Destination`" --skip-license" -PassThru
            } else {
                $Process = Start-Process -FilePath $WinGet.Fullname -ArgumentList "search $($Item.Name)" -PassThru
            }
            Watch-Process -Process $Process

            ForEach ($ScriptBlock in $Item.PostScriptBlocks) { 
                Write-Verbose "Executing: $ScriptBlock"
                If ($PSCmdlet.ShouldProcess($ScriptBlock,"Execute")) {
                    Invoke-Command -ScriptBlock ([ScriptBlock]::Create($ScriptBlock)) -NoNewScope 
                }
            }
        }

        ForEach ($ScriptBlock in $Application.Source.PostScriptBlocks) { 
            Write-Verbose "Executing: $ScriptBlock"
            If ($PSCmdlet.ShouldProcess($ScriptBlock,"Execute")) {
                Invoke-Command -ScriptBlock ([ScriptBlock]::Create($ScriptBlock)) -NoNewScope
            }
        }
    }
    End {}

}