src/private/ConvertFrom-ARM.ps1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
function ConvertFrom-ARM { [CmdletBinding()] param ( [string[]] $Targets, [ValidateSet('Azure Resource Group')] [string] $TargetType = 'Azure Resource Group', [int] $CategoryDepth = 1, [string[]] $ExcludeTypes ) begin { $rank = @{ "Microsoft.Network/publicIPAddresses" = 1 "Microsoft.Network/loadBalancers" = 2 "Microsoft.Network/virtualNetworks" = 3 "Microsoft.Network/networkSecurityGroups" = 4 "Microsoft.Network/networkInterfaces" = 5 "Microsoft.Compute/virtualMachines" = 6 } $Excluded_ARMObjects = $( "Microsoft.Network/virtualNetworks*", "Microsoft.Network/virtualNetworks/subnets*", "Microsoft.Network/networkSecurityGroups*" ) if($ExcludeTypes){ $Excluded_ARMObjects += $ExcludeTypes } # $scriptblock = [scriptblock]::Create($Excluded_ARMObjects.ForEach({'$_.type -NotLike "{0}"' -f $_}) -join ' -and ') # $scriptblock = [scriptblock]::Create($Excluded_ARMObjects.ForEach({'$_.fromcateg -NotLike "{0}" -and $_.tocateg -NotLike "{0}"' -f $_}) -join ' -and ') $scriptblock = [scriptblock]::Create( $Excluded_ARMObjects.ForEach( { '$_.fromcateg -NotLike "{0}" -and $_.tocateg -NotLike "{0}"' -f $_ }) -join ' -and ' ) } process { # $Targets | ForEach-Object -ThrottleLimit 10 -Parallel { # Import-Module Az.Resources # $TargetType = $using:TargetType # $CategoryDepth = $using:CategoryDepth # $Target = $_ # $Rank = $using:Rank # $scriptblock = [scriptblock]::Create($using:condition) Foreach($Target in $Targets){ $temp_armtemplate = New-TemporaryFile # $temp_armtemplate = (Join-Path ([System.IO.Path]::GetTempPath()) "armtemplate.json") #region obtaining-arm-template switch ($TargetType) { 'Azure Resource Group' { Write-CustomHost "Exporting ARM template of Azure resource group: `'$Target`'" -Indentation 1 -color Green $template = (Export-AzResourceGroup -ResourceGroupName $Target -SkipAllParameterization -Force -Path $temp_armtemplate -WarningAction SilentlyContinue -Verbose:$false).Path } 'File' { Write-CustomHost "Accessing ARM template from local file: `'$Target`'" -Indentation 2 -color Green $template = $Target } 'Url' { Write-CustomHost "Downloading ARM template from URL: `'$Target`'" -Indentation 2 -color Green # $Target = 'https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/101-vm-simple-linux/azuredeploy.json' $template = $temp_armtemplate Invoke-WebRequest -Uri $Target -OutFile $template -Verbose:$false # todo test-path the downloaded file } } Write-CustomHost "Processing the ARM template to extract resources" -Indentation 2 -color Green $arm = Get-Content -Path $template | ConvertFrom-Json $resources = $arm.Resources | Where-Object $scriptblock if ($resources) { Write-CustomHost "Total resources found: $($resources.count)" -Indentation 2 -color Green Write-CustomHost "Cleaning up temporary ARM template file at: $template" -Indentation 2 -color Green Remove-Item $template -Force } else { Write-CustomHost "Total resources/sub-resources found: $($resources.count)" -Indentation 2 -color Green Write-CustomHost "Skipping ${TargetType}: `"$Target`" as no resources were found." -Indentation 2 -color Green continue } #endregion obtaining-arm-template #region parsing-arm-template-and-finding-resource-dependencies $data = @() # $excluded_types = @("scheduledqueryrules","containers","solutions","modules","savedSearches") $data += $resources | Where-Object { $_.type.tostring().split("/").count -le $($CategoryDepth + 1) } | ForEach-Object { $dependson = $null if ($_.dependson) { $dependson = $_.DependsOn #| ForEach-Object { $_.ToString().split("parameters('")[1].split("')")[0]} foreach ($dependency in $dependson) { $r = $rank["$($_.type.ToString())"] [PSCustomObject]@{ fromcateg = $_.type.ToString() #.split('/')[-1] from = $_.name.ToString() #.split('/')[-1] #.split("parameters('")[1].split("')")[0] to = $dependency.tostring().replace("[resourceId(", "").replace(")]", "").Split(",")[1].replace("'", "").trim() # -join '/' #.split('/')[-1] tocateg = $dependency.tostring().replace("[resourceId(", "").replace(")]", "").Split(",")[0].replace("'", "").trim().Split("/")[0..1] -join '/' #.split('/')[-1] isdependent = $true rank = if ($r) { $r }else { 9999 } } } } else { $r = $rank["$($_.type.ToString())"] [PSCustomObject]@{ fromcateg = $_.type.ToString() #.split('/')[-1] from = $_.name.ToString() #.split("parameters('")[1].split("')")[0] to = '' tocateg = '' isdependent = $false rank = if ($r) { $r }else { 9999 } } } } | Sort-Object Rank #endregion parsing-arm-template-and-finding-resource-associations [PSCustomObject]@{ Type = $TargetType Name = $Target Resources = $data | Where-Object $scriptblock } } } end { } } |