From d181e237b8dbbdff3d48808105e61b2e456ce256 Mon Sep 17 00:00:00 2001 From: "Alexander (Sasha) Nosov" Date: Wed, 29 May 2024 11:20:45 -0700 Subject: [PATCH 01/20] initial draft --- .../install-payg-sql-server.ps1 | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 diff --git a/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 b/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 new file mode 100644 index 00000000..51a6298c --- /dev/null +++ b/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 @@ -0,0 +1,88 @@ +param ( + [string]$AzureSubscriptionId, + [string]$AzureResourceGroupUri, + [string]$location, + [string]$SqlServerInstanceName, + [string]$SqlServerAdminAccount, + [string]$SqlServerAdminPassword, + [string]$SqlServerVersion, + [string]$SqlServerEdition, + [string]$SqlServerProductKey, + [string]$SqlServerCU = "latest", + [string]$isoURL # URL to the ISO file +) + +try { + # Step 0: Check if setup.exe is already running and kill it if so + if (Get-Process setup -ErrorAction SilentlyContinue) { + Stop-Process -Name setup -Force + Write-Host "Existing setup.exe process terminated." + } + + # Step 1: Log in to Azure + az login + $subscription = Get-AzSubscription -SubscriptionId $AzureSubscriptionId -ErrorAction SilentlyContinue + if (-not $subscription) { + Write-Error "Azure subscription with ID '$AzureSubscriptionId' does not exist." + exit + } + + # Step 2: Block auto-onboarding to Arc by tagging the resource group + $existingResourceGroup = Get-AzResourceGroup -Name $AzureResourceGroupUri -ErrorAction SilentlyContinue + + if ($existingResourceGroup) { + Write-Host "Resource group '$AzureResourceGroupUri' exists." + } else { + Write-Error "Resource group '$AzureResourceGroupUri' does not exist." + exit + } + az group update --name $AzureResourceGroupUri --tags "ArcOnboarding=Blocked" + + + + # Step 3: Onboard the VM to Azure Arc + $hostName = (Get-WmiObject Win32_ComputerSystem).Name + + az arc connectedmachine create --resource-group $AzureResourceGroupUri --name $hostName --location $location + + # Step 4: Install SQL Arc extension with LT=PAYG + az connectedmachine extension create --machine-name $hostName --resource-group $AzureResourceGroupUri --name "WindowsAgent.SqlServer" --type "WindowsAgent.SqlServer" --publisher "Microsoft.AzureData" --settings '{"LicenseType":"PAYG", "SqlManagement": {"IsEnabled":true}}' + + + # Step 5: Automatically download installable media + $localPath = "C:\path\to\download\SQLServer.iso" + $freeSpace = (Get-PSDrive -Name C).Free + $isoSize = (Invoke-WebRequest -Uri $isoURL -Method Head).Headers.'Content-Length' + + if ($freeSpace -gt $isoSize) { + Start-BitsTransfer -Source $isoURL -Destination $localPath + } else { + throw "Not enough free space to download the ISO." + } + + + # Step 6: Mount the ISO file as a volume + $volumeInfo = Mount-DiskImage -ImagePath $localPath -PassThru | Get-Volume + + # Step 7: Run unattended SQL Server setup from the mounted volume + $setupPath = ($volumeInfo.DriveLetter + ":\setup.exe") + Start-Process -FilePath $setupPath -ArgumentList "/q /ACTION=Install /INSTANCENAME=$SqlServerInstanceName /FEATURES=SQL /INSTANCEDIR=C:\SQL /SQLSYSADMINACCOUNTS=$SqlServerAdminAccount /SQLSVCACCOUNT=$SqlServerAdminAccount /SQLSVCPASSWORD=$SqlServerAdminPassword /AGTSVCACCOUNT=$SqlServerAdminAccount /AGTSVCPASSWORD=$SqlServerAdminPassword /IACCEPTSQLSERVERLICENSETERMS /PID=$SqlServerProductKey /SQLSERVERUPDATE=$SqlServerCU" + + # Step 8: Dismount the ISO file after installation + Dismount-DiskImage -ImagePath $localPath + + # Step 9: Remove the media from the local file system + Remove-Item -Path $localPath + + # Step 10: Display the status of the Azure resource + az resource show --ids $AzureResourceGroupUri + + # Step 11: Verify the presence of the Arc-enabled SQL Server + az sql arc list --resource-group $AzureResourceGroupUri +} catch { + Write-Error "An error occurred: $_" + # You can add additional error handling logic here +} finally { + # Cleanup or other actions that should always run + Write-Host "Script execution completed." +} From 673feb11478ded8f3333b00a8b187109c5d798ea Mon Sep 17 00:00:00 2001 From: "Alexander (Sasha) Nosov" Date: Wed, 29 May 2024 12:20:15 -0700 Subject: [PATCH 02/20] progress --- .../install-payg-sql-server.ps1 | 121 +++++++++++++++--- 1 file changed, 104 insertions(+), 17 deletions(-) diff --git a/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 b/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 index 51a6298c..77d4501e 100644 --- a/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 +++ b/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 @@ -1,25 +1,114 @@ param ( + [Parameter (Mandatory=$true)] [string]$AzureSubscriptionId, + [Parameter (Mandatory=$true)] [string]$AzureResourceGroupUri, + [Parameter (Mandatory=$true)] [string]$location, + [Parameter (Mandatory=$false)] [string]$SqlServerInstanceName, + [Parameter (Mandatory=$true)] [string]$SqlServerAdminAccount, + [Parameter (Mandatory=$true)] [string]$SqlServerAdminPassword, + [Parameter (Mandatory=$true)] [string]$SqlServerVersion, + [Parameter (Mandatory=$true)] [string]$SqlServerEdition, + [Parameter (Mandatory=$true)] [string]$SqlServerProductKey, + [Parameter (Mandatory=$false)] [string]$SqlServerCU = "latest", - [string]$isoURL # URL to the ISO file + [Parameter (Mandatory=$false)] + [string]$isoLocation = "C:\download\SQLServer.iso" ) +# This function checks if the specified module is imported into the session and if not installes and/or imports it +function LoadModule +{ + param ( + [parameter(Mandatory = $true)][string] $name + ) + + $retVal = $true + + if (!(Get-Module -Name $name)) + { + $retVal = Get-Module -ListAvailable | Where-Object {$_.Name -eq $name} + + if ($retVal) + { + try + { + Import-Module $name -ErrorAction SilentlyContinue + } + catch + { + write-host "The request to lload module $($name) failed with the following error:" + write-host $_.Exception.Message + $retVal = $false + } + } + else { + + # If module is not imported, not available on disk, but is in online gallery then install and import + if (Find-Module -Name $name) { + Install-Module -Name $name -Force -Verbose -Scope CurrentUser + try + { + Import-Module $name -ErrorAction SilentlyContinue + } + catch + { + write-host "The request to lload module $($name) failed with the following error:" + write-host $_.Exception.Message + $retVal = $false + } + } + else { + + # If module is not imported, not available and not in online gallery then abort + write-host "Module $($name) not imported, not available and not in online gallery, exiting." + EXIT 1 + } + } + } + + return $retVal +} + try { - # Step 0: Check if setup.exe is already running and kill it if so + # ISO URL for each version + $isoURL @{ + 2012 = ""; + 2014 = ""; + 2016 = ""; + 2019 = ""; + 2022 = "https://download.microsoft.com/download/7/c/1/7c14e92e-bdcb-4f89-b7cf-93543e7112d1/SQLServer2019-x64-ENU-Dev.iso" + } + + #Step 0: Ensure PS version and load missing Azure modules + # + # Suppress warnings + # + Update-AzConfig -DisplayBreakingChangeWarning $false + + # Load required modules + $requiredModules = @( + "AzureAD", + "Az.Accounts", + "Az.ConnectedMachine", + "Az.ResourceGraph" + ) + $requiredModules | Foreach-Object {LoadModule $_} + + # Step 1: Check if setup.exe is already running and kill it if so if (Get-Process setup -ErrorAction SilentlyContinue) { Stop-Process -Name setup -Force Write-Host "Existing setup.exe process terminated." } - # Step 1: Log in to Azure + # Step 2: Log in to Azure az login $subscription = Get-AzSubscription -SubscriptionId $AzureSubscriptionId -ErrorAction SilentlyContinue if (-not $subscription) { @@ -38,8 +127,6 @@ try { } az group update --name $AzureResourceGroupUri --tags "ArcOnboarding=Blocked" - - # Step 3: Onboard the VM to Azure Arc $hostName = (Get-WmiObject Win32_ComputerSystem).Name @@ -50,29 +137,29 @@ try { # Step 5: Automatically download installable media - $localPath = "C:\path\to\download\SQLServer.iso" - $freeSpace = (Get-PSDrive -Name C).Free - $isoSize = (Invoke-WebRequest -Uri $isoURL -Method Head).Headers.'Content-Length' - - if ($freeSpace -gt $isoSize) { - Start-BitsTransfer -Source $isoURL -Destination $localPath - } else { - throw "Not enough free space to download the ISO." + + if (!(Test-Path -Path $isoLocation)) { + $freeSpace = (Get-PSDrive -Name C).Free + $isoSize = (Invoke-WebRequest -Uri $isoURL[$SqlServerVersion] -Method Head).Headers.'Content-Length' + if ($freeSpace -gt $isoSize) { + Start-BitsTransfer -Source $isoURL[$SqlServerVersion] -Destination $isoLocation + } else { + throw "Not enough free space to download the ISO." + } } - # Step 6: Mount the ISO file as a volume - $volumeInfo = Mount-DiskImage -ImagePath $localPath -PassThru | Get-Volume + $volumeInfo = Mount-DiskImage -ImagePath $isoLocation -PassThru | Get-Volume # Step 7: Run unattended SQL Server setup from the mounted volume $setupPath = ($volumeInfo.DriveLetter + ":\setup.exe") Start-Process -FilePath $setupPath -ArgumentList "/q /ACTION=Install /INSTANCENAME=$SqlServerInstanceName /FEATURES=SQL /INSTANCEDIR=C:\SQL /SQLSYSADMINACCOUNTS=$SqlServerAdminAccount /SQLSVCACCOUNT=$SqlServerAdminAccount /SQLSVCPASSWORD=$SqlServerAdminPassword /AGTSVCACCOUNT=$SqlServerAdminAccount /AGTSVCPASSWORD=$SqlServerAdminPassword /IACCEPTSQLSERVERLICENSETERMS /PID=$SqlServerProductKey /SQLSERVERUPDATE=$SqlServerCU" # Step 8: Dismount the ISO file after installation - Dismount-DiskImage -ImagePath $localPath + Dismount-DiskImage -ImagePath $isoLocation # Step 9: Remove the media from the local file system - Remove-Item -Path $localPath + Remove-Item -Path $isoLocation # Step 10: Display the status of the Azure resource az resource show --ids $AzureResourceGroupUri From 2c2c4c09be511e9321cbd1f19fdfdfb19ecbadc6 Mon Sep 17 00:00:00 2001 From: "Alexander (Sasha) Nosov" Date: Wed, 29 May 2024 13:00:21 -0700 Subject: [PATCH 03/20] Added isoURL --- .../install-payg-sql-server.ps1 | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 b/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 index 77d4501e..2794a959 100644 --- a/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 +++ b/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 @@ -17,6 +17,8 @@ param ( [string]$SqlServerEdition, [Parameter (Mandatory=$true)] [string]$SqlServerProductKey, + [Parameter (Mandatory=$true)] + [string]$isoURL, [Parameter (Mandatory=$false)] [string]$SqlServerCU = "latest", [Parameter (Mandatory=$false)] @@ -78,14 +80,6 @@ function LoadModule } try { - # ISO URL for each version - $isoURL @{ - 2012 = ""; - 2014 = ""; - 2016 = ""; - 2019 = ""; - 2022 = "https://download.microsoft.com/download/7/c/1/7c14e92e-bdcb-4f89-b7cf-93543e7112d1/SQLServer2019-x64-ENU-Dev.iso" - } #Step 0: Ensure PS version and load missing Azure modules # @@ -140,9 +134,9 @@ try { if (!(Test-Path -Path $isoLocation)) { $freeSpace = (Get-PSDrive -Name C).Free - $isoSize = (Invoke-WebRequest -Uri $isoURL[$SqlServerVersion] -Method Head).Headers.'Content-Length' + $isoSize = (Invoke-WebRequest -Uri $isoURL -Method Head).Headers.'Content-Length' if ($freeSpace -gt $isoSize) { - Start-BitsTransfer -Source $isoURL[$SqlServerVersion] -Destination $isoLocation + Start-BitsTransfer -Source $isoURL -Destination $isoLocation } else { throw "Not enough free space to download the ISO." } From 2b4156619d9537fd7c38b758d6369b8fb1837aeb Mon Sep 17 00:00:00 2001 From: "Alexander (Sasha) Nosov" Date: Thu, 6 Jun 2024 11:31:50 -0700 Subject: [PATCH 04/20] replaced az with PS, added verification KQL --- .../install-payg-sql-server.ps1 | 55 +++++++++++++------ 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 b/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 index 2794a959..c4f06b96 100644 --- a/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 +++ b/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 @@ -103,7 +103,7 @@ try { } # Step 2: Log in to Azure - az login + Connect-AzAccount $subscription = Get-AzSubscription -SubscriptionId $AzureSubscriptionId -ErrorAction SilentlyContinue if (-not $subscription) { Write-Error "Azure subscription with ID '$AzureSubscriptionId' does not exist." @@ -119,18 +119,15 @@ try { Write-Error "Resource group '$AzureResourceGroupUri' does not exist." exit } - az group update --name $AzureResourceGroupUri --tags "ArcOnboarding=Blocked" + $tags = @{"ArcOnboarding" = "Blocked"} + Set-AzResourceGroup -Name $AzureResourceGroupUri -Tag $tags # Step 3: Onboard the VM to Azure Arc $hostName = (Get-WmiObject Win32_ComputerSystem).Name - az arc connectedmachine create --resource-group $AzureResourceGroupUri --name $hostName --location $location + New-AzConnectedMachine -ResourceGroupName $AzureResourceGroupUri -Name $hostName -Location $location - # Step 4: Install SQL Arc extension with LT=PAYG - az connectedmachine extension create --machine-name $hostName --resource-group $AzureResourceGroupUri --name "WindowsAgent.SqlServer" --type "WindowsAgent.SqlServer" --publisher "Microsoft.AzureData" --settings '{"LicenseType":"PAYG", "SqlManagement": {"IsEnabled":true}}' - - - # Step 5: Automatically download installable media + # Step 4: Automatically download installable media if (!(Test-Path -Path $isoLocation)) { $freeSpace = (Get-PSDrive -Name C).Free @@ -142,24 +139,50 @@ try { } } - # Step 6: Mount the ISO file as a volume + # Step 5: Mount the ISO file as a volume $volumeInfo = Mount-DiskImage -ImagePath $isoLocation -PassThru | Get-Volume - # Step 7: Run unattended SQL Server setup from the mounted volume + # Step 6: Run unattended SQL Server setup from the mounted volume $setupPath = ($volumeInfo.DriveLetter + ":\setup.exe") Start-Process -FilePath $setupPath -ArgumentList "/q /ACTION=Install /INSTANCENAME=$SqlServerInstanceName /FEATURES=SQL /INSTANCEDIR=C:\SQL /SQLSYSADMINACCOUNTS=$SqlServerAdminAccount /SQLSVCACCOUNT=$SqlServerAdminAccount /SQLSVCPASSWORD=$SqlServerAdminPassword /AGTSVCACCOUNT=$SqlServerAdminAccount /AGTSVCPASSWORD=$SqlServerAdminPassword /IACCEPTSQLSERVERLICENSETERMS /PID=$SqlServerProductKey /SQLSERVERUPDATE=$SqlServerCU" - # Step 8: Dismount the ISO file after installation + # Step 7: Install SQL Arc extension with LT=PAYG + $Settings = @{ + SqlManagement = @{ IsEnabled = $true }; + LicenseType = "PAYG"; + enableExtendedSecurityUpdates = $True; + esuLastUpdatedTimestamp = [DateTime]::UtcNow.ToString('yyyy-MM-ddTHH:mm:ss.fffZ') + } + New-AzConnectedMachineExtension -ResourceGroupName $AzureResourceGroupUri -MachineName $hostName -Name "WindowsAgent.SqlServer" -Publisher "Microsoft.AzureData" -Type "WindowsAgent.SqlServer" -TypeHandlerVersion "1.0" -Settings $settings + + # Step 9: Dismount the ISO file after installation Dismount-DiskImage -ImagePath $isoLocation - # Step 9: Remove the media from the local file system + # Step 10: Remove the media from the local file system Remove-Item -Path $isoLocation - # Step 10: Display the status of the Azure resource - az resource show --ids $AzureResourceGroupUri + # Step 8: Display the status of the Azure resource for Arc-enabled SQL Server + $query = " + resources + | where type =~ "microsoft.hybridcompute/machines" + | where resourceGroup =~ '$($AzureResourceGroupUri)' + | where properties.detectedProperties.mssqldiscovered == "true" + | extend machineIdHasSQLServerDiscovered = id + | project name, machineIdHasSQLServerDiscovered, resourceGroup, subscriptionId + | join kind= leftouter ( + resources + | where type == "microsoft.hybridcompute/machines/extensions" | where properties.type in ("WindowsAgent.SqlServer","LinuxAgent.SqlServer") + | extend machineIdHasSQLServerExtensionInstalled = iff(id contains "/extensions/WindowsAgent.SqlServer" or id contains "/extensions/LinuxAgent.SqlServer", substring(id, 0, indexof(id, "/extensions/")), "") + | project Extension_State = properties.provisioningState, + License_Type = properties.settings.LicenseType, + ESU = iff(notnull(properties.settings.enableExtendedSecurityUpdates), iff(properties.settings.enableExtendedSecurityUpdates == true,"enabled","disabled"), ""), + Extension_Version = properties.instanceView.typeHandlerVersion, + machineIdHasSQLServerExtensionInstalled)on $left.machineIdHasSQLServerDiscovered == $right.machineIdHasSQLServerExtensionInstalled + | where isnotempty(machineIdHasSQLServerExtensionInstalled) + | project-away machineIdHasSQLServerDiscovered, machineIdHasSQLServerExtensionInstalled + " + Search-AzGraph -Query "$($query)" - # Step 11: Verify the presence of the Arc-enabled SQL Server - az sql arc list --resource-group $AzureResourceGroupUri } catch { Write-Error "An error occurred: $_" # You can add additional error handling logic here From fa3f5134959d60a43ba0f39ea6ee3075e47969af Mon Sep 17 00:00:00 2001 From: "Alexander (Sasha) Nosov" Date: Thu, 6 Jun 2024 15:14:38 -0700 Subject: [PATCH 05/20] Added edition to setup --- .../install-payg-sql-server.ps1 | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 b/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 index c4f06b96..3193cb81 100644 --- a/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 +++ b/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 @@ -144,7 +144,23 @@ try { # Step 6: Run unattended SQL Server setup from the mounted volume $setupPath = ($volumeInfo.DriveLetter + ":\setup.exe") - Start-Process -FilePath $setupPath -ArgumentList "/q /ACTION=Install /INSTANCENAME=$SqlServerInstanceName /FEATURES=SQL /INSTANCEDIR=C:\SQL /SQLSYSADMINACCOUNTS=$SqlServerAdminAccount /SQLSVCACCOUNT=$SqlServerAdminAccount /SQLSVCPASSWORD=$SqlServerAdminPassword /AGTSVCACCOUNT=$SqlServerAdminAccount /AGTSVCPASSWORD=$SqlServerAdminPassword /IACCEPTSQLSERVERLICENSETERMS /PID=$SqlServerProductKey /SQLSERVERUPDATE=$SqlServerCU" + $argumentList = " + /q + /ACTION=Install + /INSTANCENAME='$($SqlServerInstanceName)' + /FEATURES=SQL + /INSTANCEDIR=C:\SQL + /SQLSYSADMINACCOUNTS='$($SqlServerAdminAccount)' + /SQLSVCACCOUNT='$($SqlServerAdminAccount)' + /SQLSVCPASSWORD='$($SqlServerAdminPassword)' + /AGTSVCACCOUNT='$($SqlServerAdminAccount)' + /AGTSVCPASSWORD='$($SqlServerAdminPassword)' + /IACCEPTSQLSERVERLICENSETERMS + /PID='$($SqlServerProductKey)' + /SQLSERVERUPDATE='$($SqlServerCU)' + /Edition='$($SqlServerEdition)' + " + Start-Process -FilePath $setupPath -ArgumentList $argumentList # Step 7: Install SQL Arc extension with LT=PAYG $Settings = @{ @@ -164,18 +180,18 @@ try { # Step 8: Display the status of the Azure resource for Arc-enabled SQL Server $query = " resources - | where type =~ "microsoft.hybridcompute/machines" + | where type =~ 'microsoft.hybridcompute/machines' | where resourceGroup =~ '$($AzureResourceGroupUri)' - | where properties.detectedProperties.mssqldiscovered == "true" + | where properties.detectedProperties.mssqldiscovered == 'true' | extend machineIdHasSQLServerDiscovered = id | project name, machineIdHasSQLServerDiscovered, resourceGroup, subscriptionId | join kind= leftouter ( resources - | where type == "microsoft.hybridcompute/machines/extensions" | where properties.type in ("WindowsAgent.SqlServer","LinuxAgent.SqlServer") - | extend machineIdHasSQLServerExtensionInstalled = iff(id contains "/extensions/WindowsAgent.SqlServer" or id contains "/extensions/LinuxAgent.SqlServer", substring(id, 0, indexof(id, "/extensions/")), "") + | where type == 'microsoft.hybridcompute/machines/extensions' | where properties.type in ('WindowsAgent.SqlServer','LinuxAgent.SqlServer') + | extend machineIdHasSQLServerExtensionInstalled = iff(id contains '/extensions/WindowsAgent.SqlServer' or id contains '/extensions/LinuxAgent.SqlServer', substring(id, 0, indexof(id, '/extensions/')), '') | project Extension_State = properties.provisioningState, License_Type = properties.settings.LicenseType, - ESU = iff(notnull(properties.settings.enableExtendedSecurityUpdates), iff(properties.settings.enableExtendedSecurityUpdates == true,"enabled","disabled"), ""), + ESU = iff(notnull(properties.settings.enableExtendedSecurityUpdates), iff(properties.settings.enableExtendedSecurityUpdates == true,'enabled','disabled'), ''), Extension_Version = properties.instanceView.typeHandlerVersion, machineIdHasSQLServerExtensionInstalled)on $left.machineIdHasSQLServerDiscovered == $right.machineIdHasSQLServerExtensionInstalled | where isnotempty(machineIdHasSQLServerExtensionInstalled) From 3f479bbfbb2ef6105e5d3b1ec8d0475d73d16878 Mon Sep 17 00:00:00 2001 From: "Alexander (Sasha) Nosov" Date: Thu, 6 Jun 2024 15:23:21 -0700 Subject: [PATCH 06/20] Fixed azure region --- .../install-payg-sql-server.ps1 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 b/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 index 3193cb81..801cedb3 100644 --- a/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 +++ b/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 @@ -4,7 +4,7 @@ param ( [Parameter (Mandatory=$true)] [string]$AzureResourceGroupUri, [Parameter (Mandatory=$true)] - [string]$location, + [string]$AzureRegion, [Parameter (Mandatory=$false)] [string]$SqlServerInstanceName, [Parameter (Mandatory=$true)] @@ -20,9 +20,8 @@ param ( [Parameter (Mandatory=$true)] [string]$isoURL, [Parameter (Mandatory=$false)] - [string]$SqlServerCU = "latest", - [Parameter (Mandatory=$false)] - [string]$isoLocation = "C:\download\SQLServer.iso" + [string]$SqlServerCU = "latest" + ) # This function checks if the specified module is imported into the session and if not installes and/or imports it @@ -125,10 +124,11 @@ try { # Step 3: Onboard the VM to Azure Arc $hostName = (Get-WmiObject Win32_ComputerSystem).Name - New-AzConnectedMachine -ResourceGroupName $AzureResourceGroupUri -Name $hostName -Location $location + New-AzConnectedMachine -ResourceGroupName $AzureResourceGroupUri -Name $hostName -Location $AzureRegion # Step 4: Automatically download installable media + $isoLocation = "C:\download\SQLServer.iso" if (!(Test-Path -Path $isoLocation)) { $freeSpace = (Get-PSDrive -Name C).Free $isoSize = (Invoke-WebRequest -Uri $isoURL -Method Head).Headers.'Content-Length' From 0e2ae65786e724cb6fd6d9c20d22cf22c7aec145 Mon Sep 17 00:00:00 2001 From: "Alexander (Sasha) Nosov" Date: Thu, 6 Jun 2024 15:45:26 -0700 Subject: [PATCH 07/20] added svc account --- .../install-payg-sql-server.ps1 | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 b/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 index 801cedb3..25242f59 100644 --- a/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 +++ b/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 @@ -12,6 +12,10 @@ param ( [Parameter (Mandatory=$true)] [string]$SqlServerAdminPassword, [Parameter (Mandatory=$true)] + [string]$SqlServerSvcAccount, + [Parameter (Mandatory=$true)] + [string]$SqlServerSvcPassword, + [Parameter (Mandatory=$true)] [string]$SqlServerVersion, [Parameter (Mandatory=$true)] [string]$SqlServerEdition, @@ -151,10 +155,11 @@ try { /FEATURES=SQL /INSTANCEDIR=C:\SQL /SQLSYSADMINACCOUNTS='$($SqlServerAdminAccount)' - /SQLSVCACCOUNT='$($SqlServerAdminAccount)' - /SQLSVCPASSWORD='$($SqlServerAdminPassword)' - /AGTSVCACCOUNT='$($SqlServerAdminAccount)' - /AGTSVCPASSWORD='$($SqlServerAdminPassword)' + /SAPWD='$($SqlServerAdminPassword)' + /SQLSVCACCOUNT='$($SqlServerSvcAccount)' + /SQLSVCPASSWORD='$($SqlServerSvcPassword)' + /AGTSVCACCOUNT='$($SqlServerSvcAccount)' + /AGTSVCPASSWORD='$($SqlServerSvcPassword)' /IACCEPTSQLSERVERLICENSETERMS /PID='$($SqlServerProductKey)' /SQLSERVERUPDATE='$($SqlServerCU)' From a698ca951dd991d2526ed2d336c7ea6999d72e54 Mon Sep 17 00:00:00 2001 From: "Alexander (Sasha) Nosov" Date: Thu, 6 Jun 2024 15:48:32 -0700 Subject: [PATCH 08/20] removed SA password --- .../install-payg-sql-server/install-payg-sql-server.ps1 | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 b/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 index 25242f59..447012b6 100644 --- a/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 +++ b/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 @@ -8,9 +8,7 @@ param ( [Parameter (Mandatory=$false)] [string]$SqlServerInstanceName, [Parameter (Mandatory=$true)] - [string]$SqlServerAdminAccount, - [Parameter (Mandatory=$true)] - [string]$SqlServerAdminPassword, + [string]$SqlServerAdminAccounts, [Parameter (Mandatory=$true)] [string]$SqlServerSvcAccount, [Parameter (Mandatory=$true)] @@ -154,8 +152,7 @@ try { /INSTANCENAME='$($SqlServerInstanceName)' /FEATURES=SQL /INSTANCEDIR=C:\SQL - /SQLSYSADMINACCOUNTS='$($SqlServerAdminAccount)' - /SAPWD='$($SqlServerAdminPassword)' + /SQLSYSADMINACCOUNTS='$($SqlServerAdminAccounts)' /SQLSVCACCOUNT='$($SqlServerSvcAccount)' /SQLSVCPASSWORD='$($SqlServerSvcPassword)' /AGTSVCACCOUNT='$($SqlServerSvcAccount)' From 7873626aa6f1cb49a62128fd35a7378daa3f195b Mon Sep 17 00:00:00 2001 From: "Alexander (Sasha) Nosov" Date: Wed, 12 Jun 2024 10:01:36 -0700 Subject: [PATCH 09/20] Removed /SQLSERVERUPDATE --- .../install-payg-sql-server.ps1 | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 b/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 index 447012b6..6ff5d8f1 100644 --- a/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 +++ b/samples/manage/azure-arc-enabled-sql-server/install-payg-sql-server/install-payg-sql-server.ps1 @@ -20,10 +20,7 @@ param ( [Parameter (Mandatory=$true)] [string]$SqlServerProductKey, [Parameter (Mandatory=$true)] - [string]$isoURL, - [Parameter (Mandatory=$false)] - [string]$SqlServerCU = "latest" - + [string]$isoURL ) # This function checks if the specified module is imported into the session and if not installes and/or imports it @@ -149,7 +146,6 @@ try { $argumentList = " /q /ACTION=Install - /INSTANCENAME='$($SqlServerInstanceName)' /FEATURES=SQL /INSTANCEDIR=C:\SQL /SQLSYSADMINACCOUNTS='$($SqlServerAdminAccounts)' @@ -159,9 +155,12 @@ try { /AGTSVCPASSWORD='$($SqlServerSvcPassword)' /IACCEPTSQLSERVERLICENSETERMS /PID='$($SqlServerProductKey)' - /SQLSERVERUPDATE='$($SqlServerCU)' /Edition='$($SqlServerEdition)' " + if ($SqlServerInstanceName) { + $argumentList += "/INSTANCENAME='$($SqlServerInstanceName)'" + } + Start-Process -FilePath $setupPath -ArgumentList $argumentList # Step 7: Install SQL Arc extension with LT=PAYG From 01a8300e869e1b87b23a865becbd13d93d3a6c06 Mon Sep 17 00:00:00 2001 From: "Alexander (Sasha) Nosov" Date: Wed, 12 Jun 2024 17:26:46 -0700 Subject: [PATCH 10/20] added activate license script --- .../activate-pcore-license/README.md | 86 +++++++++++++++++++ .../activate-pcore-license.md | 83 ++++++++++++++++++ 2 files changed, 169 insertions(+) create mode 100644 samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/README.md create mode 100644 samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md diff --git a/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/README.md b/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/README.md new file mode 100644 index 00000000..c44992d0 --- /dev/null +++ b/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/README.md @@ -0,0 +1,86 @@ +--- +services: Azure SQL +platforms: Azure +author: anosov1960 +ms.author: sashan +ms.date: 06/12/2024 +--- + +# Overview + +This script performes a scheduled activation of a SQL Server p-core license. + +# Required permissions + +Your RBAC role must include the following permissions: + +- Microsoft.AzureArcData/SqlLicenses/read +- Microsoft.AzureArcData/SqlLicenses/write +- Microsoft.Management/managementGroups/read +- Microsoft.Resources/subscriptions/read +- Microsoft.Resources/subscriptions/resourceGroups/read +- Microsoft.Support/supporttickets/write + +# Launching the script + +The script accepts the following command line parameters: + +| **Parameter**                                         | **Value**                                                                       | **Description** | +|:--|:--|:--| +|-licenseId| License resource URI | +|-UseInRunbook| \$True or \$False (default) | Optional: must be $True when executed as a Runbook| + + +## Example + +The following command activate the license + +```PowerShell +.\activate-pcore-license.ps1 -licenseID +``` + +# Running the script using Cloud Shell + +To run the script in the Cloud Shell, use the following steps: + +1. Launch the [Cloud Shell](https://shell.azure.com/). For details, read [PowerShell in Cloud Shell](https://aka.ms/pscloudshell/docs). + +2. Upload the script to the shell using the following command: + + ```console + curl https://raw.githubusercontent.com/microsoft/sql-server-samples/master/samples/manage/azure-hybrid-benefit/sql-license-usage.ps1 -o sql-license-usage.ps1 + ``` + +3. Run the script with a set of parameters that reflect your desired configuration. + + ```console + .\activate-pcore-license.ps1 -licenseID + ``` + +> [!NOTE] +> - To paste the commands into the shell, use `Ctrl-Shift-V` on Windows or `Cmd-v` on MacOS. +> - The `curl` command will copy the script directly to the home folder associated with your Cloud Shell session. + +# Running the script as a Azure runbook + +You can scahedule to run the the command as a runbook. To set it up using Azure Portal, follow these steps. + +1. Open a command shell on your device and run this command. It will copy the script to your local folder. +```console +curl https://raw.githubusercontent.com/microsoft/sql-server-samples/master/samples/manage/azure-hybrid-benefit/sql-license-usage.ps1 -o sql-license-usage.ps1 +``` +2. [Create a new automation account](https://ms.portal.azure.com/#create/Microsoft.AutomationAccount) or open an existing one. +1. Select *Run as accounts* in the **Account Settings** group, open the automatically created *Azure Run As Account* and note or copy the Display Name property. You must add this user to all the target subscriptions with at least a *Reader* access role. To collect the Unregistered vCores, the user must be at least a *Contributor*. See [Role assignment portal](https://docs.microsoft.com/en-us/azure/role-based-access-control/role-assignments-portal) for the instructions about role assignments. +1. Select *Credentials* in the **Shared resources** group and create a credential object with the database username and password. The script will use these to connect to the specified database to save the license utilization data. +1. Select *Modules* in the **Shared resources** group and make sure your automation account have the following PowerShell modules installed. If not, add them from the Gallery. + - Az.Accounts + - Az.Resources +1. Select *Runbooks* in the **Process automation** group and click on *Import a runbook*, select the file you downloaded in Step 1 and click **Create**. +1. When import is completed, click the *Publish* button. +1. From the runbook blade, click on the *Link to schedule* button and select an existing schedule or create a new one with the desired frequency of runs and the expiration time. +1. Click on *Parameters and run settings* and specify the following parameters: + - LICENSEID. Put in teh resourec URI + - USEINRUNBOOKS. Select True to activate the logic that authenticates the runbook using the *Azure Run As Account*. +1. Click **OK** to link to the schedule and **OK** again to create the job. + +For more information about the runbooks, see the [Runbook tutorial](https://docs.microsoft.com/en-us/azure/automation/learn/automation-tutorial-runbook-textual-powershell) diff --git a/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md b/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md new file mode 100644 index 00000000..81d274ab --- /dev/null +++ b/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md @@ -0,0 +1,83 @@ +# +# This script performes a scheduled activation of a SQL Server p-core license. +# +# The script accepts the following command line parameters: +# +# -licenseID (The specific resource URI) +# + +param ( + [Parameter (Mandatory= $true)] + [string] $licenseId, + [Parameter (Mandatory= $false)] + [string] $UseInRunbook = $true +) + +function CheckModule ($m) { + + # This function ensures that the specified module is imported into the session + # If module is already imported - do nothing + + if (!(Get-Module | Where-Object {$_.Name -eq $m})) { + # If module is not imported, but available on disk then import + if (Get-Module -ListAvailable | Where-Object {$_.Name -eq $m}) { + Import-Module $m + } + else { + + # If module is not imported, not available on disk, but is in online gallery then install and import + if (Find-Module -Name $m | Where-Object {$_.Name -eq $m}) { + Install-Module -Name $m -Force -Verbose -Scope CurrentUser + Import-Module $m + } + else { + + # If module is not imported, not available and not in online gallery then abort + write-host "Module $m not imported, not available and not in online gallery, exiting." + EXIT 1 + } + } + } +} + +# +# Suppress warnings +# +Update-AzConfig -DisplayBreakingChangeWarning $false + +#The following block is required for runbooks only +if ($UseInRunbook){ + + # Ensures you do not inherit an AzContext in your runbook + Disable-AzContextAutosave –Scope Process + + $connection = Get-AutomationConnection -Name AzureRunAsConnection + + # Wrap authentication in retry logic for transient network failures + $logonAttempt = 0 + while(!($connectionResult) -and ($logonAttempt -le 10)) + { + $LogonAttempt++ + # Logging in to Azure... + $connectionResult = Connect-AzAccount ` + -ServicePrincipal ` + -Tenant $connection.TenantID ` + -ApplicationId $connection.ApplicationID ` + -CertificateThumbprint $connection.CertificateThumbprint + + Start-Sleep -Seconds 5 + } +}else{ + # Ensure that the required modules are imported + # In Runbooks these modules must be added to the automation account manually + + $requiredModules = @( + "Az.Accounts", + "Az.Resources" + ) + $requiredModules | Foreach-Object {CheckModule $_} +} + +$newActivationState = "Activated" +Set-AzResource -ResourceId $licenseId -PropertyObject @{"properties.activationState" = $newActivationState} -Force + From 6713bef69a67768caed15d567ae4a4d2b6595bf9 Mon Sep 17 00:00:00 2001 From: "Alexander (Sasha) Nosov" Date: Wed, 12 Jun 2024 17:47:02 -0700 Subject: [PATCH 11/20] fixed URL --- .../activate-pcore-license/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/README.md b/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/README.md index c44992d0..f20a6396 100644 --- a/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/README.md +++ b/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/README.md @@ -67,7 +67,7 @@ You can scahedule to run the the command as a runbook. To set it up using Azure 1. Open a command shell on your device and run this command. It will copy the script to your local folder. ```console -curl https://raw.githubusercontent.com/microsoft/sql-server-samples/master/samples/manage/azure-hybrid-benefit/sql-license-usage.ps1 -o sql-license-usage.ps1 +curl https://raw.githubusercontent.com/anosov1960/sql-server-samples/master/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md -o activate-pcore-license.ps1 ``` 2. [Create a new automation account](https://ms.portal.azure.com/#create/Microsoft.AutomationAccount) or open an existing one. 1. Select *Run as accounts* in the **Account Settings** group, open the automatically created *Azure Run As Account* and note or copy the Display Name property. You must add this user to all the target subscriptions with at least a *Reader* access role. To collect the Unregistered vCores, the user must be at least a *Contributor*. See [Role assignment portal](https://docs.microsoft.com/en-us/azure/role-based-access-control/role-assignments-portal) for the instructions about role assignments. From deccf74d928dea1de3366a3956482629cacb4bf6 Mon Sep 17 00:00:00 2001 From: "Alexander (Sasha) Nosov" Date: Wed, 12 Jun 2024 18:00:04 -0700 Subject: [PATCH 12/20] Fixed URL --- .../activate-pcore-license/README.md | 8 ++++---- .../activate-pcore-license/activate-pcore-license.md | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/README.md b/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/README.md index f20a6396..1ba9cf28 100644 --- a/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/README.md +++ b/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/README.md @@ -27,7 +27,7 @@ The script accepts the following command line parameters: | **Parameter**                                         | **Value**                                                                       | **Description** | |:--|:--|:--| -|-licenseId| License resource URI | +|-LicenseId| License resource URI | |-UseInRunbook| \$True or \$False (default) | Optional: must be $True when executed as a Runbook| @@ -36,7 +36,7 @@ The script accepts the following command line parameters: The following command activate the license ```PowerShell -.\activate-pcore-license.ps1 -licenseID +.\activate-pcore-license.ps1 -LicenseID ``` # Running the script using Cloud Shell @@ -48,13 +48,13 @@ To run the script in the Cloud Shell, use the following steps: 2. Upload the script to the shell using the following command: ```console - curl https://raw.githubusercontent.com/microsoft/sql-server-samples/master/samples/manage/azure-hybrid-benefit/sql-license-usage.ps1 -o sql-license-usage.ps1 + curl https://raw.githubusercontent.com/anosov1960/sql-server-samples/master/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md -o activate-pcore-license.ps1 ``` 3. Run the script with a set of parameters that reflect your desired configuration. ```console - .\activate-pcore-license.ps1 -licenseID + .\activate-pcore-license.ps1 -licenseID ``` > [!NOTE] diff --git a/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md b/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md index 81d274ab..34ca0399 100644 --- a/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md +++ b/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md @@ -8,7 +8,7 @@ param ( [Parameter (Mandatory= $true)] - [string] $licenseId, + [string] $LicenseId, [Parameter (Mandatory= $false)] [string] $UseInRunbook = $true ) @@ -79,5 +79,5 @@ if ($UseInRunbook){ } $newActivationState = "Activated" -Set-AzResource -ResourceId $licenseId -PropertyObject @{"properties.activationState" = $newActivationState} -Force +Set-AzResource -ResourceId $LicenseId -PropertyObject @{"properties.activationState" = $newActivationState} -Force From e0eb733357ccc3e12a896f30976fd68d435670c7 Mon Sep 17 00:00:00 2001 From: "Alexander (Sasha) Nosov" Date: Wed, 12 Jun 2024 18:02:52 -0700 Subject: [PATCH 13/20] Added instructions --- .../activate-pcore-license/activate-pcore-license.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md b/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md index 34ca0399..10be86a1 100644 --- a/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md +++ b/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md @@ -3,7 +3,8 @@ # # The script accepts the following command line parameters: # -# -licenseID (The specific resource URI) +# -LicenseID (The specific resource URI) +# -UseInRunbook (True to use Azure Runbook) # param ( From a776aecadf8952f329002d4914756d6f6a7874d0 Mon Sep 17 00:00:00 2001 From: "Alexander (Sasha) Nosov" Date: Wed, 12 Jun 2024 18:07:19 -0700 Subject: [PATCH 14/20] Temp change default --- .../activate-pcore-license/activate-pcore-license.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md b/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md index 10be86a1..6000ac8b 100644 --- a/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md +++ b/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md @@ -11,7 +11,7 @@ param ( [Parameter (Mandatory= $true)] [string] $LicenseId, [Parameter (Mandatory= $false)] - [string] $UseInRunbook = $true + [string] $UseInRunbook = $false ) function CheckModule ($m) { From a58f6f5d11e1f8b757fed270e156fffdb31e62a6 Mon Sep 17 00:00:00 2001 From: "Alexander (Sasha) Nosov" Date: Wed, 12 Jun 2024 20:23:00 -0700 Subject: [PATCH 15/20] Fixed logic --- .../activate-pcore-license/activate-pcore-license.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md b/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md index 6000ac8b..2b4ea2e1 100644 --- a/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md +++ b/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md @@ -79,6 +79,7 @@ if ($UseInRunbook){ $requiredModules | Foreach-Object {CheckModule $_} } -$newActivationState = "Activated" -Set-AzResource -ResourceId $LicenseId -PropertyObject @{"properties.activationState" = $newActivationState} -Force +$currentLicense = Get-AzResource -ResourceId $LicenseId +$currentLicense.properties.activationState = "Activated" +$currentLicense | Set-AzResource -Force From 01020de8cb281bb1fd4280f5de2643fdd06f3429 Mon Sep 17 00:00:00 2001 From: "Alexander (Sasha) Nosov" Date: Wed, 12 Jun 2024 23:37:15 -0700 Subject: [PATCH 16/20] Fix parameters --- .../activate-pcore-license/README.md | 6 +----- .../activate-pcore-license/activate-pcore-license.md | 4 ++-- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/README.md b/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/README.md index 1ba9cf28..edc77eeb 100644 --- a/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/README.md +++ b/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/README.md @@ -70,11 +70,7 @@ You can scahedule to run the the command as a runbook. To set it up using Azure curl https://raw.githubusercontent.com/anosov1960/sql-server-samples/master/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md -o activate-pcore-license.ps1 ``` 2. [Create a new automation account](https://ms.portal.azure.com/#create/Microsoft.AutomationAccount) or open an existing one. -1. Select *Run as accounts* in the **Account Settings** group, open the automatically created *Azure Run As Account* and note or copy the Display Name property. You must add this user to all the target subscriptions with at least a *Reader* access role. To collect the Unregistered vCores, the user must be at least a *Contributor*. See [Role assignment portal](https://docs.microsoft.com/en-us/azure/role-based-access-control/role-assignments-portal) for the instructions about role assignments. -1. Select *Credentials* in the **Shared resources** group and create a credential object with the database username and password. The script will use these to connect to the specified database to save the license utilization data. -1. Select *Modules* in the **Shared resources** group and make sure your automation account have the following PowerShell modules installed. If not, add them from the Gallery. - - Az.Accounts - - Az.Resources +1. Select *Run as accounts* in the **Account Settings** group, open the automatically created *Azure Run As Account* and note or copy the Display Name property. 1. Select *Runbooks* in the **Process automation** group and click on *Import a runbook*, select the file you downloaded in Step 1 and click **Create**. 1. When import is completed, click the *Publish* button. 1. From the runbook blade, click on the *Link to schedule* button and select an existing schedule or create a new one with the desired frequency of runs and the expiration time. diff --git a/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md b/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md index 2b4ea2e1..5d400201 100644 --- a/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md +++ b/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md @@ -10,8 +10,8 @@ param ( [Parameter (Mandatory= $true)] [string] $LicenseId, - [Parameter (Mandatory= $false)] - [string] $UseInRunbook = $false + [Parameter (Mandatory= $true)] + [string] $UseInRunbook ) function CheckModule ($m) { From 58a15954a2bdc1f9eaf05303c485e8c177a33330 Mon Sep 17 00:00:00 2001 From: "Alexander (Sasha) Nosov" Date: Wed, 12 Jun 2024 23:41:11 -0700 Subject: [PATCH 17/20] Fix type --- .../activate-pcore-license/activate-pcore-license.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md b/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md index 5d400201..35ca9ccb 100644 --- a/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md +++ b/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md @@ -11,7 +11,7 @@ param ( [Parameter (Mandatory= $true)] [string] $LicenseId, [Parameter (Mandatory= $true)] - [string] $UseInRunbook + [bool] $UseInRunbook ) function CheckModule ($m) { From fa6bd5dbdde4d13fcb744edaf4b8cae9029d06e6 Mon Sep 17 00:00:00 2001 From: "Alexander (Sasha) Nosov" Date: Sat, 15 Jun 2024 20:05:07 -0700 Subject: [PATCH 18/20] Tested version --- .../activate-pcore-license.md | 87 ++++--------------- 1 file changed, 19 insertions(+), 68 deletions(-) diff --git a/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md b/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md index 35ca9ccb..ac230f79 100644 --- a/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md +++ b/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md @@ -1,82 +1,33 @@ -# -# This script performes a scheduled activation of a SQL Server p-core license. -# -# The script accepts the following command line parameters: -# -# -LicenseID (The specific resource URI) -# -UseInRunbook (True to use Azure Runbook) -# +<# + .DESCRIPTION + This runbook activates a SQL Server license using the Managed Identity + The runbook accepts the following parameters: + + -LicenseID (The license resource URI) + + .NOTES + AUTHOR: Alexander (Sasha) Nosov + LASTEDIT: June 15, 2024 +#> param ( [Parameter (Mandatory= $true)] [string] $LicenseId, - [Parameter (Mandatory= $true)] - [bool] $UseInRunbook ) -function CheckModule ($m) { - - # This function ensures that the specified module is imported into the session - # If module is already imported - do nothing - - if (!(Get-Module | Where-Object {$_.Name -eq $m})) { - # If module is not imported, but available on disk then import - if (Get-Module -ListAvailable | Where-Object {$_.Name -eq $m}) { - Import-Module $m - } - else { - - # If module is not imported, not available on disk, but is in online gallery then install and import - if (Find-Module -Name $m | Where-Object {$_.Name -eq $m}) { - Install-Module -Name $m -Force -Verbose -Scope CurrentUser - Import-Module $m - } - else { - - # If module is not imported, not available and not in online gallery then abort - write-host "Module $m not imported, not available and not in online gallery, exiting." - EXIT 1 - } - } - } -} - # # Suppress warnings # Update-AzConfig -DisplayBreakingChangeWarning $false -#The following block is required for runbooks only -if ($UseInRunbook){ - - # Ensures you do not inherit an AzContext in your runbook - Disable-AzContextAutosave –Scope Process - - $connection = Get-AutomationConnection -Name AzureRunAsConnection - - # Wrap authentication in retry logic for transient network failures - $logonAttempt = 0 - while(!($connectionResult) -and ($logonAttempt -le 10)) - { - $LogonAttempt++ - # Logging in to Azure... - $connectionResult = Connect-AzAccount ` - -ServicePrincipal ` - -Tenant $connection.TenantID ` - -ApplicationId $connection.ApplicationID ` - -CertificateThumbprint $connection.CertificateThumbprint - - Start-Sleep -Seconds 5 - } -}else{ - # Ensure that the required modules are imported - # In Runbooks these modules must be added to the automation account manually - - $requiredModules = @( - "Az.Accounts", - "Az.Resources" - ) - $requiredModules | Foreach-Object {CheckModule $_} +# Logging in to Azure..." +try +{ + Connect-AzAccount -Identity +} +catch { + Write-Error -Message $_.Exception + throw $_.Exception } $currentLicense = Get-AzResource -ResourceId $LicenseId From d17352781f22d9c1d9968ef29f385fc8269b4059 Mon Sep 17 00:00:00 2001 From: "Alexander (Sasha) Nosov" Date: Mon, 24 Jun 2024 16:21:09 -0700 Subject: [PATCH 19/20] Updated read.me --- .../activate-pcore-license/README.md | 47 ++----------------- 1 file changed, 3 insertions(+), 44 deletions(-) diff --git a/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/README.md b/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/README.md index edc77eeb..67334113 100644 --- a/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/README.md +++ b/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/README.md @@ -3,7 +3,7 @@ services: Azure SQL platforms: Azure author: anosov1960 ms.author: sashan -ms.date: 06/12/2024 +ms.date: 06/24/2024 --- # Overview @@ -21,47 +21,7 @@ Your RBAC role must include the following permissions: - Microsoft.Resources/subscriptions/resourceGroups/read - Microsoft.Support/supporttickets/write -# Launching the script - -The script accepts the following command line parameters: - -| **Parameter**                                         | **Value**                                                                       | **Description** | -|:--|:--|:--| -|-LicenseId| License resource URI | -|-UseInRunbook| \$True or \$False (default) | Optional: must be $True when executed as a Runbook| - - -## Example - -The following command activate the license - -```PowerShell -.\activate-pcore-license.ps1 -LicenseID -``` - -# Running the script using Cloud Shell - -To run the script in the Cloud Shell, use the following steps: - -1. Launch the [Cloud Shell](https://shell.azure.com/). For details, read [PowerShell in Cloud Shell](https://aka.ms/pscloudshell/docs). - -2. Upload the script to the shell using the following command: - - ```console - curl https://raw.githubusercontent.com/anosov1960/sql-server-samples/master/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md -o activate-pcore-license.ps1 - ``` - -3. Run the script with a set of parameters that reflect your desired configuration. - - ```console - .\activate-pcore-license.ps1 -licenseID - ``` - -> [!NOTE] -> - To paste the commands into the shell, use `Ctrl-Shift-V` on Windows or `Cmd-v` on MacOS. -> - The `curl` command will copy the script directly to the home folder associated with your Cloud Shell session. - -# Running the script as a Azure runbook +# Creating a Azure runbook You can scahedule to run the the command as a runbook. To set it up using Azure Portal, follow these steps. @@ -73,10 +33,9 @@ curl https://raw.githubusercontent.com/anosov1960/sql-server-samples/master/samp 1. Select *Run as accounts* in the **Account Settings** group, open the automatically created *Azure Run As Account* and note or copy the Display Name property. 1. Select *Runbooks* in the **Process automation** group and click on *Import a runbook*, select the file you downloaded in Step 1 and click **Create**. 1. When import is completed, click the *Publish* button. -1. From the runbook blade, click on the *Link to schedule* button and select an existing schedule or create a new one with the desired frequency of runs and the expiration time. +1. From the runbook blade, click on the *Link to schedule* button and select an existing schedule or create a new one withand spesify the designed launch time. 1. Click on *Parameters and run settings* and specify the following parameters: - LICENSEID. Put in teh resourec URI - - USEINRUNBOOKS. Select True to activate the logic that authenticates the runbook using the *Azure Run As Account*. 1. Click **OK** to link to the schedule and **OK** again to create the job. For more information about the runbooks, see the [Runbook tutorial](https://docs.microsoft.com/en-us/azure/automation/learn/automation-tutorial-runbook-textual-powershell) From ab587b593f58b4fad4ec1cb92f2d873cd84c6c66 Mon Sep 17 00:00:00 2001 From: "Alexander (Sasha) Nosov" Date: Mon, 24 Jun 2024 16:24:24 -0700 Subject: [PATCH 20/20] Updated URL for curl --- .../activate-pcore-license/README.md | 2 +- .../activate-pcore-license/activate-pcore-license.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/README.md b/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/README.md index 67334113..4fb20a44 100644 --- a/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/README.md +++ b/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/README.md @@ -27,7 +27,7 @@ You can scahedule to run the the command as a runbook. To set it up using Azure 1. Open a command shell on your device and run this command. It will copy the script to your local folder. ```console -curl https://raw.githubusercontent.com/anosov1960/sql-server-samples/master/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md -o activate-pcore-license.ps1 +curl https://raw.githubusercontent.com/microsoft/sql-server-samples/master/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md -o activate-pcore-license.ps1 ``` 2. [Create a new automation account](https://ms.portal.azure.com/#create/Microsoft.AutomationAccount) or open an existing one. 1. Select *Run as accounts* in the **Account Settings** group, open the automatically created *Azure Run As Account* and note or copy the Display Name property. diff --git a/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md b/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md index ac230f79..c0fa4e93 100644 --- a/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md +++ b/samples/manage/azure-arc-enabled-sql-server/activate-pcore-license/activate-pcore-license.md @@ -7,7 +7,7 @@ .NOTES AUTHOR: Alexander (Sasha) Nosov - LASTEDIT: June 15, 2024 + LASTEDIT: June 24, 2024 #> param (