functions/Invoke-AzOpsPull.ps1
function Invoke-AzOpsPull { <# .SYNOPSIS Setup a repository for the AzOps workflow, based off templates and an existing Azure deployment. .DESCRIPTION Setup a repository for the AzOps workflow, based off templates and an existing Azure deployment. .PARAMETER IncludeResourcesInResourceGroup Discover only resources in these resource groups. .PARAMETER IncludeResourceType Discover only specific resource types. .PARAMETER SkipChildResource Skip childResource discovery. .PARAMETER SkipPim Skip discovery of Privileged Identity Management resources. .PARAMETER SkipLock Skip discovery of resource lock resources. .PARAMETER SkipPolicy Skip discovery of policies. .PARAMETER SkipRole Skip discovery of role. .PARAMETER SkipResourceGroup Skip discovery of resource groups .PARAMETER SkipResource Skip discovery of resources inside resource groups. .PARAMETER Rebuild Delete all AutoGeneratedTemplateFolderPath folders inside AzOpsState directory. .PARAMETER Force Delete $script:AzOpsState directory. .PARAMETER StatePath The root folder under which to write the resource json. .EXAMPLE > Invoke-AzOpsPull Setup a repository for the AzOps workflow, based off templates and an existing Azure deployment. #> [CmdletBinding()] [Alias("Initialize-AzOpsRepository")] param ( [string[]] $IncludeResourcesInResourceGroup = (Get-PSFConfigValue -FullName 'AzOps.Core.IncludeResourcesInResourceGroup'), [string[]] $IncludeResourceType = (Get-PSFConfigValue -FullName 'AzOps.Core.IncludeResourceType'), [switch] $SkipChildResource = (Get-PSFConfigValue -FullName 'AzOps.Core.SkipChildResource'), [switch] $SkipPim = (Get-PSFConfigValue -FullName 'AzOps.Core.SkipPim'), [switch] $SkipLock = (Get-PSFConfigValue -FullName 'AzOps.Core.SkipLock'), [switch] $SkipPolicy = (Get-PSFConfigValue -FullName 'AzOps.Core.SkipPolicy'), [switch] $SkipResource = (Get-PSFConfigValue -FullName 'AzOps.Core.SkipResource'), [switch] $SkipResourceGroup = (Get-PSFConfigValue -FullName 'AzOps.Core.SkipResourceGroup'), [string[]] $SkipResourceType = (Get-PSFConfigValue -FullName 'AzOps.Core.SkipResourceType'), [switch] $SkipRole = (Get-PSFConfigValue -FullName 'AzOps.Core.SkipRole'), [switch] $Rebuild, [switch] $Force, [string] $StatePath = (Get-PSFConfigValue -FullName 'AzOps.Core.State'), [string] $TemplateParameterFileSuffix = (Get-PSFConfigValue -FullName 'AzOps.Core.TemplateParameterFileSuffix') ) begin { #region Prepare if (-not $SkipPim) { try { Write-PSFMessage -Level Verbose -String 'Invoke-AzOpsPull.Validating.UserRole' $null = Get-AzADUser -First 1 -ErrorAction Stop Write-PSFMessage -Level Verbose -String 'Invoke-AzOpsPull.Validating.UserRole.Success' Write-PSFMessage -Level Verbose -String 'Invoke-AzOpsPull.Validating.AADP2' $servicePlanName = "AAD_PREMIUM_P2" $subscribedSkus = Invoke-AzRestMethod -Uri https://graph.microsoft.com/v1.0/subscribedSkus -ErrorAction Stop $subscribedSkusValue = $subscribedSkus.Content | ConvertFrom-Json -Depth 100 | Select-Object value if ($servicePlanName -in $subscribedSkusValue.value.servicePlans.servicePlanName) { Write-PSFMessage -Level Verbose -String 'Invoke-AzOpsPull.Validating.AADP2.Success' } else { Write-PSFMessage -Level Warning -String 'Invoke-AzOpsPull.Validating.AADP2.Failed' $SkipPim = $true } } catch { Write-PSFMessage -Level Warning -String 'Invoke-AzOpsPull.Validating.UserRole.Failed' $SkipPim = $true } } if ($false -eq $SkipChildResource -or $false -eq $SkipResource -and $true -eq $SkipResourceGroup) { Write-PSFMessage -Level Warning -String 'Invoke-AzOpsPull.Validating.ResourceGroupDiscovery.Failed' -StringValues "`n" } $resourceTypeDiff = Compare-Object -ReferenceObject $SkipResourceType -DifferenceObject $IncludeResourceType -ExcludeDifferent if ($resourceTypeDiff) { Write-PSFMessage -Level Warning -Message "SkipResourceType setting conflict found in IncludeResourceType, ignoring $($resourceTypeDiff.InputObject) from IncludeResourceType. To avoid this remove $($resourceTypeDiff.InputObject) from IncludeResourceType or SkipResourceType" $IncludeResourceType = $IncludeResourceType | Where-Object { $_ -notin $resourceTypeDiff.InputObject } } Assert-AzOpsInitialization -Cmdlet $PSCmdlet -StatePath $StatePath $tenantId = (Get-AzContext).Tenant.Id Write-PSFMessage -Level Important -String 'Invoke-AzOpsPull.Tenant' -StringValues $tenantId Write-PSFMessage -Level Verbose -String 'Invoke-AzOpsPull.TemplateParameterFileSuffix' -StringValues (Get-PSFConfigValue -FullName 'AzOps.Core.TemplateParameterFileSuffix') Write-PSFMessage -Level Important -String 'Invoke-AzOpsPull.Initialization.Completed' $stopWatch = [System.Diagnostics.Stopwatch]::StartNew() #endregion Initialize & Prepare } process { #region Existing Content if (Test-Path $StatePath) { $migrationRequired = (Get-ChildItem -Recurse -Force -Path $StatePath -File | Where-Object { $_.Name -like $("Microsoft.Management_managementGroups-" + $tenantId + $TemplateParameterFileSuffix) } | Select-Object -ExpandProperty FullName -First 1) -notmatch '\((.*)\)' if ($migrationRequired) { Write-PSFMessage -Level Important -String 'Invoke-AzOpsPull.Migration.Required' } if ($Force -or $migrationRequired) { Invoke-PSFProtectedCommand -ActionString 'Invoke-AzOpsPull.Deleting.State' -ActionStringValues $StatePath -Target $StatePath -ScriptBlock { Remove-Item -Path $StatePath -Recurse -Force -Confirm:$false -ErrorAction Stop } -EnableException $true -PSCmdlet $PSCmdlet } if ($Rebuild) { Invoke-PSFProtectedCommand -ActionString 'Invoke-AzOpsPull.Rebuilding.State' -ActionStringValues $StatePath -Target $StatePath -ScriptBlock { Get-ChildItem -Path $StatePath -File -Recurse -Force -Filter 'Microsoft.*_*.json' | Remove-Item -Force -Recurse -Confirm:$false -ErrorAction Stop } -EnableException $true -PSCmdlet $PSCmdlet } } #endregion Existing Content #region Root Scopes $rootScope = '/providers/Microsoft.Management/managementGroups/{0}' -f $tenantId if ($script:AzOpsPartialRoot.id) { $rootScope = $script:AzOpsPartialRoot.id | Sort-Object -Unique } # Parameters $parameters = $PSBoundParameters | ConvertTo-PSFHashtable -Inherit -Include IncludeResourcesInResourceGroup, IncludeResourceType, SkipPim, SkipLock, SkipPolicy, SkipRole, SkipResourceGroup, SkipChildResource, SkipResource, SkipResourceType, StatePath Write-PSFMessage -Level Important -String 'Invoke-AzOpsPull.Building.State' -StringValues $StatePath if ($rootScope -and $script:AzOpsAzManagementGroup) { foreach ($root in $rootScope) { # Create AzOpsState structure recursively Save-AzOpsManagementGroupChild -Scope $root -StatePath $StatePath Get-AzOpsResourceDefinition -Scope $root @parameters } } else { # If no management groups are found, iterate through each subscription foreach ($subscription in $script:AzOpsSubscriptions) { Get-AzOpsResourceDefinition -Scope $subscription.id @parameters } } #endregion Root Scopes } end { $stopWatch.Stop() Write-PSFMessage -Level Important -String 'Invoke-AzOpsPull.Duration' -StringValues $stopWatch.Elapsed -Data @{ Elapsed = $stopWatch.Elapsed } } } |