diff --git a/03-Azure/01-02 Data/02-SQL_Modernization/labautomation/infra/main-shared.bicep b/03-Azure/01-02 Data/02-SQL_Modernization/labautomation/infra/main-shared.bicep
index fff8c9312..0ed48281e 100644
--- a/03-Azure/01-02 Data/02-SQL_Modernization/labautomation/infra/main-shared.bicep
+++ b/03-Azure/01-02 Data/02-SQL_Modernization/labautomation/infra/main-shared.bicep
@@ -90,6 +90,16 @@ module bastion 'modules/bastion.bicep' = {
}
}
+module logAnalytics 'modules/loganalytics.bicep' = {
+ name: 'loganalytics'
+ scope: resourceGroup
+ params: {
+ location: location
+ workspaceName: 'sqlhack-loganalytics'
+ retentionInDays: 30
+ }
+}
+
module legacySqlVm 'modules/sql2016-vm.bicep' = {
name: '${legacySQLName}-vm'
scope: resourceGroup
diff --git a/03-Azure/01-02 Data/02-SQL_Modernization/labautomation/infra/modules/loganalytics.bicep b/03-Azure/01-02 Data/02-SQL_Modernization/labautomation/infra/modules/loganalytics.bicep
new file mode 100644
index 000000000..dd5ab9be9
--- /dev/null
+++ b/03-Azure/01-02 Data/02-SQL_Modernization/labautomation/infra/modules/loganalytics.bicep
@@ -0,0 +1,28 @@
+@description('Name of the Log Analytics Workspace')
+param workspaceName string
+
+@description('Azure Region')
+param location string = resourceGroup().location
+
+@description('Retention in days')
+param retentionInDays int = 30
+
+resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2023-09-01' = {
+ name: workspaceName
+ location: location
+
+ properties: {
+ retentionInDays: retentionInDays
+ features: {
+ searchVersion: 1
+ legacy: 0
+ enableLogAccessUsingOnlyResourcePermissions: true
+ }
+ sku: {
+ name: 'PerGB2018'
+ }
+ }
+}
+
+output workspaceId string = logAnalyticsWorkspace.id
+output workspaceCustomerId string = logAnalyticsWorkspace.properties.customerId
diff --git a/03-Azure/01-02 Data/02-SQL_Modernization/labautomation/infra/modules/team-vm-cse.bicep b/03-Azure/01-02 Data/02-SQL_Modernization/labautomation/infra/modules/team-vm-cse.bicep
index 565ef49d8..1583be22a 100644
--- a/03-Azure/01-02 Data/02-SQL_Modernization/labautomation/infra/modules/team-vm-cse.bicep
+++ b/03-Azure/01-02 Data/02-SQL_Modernization/labautomation/infra/modules/team-vm-cse.bicep
@@ -39,6 +39,7 @@ resource ConfigureTeamMachine 'Microsoft.Compute/virtualMachines/extensions@2024
'${repoBaseURL}/scripts/Download-Samples.ps1'
'${repoBaseURL}/scripts/bootstrap-teamvm.ps1'
'${repoBaseURL}/scripts/Configure-Teams-Shortcuts.ps1'
+ '${repoBaseURL}/scripts/Configure-TeamVM.ps1'
'${repoBaseURL}/scripts/Restore-TeamDatabases.ps1'
'${repoBaseURL}/scripts/Configure-legacySQL-DB.ps1'
'${repoBaseURL}/scripts/Configure-SQLMI-Sysadmins.ps1'
diff --git a/03-Azure/01-02 Data/02-SQL_Modernization/labautomation/scripts/Configure-SQLMI-Sysadmins.ps1 b/03-Azure/01-02 Data/02-SQL_Modernization/labautomation/scripts/Configure-SQLMI-Sysadmins.ps1
index 2f3fed987..2a2775d93 100644
--- a/03-Azure/01-02 Data/02-SQL_Modernization/labautomation/scripts/Configure-SQLMI-Sysadmins.ps1
+++ b/03-Azure/01-02 Data/02-SQL_Modernization/labautomation/scripts/Configure-SQLMI-Sysadmins.ps1
@@ -27,9 +27,6 @@ END
ALTER SERVER ROLE [sysadmin] ADD MEMBER [$sqlMiSysadminUser];
"@
-[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo") | Out-Null
-[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | Out-Null
-
$connectionString = "Data Source=$ManagedInstanceServer;Initial Catalog=master;TrustServerCertificate=True;"
$Connection = New-Object System.Data.SqlClient.SqlConnection($connectionString)
[System.Security.SecureString]$SQLPwd = $sqlpassword | ConvertTo-SecureString -AsPlainText -Force
@@ -37,16 +34,21 @@ $SQLPwd.MakeReadOnly()
$cred = New-Object System.Data.SqlClient.SqlCredential($sqlusername,$SQLPwd)
$Connection.credential = $cred
-# 5. SMO-Serververbindung initialisieren
-$serverConnection = New-Object Microsoft.SqlServer.Management.Common.ServerConnection($Connection)
-$server = New-Object Microsoft.SqlServer.Management.Smo.Server($serverConnection)
-
try {
- # Ausführung des Skripts inkl. GO-Trenner
- [void]$server.ConnectionContext.ExecuteNonQuery($ConfigureSql)
- #Write-Host "Skript erfolgreich auf SQL MI ausgeführt." -ForegroundColor Green
+ $Connection.open()
+
+ $command = New-Object system.Data.SqlClient.SqlCommand($Connection)
+ $command.Connection = $Connection
+ $command.CommandTimeout = $QueryTimeout
+
+ $command.CommandText = $ConfigureSql
+ $result = $command.ExecuteNonQuery()
+ #$result = $command.ExecuteReader()
+ #$table = New-Object System.Data.DataTable
+ #$table.Load($result)
}
catch {
+ Write-Host $result
$ErrorString = $_ | format-list -force | Out-String
Write-Error "ERR: $ErrorString"
}
diff --git a/03-Azure/01-02 Data/02-SQL_Modernization/labautomation/scripts/Configure-TeamVM.ps1 b/03-Azure/01-02 Data/02-SQL_Modernization/labautomation/scripts/Configure-TeamVM.ps1
new file mode 100644
index 000000000..b4021e635
--- /dev/null
+++ b/03-Azure/01-02 Data/02-SQL_Modernization/labautomation/scripts/Configure-TeamVM.ps1
@@ -0,0 +1,160 @@
+# Disable Privacy Experience / First Sign-In Experience
+# Run as Administrator
+
+$ErrorActionPreference = 'Stop'
+
+$logPath = 'C:\Windows\Temp\Configure-TeamVM.log'
+Start-Transcript -Path $logPath -Append
+
+$policies = @(
+ "HKLM:\SOFTWARE\Policies\Microsoft\Windows\OOBE",
+ "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CloudContent",
+ "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection",
+ "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\OOBE"
+)
+
+foreach ($path in $policies)
+{
+ if (-not (Test-Path $path))
+ {
+ New-Item -Path $path -Force | Out-Null
+ }
+}
+
+# Skip privacy experience
+New-ItemProperty `
+ -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\OOBE" `
+ -Name "DisablePrivacyExperience" `
+ -Value 1 `
+ -PropertyType DWord `
+ -Force | Out-Null
+
+# Disable consumer experiences
+New-ItemProperty `
+ -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CloudContent" `
+ -Name "DisableWindowsConsumerFeatures" `
+ -Value 1 `
+ -PropertyType DWord `
+ -Force | Out-Null
+
+# Required diagnostics only
+New-ItemProperty `
+ -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection" `
+ -Name "AllowTelemetry" `
+ -Value 1 `
+ -PropertyType DWord `
+ -Force | Out-Null
+
+# Skip user privacy consent prompts
+New-ItemProperty `
+ -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\OOBE" `
+ -Name "PrivacyConsentStatus" `
+ -Value 1 `
+ -PropertyType DWord `
+ -Force | Out-Null
+
+# Disable "Let's finish setting up your device"
+New-ItemProperty `
+ -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CloudContent" `
+ -Name "DisableSoftLanding" `
+ -Value 1 `
+ -PropertyType DWord `
+ -Force | Out-Null
+
+# Disable welcome experience
+New-ItemProperty `
+ -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CloudContent" `
+ -Name "DisableWindowsSpotlightWindowsWelcomeExperience" `
+ -Value 1 `
+ -PropertyType DWord `
+ -Force | Out-Null
+
+$cdmPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CloudContent"
+
+New-ItemProperty -Path $cdmPath `
+ -Name "DisableTailoredExperiencesWithDiagnosticData" `
+ -Value 1 `
+ -PropertyType DWord `
+ -Force
+
+New-ItemProperty -Path $cdmPath `
+ -Name "DisableThirdPartySuggestions" `
+ -Value 1 `
+ -PropertyType DWord `
+ -Force
+
+New-ItemProperty -Path $cdmPath `
+ -Name "DisableConsumerAccountStateContent" `
+ -Value 1 `
+ -PropertyType DWord `
+ -Force
+
+Write-Output "Privacy Experience disabled."
+
+# Disable Microsoft Edge First Run Experience
+# Run as Administrator
+
+$edgePolicyPath = "HKLM:\SOFTWARE\Policies\Microsoft\Edge"
+
+if (-not (Test-Path $edgePolicyPath))
+{
+ New-Item -Path $edgePolicyPath -Force | Out-Null
+}
+
+# Disable First Run Experience entirely
+New-ItemProperty `
+ -Path $edgePolicyPath `
+ -Name "HideFirstRunExperience" `
+ -Value 1 `
+ -PropertyType DWord `
+ -Force | Out-Null
+
+# Disable browser sign-in prompts
+New-ItemProperty `
+ -Path $edgePolicyPath `
+ -Name "BrowserSignin" `
+ -Value 0 `
+ -PropertyType DWord `
+ -Force | Out-Null
+
+# Disable importing browser data prompts
+New-ItemProperty `
+ -Path $edgePolicyPath `
+ -Name "ImportOnEachLaunch" `
+ -Value 0 `
+ -PropertyType DWord `
+ -Force | Out-Null
+
+# Disable profile creation prompts
+New-ItemProperty `
+ -Path $edgePolicyPath `
+ -Name "ImplicitSignInEnabled" `
+ -Value 0 `
+ -PropertyType DWord `
+ -Force | Out-Null
+
+# Optional: Disable Edge promotional dialogs
+New-ItemProperty `
+ -Path $edgePolicyPath `
+ -Name "ShowRecommendationsEnabled" `
+ -Value 0 `
+ -PropertyType DWord `
+ -Force | Out-Null
+
+Write-Output "Edge First Run Experience disabled."
+
+New-ItemProperty `
+ -Path $edgePolicyPath `
+ -Name "PromotionalTabsEnabled" `
+ -Value 0 `
+ -PropertyType DWord `
+ -Force
+
+New-ItemProperty `
+ -Path $edgePolicyPath `
+ -Name "EdgeWelcomePageEnabled" `
+ -Value 0 `
+ -PropertyType DWord `
+ -Force
+
+Stop-Transcript
\ No newline at end of file
diff --git a/03-Azure/01-02 Data/02-SQL_Modernization/labautomation/scripts/bootstrap-teamvm.ps1 b/03-Azure/01-02 Data/02-SQL_Modernization/labautomation/scripts/bootstrap-teamvm.ps1
index 7dbc860f6..3de8e7e21 100644
--- a/03-Azure/01-02 Data/02-SQL_Modernization/labautomation/scripts/bootstrap-teamvm.ps1
+++ b/03-Azure/01-02 Data/02-SQL_Modernization/labautomation/scripts/bootstrap-teamvm.ps1
@@ -21,6 +21,9 @@ Start-Transcript -Path $logPath -Append
Write-Host "Configuring TEAM VM..."
+Write-Host "Configure Team VM (Privacy Experience / OOBE Privacy Consent Page) ..."
+& .\Configure-TeamVM.ps1
+
##Not working with Bastion, so we will not set wallpaper for now. If you want to set wallpaper, you can run the following command after you RDP into the VM.
Write-Host "Configure Team Wallpaper..."
& .\Configure-TeamWallpaper.ps1 -WallpaperUri $WallpaperUri -TeamName $TeamName
diff --git a/03-Azure/01-02 Data/02-SQL_Modernization/labautomation/shared-deploy-lab.ps1 b/03-Azure/01-02 Data/02-SQL_Modernization/labautomation/shared-deploy-lab.ps1
index e5324b91c..91b4f7dd3 100644
--- a/03-Azure/01-02 Data/02-SQL_Modernization/labautomation/shared-deploy-lab.ps1
+++ b/03-Azure/01-02 Data/02-SQL_Modernization/labautomation/shared-deploy-lab.ps1
@@ -35,7 +35,9 @@ $requiredProviders = @(
"Microsoft.Storage",
"Microsoft.Sql",
"Microsoft.SqlVirtualMachine",
- "Microsoft.DevTestLab"
+ "Microsoft.DevTestLab",
+ "Microsoft.OperationalInsights",
+ "Microsoft.Insights"
)
foreach($provider in $requiredProviders) {
$state = (Get-AzResourceProvider -ProviderNamespace $provider -ErrorAction SilentlyContinue | Select-Object -First 1).RegistrationState
@@ -240,6 +242,74 @@ if (-not $found)
throw "Expected Entra ID Admin was not configured within 2 minutes."
}
+#Configure Log Settings for SQLMI
+$ErrorOccurred = $false
+try {
+
+ $databaseName = "TenantCRM"
+ $workspaceName = "sqlhack-loganalytics"
+ $workspace = Get-AzOperationalInsightsWorkspace -ResourceGroupName $sharedResourceGroup -Name $WorkspaceName -ErrorAction Stop
+ $workspaceResourceId = $workspace.ResourceId
+
+ #----------------------------------------------------------
+ # Managed Instance
+ #----------------------------------------------------------
+ $miCategories = Get-AzDiagnosticSettingCategory -ResourceId $managedInstance.Id
+ $miLogs = @()
+ foreach ($category in $miCategories)
+ {
+ if ($category.CategoryType -eq "Logs")
+ {
+ $miLogs += New-AzDiagnosticSettingLogSettingsObject -Enabled $true -Category $category.Name
+ }
+ }
+ $miMetrics = @()
+ foreach ($category in $miCategories)
+ {
+ if ($category.CategoryType -eq "Metrics")
+ {
+ $miMetrics += New-AzDiagnosticSettingMetricSettingsObject -Enabled $true -Category $category.Name
+ }
+ }
+ New-AzDiagnosticSetting -Name "sqlmi-alllogs" -ResourceId $managedInstance.Id -WorkspaceId $workspaceResourceId -Log $miLogs -Metric $miMetrics -ErrorAction Stop
+
+ #----------------------------------------------------------
+ # Datenbank TENANTCRM
+ #----------------------------------------------------------
+ $db = Get-AzResource -ResourceType "Microsoft.Sql/managedInstances/databases" | Where-Object { $_.Name -eq "$managedInstanceName/$databaseName" }
+ if (-not $db)
+ {
+ throw "Datenbank $databaseName wurde nicht gefunden."
+ }
+ $dbCategories = Get-AzDiagnosticSettingCategory -ResourceId $db.ResourceId
+ $dbLogs = @()
+ foreach ($category in $dbCategories)
+ {
+ if ($category.CategoryType -eq "Logs")
+ {
+ $dbLogs += New-AzDiagnosticSettingLogSettingsObject -Enabled $true -Category $category.Name
+ }
+ }
+ $dbMetrics = @()
+ foreach ($category in $dbCategories)
+ {
+ if ($category.CategoryType -eq "Metrics")
+ {
+ $dbMetrics += New-AzDiagnosticSettingMetricSettingsObject -Enabled $true -Category $category.Name
+ }
+ }
+ New-AzDiagnosticSetting -Name "$databaseName-alllogs" -ResourceId $db.ResourceId -WorkspaceId $workspaceResourceId -Log $dbLogs -Metric $dbMetrics -ErrorAction Stop
+}
+catch {
+ Write-Host "Could not configure log settings."
+ $ErrorString = $_ | format-list -force | Out-String
+ Write-Error "ERR: $ErrorString"
+ $ErrorOccurred = $true
+}
+if ($ErrorOccurred) {
+ throw "Errors occurred during log settings configuration. Please check the logs for details."
+}
+
$rg = Get-AzResourceGroup -Name $sharedResourceGroup -ErrorAction SilentlyContinue
$tags = $rg.Tags
$tags["microhack-shared-deployment"] = "Succeeded"
diff --git a/03-Azure/01-02 Data/02-SQL_Modernization/walkthrough/challenge-01/solution-01.md b/03-Azure/01-02 Data/02-SQL_Modernization/walkthrough/challenge-01/solution-01.md
index 29a03f56e..9985c6175 100644
--- a/03-Azure/01-02 Data/02-SQL_Modernization/walkthrough/challenge-01/solution-01.md
+++ b/03-Azure/01-02 Data/02-SQL_Modernization/walkthrough/challenge-01/solution-01.md
@@ -24,9 +24,7 @@

-
# Generic Migration Content
-
| **Narrative** | **Notes** |
|:-----|:-------|
| *Notes for outside of the workshop:* *Familiarise yourself with the new Microsoft migration capabilities with SQL Server Management Studio and Migration options by using Arc* | Migrate SQL Server to Azure SQL (SSMS): [https://learn.microsoft.com/en-us/ssms/migrate/migrate-sql-server-azure-sql?tabs=sql-standard](https://learn.microsoft.com/en-us/ssms/migrate/migrate-sql-server-azure-sql?tabs=sql-standard) This article covers the migration from Arc-Enabled SQL Server instances and Non Arc-Enabled SQL Server instances. For Non Arc-Enabled SQL Server instances there will be no performance-based sizing recommendation. |
@@ -34,7 +32,7 @@
# Connect to your Win11 VM
|**Narrative**| **Screenshot**| **Notes**|
|:------------|:--------------|:---------|
-|Connect to the Azure Portal with and password . In the Azure Portal open your Win11 VM . Connect to the VM with Bastion with the following VM connection credentials Username and password . Please make sure to select the correct keyboard layout.|| |
+|Connect to the Azure Portal with and password .
In the Azure Portal open your Win11 VM .
Connect to the VM with Bastion with the following VM connection credentials Username and password .
Please make sure to select the correct keyboard language.|| |