Public/Get-EvergreenApp.ps1
|
function Get-EvergreenApp { <# .EXTERNALHELP Evergreen-help.xml #> [OutputType([System.Management.Automation.PSObject])] [CmdletBinding(SupportsShouldProcess = $false)] [Alias("gea")] param ( [Parameter( Mandatory = $false, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName, HelpMessage = "Specify an application name. Use Find-EvergreenApp to list supported applications.")] [ValidateNotNullOrEmpty()] [ValidateScript({ if ([System.Management.Automation.WildcardPattern]::ContainsWildcardCharacters($_) -or $_ -match '[\\/]' -or [System.IO.Path]::GetFileName($_) -cne $_ -or $_ -in @(".", "..")) { throw "Name must be an application name, not a path or wildcard pattern." } if ($_ -match '[<>:"|\x00-\x1F]') { throw "Name contains characters that are not valid in an application name." } $true })] [Alias("ApplicationName")] [System.String] $Name = "Microsoft365Apps", [Parameter( Mandatory = $false, Position = 1, HelpMessage = "Specify a hashtable of parameters to pass to the internal application function.")] [System.Collections.Hashtable] $AppParams, [Parameter(Mandatory = $false, Position = 2)] [System.String] $Proxy, [Parameter(Mandatory = $false, Position = 3)] [System.Management.Automation.PSCredential] $ProxyCredential = [System.Management.Automation.PSCredential]::Empty, [Parameter()] [System.Management.Automation.SwitchParameter] $SkipCertificateCheck ) begin { if ($PSBoundParameters.ContainsKey("ProxyCredential") -and -not($PSBoundParameters.ContainsKey("Proxy"))) { throw [System.ArgumentException]::New("ProxyCredential requires Proxy.") } # 'res' is reserved for the application manifest passed to the application function if ($PSBoundParameters.ContainsKey("AppParams") -and $AppParams.ContainsKey("res")) { throw [System.ArgumentException]::New("AppParams must not include the reserved key 'res'.") } # Set the proxy environment once for all pipeline input; removed in the end block or on a terminating error if ($PSBoundParameters.ContainsKey("Proxy")) { if ($PSBoundParameters.ContainsKey("ProxyCredential")) { Set-ProxyEnv -Proxy $Proxy -ProxyCredential $ProxyCredential } else { Set-ProxyEnv -Proxy $Proxy } } # Force Invoke-EvergreenRestMethod and Invoke-EvergreenWebRequest to ignore certificate errors if ($SkipCertificateCheck.IsPresent) { $script:SkipCertificateCheck = $true } } process { # Build a path to the application function # This will build a path like: %LocalAppData%\Evergreen\Apps\Get-TeamViewer.ps1 $FunctionPath = [System.IO.Path]::Combine((Get-EvergreenAppsPath), "Apps", "Get-$Name.ps1") Write-Verbose -Message "Function path: $FunctionPath" $Completed = $false try { #region Test that the function exists and run it to return output if (Test-Path -Path $FunctionPath -PathType "Leaf" -ErrorAction "SilentlyContinue") { Write-Verbose -Message "Function exists: $FunctionPath." # Dot source the function so that we can use it # Import function here rather than at module import to reduce IO and memory footprint as the module grows # This also allows us to add an application manifest and function without having to re-load the module Write-Verbose -Message "Dot sourcing: $FunctionPath." try { . $FunctionPath } catch { Write-Warning -Message "Failed to dot source application function from: $FunctionPath." Write-ErrorDetail -ErrorRecord $_ -LastFrame "Get-EvergreenApp" $PSCmdlet.ThrowTerminatingError($_) } try { # Run the function to grab the application details; pass the per-app manifest to the app function # Application manifests are located under Evergreen/Manifests $params = @{ res = (Get-FunctionResource -AppName $Name) } if ($PSBoundParameters.ContainsKey("AppParams")) { Write-Verbose -Message "Adding AppParams." $params += $AppParams } # Run the application function and collect the output Write-Verbose -Message "Calling: Get-$Name." # Standardise the output via the app's filter, if one exists & Get-$Name @params | Invoke-OutputFilter -Name $Name } catch { # Display the function name, script file and line number where the error occurred Write-ErrorDetail -ErrorRecord $_ -LastFrame "Get-EvergreenApp" $Msg = "Run 'Get-EvergreenApp -Name `"$Name`" -Verbose' to review additional details for troubleshooting." Write-Warning -Message $Msg # Re-throw the original error record to preserve its origin (InvocationInfo and stack trace) $PSCmdlet.ThrowTerminatingError($_) } } else { Write-AppNotFoundHelp -Name $Name $Msg = "Failed to retrieve manifest for application: $Name at '$FunctionPath'." throw [System.IO.FileNotFoundException]::New($Msg) } #endregion $Completed = $true } finally { # The end block does not run when a terminating error stops the pipeline, so clean up here on failure if (-not $Completed) { if ($PSBoundParameters.ContainsKey("Proxy")) { Remove-ProxyEnv } if ($SkipCertificateCheck.IsPresent) { $script:SkipCertificateCheck = $false } } } } end { if ($PSBoundParameters.ContainsKey("Proxy")) { Remove-ProxyEnv } if ($SkipCertificateCheck.IsPresent) { $script:SkipCertificateCheck = $false } } } |