Functions/AppManagement/Get-AppDependencyOrder.ps1
function Get-AppDependencyOrder { [CmdletBinding(DefaultParameterSetName='FilePath')] param( [Parameter(Mandatory=$true, ParameterSetName = "FilePath")] [string[]] $Path, [Parameter(Mandatory=$true, ParameterSetName = "AppObject")] [object[]] $Apps, [Parameter(Mandatory=$true, ParameterSetName = "AppObject")] [string] $ServerInstance ) if($PSCmdlet.ParameterSetName -eq 'FilePath'){ $AllAppFiles = @() $Path | ForEach-Object { $AllAppFiles += Get-ChildItem -Path $_ -Recurse -Filter "*.app" } $AllApps = @() foreach ($AppFile in $AllAppFiles) { $App = Get-NAVAppInfo -Path $AppFile.FullName $AllApps += [PSCustomObject]@{ AppId = $App.AppId Version = $App.Version Name = $App.Name Publisher = $App.Publisher ProcessOrder = 0 Dependencies = $App.Dependencies Path = $AppFile.FullName Length = $AppFile.Length} } } if($PSCmdlet.ParameterSetName -eq 'AppObject'){ $AllApps = @() foreach ($App in $Apps) { $App = Get-NAVAppInfo -ServerInstance $ServerInstance -Id $App.AppId.Value.Guid -Version $App.Version $AllApps += [PSCustomObject]@{ AppId = $App.AppId Version = $App.Version Name = $App.Name Publisher = $App.Publisher ProcessOrder = 0 Dependencies = $App.Dependencies Path = 'unknown' Length = 'unknown'} } } # Check on AppId Uniqueness $Result = Get-BCAppidUnique ($AllApps) if ($Result) { Write-Error ($Result | Out-String) } # Apps are devided in two layers. The layers can be seperated by the Application proxy instead of direct dependencies. # To resolve this the dependency tree for each layer is calculated separatly and joined afterwards. # LayerOne: Microsoft System Application, Base application, Application (proxy app) # LayerTwo: Extensions on the base application and extensions on extensions. $Filter = @('Application') $Filter += ($AllApps | Where-Object -Property Name -eq 'Application').Dependencies.Name $LayerOne = @() $LayerOneApps = $AllApps | Where-Object -Property Name -In $Filter $LayerOneApps | ForEach-Object { [array] $LayerOne = Add-BCAppToDependencyTree ` -App $_ ` -DependencyArray $LayerOne ` -AppCollection $LayerOneApps ` -Order $LayerOneApps.Count } $LayerTwo = @() $LayerTwoApps = $AllApps | Where-Object -Property Name -NotIn $Filter $LayerTwoApps | ForEach-Object { [array] $LayerTwo = Add-BCAppToDependencyTree ` -App $_ ` -DependencyArray $LayerTwo ` -AppCollection $LayerTwoApps ` -Order ($LayerTwoApps.Count + $LayerOneApps.Count) } $FinalResult = $LayerOne + $LayerTwo return $FinalResult | Sort-Object ProcessOrder } Export-ModuleMember -Function Get-AppDependencyOrder function Add-BCAppToDependencyTree() { param( [PSObject] $App, [PSObject[]] $DependencyArray, [PSObject[]] $AppCollection, [Int] $Order = 1 ) foreach ($Dependency in $App.Dependencies) { $DependencyArray = Add-BCAppToDependencyTree ` -App ($AppCollection | Where-Object AppId -eq $Dependency.AppId) ` -DependencyArray $DependencyArray ` -AppCollection $AppCollection ` -Order ($Order - 1) } if (-not($DependencyArray | Where-Object AppId -eq $App.AppId)) { if($App.AppId){ $DependencyArray += $App Write-Verbose ('App: {0} - Order: {1}' -f $App.Name, $Order) $Result = ($DependencyArray | Where-Object AppId -eq $App.AppId) if ($Result) { $Result.ProcessOrder = $Order } } } else { if (($DependencyArray | Where-Object AppId -eq $App.AppId).ProcessOrder -gt $Order) { ($DependencyArray | Where-Object AppId -eq $App.AppId).ProcessOrder = $Order } } $DependencyArray } function Get-BCAppidUnique() { param( [Parameter(Mandatory=$true)] [PSObject] $Apps ) # $Appslist is sorted on AppId $AppsList = $Apps | Sort-Object Appid $Result = @() for ($i=1; $i -lt $AppsList.Count; $i++) { if ($AppsList[$i -1].AppId.Value.Guid -eq $AppsList[$i].AppId.Value.Guid) { # Found Duplicate Appid $Result += 'Found Duplicate Appid:' $Result += '{0}[{1}]' -f $AppsList[$i-1].Name, $AppsList[$i-1].AppId $Result += '{0}[{1}]' -f $AppsList[$i].Name, $AppsList[$i].AppId } } return $Result } |