5151
5252param (
5353 [Parameter (Mandatory = $false )]
54- [string ] $SubId ,
54+ [string ] $SubId = " 216b4c73-ee15-4ce0-957b-0a3bc0ec9975 " ,
5555
5656 [Parameter (Mandatory = $false )]
5757 [string ] $ResourceGroup ,
@@ -82,48 +82,83 @@ param (
8282 [object ] $ExclusionTags ,
8383
8484 [Parameter (Mandatory = $false )]
85- [string ] $TenantId ,
85+ [string ] $TenantId = " bad63398-8c5a-4af1-a2f8-b95c2f57d2b3 " ,
8686
8787 [Parameter (Mandatory = $false )]
88- [switch ] $ReportOnly ,
88+ [switch ] $ReportOnly = $true ,
8989
9090 [Parameter (Mandatory = $false )]
91- [switch ] $UseManagedIdentity
92-
91+ [switch ] $UseManagedIdentity ,
92+ [Parameter (Mandatory = $false )]
93+ [int ] $batchSize = 500
9394)
9495
96+ $scriptStartTime = Get-Date
97+ Write-Output " Script execution started at: $ ( $scriptStartTime.ToString (' yyyy-MM-dd HH:mm:ss' )) "
98+
99+
95100function Connect-Azure {
96101 [CmdletBinding ()]
97102 param (
98- [Parameter (Mandatory = $true )]
99- [string ] $TenantId ,
103+ [Parameter (Mandatory = $false )]
104+ [string ] $TenantId = $null ,
100105
101- [Parameter (Mandatory = $false )]
102- [switch ]$UseManagedIdentity
106+ [Parameter (Mandatory = $false )]
107+ [switch ] $UseManagedIdentity
103108 )
104109
105- # 1) Detect environment
106- $envType = " Local"
107- if ($env: AZUREPS_HOST_ENVIRONMENT -and $ env: AZUREPS_HOST_ENVIRONMENT - like ' cloud-shell*' ) {
108- $envType = " CloudShell"
110+ # 1) Detect host environment
111+ $envType = ' Local'
112+ if ($env: AZUREPS_HOST_ENVIRONMENT -like ' cloud-shell*' ) {
113+ $envType = ' CloudShell'
109114 }
110- elseif (($env: AZUREPS_HOST_ENVIRONMENT -and $ env: AZUREPS_HOST_ENVIRONMENT - like ' AzureAutomation*' ) -or $PSPrivateMetadata.JobId ) {
111- $envType = " AzureAutomation"
112- $UseManagedIdentity = $true
115+ elseif (($env: AZUREPS_HOST_ENVIRONMENT -like ' AzureAutomation*' ) -or $PSPrivateMetadata.JobId ) {
116+ $envType = ' AzureAutomation'
117+ $UseManagedIdentity = $true
113118 }
114- Write-Verbose " Environment detected: $envType "
119+ Write-Output " Environment detected: $envType "
115120
116121 # 2) Ensure Az.PowerShell context
117- Write-Output " Not connected to Azure PowerShell. Running Connect-AzAccount..."
118- if ($UseManagedIdentity -or $envType -eq ' AzureAutomation' ) {
119- $ctx = Connect-AzAccount - Tenant $TenantId - Identity - ErrorAction Stop | Out-Null
122+ $currentCtx = Get-AzContext - ErrorAction SilentlyContinue
123+ if ($currentCtx -and $currentCtx.Account ) {
124+ if ($TenantId ) {
125+ if ($currentCtx.Tenant.Id -eq $TenantId ) {
126+ Write-Output " Already in Az tenant $TenantId "
127+ }
128+ else {
129+ Write-Output " Switching Az context to tenant $TenantId without re-authentication"
130+ $newContext = Set-AzContext - Tenant $TenantId - ErrorAction SilentlyContinue
131+ if ($null -eq $newContext -or $newContext.TenantId -ne $TenantId )
132+ {
133+ Connect-AzAccount - Tenant $TenantId | Out-Null
134+ }
135+ }
136+ }
137+ else {
138+ Write-Output " Using existing Az context: Tenant $ ( $currentCtx.Tenant.Id ) "
139+ }
120140 }
121141 else {
122- $ctx = Connect-AzAccount - Tenant $TenantId - ErrorAction Stop | Out-Null
142+ Write-Output " Not connected to Az PowerShell—authenticating..."
143+ if ($UseManagedIdentity ) {
144+ if ($TenantId ) {
145+ Connect-AzAccount - Identity - Tenant $TenantId | Out-Null
146+ }
147+ else {
148+ Connect-AzAccount - Identity - ErrorAction Stop | Out-Null
149+ }
150+ }
151+ else {
152+ if ($TenantId ) {
153+ Connect-AzAccount - Tenant $TenantId | Out-Null
154+ }
155+ else {
156+ Connect-AzAccount | Out-Null
157+ }
158+ }
159+ $ctx = Get-AzContext
160+ Write-Output " Connected to Az PowerShell as: $ ( $ctx.Account ) in tenant $ ( $ctx.Tenant.Id ) "
123161 }
124- Write-Output " Connected to Azure PowerShell as: $ ( $ctx.Account ) "
125-
126-
127162}
128163
129164
@@ -138,44 +173,33 @@ if($null -ne $ExclusionTags){
138173 }
139174 }
140175}
176+ # Ensure connection with both PowerShell and CLI.
177+ if ($UseManagedIdentity -or $envType -eq ' AzureAutomation' ) {
178+ if ($TenantId ) {
179+ Connect-Azure - TenantId $TenantId - UseManagedIdentity $UseManagedIdentity
180+ } else {
181+ Connect-Azure - UseManagedIdentity $UseManagedIdentity
182+ }
183+ } else {
184+ if ($TenantId ) {
185+ Connect-Azure - TenantId $TenantId
186+ } else {
187+ Connect-Azure
188+ }
189+ }
190+
191+ $context = Get-AzContext - ErrorAction SilentlyContinue
192+ Write-Output " Connected to Azure as: $ ( $context.Account ) "
141193
142194if (-not $TenantId ) {
143- $TenantId = ( Get-AzContext ) .Tenant.Id
195+ $TenantId = $context .Tenant.Id
144196 Write-Output " No TenantId provided. Using current context TenantId: $TenantId "
145197} else {
146198 Write-Output " Using provided TenantId: $TenantId "
147199}
148- # Ensure connection with both PowerShell and CLI.
149- if ($UseManagedIdentity ) {
150- Connect-Azure ($TenantId , $UseManagedIdentity )
151- }else {
152- Connect-Azure ($TenantId )
153- }
154-
155- # Ensure the required modules are imported
156200
157201
158- # Ensure NuGet provider is available
159- if (-not (Get-PackageProvider - Name NuGet - ErrorAction SilentlyContinue)) {
160- Install-PackageProvider - Name NuGet - Force
161- }
162-
163- # Check if Az module is installed
164- $installedModule = Get-InstalledModule - Name Az - ErrorAction SilentlyContinue
165-
166- if (-not $installedModule ) {
167- Write-Host " Az module not found. Installing latest version..."
168- Install-Module - Name Az - Scope CurrentUser - Repository PSGallery - Force
169- } else {
170- # Get the latest version available in the PSGallery
171- $latestVersion = (Find-Module - Name Az - Repository PSGallery).Version
172- if ($installedModule.Version -lt $latestVersion ) {
173- Write-Host " Az module is outdated. Updating to latest version..."
174- Update-Module - Name Az - Force
175- } else {
176- Write-Host " Az module is already up to date. No action needed."
177- }
178- }
202+ # Ensure the required modules are imported
179203
180204try {
181205 Import-Module Az.Accounts
@@ -200,10 +224,10 @@ $modifiedResources = @()
200224if ($SubId -like " *.csv" ) {
201225 $subscriptions = Import-Csv $SubId
202226}elseif ($SubId -ne " " ) {
203- $subscriptions = Get-AzSubscription - SubscriptionId $ SubId | Sort-Object TenantId
204-
227+ Write-Output " Passed Subscription $ ( $ SubId) "
228+ $subscriptions = Get-AzSubscription - SubscriptionId $SubId
205229}else {
206- $subscriptions = Get-AzSubscription | Where-Object { $_.TenantId -eq $tenantId }
230+ $subscriptions = Get-AzSubscription | Where-Object { $_.TenantId -eq $tenantId }
207231}
208232
209233# Handle MachineName input (single or CSV)
@@ -258,7 +282,7 @@ foreach ($sub in $subscriptions) {
258282
259283 $query += "
260284 | extend machineId = tolower(tostring(id))
261- | project machineId, machineName = name
285+ | project machineId, machineName = tolower( name)
262286 | join kind= inner (
263287 resources
264288 | where subscriptionId =~ '$ ( $sub.Id ) '
@@ -269,27 +293,38 @@ foreach ($sub in $subscriptions) {
269293 | extend extensionName = name
270294 | extend extensionPublisher = properties.publisher
271295 | extend extensionType = properties.type
272- | parse id with '/subscriptions/' subscriptionId '/resourceGroups/' resourceGroup '/providers/Microsoft.HybridCompute/machines/' machineName '/extensions/' extensionName
273- ) on `$ left.machineName == `$ right.machineName
296+ | parse id with '/subscriptions/' subscriptionId '/resourceGroups/' resourceGroup '/providers/Microsoft.HybridCompute/machines/' machineNameRaw '/extensions/' extensionName
297+ | extend machineName = tolower(machineNameRaw)
298+ ) on `$ left.machineName == `$ right.machineName
274299 | project machineName, extensionName, resourceGroup, location, subscriptionId, extensionPublisher, extensionType
275- "
300+ | order by machineName asc"
301+
302+ $skipToken = $null
276303
277- # Write-Output $query
304+ Write-Output $query
278305
279- $resources = Search-AzGraph - Query " $ ( $query ) "
280306 Write-Output " Found $ ( $resources.Count ) resource(s) to update"
281- $count = $resources.Count
307+ $allResults = [System.Collections.Generic.List [PSObject ]]::new()
308+ do {
309+ $resources = Search-AzGraph - Query " $ ( $query ) " - First $batchSize - SkipToken $skipToken
310+ $allResults.AddRange ($resources )
311+ $skipToken = $resources.SkipToken
312+ }while ($skipToken )
313+
314+
315+ $count = $allResults.Count
316+
282317
283318 while ($count -gt 0 ) {
284319 $count -= 1
285320 $setID = @ {
286- MachineName = $resources [$count ].MachineName
287- Name = $resources [$count ].extensionName
288- ResourceGroup = $resources [$count ].resourceGroup
289- Location = $resources [$count ].location
290- SubscriptionId = $resources [$count ].subscriptionId
291- Publisher = $resources [$count ].extensionPublisher
292- ExtensionType = $resources [$count ].extensionType
321+ MachineName = $allResults [$count ].MachineName
322+ Name = $allResults [$count ].extensionName
323+ ResourceGroup = $allResults [$count ].resourceGroup
324+ Location = $allResults [$count ].location
325+ SubscriptionId = $allResults [$count ].subscriptionId
326+ Publisher = $allResults [$count ].extensionPublisher
327+ ExtensionType = $allResults [$count ].extensionType
293328 }
294329
295330 write-Output " MachineName - $ ( $setID.MachineName ) "
@@ -407,6 +442,7 @@ foreach ($sub in $subscriptions) {
407442 Write-Output " ReportOnly mode enabled. Skipping modification for: $ ( $setID.MachineName ) "
408443 }
409444 }
445+
410446 }
411447 }
412448}
@@ -421,3 +457,8 @@ if ($modifiedResources.Count -gt 0) {
421457}
422458
423459write-Output " Arc SQL Update Script completed"
460+
461+ $scriptEndTime = Get-Date
462+ $executionDuration = $scriptEndTime - $scriptStartTime
463+ Write-Output " Script execution ended at: $ ( $scriptEndTime.ToString (' yyyy-MM-dd HH:mm:ss' )) "
464+ Write-Output " Total execution time: $ ( $executionDuration.ToString (' hh\:mm\:ss' )) "
0 commit comments