functions/Remove-UnifiedEnvironmentPackage.ps1
|
<#
.SYNOPSIS Remove UDE environment packages. .DESCRIPTION Removes UDE environment packages (msprov_fnopackage records) for a specified environment. Packages are matched by package id and name. Nothing is removed unless the -Force switch is supplied. Without -Force the cmdlet lists the packages that would be removed. .PARAMETER EnvironmentId The id of the environment that you want to work against .PARAMETER PackageId The id of the package that you want to remove. Supports wildcard characters for flexible matching against the package id. .PARAMETER Name The name of the package that you want to remove. Supports wildcard characters for flexible matching against the package name. .PARAMETER Force Instructs the function to proceed with removing the packages. Nothing happens unless this parameter is supplied. .EXAMPLE PS C:\> Remove-UnifiedEnvironmentPackage -EnvironmentId "env-123" -PackageId "a1b2c3d4-e5f6-47a8-b9c0-d1e2f3a4b5c6" This will show the package that would be removed for the specified environment id. It will NOT remove the package yet, allowing you to review it before deciding to remove it. .EXAMPLE PS C:\> Remove-UnifiedEnvironmentPackage -EnvironmentId "env-123" -PackageId "a1b2c3d4-e5f6-47a8-b9c0-d1e2f3a4b5c6" -Force This will remove the specified package for the specified environment id without further confirmation. .EXAMPLE PS C:\> Get-UnifiedEnvironmentPackage -EnvironmentId "env-123" | Remove-UnifiedEnvironmentPackage -Force This will remove all packages returned for the specified environment id without further confirmation. .NOTES Author: Mötz Jensen (@Splaxi) #> function Remove-UnifiedEnvironmentPackage { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] param ( [Parameter (Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias("PpacEnvId")] [string] $EnvironmentId, [Parameter (ValueFromPipelineByPropertyName = $true)] [string] $PackageId = "*", [Parameter (ValueFromPipelineByPropertyName = $true)] [string] $Name = "*", [switch] $Force ) begin { } process { if (Test-PSFFunctionInterrupt) { return } $envObj = Get-UnifiedEnvironment -EnvironmentId $EnvironmentId -SkipVersionDetails | Select-Object -First 1 if ($null -eq $envObj) { $messageString = "Could not find environment with Id <c='em'>$EnvironmentId</c>. Please verify the Id and try again, or list available environments using <c='em'>Get-UnifiedEnvironment</c>. Consider using wildcards if needed." Write-PSFMessage -Level Important -Message $messageString Stop-PSFFunction -Message "Stopping because environment was NOT found based on the id." ` -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) return } $baseUri = $envObj.PpacEnvUri + "/" #! Very important to have the trailing slash $secureToken = (Get-AzAccessToken -ResourceUrl $baseUri -AsSecureString).Token $tokenWebApiValue = ConvertFrom-SecureString -AsPlainText -SecureString $secureToken $headers = @{ "Authorization" = "Bearer $($tokenWebApiValue)" "Accept" = "application/json;odata.metadata=minimal" # minimal || full "OData-MaxVersion" = "4.0" "OData-Version" = "4.0" "Prefer" = "odata.include-annotations=*" } $localUri = $baseUri + "api/data/v9.0/msprov_fnopackages" $colPackages = Invoke-RestMethod -Uri $localUri ` -Method Get ` -Headers $headers | ` Select-Object -ExpandProperty value | ` Sort-Object -Property modifiedon -Descending $resCol = @( $colPackages | Select-PSFObject -TypeName 'D365Bap.Tools.UdeEnvironmentPackage' ` -Property "msprov_name As Name", "msprov_fnopackageid As PackageId", "'_createdby_value@OData.Community.Display.V1.FormattedValue' As CreatedBy", "'_modifiedby_value@OData.Community.Display.V1.FormattedValue' As ModifiedBy", "'msprov_packagetype@OData.Community.Display.V1.FormattedValue' As PackageType", "'msprov_buildtype@OData.Community.Display.V1.FormattedValue' As BuildType", "'msprov_dbsyncoptions@OData.Community.Display.V1.FormattedValue' As DbSync", "'statuscode@OData.Community.Display.V1.FormattedValue' As Status", "'statecode@OData.Community.Display.V1.FormattedValue' As State", "createdon As Created", "modifiedon As Modified", "versionnumber As Version", * ` -ExcludeProperty '@odata.etag' ) $colFiltered = @($resCol | Where-Object { $_.PackageId -like $PackageId -and $_.Name -like $Name }) if ($colFiltered.Count -lt 1) { $messageString = "No packages found for environment <c='em'>$EnvironmentId</c> matching PackageId <c='em'>$PackageId</c> and Name <c='em'>$Name</c>. Please verify the filters and try again, or list available packages using <c='em'>Get-UnifiedEnvironmentPackage</c>." Write-PSFMessage -Level Important -Message $messageString Stop-PSFFunction -Message "Stopping because no packages were found based on the supplied filters." ` -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) return } if (-not $Force) { Write-PSFMessage -Level Important -Message "The following packages would be removed:" $colFiltered | ForEach-Object { Write-PSFMessage -Level Important -Message " - <c='em'>$($_.Name)</c> ($($_.PackageId))" } $messageString = "This will remove the listed packages. If you are sure, please re-run the command with the <c='em'>-Force</c> parameter." Write-PSFMessage -Level Important -Message $messageString Stop-PSFFunction -Message "Stopping because Force parameter wasn't supplied." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) return } [System.Collections.Generic.List[System.Object]] $arrFailed = @() foreach ($packageObj in $colFiltered) { $deleteUri = $baseUri + "api/data/v9.0/msprov_fnopackages($($packageObj.PackageId))" $deleteParams = @{ Method = 'Delete' Uri = $deleteUri Headers = $headers SkipHttpErrorCheck = $true StatusCodeVariable = 'statusDelete' } Invoke-RestMethod @deleteParams > $null 4>$null if (-not ($statusDelete -like "2**")) { Write-PSFMessage -Level Important -Message "Failed to remove package <c='em'>$($packageObj.Name)</c> ($($packageObj.PackageId)). HTTP status code: $statusDelete." $arrFailed.Add($packageObj) } else { Write-PSFMessage -Level Verbose -Message "Removed package '$($packageObj.Name)' ($($packageObj.PackageId))." } } if ($arrFailed.Count -gt 0) { $messageString = "The following packages <c='em'>failed to be removed</c>:" Write-PSFMessage -Level Important -Message $messageString $arrFailed.ToArray() if ($arrFailed.Count -eq $colFiltered.Count) { Stop-PSFFunction -Message "Stopping because all package removals failed." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) return } } } end { } } |