DependsOn.psm1
$Script:PSModuleRoot = $PSScriptRoot # Importing from [C:\ldx\DependsOn\DependsOn\Public] # .\DependsOn\Public\Resolve-DependencyOrder.ps1 function Resolve-DependencyOrder { <# .DESCRIPTION Takes a list of objects that depend on each other and orders them. .Example Resolve-DependencyOrder -InputObject @( @{Name='Girl';DependsOn='Dad','Mom'} @{Name='Mom';DependsOn='Dad'} @{Name='Dad';DependsOn='Grandpa','Grandma'} @{Name='Grandpa';DependsOn=$null} @{Name='Grandma';DependsOn='Grandpa'} @{Name='Boy';DependsOn='Dad','Mom'} ) -Key {$_.name} -DependsOn {$_.DependsOn} Takes a collection of hashtables and orders them so the dependant object come first. .EXAMPLE $map = [ordered]@{ 'Girl'='Dad','Mom' 'Mom'='Dad' 'Grandpa' = $null 'Dad'='Grandpa','Grandma' 'Grandma'='Grandpa' 'Boy'='Dad','Mom' } Resolve-DependencyOrder -InputObject $map.Keys -DependsOn {$map[$_]} Uses an external source for the mapping of strings. .NOTES An exception will be thrown if there are duplicate keys Circular dependancies are only walked once and then ignored without warning If a key is not provided, the tostring() of the object is used Each object will only show up once in the output The DependsOn can be an array of strings Order of objects is preserved until a DependsOn is identified Dependencies will be walked in order that they are defined in the DependsOn #> [Alias('DependsOn')] [cmdletbinding()] param( # Collection of objects to order [parameter( Mandatory, Position = 0, ValueFromPipeline )] [ValidateNotNullOrEmpty()] [PSObject[]] $InputObject, # scriptblock that generates a unique key for each object [parameter( Position = 1, ValueFromPipelineByPropertyName )] [scriptblock]$Key = {"$PSItem"}, # scriptblock that generates a list of keys this each item depends on [parameter( Mandatory, Position = 2, ValueFromPipelineByPropertyName )] [scriptblock]$DependsOn ) begin { # using an uncommon name to avoid collisions ${*map} = [DependsOn.DependencyMap]::new() } process { foreach ($node in $InputObject) { $dependsOnValue = $node | ForEach-Object $DependsOn $keyValue = $node | ForEach-Object $Key ${*map}.Add($node, $keyValue, $dependsOnValue) } } end { ${*map}.ToArray() } } |