Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -76,85 +76,85 @@
}
]
},
// "linkedWorkspaceId": {
// "value": "/subscriptions/<<subscriptionId>>/resourcegroups/test-rg/providers/Microsoft.OperationalInsights/workspaces/test-law"
// },
// "gallerySolutions": {
// "value": [
// "Updates"
// ]
// },
// "softwareUpdateConfigurations": {
// "value": [
// {
// "name": "Windows_ZeroDay",
// "frequency": "Month",
// "operatingSystem": "Windows",
// "rebootSetting": "IfRequired",
// "scopeByTags": {
// "Update": [
// "Automatic-Wave1"
// ]
// },
// "maintenanceWindow": "PT4H",
// "updateClassifications": [
// "Critical",
// "Security",
// "UpdateRollup",
// "FeaturePack",
// "ServicePack",
// "Definition",
// "Tools",
// "Updates"
// ],
// "includeUpdates": [
// "654321"
// ],
// "excludeUpdates": [
// "123456"
// ],
// "interval": 1,
// "monthlyOccurrences": [
// {
// "occurrence": 3,
// "day": "Friday"
// }
// ],
// "startTime": "22:00"
// },
// {
// "name": "Linux_ZeroDay",
// "frequency": "OneTime",
// "operatingSystem": "Linux",
// "rebootSetting": "IfRequired",
// "maintenanceWindow": "PT4H",
// "updateClassifications": [
// "Critical",
// "Security",
// "Other"
// ],
// "includeUpdates": [
// "kernel"
// ],
// "excludeUpdates": [
// "icacls"
// ],
// "startTime": "2021-12-31T06:00"
// }
// ]
// },
// "privateEndpoints": {
// "value": [
// {
// "subnetResourceId": "/subscriptions/<<subscriptionId>>/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/adp-sxx-az-vnet-x-001/subnets/sxx-az-subnet-x-005-privateEndpoints",
// "service": "Webhook"
// },
// {
// "subnetResourceId": "/subscriptions/<<subscriptionId>>/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/adp-sxx-az-vnet-x-001/subnets/sxx-az-subnet-x-005-privateEndpoints",
// "service": "DSCAndHybridWorker"
// }
// ]
// },
"linkedWorkspaceId": {
"value": "/subscriptions/<<subscriptionId>>/resourcegroups/validation-rg/providers/microsoft.operationalinsights/workspaces/adp-sxx-az-law-x-001"
},
"gallerySolutions": {
"value": [
"Updates"
]
},
"softwareUpdateConfigurations": {
"value": [
{
"name": "Windows_ZeroDay",
"frequency": "Month",
"operatingSystem": "Windows",
"rebootSetting": "IfRequired",
"scopeByTags": {
"Update": [
"Automatic-Wave1"
]
},
"maintenanceWindow": "PT4H",
"updateClassifications": [
"Critical",
"Security",
"UpdateRollup",
"FeaturePack",
"ServicePack",
"Definition",
"Tools",
"Updates"
],
"includeUpdates": [
"654321"
],
"excludeUpdates": [
"123456"
],
"interval": 1,
"monthlyOccurrences": [
{
"occurrence": 3,
"day": "Friday"
}
],
"startTime": "22:00"
},
{
"name": "Linux_ZeroDay",
"frequency": "OneTime",
"operatingSystem": "Linux",
"rebootSetting": "IfRequired",
"maintenanceWindow": "PT4H",
"updateClassifications": [
"Critical",
"Security",
"Other"
],
"includeUpdates": [
"kernel"
],
"excludeUpdates": [
"icacls"
],
"startTime": "2021-12-31T06:00"
}
]
},
"privateEndpoints": {
"value": [
{
"subnetResourceId": "/subscriptions/<<subscriptionId>>/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/adp-sxx-az-vnet-x-001/subnets/sxx-az-subnet-x-005-privateEndpoints",
"service": "Webhook"
},
{
"subnetResourceId": "/subscriptions/<<subscriptionId>>/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/adp-sxx-az-vnet-x-001/subnets/sxx-az-subnet-x-005-privateEndpoints",
"service": "DSCAndHybridWorker"
}
]
},
"systemAssignedIdentity": {
"value": true
},
Expand Down
12 changes: 12 additions & 0 deletions utilities/pipelines/resourceRemoval/Remove-DeployedModule.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,18 @@
}
Remove-VirtualMachine @inputObject -Verbose
}
'automationAccounts' {
Write-Verbose 'Run automation account removal script' -Verbose
# Load function
. (Join-Path $PSScriptRoot 'helper' 'Remove-AutomationAccount.ps1')

# Invoke removal
$inputObject = @{
deploymentName = $deploymentName
ResourceGroupName = $ResourceGroupName
}
Remove-AutomationAccount @inputObject -Verbose
}
default {
Write-Verbose 'Run default removal script' -Verbose
# Load function
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<#
.SYNOPSIS
Remove Automation account, Log analytics link and Update solution deployed with a given deployment name. Resources will be removed even if Log Analytics is in a different resource group than the Automation Account

.DESCRIPTION
Remove Automation account, Log analytics link and Update solution deployed with a given deployment name. Resources will be removed even if Log Analytics is in a different resource group than the Automation Account

.PARAMETER deploymentName
Mandatory. The deployment name to use and find resources to remove

.PARAMETER searchRetryLimit
Optional. The maximum times to retry the search for resources via their removal tag

.PARAMETER searchRetryInterval
Optional. The time to wait in between the search for resources via their remove tags

.EXAMPLE
Remove-AutomationAccount -deploymentname 'aa-12345'

Remove Automation account, Log analytics link and Update solution deployed starting with the deployment name 'aa-12345'.
#>
function Remove-AutomationAccount {

[Cmdletbinding(SupportsShouldProcess)]
param(
[Parameter(Mandatory = $true)]
[string] $deploymentName,

[Parameter(Mandatory = $false)]
[string] $ResourceGroupName = 'validation-rg',

[Parameter(Mandatory = $false)]
[int] $searchRetryLimit = 40,

[Parameter(Mandatory = $false)]
[int] $searchRetryInterval = 60
)

begin {
Write-Debug ('{0} entered' -f $MyInvocation.MyCommand)

# Load helper
. (Join-Path $PSScriptRoot 'Remove-Resource.ps1')
}

process {

# Identify resources
# ------------------
$searchRetryCount = 1
do {
$deployments = Get-AzResourceGroupDeploymentOperation -DeploymentName $deploymentName -ResourceGroupName $resourceGroupName -ErrorAction 'SilentlyContinue'
if ($deployments) {
break
}
Write-Verbose ('[Failure] not to find Automation Account deployment resources by name [{0}] in scope [{1}]. Retrying in [{2}] seconds [{3}/{4}]' -f $deploymentName, $deploymentScope, $searchRetryInterval, $searchRetryCount, $searchRetryLimit) -Verbose
Start-Sleep $searchRetryInterval
$searchRetryCount++
} while ($searchRetryCount -le $searchRetryLimit)

if (-not $deployments) {
throw "No deployment found for [$deploymentName]"
}

$resourcesToRemove = @()
$unorderedResourceIds = $deployments.TargetResource | Where-Object { $_ -and $_ -notmatch '/deployments/' }
$childDeploymentsIds = $deployments.TargetResource | Where-Object { $_ -and $_ -match '/deployments/' }

foreach ($childDeploymentId in $childDeploymentsIds) {
$searchRetryCount = 1
$childDeploymentTokens = $childDeploymentId.Split('/')
$childDeploymentName = $childDeploymentTokens[8]
$childDeploymentResourceGroup = $childDeploymentTokens[4]
do {
Write-Verbose ('Searching child deployment named [{0}] in resource group [{1}]. Attempt [{2}/{3}]' -f $childDeploymentName, $childDeploymentResourceGroup, $searchRetryCount, $searchRetryLimit) -Verbose
$childDeployment = Get-AzResourceGroupDeploymentOperation -DeploymentName $childDeploymentName -ResourceGroupName $childDeploymentResourceGroup -ErrorAction 'SilentlyContinue'
if ($childDeployment) {
Write-Verbose ('[Success] Child deployment named [{0}] in resource group [{1}] found' -f $childDeploymentName, $childDeploymentResourceGroup) -Verbose
$unorderedResourceIds += $childDeployment.TargetResource
break
}
Write-Verbose ('[Failure] Did not to find child deployment named [{0}] in resource group [{1}]. Retrying in [{2}] seconds [{3}/{4}]' -f $childDeploymentName, $childDeploymentResourceGroup, $searchRetryInterval, $searchRetryCount, $searchRetryLimit) -Verbose
Start-Sleep $searchRetryInterval
$searchRetryCount++
} while ($searchRetryCount -le $searchRetryLimit)
}

$unorderedResourceIds = $unorderedResourceIds | Where-Object { $_ `
-and ($_ -notmatch '/Microsoft.Insights/diagnosticSettings/') `
-and ($_ -notmatch '/variables/') `
-and ($_ -notmatch '/softwareUpdateConfigurations/') `
-and ($_ -notmatch '/jobSchedules/') `
-and ($_ -notmatch '/schedules/') `
-and ($_ -notmatch '/runbooks/') `
-and ($_ -notmatch '/modules/') `
-and ($_ -notmatch '/Microsoft.Authorization/roleAssignments/') `
} | Select-Object -Unique

$orderedResourceIds = @(
$unorderedResourceIds | Where-Object { $_ -match 'Microsoft.OperationsManagement/solutions/Updates' }
$unorderedResourceIds | Where-Object { $_ -match 'linkedServices/automation' }
$unorderedResourceIds | Where-Object { $_ -match 'Microsoft.Insights/diagnosticSettings' }
$unorderedResourceIds | Where-Object { $_ -match 'Microsoft.Automation/automationAccounts' }
)

$resourcesToRemove = $orderedResourceIds | ForEach-Object {
@{
resourceId = $_
name = $_.Split('/')[-1]
type = $_.Split('/')[6..7] -join '/'
}
}

# Remove resources
# ----------------
if ($PSCmdlet.ShouldProcess(('[{0}] resources' -f $resourcesToRemove.Count), 'Remove')) {
Remove-Resource -resourceToRemove $resourcesToRemove -Verbose
}
}

end {
Write-Debug ('{0} exited' -f $MyInvocation.MyCommand)
}
}