CmdLets/Library/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 ($App in $Application) {
            $Destination = Join-Path -Path $Path -ChildPath $App.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 ($ScriptBlock in $App.Source.PreScriptBlocks) {
                Write-Verbose "Executing: $ScriptBlock"
                Invoke-Command -ScriptBlock ([ScriptBlock]::Create($ScriptBlock)) -NoNewScope
            }

            ForEach ($Item in $App.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 $App.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 $App.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 $App.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 $App.Source.PostScriptBlocks) { 
                Write-Verbose "Executing: $ScriptBlock"
                If ($PSCmdlet.ShouldProcess($ScriptBlock,"Execute")) {
                    Invoke-Command -ScriptBlock ([ScriptBlock]::Create($ScriptBlock)) -NoNewScope
                }
            }
        }
    }
    End {}
}