1+ param (
2+ [string ]$resourceGroupName ,
3+ [Parameter (Mandatory = $true )]
4+ [string ]$subscriptionId ,
5+ [bool ]$whatIf = $false
6+ )
7+
8+ if ([string ]::IsNullOrEmpty($subscriptionId )) {
9+ $subscriptionId = Read-Host - Prompt " Please enter the subscription ID"
10+ }
11+
12+ # if ([string]::IsNullOrEmpty($resourceGroupName)) {
13+ # $resourceGroupName = Read-Host -Prompt "Please enter the resource group name"
14+ # }
15+
16+ if ([string ]::IsNullOrEmpty($whatIf )) {
17+ $dryRun = Read-Host - Prompt " Would you like to run this as a dry run? (yes/no)"
18+ if ($dryRun -eq " yes" ) {
19+ $whatIf = $true
20+ } else {
21+ $whatIf = $false
22+ }
23+ }
24+
25+ Write-Host " Resource Group Name: $resourceGroupName "
26+ Write-Host " Subscription ID: $subscriptionId "
27+ Write-Host " WhatIf: $WhatIf "
28+
29+ if ([string ]::IsNullOrEmpty($subscriptionId )) {
30+ Write-Host " The subscription ID is required."
31+ exit
32+ }
33+
34+ $minSupportedApiVersion = ' 2024-07-10'
35+ $query = $null
36+ $resources = $null
37+
38+ if ([string ]::IsNullOrEmpty($resourceGroupName )){
39+ $query = "
40+ Resources
41+ | where type =~ 'microsoft.azurearcdata/sqlserverinstances'
42+ | where subscriptionId =~ '$subscriptionId '
43+ | project name, resourceGroup
44+ "
45+ } else {
46+ $query = "
47+ Resources
48+ | where type =~ 'microsoft.azurearcdata/sqlserverinstances'
49+ | where resourceGroup =~ '$resourceGroupName '
50+ | where subscriptionId =~ '$subscriptionId '
51+ | project name, resourceGroup
52+ "
53+ }
54+
55+ $resources = Search-AzGraph - Query $query
56+
57+ if ([string ]::IsNullOrEmpty($resources )) {
58+ Write-Host " No SQL Server Instances were found in this scope."
59+ exit
60+ }
61+
62+ $resources = $resources | ForEach-Object {
63+ [pscustomobject ]@ {
64+ ResourceGroup = $_.resourceGroup
65+ SqlArcResource = $_.name
66+ }
67+ }
68+
69+ $arcMachineResourceIds = @ ()
70+ foreach ($resource in $resources ) {
71+ Write-Host " ResourceGroup: $ ( $resource.ResourceGroup ) , Sql Arc resource: $ ( $resource.SqlArcResource ) "
72+
73+ $hybridComputeResourceId = Get-AzResource - ResourceName $resource.SqlArcResource - ResourceGroupName $resource.ResourceGroup - ResourceType " Microsoft.AzureArcData/sqlServerInstances" | Select-Object - ExpandProperty Properties | Select-Object - ExpandProperty containerResourceId
74+ $arcMachineResourceIds += $hybridComputeResourceId
75+ }
76+
77+ $arcMachineUniqueResourceIds = $arcMachineResourceIds | Get-Unique
78+ Write-Output " Arc Machine Resource Ids:"
79+ Write-Output $arcMachineUniqueResourceIds
80+
81+ foreach ($arcMachineUniqueResourceId in $arcMachineUniqueResourceIds ) {
82+ Write-Host " ----- Attempting to remove settings from machine: $ ( $arcMachineUniqueResourceId ) -----"
83+ $computeMachineResource = Get-AzResource - ResourceId " $arcMachineUniqueResourceId "
84+ $extensionResource = Get-AzResource - ResourceId " $arcMachineUniqueResourceId /extensions/WindowsAgent.SqlServer" - ApiVersion $minSupportedApiVersion
85+ $currentSettings = $extensionResource.properties.settings
86+
87+ $parsedData = @ {
88+ " ExtensionAgentStatus" = $null
89+ " TimestampUTC" = $null
90+ }
91+
92+ if ($extensionResource.properties.instanceView.status -match " SQL Server Extension Agent: (\w+);" ) {
93+ $parsedData [" ExtensionAgentStatus" ] = $matches [1 ]
94+ }
95+
96+ if ($extensionResource.properties.instanceView.status -match " timestampUTC : ([\d\/:., ]+);" ) {
97+ $parsedData [" TimestampUTC" ] = [datetime ]::ParseExact($matches [1 ], " yyyy/MM/dd, HH:mm:ss.fff" , $null )
98+ }
99+
100+ # Check if the Extension Agent is healthy and the timestamp is within the last 24 hours
101+ $extensionAgentHealthy = $parsedData [" ExtensionAgentStatus" ] -eq " Healthy"
102+ $timestampWithin24Hours = ($parsedData [" TimestampUTC" ] -gt (Get-Date ).AddHours(-24 ))
103+
104+ if ($computeMachineResource.properties.status -ne " Connected" ) {
105+ Write-Host " This machine has status: $ ( $computeMachineResource.properties.status ) . We will skip removing the configurations on this machine."
106+ continue
107+ } elseif (-not ($extensionAgentHealthy -and $timestampWithin24Hours )) {
108+ Write-Host " The extension agent status is: $ ( $parsedData [" ExtensionAgentStatus" ]) and was last updated: $ ( $ ($parsedData [" TimestampUTC" ])) ."
109+ Write-Host " The extension status must be healthy and updated within 24hrs for us to proceed. We will skip removing the configurations on this machine."
110+ continue
111+ } else {
112+ Write-Host " This machine has status: $ ( $computeMachineResource.properties.status ) . We will proceed to remove the configurations."
113+ }
114+
115+ # Disable ESU
116+ if ($currentSettings.PSobject.Properties.Name -contains " EnableExtendedSecurityUpdates" ) {
117+ $currentSettings.EnableExtendedSecurityUpdates = $false
118+ }
119+ # Disable Microsoft Updates
120+ if ($currentSettings.PSobject.Properties.Name -contains " MicrosoftUpdateConfiguration" ) {
121+ $currentSettings.MicrosoftUpdateConfiguration.EnableMicrosoftUpdate = $false
122+ }
123+ # Disable BPA
124+ if ($currentSettings.PSobject.Properties.Name -contains " AssessmentSettings" ) {
125+ $currentSettings.AssessmentSettings.Enable = $false
126+ }
127+
128+ $newProperties = $extensionResource.properties
129+ $newProperties.settings = $currentSettings
130+
131+ $newProperties | ConvertTo-Json | Out-File " settingsInFile.json"
132+
133+ try {
134+ if ($whatIf ) {
135+ $extensionResource | Set-AzResource - Properties $newProperties - UsePatchSemantics - Pre - ErrorAction Stop - WhatIf - AsJob
136+ } else {
137+ $extensionResource | Set-AzResource - Properties $newProperties - UsePatchSemantics - Pre - ErrorAction Stop - Force - AsJob
138+ }
139+ Write-Host " Command executed."
140+ } catch {
141+ Write-Host " Command failed with the following error:"
142+ Write-Host $_.Exception.Message
143+ }
144+ }
0 commit comments